1
0
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:
Alasdair G Kergon 2014-09-16 00:13:46 +01:00
parent 829e5a4037
commit 979be63f25
15 changed files with 45 additions and 22 deletions

View File

@ -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.

View File

@ -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:

View File

@ -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},

View File

@ -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;

View File

@ -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) ?

View File

@ -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.");

View File

@ -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)

View File

@ -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;
return dev_name(seg_dev(seg, 0));
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;

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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))

View File

@ -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;