mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
mirrors: Fix checks for mirror/raid/pvmove LVs.
Try to enforce consistent macro usage along these lines: lv_is_mirror - mirror that uses the original dm-raid1 implementation (segment type "mirror") lv_is_mirror_type - also includes internal mirror image and log LVs lv_is_raid - raid volume that uses the new dm-raid implementation (segment type "raid") lv_is_raid_type - also includes internal raid image / log / metadata LVs lv_is_mirrored - LV is mirrored using either kernel implementation (excludes non-mirror modes like raid5 etc.) lv_is_pvmove - internal pvmove volume
This commit is contained in:
parent
829e5a4037
commit
979be63f25
@ -1,5 +1,8 @@
|
||||
Version 2.02.112 -
|
||||
=====================================
|
||||
Review internal checks for mirror/raid/pvmove volumes.
|
||||
Track mirror segment type with separate MIRROR flag.
|
||||
Fix cmirror endian conversions.
|
||||
Introduce lv_is_pvmove/locked/converting/merging macros.
|
||||
Avoid leaving linear logical volume when thin pool creation fails.
|
||||
Demote an error to a warning when devices known to lvmetad are filtered out.
|
||||
|
@ -2917,7 +2917,7 @@ static int _tree_action(struct dev_manager *dm, struct logical_volume *lv,
|
||||
break;
|
||||
case SUSPEND:
|
||||
dm_tree_skip_lockfs(root);
|
||||
if (!dm->flush_required && !seg_is_raid(first_seg(lv)) && lv_is_mirrored(lv) && !lv_is_pvmove(lv))
|
||||
if (!dm->flush_required && lv_is_mirror(lv) && !lv_is_pvmove(lv))
|
||||
dm_tree_use_no_flush_suspend(root);
|
||||
/* Fall through */
|
||||
case SUSPEND_WITH_LOCKFS:
|
||||
|
@ -67,6 +67,7 @@ static const struct flag _lv_flags[] = {
|
||||
{RAID, NULL, 0},
|
||||
{RAID_META, NULL, 0},
|
||||
{RAID_IMAGE, NULL, 0},
|
||||
{MIRROR, NULL, 0},
|
||||
{MIRROR_IMAGE, NULL, 0},
|
||||
{MIRROR_LOG, NULL, 0},
|
||||
{MIRRORED, NULL, 0},
|
||||
|
@ -386,6 +386,9 @@ static int _read_segment(struct logical_volume *lv, const struct dm_config_node
|
||||
*/
|
||||
_insert_segment(lv, seg);
|
||||
|
||||
if (seg_is_mirror(seg))
|
||||
lv->status |= MIRROR;
|
||||
|
||||
if (seg_is_mirrored(seg))
|
||||
lv->status |= MIRRORED;
|
||||
|
||||
|
@ -361,7 +361,7 @@ char *lv_move_pv_dup(struct dm_pool *mem, const struct logical_volume *lv)
|
||||
if (seg->status & PVMOVE) {
|
||||
if (seg_type(seg, 0) == AREA_LV) { /* atomic pvmove */
|
||||
mimage0_lv = seg_lv(seg, 0);
|
||||
if (!lv_is_mirrored(mimage0_lv)) {
|
||||
if (!lv_is_mirror_image(mimage0_lv)) {
|
||||
log_error(INTERNAL_ERROR
|
||||
"Bad pvmove structure");
|
||||
return NULL;
|
||||
@ -648,7 +648,7 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
|
||||
repstr[0] = 'C';
|
||||
else if (lv_is_raid(lv))
|
||||
repstr[0] = (lv->status & LV_NOTSYNCED) ? 'R' : 'r';
|
||||
else if (lv_is_mirrored(lv))
|
||||
else if (lv_is_mirror(lv))
|
||||
repstr[0] = (lv->status & LV_NOTSYNCED) ? 'M' : 'm';
|
||||
else if (lv_is_thin_volume(lv))
|
||||
repstr[0] = lv_is_merging_origin(lv) ?
|
||||
|
@ -231,6 +231,10 @@ static int _lv_layout_and_role_raid(struct dm_pool *mem,
|
||||
if (!str_list_add_no_dup_check(mem, role, _lv_type_names[LV_TYPE_RAID]) ||
|
||||
!str_list_add_no_dup_check(mem, role, _lv_type_names[LV_TYPE_METADATA]))
|
||||
goto_bad;
|
||||
} else if (lv_is_pvmove(lv)) {
|
||||
if (!str_list_add_no_dup_check(mem, role, _lv_type_names[LV_TYPE_PVMOVE]) ||
|
||||
!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_RAID]))
|
||||
goto_bad;
|
||||
} else
|
||||
top_level = 1;
|
||||
|
||||
@ -464,7 +468,7 @@ int lv_layout_and_role(struct dm_pool *mem, const struct logical_volume *lv,
|
||||
}
|
||||
|
||||
/* Mirrors and related */
|
||||
if ((lv_is_mirror_type(lv) || lv_is_pvmove(lv)) && !lv_is_raid(lv) &&
|
||||
if ((lv_is_mirror_type(lv) || lv_is_pvmove(lv)) &&
|
||||
!_lv_layout_and_role_mirror(mem, lv, *layout, *role, &public_lv))
|
||||
goto_bad;
|
||||
|
||||
@ -985,6 +989,12 @@ struct lv_segment *alloc_lv_segment(const struct segment_type *segtype,
|
||||
if (log_lv && !attach_mirror_log(seg, log_lv))
|
||||
return_NULL;
|
||||
|
||||
if (segtype_is_mirror(segtype))
|
||||
lv->status |= MIRROR;
|
||||
|
||||
if (segtype_is_mirrored(segtype))
|
||||
lv->status |= MIRRORED;
|
||||
|
||||
return seg;
|
||||
}
|
||||
|
||||
@ -1347,9 +1357,10 @@ int replace_lv_with_error_segment(struct logical_volume *lv)
|
||||
* an error segment, we should also clear any flags
|
||||
* that suggest it is anything other than "error".
|
||||
*/
|
||||
lv->status &= ~(MIRRORED|PVMOVE|LOCKED);
|
||||
/* FIXME Check for other flags that need removing */
|
||||
lv->status &= ~(MIRROR|MIRRORED|PVMOVE|LOCKED);
|
||||
|
||||
/* FIXME: Should we bug if we find a log_lv attached? */
|
||||
/* FIXME Check for any attached LVs that will become orphans e.g. mirror logs */
|
||||
|
||||
if (!lv_add_virtual_segment(lv, 0, len, get_segtype_from_string(lv->vg->cmd, "error"), NULL))
|
||||
return_0;
|
||||
@ -1858,9 +1869,6 @@ static int _setup_alloced_segment(struct logical_volume *lv, uint64_t status,
|
||||
lv->le_count += extents;
|
||||
lv->size += (uint64_t) extents *lv->vg->extent_size;
|
||||
|
||||
if (segtype_is_mirrored(segtype))
|
||||
lv->status |= MIRRORED;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -6723,8 +6731,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (lv_is_mirror_type(org) &&
|
||||
!seg_is_raid(first_seg(org))) {
|
||||
if (lv_is_mirror_type(org)) {
|
||||
log_warn("WARNING: Snapshots of mirrors can deadlock under rare device failures.");
|
||||
log_warn("WARNING: Consider using the raid1 mirror type to avoid this.");
|
||||
log_warn("WARNING: See global/mirror_segtype_default in lvm.conf.");
|
||||
|
@ -67,6 +67,7 @@
|
||||
#define LOCKED UINT64_C(0x0000000000004000) /* LV */
|
||||
#define MIRRORED UINT64_C(0x0000000000008000) /* LV - internal use only */
|
||||
//#define VIRTUAL UINT64_C(0x0000000000010000) /* LV - internal use only */
|
||||
#define MIRROR UINT64_C(0x0002000000000000) /* LV - Internal use only */
|
||||
#define MIRROR_LOG UINT64_C(0x0000000000020000) /* LV - Internal use only */
|
||||
#define MIRROR_IMAGE UINT64_C(0x0000000000040000) /* LV - Internal use only */
|
||||
|
||||
@ -115,7 +116,7 @@
|
||||
#define CACHE_POOL_METADATA UINT64_C(0x0000800000000000) /* LV - Internal use only */
|
||||
#define CACHE UINT64_C(0x0001000000000000) /* LV - Internal use only */
|
||||
|
||||
/* Next unused flag: UINT64_C(0x0002000000000000) */
|
||||
/* Next unused flag: UINT64_C(0x0004000000000000) */
|
||||
|
||||
/* Format features flags */
|
||||
#define FMT_SEGMENTS 0x00000001U /* Arbitrary segment params? */
|
||||
@ -181,7 +182,8 @@
|
||||
|
||||
#define lv_is_mirror_image(lv) (((lv)->status & MIRROR_IMAGE) ? 1 : 0)
|
||||
#define lv_is_mirror_log(lv) (((lv)->status & MIRROR_LOG) ? 1 : 0)
|
||||
#define lv_is_mirror_type(lv) (((lv)->status & (MIRROR_LOG | MIRROR_IMAGE | MIRRORED)) ? 1 : 0)
|
||||
#define lv_is_mirror(lv) (((lv)->status & MIRROR) ? 1 : 0)
|
||||
#define lv_is_mirror_type(lv) (((lv)->status & (MIRROR | MIRROR_LOG | MIRROR_IMAGE)) ? 1 : 0)
|
||||
|
||||
#define lv_is_pvmove(lv) (((lv)->status & PVMOVE) ? 1 : 0)
|
||||
|
||||
|
@ -742,6 +742,7 @@ static int _split_mirror_images(struct logical_volume *lv,
|
||||
detached_log_lv = detach_mirror_log(mirrored_seg);
|
||||
if (!remove_layer_from_lv(lv, sub_lv))
|
||||
return_0;
|
||||
lv->status &= ~MIRROR;
|
||||
lv->status &= ~MIRRORED;
|
||||
lv->status &= ~LV_NOTSYNCED;
|
||||
}
|
||||
@ -941,6 +942,7 @@ static int _remove_mirror_images(struct logical_volume *lv,
|
||||
* mirror. Fix up the flags if we only have one image left.
|
||||
*/
|
||||
if (lv_mirror_count(lv) == 1) {
|
||||
lv->status &= ~MIRROR;
|
||||
lv->status &= ~MIRRORED;
|
||||
lv->status &= ~LV_NOTSYNCED;
|
||||
}
|
||||
@ -957,6 +959,7 @@ static int _remove_mirror_images(struct logical_volume *lv,
|
||||
/* All mirror images are gone.
|
||||
* It can happen for vgreduce --removemissing. */
|
||||
detached_log_lv = detach_mirror_log(mirrored_seg);
|
||||
lv->status &= ~MIRROR;
|
||||
lv->status &= ~MIRRORED;
|
||||
lv->status &= ~LV_NOTSYNCED;
|
||||
if (!replace_lv_with_error_segment(lv))
|
||||
@ -1502,9 +1505,10 @@ const char *get_pvmove_pvname_from_lv_mirr(struct logical_volume *lv_mirr)
|
||||
dm_list_iterate_items(seg, &lv_mirr->segments) {
|
||||
if (!seg_is_mirrored(seg))
|
||||
continue;
|
||||
if (seg_type(seg, 0) != AREA_PV)
|
||||
continue;
|
||||
if (seg_type(seg, 0) == AREA_PV)
|
||||
return dev_name(seg_dev(seg, 0));
|
||||
if (seg_type(seg, 0) == AREA_LV)
|
||||
return dev_name(seg_dev(first_seg(seg_lv(seg, 0)), 0));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -1403,6 +1403,7 @@ static int _convert_mirror_to_raid1(struct logical_volume *lv,
|
||||
|
||||
log_debug_metadata("Setting new segtype for %s", lv->name);
|
||||
seg->segtype = new_segtype;
|
||||
lv->status &= ~MIRROR;
|
||||
lv->status &= ~MIRRORED;
|
||||
lv->status |= RAID;
|
||||
seg->status |= RAID;
|
||||
|
@ -43,11 +43,13 @@ struct dev_manager;
|
||||
#define SEG_THIN_VOLUME 0x00001000U
|
||||
#define SEG_CACHE 0x00002000U
|
||||
#define SEG_CACHE_POOL 0x00004000U
|
||||
#define SEG_MIRROR 0x00008000U
|
||||
#define SEG_UNKNOWN 0x80000000U
|
||||
|
||||
#define segtype_is_cache(segtype) ((segtype)->flags & SEG_CACHE ? 1 : 0)
|
||||
#define segtype_is_cache_pool(segtype) ((segtype)->flags & SEG_CACHE_POOL ? 1 : 0)
|
||||
#define segtype_is_mirrored(segtype) ((segtype)->flags & SEG_AREAS_MIRRORED ? 1 : 0)
|
||||
#define segtype_is_mirror(segtype) ((segtype)->flags & SEG_MIRROR ? 1 : 0)
|
||||
#define segtype_is_pool(segtype) ((segtype)->flags & (SEG_CACHE_POOL | SEG_THIN_POOL) ? 1 : 0)
|
||||
#define segtype_is_raid(segtype) ((segtype)->flags & SEG_RAID ? 1 : 0)
|
||||
#define segtype_is_striped(segtype) ((segtype)->flags & SEG_AREAS_STRIPED ? 1 : 0)
|
||||
@ -59,6 +61,7 @@ struct dev_manager;
|
||||
#define seg_is_cache(seg) segtype_is_cache((seg)->segtype)
|
||||
#define seg_is_cache_pool(seg) segtype_is_cache_pool((seg)->segtype)
|
||||
#define seg_is_linear(seg) (seg_is_striped(seg) && ((seg)->area_count == 1))
|
||||
#define seg_is_mirror(seg) segtype_is_mirror((seg)->segtype)
|
||||
#define seg_is_mirrored(seg) segtype_is_mirrored((seg)->segtype)
|
||||
#define seg_is_pool(seg) segtype_is_pool((seg)->segtype)
|
||||
#define seg_is_raid(seg) segtype_is_raid((seg)->segtype)
|
||||
|
@ -628,7 +628,7 @@ struct segment_type *init_segtype(struct cmd_context *cmd)
|
||||
segtype->ops = &_mirrored_ops;
|
||||
segtype->name = "mirror";
|
||||
segtype->private = NULL;
|
||||
segtype->flags = SEG_AREAS_MIRRORED;
|
||||
segtype->flags = SEG_MIRROR | SEG_AREAS_MIRRORED;
|
||||
|
||||
#ifdef DEVMAPPER_SUPPORT
|
||||
# ifdef DMEVENTD
|
||||
|
@ -1042,8 +1042,7 @@ static int _copypercent_disp(struct dm_report *rh,
|
||||
dm_percent_t percent = DM_PERCENT_INVALID;
|
||||
|
||||
if (((lv_is_raid(lv) && lv_raid_percent(lv, &percent)) ||
|
||||
((lv_is_pvmove(lv) || lv_is_mirrored(lv)) &&
|
||||
lv_mirror_percent(lv->vg->cmd, lv, 0, &percent, NULL))) &&
|
||||
(lv_is_mirror(lv) && lv_mirror_percent(lv->vg->cmd, lv, 0, &percent, NULL))) &&
|
||||
(percent != DM_PERCENT_INVALID)) {
|
||||
percent = copy_percent(lv);
|
||||
return dm_report_field_percent(rh, field, &percent);
|
||||
|
@ -287,7 +287,7 @@ static int lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
|
||||
dm_list_init(&device_list);
|
||||
|
||||
if (!lv_is_mirrored(lv) && !seg_is_raid(seg)) {
|
||||
if (!seg_is_mirror(seg) && !seg_is_raid(seg)) {
|
||||
log_error("Unable to resync %s. It is not RAID or mirrored.",
|
||||
lv->name);
|
||||
return 0;
|
||||
|
@ -325,7 +325,7 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
|
||||
*
|
||||
* Allow clustered mirror, but not raid mirror.
|
||||
*/
|
||||
if (vg_is_clustered(lv->vg) && (!lv_is_mirror_type(lv) || lv_is_raid(lv)))
|
||||
if (vg_is_clustered(lv->vg) && !lv_is_mirror_type(lv))
|
||||
continue;
|
||||
|
||||
if (!lv_is_on_pvs(lv, source_pvl))
|
||||
|
@ -95,7 +95,7 @@ static int _make_vg_consistent(struct cmd_context *cmd, struct volume_group *vg)
|
||||
goto restart;
|
||||
}
|
||||
|
||||
if (lv_is_mirrored(lv)) {
|
||||
if (lv_is_mirror(lv)) {
|
||||
if (!mirror_remove_missing(cmd, lv, 1))
|
||||
return_0;
|
||||
goto restart;
|
||||
|
Loading…
Reference in New Issue
Block a user