diff --git a/WHATS_NEW b/WHATS_NEW index 76be4744b..99926b788 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.89 - ================================== + Add ability to extend mirrors with '--nosync' option. Fix splitmirror in cluster having different DM/LVM views of storage. Fix improper udev settings during suspend/resume for mirror sub-LVs. Fix vgsplit when there are mirrors that have mirrored logs. diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c index 81fef235b..fe325fac9 100644 --- a/lib/metadata/lv_manip.c +++ b/lib/metadata/lv_manip.c @@ -2599,10 +2599,11 @@ int lv_extend(struct logical_volume *lv, return 0; } - r = _lv_extend_layered_lv(ah, lv, extents, 0, - stripes, stripe_size); + if (!(r = _lv_extend_layered_lv(ah, lv, extents, 0, + stripes, stripe_size))) + goto out; - if (r && segtype_is_thin_pool(segtype)) { + if (segtype_is_thin_pool(segtype)) { /* FIXME: resize metadata size here for now */ struct logical_volume *tmeta = first_seg(lv)->pool_metadata_lv; if ((r = lv_add_segment(ah, ah->area_count, 1, tmeta, @@ -2613,7 +2614,52 @@ int lv_extend(struct logical_volume *lv, } else stack; } + + /* + * If we are expanding an existing mirror, we can skip the + * resync of the extension if the LV is currently in-sync + * and the LV has the LV_NOTSYNCED flag set. + */ + if ((lv->le_count != extents) && + segtype_is_mirrored(segtype) && + (lv->status & LV_NOTSYNCED)) { + percent_t sync_percent = PERCENT_INVALID; + + if (!lv_is_active(lv)) { + log_print("%s/%s is not active." + " Unable to get sync percent.", + lv->vg->name, lv->name); + if (yes_no_prompt("Do full resync of extended " + "portion of %s/%s? [y/n]: ", + lv->vg->name, lv->name) == 'y') + goto out; + r = 0; + goto out; + } + + r = 0; + if (!lv_mirror_percent(lv->vg->cmd, lv, 0, + &sync_percent, NULL)) { + log_error("Failed to get sync percent for %s/%s", + lv->vg->name, lv->name); + goto out; + } else if (sync_percent == PERCENT_100) { + log_verbose("Skipping initial resync for " + "extended portion of %s/%s", + lv->vg->name, lv->name); + init_mirror_in_sync(1); + lv->status |= LV_NOTSYNCED; + } else { + log_error("%s/%s cannot be extended while" + " it is recovering.", + lv->vg->name, lv->name); + goto out; + } + r = 1; + } } + +out: alloc_destroy(ah); return r; } diff --git a/tools/commands.h b/tools/commands.h index 56e0d370a..e6ac8c108 100644 --- a/tools/commands.h +++ b/tools/commands.h @@ -265,6 +265,7 @@ xx(lvextend, "\t{-l|--extents [+]LogicalExtentsNumber[%{VG|LV|PVS|FREE|ORIGIN}] |\n" "\t -L|--size [+]LogicalVolumeSize[bBsSkKmMgGtTpPeE]}\n" "\t[-m|--mirrors Mirrors]\n" + "\t[--nosync]\n" "\t[--use-policies]\n" "\t[-n|--nofsck]\n" "\t[--noudevsync]\n" @@ -276,7 +277,7 @@ xx(lvextend, "\tLogicalVolume[Path] [ PhysicalVolumePath... ]\n", alloc_ARG, autobackup_ARG, extents_ARG, force_ARG, mirrors_ARG, - nofsck_ARG, noudevsync_ARG, resizefs_ARG, size_ARG, stripes_ARG, + nofsck_ARG, nosync_ARG, noudevsync_ARG, resizefs_ARG, size_ARG, stripes_ARG, stripesize_ARG, test_ARG, type_ARG, use_policies_ARG) xx(lvmchange, diff --git a/tools/lvresize.c b/tools/lvresize.c index 96e623e1d..f4b81da34 100644 --- a/tools/lvresize.c +++ b/tools/lvresize.c @@ -504,6 +504,13 @@ static int _lvresize(struct cmd_context *cmd, struct volume_group *vg, /* If extending, find mirrors of last segment */ if ((lp->extents > lv->le_count)) { + /* + * Has the user specified that they would like the additional + * extents of a mirror not to have an initial sync? + */ + if (seg_is_mirrored(first_seg(lv)) && arg_count(cmd, nosync_ARG)) + lv->status |= LV_NOTSYNCED; + dm_list_iterate_back_items(mirr_seg, &lv->segments) { if (seg_is_mirrored(mirr_seg)) seg_mirrors = lv_mirror_count(mirr_seg->lv);