mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-02 01:18:26 +03:00
lvconvert: Implement --splitsnapshot.
This commit is contained in:
parent
ff769ecfe7
commit
7b65363bf7
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.105 -
|
Version 2.02.105 -
|
||||||
=====================================
|
=====================================
|
||||||
|
Add --splitsnapshot to lvconvert to separate out cow LV.
|
||||||
Reinstate origin reload to complete lvconvert -s with active LVs. (2.02.98)
|
Reinstate origin reload to complete lvconvert -s with active LVs. (2.02.98)
|
||||||
Select only active volume groups if vgdisplay -A is used.
|
Select only active volume groups if vgdisplay -A is used.
|
||||||
Add -p and LVM_LVMETAD_PID env var to lvmetad to change pid file.
|
Add -p and LVM_LVMETAD_PID env var to lvmetad to change pid file.
|
||||||
|
@ -38,6 +38,14 @@ lvconvert \- convert a logical volume from linear to mirror or snapshot
|
|||||||
.RI [ SplittablePhysicalVolume [ Path ][ :PE [ -PE ]]...]
|
.RI [ SplittablePhysicalVolume [ Path ][ :PE [ -PE ]]...]
|
||||||
.sp
|
.sp
|
||||||
.B lvconvert
|
.B lvconvert
|
||||||
|
.BR \-\-splitsnapshot
|
||||||
|
.RB [ \-h | \-? | \-\-help ]
|
||||||
|
.RB [ \-\-noudevsync ]
|
||||||
|
.RB [ \-v | \-\-verbose ]
|
||||||
|
.RB [ \-\-version ]
|
||||||
|
.IR SnapshotLogicalVolume [ Path ]
|
||||||
|
.sp
|
||||||
|
.B lvconvert
|
||||||
.BR \-s | \-\-snapshot
|
.BR \-s | \-\-snapshot
|
||||||
.RB [ \-c | \-\-chunksize
|
.RB [ \-c | \-\-chunksize
|
||||||
.IR ChunkSize [ bBsSkK ]]
|
.IR ChunkSize [ bBsSkK ]]
|
||||||
@ -128,6 +136,7 @@ Exactly one of
|
|||||||
.BR \-\-mirrors ,
|
.BR \-\-mirrors ,
|
||||||
.BR \-\-repair ,
|
.BR \-\-repair ,
|
||||||
.BR \-\-replace ,
|
.BR \-\-replace ,
|
||||||
|
.BR \-\-splitsnapshot ,
|
||||||
.BR \-\-snapshot ,
|
.BR \-\-snapshot ,
|
||||||
.BR \-\-splitmirrors
|
.BR \-\-splitmirrors
|
||||||
or
|
or
|
||||||
@ -200,9 +209,17 @@ the data changed get resynchronized.
|
|||||||
Please note that this feature is only supported with the new md-based mirror
|
Please note that this feature is only supported with the new md-based mirror
|
||||||
implementation and not with the original device-mapper mirror implementation.
|
implementation and not with the original device-mapper mirror implementation.
|
||||||
.TP
|
.TP
|
||||||
|
.B \-\-splitsnapshot
|
||||||
|
Separates SnapshotLogicalVolume from its origin.
|
||||||
|
The volume that is split off contains the chunks that differ from the origin
|
||||||
|
along with the metadata describing them. This volume can be wiped and then
|
||||||
|
destroyed with lvremove.
|
||||||
|
The inverse of \-\-snapshot.
|
||||||
|
.TP
|
||||||
.B \-s, \-\-snapshot
|
.B \-s, \-\-snapshot
|
||||||
Creates a snapshot from existing logical volume using another
|
Recreates a snapshot from constituent logical volumes (or copies of them) after
|
||||||
existing logical volume as its origin.
|
having been separated using \-\-splitsnapshot. For this to work correctly, no
|
||||||
|
changes may be made to the contents of either volume after the split.
|
||||||
.TP
|
.TP
|
||||||
.BR \-c ", " \-\-chunksize " " \fIChunkSize [ \fIbBsSkKmMgG ]
|
.BR \-c ", " \-\-chunksize " " \fIChunkSize [ \fIbBsSkKmMgG ]
|
||||||
Gives the size of chunk for snapshot and thin pool logical volumes.
|
Gives the size of chunk for snapshot and thin pool logical volumes.
|
||||||
|
@ -101,6 +101,7 @@ arg(profile_ARG, '\0', "profile", string_arg, 0)
|
|||||||
arg(detachprofile_ARG, '\0', "detachprofile", NULL, 0)
|
arg(detachprofile_ARG, '\0', "detachprofile", NULL, 0)
|
||||||
arg(mergedconfig_ARG, '\0', "mergedconfig", NULL, 0)
|
arg(mergedconfig_ARG, '\0', "mergedconfig", NULL, 0)
|
||||||
arg(ignoreskippedcluster_ARG, '\0', "ignoreskippedcluster", NULL, 0)
|
arg(ignoreskippedcluster_ARG, '\0', "ignoreskippedcluster", NULL, 0)
|
||||||
|
arg(splitsnapshot_ARG, '\0', "splitsnapshot", NULL, 0)
|
||||||
|
|
||||||
/* Allow some variations */
|
/* Allow some variations */
|
||||||
arg(resizable_ARG, '\0', "resizable", yes_no_arg, 0)
|
arg(resizable_ARG, '\0', "resizable", yes_no_arg, 0)
|
||||||
|
@ -171,6 +171,15 @@ xx(lvconvert,
|
|||||||
"[--splitmirrors Images --name SplitLogicalVolumeName]\n"
|
"[--splitmirrors Images --name SplitLogicalVolumeName]\n"
|
||||||
"\tLogicalVolume[Path] [SplittablePhysicalVolume[Path]...]\n\n"
|
"\tLogicalVolume[Path] [SplittablePhysicalVolume[Path]...]\n\n"
|
||||||
|
|
||||||
|
"lvconvert "
|
||||||
|
"--splitsnapshot\n"
|
||||||
|
"\t[-d|--debug]\n"
|
||||||
|
"\t[-h|-?|--help]\n"
|
||||||
|
"\t[--noudevsync]\n"
|
||||||
|
"\t[-v|--verbose]\n"
|
||||||
|
"\t[--version]" "\n"
|
||||||
|
"\tSnapshotLogicalVolume[Path]\n\n"
|
||||||
|
|
||||||
"lvconvert "
|
"lvconvert "
|
||||||
"[-s|--snapshot]\n"
|
"[-s|--snapshot]\n"
|
||||||
"\t[-c|--chunksize]\n"
|
"\t[-c|--chunksize]\n"
|
||||||
@ -209,9 +218,9 @@ xx(lvconvert,
|
|||||||
force_ARG, interval_ARG, merge_ARG, mirrorlog_ARG, mirrors_ARG, name_ARG,
|
force_ARG, interval_ARG, merge_ARG, mirrorlog_ARG, mirrors_ARG, name_ARG,
|
||||||
noudevsync_ARG, originname_ARG, poolmetadata_ARG, poolmetadatasize_ARG,
|
noudevsync_ARG, originname_ARG, poolmetadata_ARG, poolmetadatasize_ARG,
|
||||||
poolmetadataspare_ARG, readahead_ARG, regionsize_ARG, repair_ARG,
|
poolmetadataspare_ARG, readahead_ARG, regionsize_ARG, repair_ARG,
|
||||||
replace_ARG, snapshot_ARG, splitmirrors_ARG, stripes_long_ARG,
|
replace_ARG, snapshot_ARG, splitmirrors_ARG, splitsnapshot_ARG,
|
||||||
stripesize_ARG, test_ARG, thin_ARG, thinpool_ARG, trackchanges_ARG,
|
stripes_long_ARG, stripesize_ARG, test_ARG, thin_ARG, thinpool_ARG,
|
||||||
type_ARG, use_policies_ARG, zero_ARG)
|
trackchanges_ARG, type_ARG, use_policies_ARG, zero_ARG)
|
||||||
|
|
||||||
xx(lvcreate,
|
xx(lvcreate,
|
||||||
"Create a logical volume",
|
"Create a logical volume",
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
struct lvconvert_params {
|
struct lvconvert_params {
|
||||||
int force;
|
int force;
|
||||||
int snapshot;
|
int snapshot;
|
||||||
|
int splitsnapshot;
|
||||||
int merge;
|
int merge;
|
||||||
int merge_mirror;
|
int merge_mirror;
|
||||||
int poolmetadataspare;
|
int poolmetadataspare;
|
||||||
@ -170,6 +171,11 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lp->splitsnapshot && *pargc) {
|
||||||
|
log_error("Too many arguments provided with --splitsnapshot.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (lp->pool_data_lv_name && lp->lv_name && lp->poolmetadata_size) {
|
if (lp->pool_data_lv_name && lp->lv_name && lp->poolmetadata_size) {
|
||||||
log_error("Please specify either metadata logical volume or its size.");
|
log_error("Please specify either metadata logical volume or its size.");
|
||||||
return 0;
|
return 0;
|
||||||
@ -223,6 +229,9 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
|
|||||||
if (!_check_conversion_type(cmd, type_str))
|
if (!_check_conversion_type(cmd, type_str))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
|
if (arg_count(cmd, splitsnapshot_ARG))
|
||||||
|
lp->splitsnapshot = 1;
|
||||||
|
|
||||||
if ((snapshot_type_requested(cmd, type_str) || arg_count(cmd, merge_ARG)) &&
|
if ((snapshot_type_requested(cmd, type_str) || arg_count(cmd, merge_ARG)) &&
|
||||||
(arg_count(cmd, mirrorlog_ARG) || mirror_or_raid_type_requested(cmd, type_str) ||
|
(arg_count(cmd, mirrorlog_ARG) || mirror_or_raid_type_requested(cmd, type_str) ||
|
||||||
arg_count(cmd, repair_ARG) || arg_count(cmd, thinpool_ARG))) {
|
arg_count(cmd, repair_ARG) || arg_count(cmd, thinpool_ARG))) {
|
||||||
@ -348,9 +357,24 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
|
|||||||
lp->mirrors_sign = arg_sign_value(cmd, mirrors_ARG, SIGN_NONE);
|
lp->mirrors_sign = arg_sign_value(cmd, mirrors_ARG, SIGN_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lp->splitsnapshot &&
|
||||||
|
(lp->snapshot || lp->thin || lp->merge || lp->merge_mirror || arg_count(cmd, thinpool_ARG) ||
|
||||||
|
arg_count(cmd, mirrors_ARG) || arg_count(cmd, repair_ARG) || arg_count(cmd, replace_ARG) ||
|
||||||
|
arg_count(cmd, chunksize_ARG) || arg_count(cmd, zero_ARG) || arg_count(cmd, regionsize_ARG) ||
|
||||||
|
arg_count(cmd, poolmetadata_ARG) || arg_count(cmd, poolmetadatasize_ARG) ||
|
||||||
|
arg_count(cmd, readahead_ARG) || arg_count(cmd, stripes_long_ARG) ||
|
||||||
|
arg_count(cmd, stripesize_ARG) || arg_count(cmd, background_ARG) ||
|
||||||
|
arg_count(cmd, interval_ARG) || arg_count(cmd, type_ARG) || arg_count(cmd, alloc_ARG) ||
|
||||||
|
arg_count(cmd, corelog_ARG) || arg_count(cmd, mirrorlog_ARG) ||
|
||||||
|
arg_count(cmd, splitmirrors_ARG) || arg_count(cmd, originname_ARG) ||
|
||||||
|
arg_count(cmd, trackchanges_ARG) || arg_count(cmd, use_policies_ARG))) {
|
||||||
|
log_error("Incompatible arguments supplied with --splitsnapshot.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
lp->alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, ALLOC_INHERIT);
|
lp->alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, ALLOC_INHERIT);
|
||||||
|
|
||||||
/* There are three types of lvconvert. */
|
/* There are six types of lvconvert. */
|
||||||
if (lp->merge) { /* Snapshot merge */
|
if (lp->merge) { /* Snapshot merge */
|
||||||
if (arg_count(cmd, regionsize_ARG) || arg_count(cmd, chunksize_ARG) ||
|
if (arg_count(cmd, regionsize_ARG) || arg_count(cmd, chunksize_ARG) ||
|
||||||
arg_count(cmd, zero_ARG) || arg_count(cmd, regionsize_ARG) ||
|
arg_count(cmd, zero_ARG) || arg_count(cmd, regionsize_ARG) ||
|
||||||
@ -364,8 +388,9 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
|
|||||||
|
|
||||||
if (!(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
|
if (!(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
|
||||||
return_0;
|
return_0;
|
||||||
|
} else if (lp->splitsnapshot) /* Destroy snapshot retaining cow as separate LV */
|
||||||
} else if (lp->snapshot) { /* Snapshot creation from pre-existing cow */
|
;
|
||||||
|
else if (lp->snapshot) { /* Snapshot creation from pre-existing cow */
|
||||||
if (arg_count(cmd, regionsize_ARG)) {
|
if (arg_count(cmd, regionsize_ARG)) {
|
||||||
log_error("--regionsize is only available with mirrors");
|
log_error("--regionsize is only available with mirrors");
|
||||||
return 0;
|
return 0;
|
||||||
@ -1648,7 +1673,7 @@ static int _lvconvert_mirrors(struct cmd_context *cmd,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_valid_raid_conversion(const struct segment_type *from_segtype,
|
static int _is_valid_raid_conversion(const struct segment_type *from_segtype,
|
||||||
const struct segment_type *to_segtype)
|
const struct segment_type *to_segtype)
|
||||||
{
|
{
|
||||||
if (from_segtype == to_segtype)
|
if (from_segtype == to_segtype)
|
||||||
@ -1695,7 +1720,7 @@ static void _lvconvert_raid_repair_ask(struct cmd_context *cmd, int *replace_dev
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *lp)
|
static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *lp)
|
||||||
{
|
{
|
||||||
int replace = 0;
|
int replace = 0;
|
||||||
int uninitialized_var(image_count);
|
int uninitialized_var(image_count);
|
||||||
@ -1718,7 +1743,7 @@ static int lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *lp
|
|||||||
if (!_lvconvert_validate_thin(lv, lp))
|
if (!_lvconvert_validate_thin(lv, lp))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
if (!is_valid_raid_conversion(seg->segtype, lp->segtype)) {
|
if (!_is_valid_raid_conversion(seg->segtype, lp->segtype)) {
|
||||||
log_error("Unable to convert %s/%s from %s to %s",
|
log_error("Unable to convert %s/%s from %s to %s",
|
||||||
lv->vg->name, lv->name,
|
lv->vg->name, lv->name,
|
||||||
seg->segtype->ops->name(seg), lp->segtype->name);
|
seg->segtype->ops->name(seg), lp->segtype->name);
|
||||||
@ -1819,9 +1844,83 @@ static int lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *lp
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lvconvert_snapshot(struct cmd_context *cmd,
|
static int _lvconvert_splitsnapshot(struct cmd_context *cmd, struct logical_volume *cow,
|
||||||
struct logical_volume *lv,
|
struct lvconvert_params *lp)
|
||||||
struct lvconvert_params *lp)
|
{
|
||||||
|
struct lvinfo info;
|
||||||
|
struct volume_group *vg = cow->vg;
|
||||||
|
|
||||||
|
if (!lv_is_cow(cow)) {
|
||||||
|
log_error("%s/%s is not a snapshot.", vg->name, cow->name);
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lv_is_origin(cow) || lv_is_external_origin(cow)) {
|
||||||
|
log_error("Unable to split LV %s/%s that is a snapshot origin.", vg->name, cow->name);
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lv_is_merging_cow(cow)) {
|
||||||
|
log_error("Unable to split off snapshot %s/%s being merged into its origin.", vg->name, cow->name);
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lv_is_virtual_origin(origin_from_cow(cow))) {
|
||||||
|
log_error("Unable to split off snapshot %s/%s with virtual origin.", vg->name, cow->name);
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lv_is_thin_pool(cow) || lv_is_pool_metadata_spare(cow)) {
|
||||||
|
log_error("Unable to split off LV %s/%s needed by thin volume(s).", vg->name, cow->name);
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(vg->fid->fmt->features & FMT_MDAS)) {
|
||||||
|
log_error("Unable to split off snapshot %s/%s using old LVM1-style metadata.", vg->name, cow->name);
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vg_check_status(vg, LVM_WRITE))
|
||||||
|
return_ECMD_FAILED;
|
||||||
|
|
||||||
|
if (lv_is_mirror_type(cow) || lv_is_raid_type(cow) || lv_is_thin_type(cow)) {
|
||||||
|
log_error("LV %s/%s type is unsupported with --splitsnapshot.", vg->name, cow->name);
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lv_info(cmd, cow, 0, &info, 1, 0)) {
|
||||||
|
if (!lv_check_not_in_use(cmd, cow, &info))
|
||||||
|
return_0;
|
||||||
|
|
||||||
|
if ((lp->force == PROMPT) &&
|
||||||
|
lv_is_visible(cow) &&
|
||||||
|
lv_is_active(cow)) {
|
||||||
|
if (yes_no_prompt("Do you really want to split off active "
|
||||||
|
"logical volume %s? [y/n]: ", cow->name) == 'n') {
|
||||||
|
log_error("Logical volume %s not split.", cow->name);
|
||||||
|
return ECMD_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!archive(vg))
|
||||||
|
return_ECMD_FAILED;
|
||||||
|
|
||||||
|
log_verbose("Splitting snapshot %s/%s from its origin.", vg->name, cow->name);
|
||||||
|
|
||||||
|
if (!vg_remove_snapshot(cow))
|
||||||
|
return_ECMD_FAILED;
|
||||||
|
|
||||||
|
backup(vg);
|
||||||
|
|
||||||
|
log_print_unless_silent("Logical Volume %s/%s split from its origin.", vg->name, cow->name);
|
||||||
|
|
||||||
|
return ECMD_PROCESSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _lvconvert_snapshot(struct cmd_context *cmd,
|
||||||
|
struct logical_volume *lv,
|
||||||
|
struct lvconvert_params *lp)
|
||||||
{
|
{
|
||||||
struct logical_volume *org;
|
struct logical_volume *org;
|
||||||
|
|
||||||
@ -2602,7 +2701,7 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lv_is_cow(lv) && !lp->merge) {
|
if (lv_is_cow(lv) && !lp->merge && !lp->splitsnapshot) {
|
||||||
log_error("Can't convert snapshot logical volume \"%s\"",
|
log_error("Can't convert snapshot logical volume \"%s\"",
|
||||||
lv->name);
|
lv->name);
|
||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
@ -2613,6 +2712,9 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lp->splitsnapshot)
|
||||||
|
return _lvconvert_splitsnapshot(cmd, lv, lp);
|
||||||
|
|
||||||
if (arg_count(cmd, repair_ARG) && lv_is_thin_pool(lv))
|
if (arg_count(cmd, repair_ARG) && lv_is_thin_pool(lv))
|
||||||
return _lvconvert_thinpool_repair(cmd, lv, lp);
|
return _lvconvert_thinpool_repair(cmd, lv, lp);
|
||||||
|
|
||||||
@ -2652,7 +2754,7 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
if (!archive(lv->vg))
|
if (!archive(lv->vg))
|
||||||
return_ECMD_FAILED;
|
return_ECMD_FAILED;
|
||||||
|
|
||||||
if (!lvconvert_snapshot(cmd, lv, lp))
|
if (!_lvconvert_snapshot(cmd, lv, lp))
|
||||||
return_ECMD_FAILED;
|
return_ECMD_FAILED;
|
||||||
|
|
||||||
} else if (arg_count(cmd, thinpool_ARG)) {
|
} else if (arg_count(cmd, thinpool_ARG)) {
|
||||||
@ -2667,7 +2769,7 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
if (!archive(lv->vg))
|
if (!archive(lv->vg))
|
||||||
return_ECMD_FAILED;
|
return_ECMD_FAILED;
|
||||||
|
|
||||||
if (!lvconvert_raid(lv, lp))
|
if (!_lvconvert_raid(lv, lp))
|
||||||
return_ECMD_FAILED;
|
return_ECMD_FAILED;
|
||||||
|
|
||||||
if (!(failed_pvs = _failed_pv_list(lv->vg)))
|
if (!(failed_pvs = _failed_pv_list(lv->vg)))
|
||||||
@ -2698,7 +2800,7 @@ static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME move to toollib along with the rest of the drop/reacquire
|
* FIXME move to toollib along with the rest of the drop/reacquire
|
||||||
* VG locking that is used by lvconvert_merge_single()
|
* VG locking that is used by _lvconvert_merge_single()
|
||||||
*/
|
*/
|
||||||
static struct logical_volume *get_vg_lock_and_logical_volume(struct cmd_context *cmd,
|
static struct logical_volume *get_vg_lock_and_logical_volume(struct cmd_context *cmd,
|
||||||
const char *vg_name,
|
const char *vg_name,
|
||||||
@ -2727,7 +2829,7 @@ static struct logical_volume *get_vg_lock_and_logical_volume(struct cmd_context
|
|||||||
return lv;
|
return lv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int poll_logical_volume(struct cmd_context *cmd, struct logical_volume *lv,
|
static int _poll_logical_volume(struct cmd_context *cmd, struct logical_volume *lv,
|
||||||
int wait_completion)
|
int wait_completion)
|
||||||
{
|
{
|
||||||
struct lvinfo info;
|
struct lvinfo info;
|
||||||
@ -2783,7 +2885,7 @@ bad:
|
|||||||
unlock_vg(cmd, lp->vg_name);
|
unlock_vg(cmd, lp->vg_name);
|
||||||
|
|
||||||
if (ret == ECMD_PROCESSED && lp->need_polling)
|
if (ret == ECMD_PROCESSED && lp->need_polling)
|
||||||
ret = poll_logical_volume(cmd, lp->lv_to_poll,
|
ret = _poll_logical_volume(cmd, lp->lv_to_poll,
|
||||||
lp->wait_completion);
|
lp->wait_completion);
|
||||||
|
|
||||||
release_vg(lv->vg);
|
release_vg(lv->vg);
|
||||||
@ -2792,7 +2894,7 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lvconvert_merge_single(struct cmd_context *cmd, struct logical_volume *lv,
|
static int _lvconvert_merge_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||||
void *handle)
|
void *handle)
|
||||||
{
|
{
|
||||||
struct lvconvert_params *lp = handle;
|
struct lvconvert_params *lp = handle;
|
||||||
@ -2802,10 +2904,10 @@ static int lvconvert_merge_single(struct cmd_context *cmd, struct logical_volume
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME can't trust lv's VG to be current given that caller
|
* FIXME can't trust lv's VG to be current given that caller
|
||||||
* is process_each_lv() -- poll_logical_volume() may have
|
* is process_each_lv() -- _poll_logical_volume() may have
|
||||||
* already updated the VG's metadata in an earlier iteration.
|
* already updated the VG's metadata in an earlier iteration.
|
||||||
* - preemptively drop the VG lock, as is needed for
|
* - preemptively drop the VG lock, as is needed for
|
||||||
* poll_logical_volume(), refresh LV (and VG in the process).
|
* _poll_logical_volume(), refresh LV (and VG in the process).
|
||||||
*/
|
*/
|
||||||
vg_name = lv->vg->name;
|
vg_name = lv->vg->name;
|
||||||
unlock_vg(cmd, vg_name);
|
unlock_vg(cmd, vg_name);
|
||||||
@ -2825,7 +2927,7 @@ static int lvconvert_merge_single(struct cmd_context *cmd, struct logical_volume
|
|||||||
*/
|
*/
|
||||||
unlock_vg(cmd, vg_name);
|
unlock_vg(cmd, vg_name);
|
||||||
|
|
||||||
ret = poll_logical_volume(cmd, lp->lv_to_poll,
|
ret = _poll_logical_volume(cmd, lp->lv_to_poll,
|
||||||
lp->wait_completion);
|
lp->wait_completion);
|
||||||
|
|
||||||
/* use LCK_VG_WRITE to match lvconvert()'s READ_FOR_UPDATE */
|
/* use LCK_VG_WRITE to match lvconvert()'s READ_FOR_UPDATE */
|
||||||
@ -2856,7 +2958,7 @@ int lvconvert(struct cmd_context * cmd, int argc, char **argv)
|
|||||||
return EINVALID_CMD_LINE;
|
return EINVALID_CMD_LINE;
|
||||||
}
|
}
|
||||||
return process_each_lv(cmd, argc, argv, READ_FOR_UPDATE, &lp,
|
return process_each_lv(cmd, argc, argv, READ_FOR_UPDATE, &lp,
|
||||||
&lvconvert_merge_single);
|
&_lvconvert_merge_single);
|
||||||
}
|
}
|
||||||
|
|
||||||
return lvconvert_single(cmd, &lp);
|
return lvconvert_single(cmd, &lp);
|
||||||
|
Loading…
Reference in New Issue
Block a user