summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2016-12-19 15:53:21 -0600
committerDavid Teigland <teigland@redhat.com>2016-12-19 16:59:42 -0600
commitbfcc1f0cccc169d337c7fe72575e6236f38a43c6 (patch)
tree51d83d5508fe499d35b12ac6c4bff12a1eab6809
parent27e29026727db59c10ea4c68361cfa926a0a1121 (diff)
downloadlvm2-dev-dct-cmd-defs62.tar.gz
lvconvert: use command defs for raid/mirror typesdev-dct-cmd-defs62
All lvconvert functionality has been moved out of the previous monolithic lvconvert code, except conversions related to raid/mirror/striped/linear. This switches that remaining code to be based on command defs, and standard process_each_lv arg processing. This final switch results in quite a bit of dead code that is also removed.
-rw-r--r--tools/command-lines.in7
-rw-r--r--tools/lvconvert.c1097
-rw-r--r--tools/lvmcmdline.c13
-rw-r--r--tools/tools.h3
4 files changed, 323 insertions, 797 deletions
diff --git a/tools/command-lines.in b/tools/command-lines.in
index 13e93bca8..3e4b4a9c3 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -337,24 +337,28 @@ OO: OO_LVCONVERT_RAID, OO_LVCONVERT
OP: PV ...
ID: lvconvert_raid_types
DESC: Convert LV to striped.
+RULE: all not lv_is_locked lv_is_pvmove
lvconvert --type mirror LV
OO: OO_LVCONVERT_RAID, OO_LVCONVERT, --mirrorlog MirrorLog
OP: PV ...
ID: lvconvert_raid_types
DESC: Convert LV to type mirror (also see type raid1).
+RULE: all not lv_is_locked lv_is_pvmove
lvconvert --type raid LV
OO: OO_LVCONVERT_RAID, OO_LVCONVERT
OP: PV ...
ID: lvconvert_raid_types
DESC: Convert LV to raid.
+RULE: all not lv_is_locked lv_is_pvmove
lvconvert --mirrors SNumber LV
OO: OO_LVCONVERT_RAID, OO_LVCONVERT, --mirrorlog MirrorLog
OP: PV ...
ID: lvconvert_raid_types
DESC: Convert LV to raid1 or mirror, or change number of mirror images.
+RULE: all not lv_is_locked lv_is_pvmove
---
@@ -366,12 +370,14 @@ OO: OO_LVCONVERT
OP: PV ...
ID: lvconvert_split_mirror_images
DESC: Split images from a raid1 or mirror LV and use them to create a new LV.
+RULE: all not lv_is_locked lv_is_pvmove
lvconvert --splitmirrors Number --trackchanges LV_raid1_cache
OO: OO_LVCONVERT
OP: PV ...
ID: lvconvert_split_mirror_images
DESC: Split images from a raid1 LV and track changes to origin.
+RULE: all not lv_is_locked lv_is_pvmove
lvconvert --mergemirrors LV_linear_raid|VG|Tag ...
OO: OO_LVCONVERT
@@ -384,6 +390,7 @@ OO: OO_LVCONVERT
OP: PV ...
ID: lvconvert_change_mirrorlog
DESC: Change the type of mirror log used by a mirror LV.
+RULE: all not lv_is_locked lv_is_pvmove
---
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 6ada3b777..30d0f20ba 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -39,40 +39,15 @@
*/
typedef enum {
- /* Merge:
- * If merge_snapshot is also set:
- * merge thin snapshot LV into its origin
- * merge old snapshot COW into its origin
- * or if merge_mirror is also set
- * merge LV previously split from mirror back into mirror
- */
- CONV_MERGE = 1,
-
/* Split:
- * For a snapshot, split it apart into COW and origin for future recombination
- * For a cached LV, split it apart into the cached LV and its pool
* For a mirrored or raid LV, split mirror into two mirrors, optionally tracking
* future changes to the main mirror to allow future recombination.
*/
- CONV_SPLIT = 2,
- CONV_SPLIT_SNAPSHOT = 3,
- CONV_SPLIT_CACHE = 4,
- CONV_SPLIT_MIRRORS = 5,
-
- /* Start to cache an LV */
- CONV_CACHE = 6,
-
- /* Destroy the cache attached to a cached LV */
- CONV_UNCACHE = 7,
-
- /* Reconstruct a snapshot from its origin and COW */
- CONV_SNAPSHOT = 8,
-
- /* Convert normal LV into one in a thin pool */
- CONV_THIN = 11,
+ CONV_SPLIT = 1,
+ CONV_SPLIT_MIRRORS = 2,
/* Every other segment type or mirror log conversion we haven't separated out */
- CONV_OTHER = 12,
+ CONV_OTHER = 3,
} conversion_type_t;
struct lvconvert_params {
@@ -170,165 +145,6 @@ static void _set_conv_type(struct lvconvert_params *lp, int conv_type)
lp->conv_type = conv_type;
}
-static int _lvconvert_validate_names(struct lvconvert_params *lp)
-{
- unsigned i, j;
- const char *names[] = {
- (lp->lv_name == lp->pool_data_name) ? NULL : lp->lv_name, "converted",
- lp->pool_data_name, "pool",
- lp->pool_metadata_name, "pool metadata",
- lp->origin_name, "origin",
- };
-
- for (i = 0; i < DM_ARRAY_SIZE(names); i += 2)
- if (names[i])
- for (j = i + 2; j < DM_ARRAY_SIZE(names); j += 2)
- if (names[j] && !strcmp(names[i], names[j])) {
- log_error("Can't use same name %s for %s and %s volume.",
- names[i], names[i + 1], names[j + 1]);
- return 0;
- }
-
- return 1;
-}
-
-static int _lvconvert_name_params(struct lvconvert_params *lp,
- struct cmd_context *cmd,
- int *pargc, char ***pargv)
-{
- if (lp->merge) {
- /* FIXME Multiple arguments that mix snap and mirror? */
- if (!*pargc) {
- log_error("Please specify a logical volume path.");
- return 0;
- }
-
- if (!strstr((*pargv)[0], "_rimage_")) { /* Snapshot */
- lp->type_str = SEG_TYPE_NAME_SNAPSHOT;
- lp->merge_snapshot = 1;
-
- return 1;
- }
-
- /* Mirror */
- lp->merge_mirror = 1;
- }
-
- if (!*pargc) {
- if (lp->cache) {
- log_error("Logical volume name for caching is missing.");
- return 0;
- }
- if (lp->thin) {
- log_error("Please specify a logical volume to act as "
- "the external origin.");
- return 0;
- }
- if (lp->snapshot) {
- log_error("Please specify a logical volume to act as "
- "the snapshot exception store.");
- return 0;
- }
- if (lp->split) {
- log_error("Logical volume for split is missing.");
- return 0;
- }
- if (lp->splitcache) {
- log_error("Cache logical volume for split is missing.");
- return 0;
- }
- if (lp->uncache) {
- log_error("Cache logical volume for uncache is missing.");
- return 0;
- }
- if (!lp->lv_name_full) {
- log_error("Please provide logical volume path.");
- return 0;
- }
- } else if (!lp->lv_name_full) {
- lp->lv_name_full = (*pargv)[0];
- (*pargv)++, (*pargc)--;
- }
-
- if (!validate_restricted_lvname_param(cmd, &lp->vg_name, &lp->pool_metadata_name))
- return_0;
-
- if (!validate_restricted_lvname_param(cmd, &lp->vg_name, &lp->pool_data_name))
- return_0;
-
- if (!validate_restricted_lvname_param(cmd, &lp->vg_name, &lp->origin_name))
- return_0;
-
- if (!validate_restricted_lvname_param(cmd, &lp->vg_name, &lp->lv_split_name))
- return_0;
-
- if (!lp->vg_name && !strchr(lp->lv_name_full, '/')) {
- /* Check for $LVM_VG_NAME */
- if (!(lp->vg_name = extract_vgname(cmd, NULL))) {
- log_error("Please specify a logical volume path.");
- return 0;
- }
- }
-
- if (!validate_lvname_param(cmd, &lp->vg_name, &lp->lv_name_full))
- return_0;
-
- lp->lv_name = lp->lv_name_full;
-
- if (!validate_name(lp->vg_name)) {
- log_error("Please provide a valid volume group name");
- return 0;
- }
-
- /*
- * FIXME: avoid this distinct validation out of scope of _convert_*()
- *
- * We should not rely on namespace here any more!
- * It is the duty of lvcreate/lvrename to avoid reserved names.
- */
- if (!lp->merge_mirror &&
- !lp->keep_mimages &&
- !strstr(lp->lv_name, "_tdata") &&
- !strstr(lp->lv_name, "_tmeta") &&
- !strstr(lp->lv_name, "_cdata") &&
- !strstr(lp->lv_name, "_cmeta") &&
- !strstr(lp->lv_name, "_corig") &&
- !apply_lvname_restrictions(lp->lv_name))
- return_0;
-
- if (*pargc) {
- if (lp->snapshot) {
- log_error("Too many arguments provided for snapshots.");
- return 0;
- }
- if (lp->splitsnapshot) {
- log_error("Too many arguments provided with --splitsnapshot.");
- return 0;
- }
- if (lp->splitcache) {
- log_error("Too many arguments provided with --splitcache.");
- return 0;
- }
- if (lp->split) {
- log_error("Too many arguments provided with --split.");
- return 0;
- }
- if (lp->uncache) {
- log_error("Too many arguments provided with --uncache.");
- return 0;
- }
- if (lp->pool_data_name && lp->pool_metadata_name) {
- log_error("Too many arguments provided for pool.");
- return 0;
- }
- }
-
- if (!_lvconvert_validate_names(lp))
- return_0;
-
- return 1;
-}
-
/* -s/--snapshot and --type snapshot are synonyms */
static int _snapshot_type_requested(struct cmd_context *cmd, const char *type_str)
{
@@ -379,113 +195,9 @@ static int _read_conversion_type(struct cmd_context *cmd,
return 0;
}
-static int _read_pool_params(struct cmd_context *cmd, int *pargc, char ***pargv,
- struct lvconvert_params *lp)
-{
- int cachepool = 0;
- int thinpool = 0;
- struct segment_type *segtype;
-
- if ((lp->pool_data_name = arg_str_value(cmd, cachepool_ARG, NULL))) {
- if (lp->type_str[0] &&
- strcmp(lp->type_str, SEG_TYPE_NAME_CACHE) &&
- strcmp(lp->type_str, SEG_TYPE_NAME_CACHE_POOL)) {
- log_error("--cachepool argument is only valid with "
- "the cache or cache-pool segment type.");
- return 0;
- }
- cachepool = 1;
- lp->type_str = SEG_TYPE_NAME_CACHE_POOL;
- } else if (!strcmp(lp->type_str, SEG_TYPE_NAME_CACHE_POOL))
- cachepool = 1;
- else if ((lp->pool_data_name = arg_str_value(cmd, thinpool_ARG, NULL))) {
- if (lp->type_str[0] &&
- strcmp(lp->type_str, SEG_TYPE_NAME_THIN) &&
- strcmp(lp->type_str, SEG_TYPE_NAME_THIN_POOL)) {
- log_error("--thinpool argument is only valid with "
- "the thin or thin-pool segment type.");
- return 0;
- }
- thinpool = 1;
- lp->type_str = SEG_TYPE_NAME_THIN_POOL;
- } else if (!strcmp(lp->type_str, SEG_TYPE_NAME_THIN_POOL))
- thinpool = 1;
-
- if (lp->cache && !cachepool) {
- log_error("--cache requires --cachepool.");
- return 0;
- }
-
- if ((lp->cache || cachepool) &&
- !get_cache_params(cmd, &lp->cache_mode, &lp->policy_name, &lp->policy_settings)) {
- log_error("Failed to parse cache policy and/or settings.");
- return 0;
- }
-
- if (thinpool) {
- lp->discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_PASSDOWN);
- lp->origin_name = arg_str_value(cmd, originname_ARG, NULL);
- } else {
- if (arg_from_list_is_set(cmd, "is valid only with thin pools",
- discards_ARG, originname_ARG, thinpool_ARG,
- -1))
- return_0;
- if (lp->thin) {
- log_error("--thin requires --thinpool.");
- return 0;
- }
- }
-
- if (thinpool || cachepool) {
- if (arg_from_list_is_set(cmd, "is invalid with pools",
- merge_ARG, mirrors_ARG, repair_ARG, snapshot_ARG,
- splitmirrors_ARG, splitsnapshot_ARG, -1))
- return_0;
-
- if (!(segtype = get_segtype_from_string(cmd, lp->type_str)))
- return_0;
-
- if (!get_pool_params(cmd, segtype, &lp->passed_args,
- &lp->pool_metadata_size,
- &lp->poolmetadataspare,
- &lp->chunk_size, &lp->discards,
- &lp->zero))
- return_0;
-
- if ((lp->pool_metadata_name = arg_str_value(cmd, poolmetadata_ARG, NULL)) &&
- arg_from_list_is_set(cmd, "is invalid with --poolmetadata",
- stripesize_ARG, stripes_long_ARG,
- readahead_ARG, -1))
- return_0;
-
- if (!lp->pool_data_name) {
- if (!*pargc) {
- log_error("Please specify the pool data LV.");
- return 0;
- }
- lp->pool_data_name = (*pargv)[0];
- (*pargv)++, (*pargc)--;
- }
-
- if (!lp->thin && !lp->cache)
- lp->lv_name_full = lp->pool_data_name;
-
- /* Hmm _read_activation_params */
- lp->read_ahead = arg_uint_value(cmd, readahead_ARG,
- cmd->default_settings.read_ahead);
-
- } else if (arg_from_list_is_set(cmd, "is valid only with pools",
- poolmetadatasize_ARG, poolmetadataspare_ARG,
- zero_ARG,
- -1))
- return_0;
-
- return 1;
-}
-
-static int _read_params(struct cmd_context *cmd, int argc, char **argv,
- struct lvconvert_params *lp)
+static int _read_params(struct cmd_context *cmd, struct lvconvert_params *lp)
{
+ const char *vg_name = NULL;
int region_size;
int pagesize = lvm_getpagesize();
@@ -506,16 +218,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
lp->mirrorlog = 1;
}
- if (arg_is_set(cmd, merge_ARG)) {
- if (arg_outside_list_is_set(cmd, "cannot be used with --merge",
- merge_ARG,
- background_ARG, interval_ARG,
- force_ARG, noudevsync_ARG, test_ARG,
- -1))
- return_0;
- lp->merge = 1;
- _set_conv_type(lp, CONV_MERGE);
- } else if (arg_is_set(cmd, split_ARG)) {
+ if (arg_is_set(cmd, split_ARG)) {
if (arg_outside_list_is_set(cmd, "cannot be used with --split",
split_ARG,
name_ARG,
@@ -524,79 +227,17 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
return_0;
lp->split = 1;
_set_conv_type(lp, CONV_SPLIT);
- } else if (arg_is_set(cmd, splitcache_ARG)) {
- if (arg_outside_list_is_set(cmd, "cannot be used with --splitcache",
- splitcache_ARG,
- force_ARG, noudevsync_ARG, test_ARG,
- -1))
- return_0;
- lp->splitcache = 1;
- _set_conv_type(lp, CONV_SPLIT_CACHE);
- } else if (arg_is_set(cmd, splitsnapshot_ARG)) {
- if (arg_outside_list_is_set(cmd, "cannot be used with --splitsnapshot",
- splitsnapshot_ARG,
- force_ARG, noudevsync_ARG, test_ARG,
- -1))
- return_0;
- lp->splitsnapshot = 1;
- _set_conv_type(lp, CONV_SPLIT_SNAPSHOT);
- } else if (arg_is_set(cmd, uncache_ARG)) {
- if (arg_outside_list_is_set(cmd, "cannot be used with --uncache",
- uncache_ARG,
- force_ARG, noudevsync_ARG, test_ARG,
- -1))
- return_0;
- lp->uncache = 1;
- _set_conv_type(lp, CONV_UNCACHE);
- }
-
- if (arg_is_set(cmd, cache_ARG)) {
- lp->cache = 1;
- _set_conv_type(lp, CONV_CACHE);
- }
-
- if (!strcmp(lp->type_str, SEG_TYPE_NAME_CACHE))
- lp->cache = 1;
- else if (lp->cache) {
- if (lp->type_str[0]) {
- log_error("--cache is incompatible with --type %s", lp->type_str);
- return 0;
- }
- lp->type_str = SEG_TYPE_NAME_CACHE;
- }
-
- if (arg_is_set(cmd, thin_ARG)) {
- lp->thin = 1;
- _set_conv_type(lp, CONV_THIN);
- }
-
- if (!strcmp(lp->type_str, SEG_TYPE_NAME_THIN))
- lp->thin = 1;
- else if (lp->thin) {
- if (lp->type_str[0]) {
- log_error("--thin is incompatible with --type %s", lp->type_str);
- return 0;
- }
- lp->type_str = SEG_TYPE_NAME_THIN;
}
-
+
if (arg_is_set(cmd, trackchanges_ARG))
lp->track_changes = 1;
- if (!_read_pool_params(cmd, &argc, &argv, lp))
- return_0;
-
- if (_snapshot_type_requested(cmd, lp->type_str)) {
- if (lp->merge) {
- log_error("--snapshot and --merge are mutually exclusive.");
- return 0;
+ if (lp->split) {
+ if ((lp->lv_split_name = arg_str_value(cmd, name_ARG, NULL))) {
+ if (!validate_restricted_lvname_param(cmd, &vg_name, &lp->lv_split_name))
+ return_0;
}
- lp->snapshot = 1;
- _set_conv_type(lp, CONV_SNAPSHOT);
- }
- if (lp->split) {
- lp->lv_split_name = arg_str_value(cmd, name_ARG, NULL);
/*
* The '--splitmirrors n' argument is equivalent to '--mirrors -n'
@@ -616,7 +257,11 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
return 0;
}
- lp->lv_split_name = arg_str_value(cmd, name_ARG, NULL);
+ if ((lp->lv_split_name = arg_str_value(cmd, name_ARG, NULL))) {
+ if (!validate_restricted_lvname_param(cmd, &vg_name, &lp->lv_split_name))
+ return_0;
+ }
+
lp->keep_mimages = 1;
_set_conv_type(lp, CONV_SPLIT_MIRRORS);
lp->mirrors = arg_uint_value(cmd, splitmirrors_ARG, 0);
@@ -633,22 +278,11 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
}
/* If no other case was identified, then use of --stripes means --type striped */
- if (!arg_is_set(cmd, type_ARG) && !*lp->type_str && !lp->merge && !lp->splitsnapshot &&
- !lp->splitcache && !lp->split && !lp->snapshot && !lp->uncache && !lp->cache && !lp->thin &&
- !lp->mirrorlog && !lp->corelog &&
+ if (!arg_is_set(cmd, type_ARG) && !*lp->type_str &&
+ !lp->split && !lp->mirrorlog && !lp->corelog &&
(arg_is_set(cmd, stripes_long_ARG) || arg_is_set(cmd, stripesize_ARG)))
lp->type_str = SEG_TYPE_NAME_STRIPED;
- if ((_snapshot_type_requested(cmd, lp->type_str) || lp->merge) &&
- (lp->mirrorlog || _mirror_or_raid_type_requested(cmd, lp->type_str) ||
- arg_is_set(cmd, thinpool_ARG) || _raid0_type_requested(lp->type_str) ||
- _striped_type_requested(lp->type_str))) {
- log_error("--snapshot/--type snapshot or --merge argument "
- "cannot be mixed with --mirrors/--type mirror/--type raid*/--stripes/--type striped/--type linear, "
- "--mirrorlog, --repair or --thinpool.");
- return 0;
- }
-
if ((arg_is_set(cmd, stripes_long_ARG) || arg_is_set(cmd, stripesize_ARG)) &&
!(_mirror_or_raid_type_requested(cmd, lp->type_str) || _striped_type_requested(lp->type_str) ||
_raid0_type_requested(lp->type_str) || arg_is_set(cmd, thinpool_ARG))) {
@@ -667,72 +301,22 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
lp->alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, ALLOC_INHERIT);
/* We should have caught all these cases already. */
- if (lp->merge + lp->splitsnapshot + lp->splitcache + lp->split + lp->uncache +
- lp->cache + lp->thin + lp->keep_mimages + lp->snapshot > 1) {
+ if (lp->split + lp->keep_mimages > 1) {
log_error(INTERNAL_ERROR "Unexpected combination of incompatible options selected.");
return 0;
}
-
/*
* Final checking of each case:
- * lp->merge
- * lp->splitsnapshot
- * lp->splitcache
* lp->split
- * lp->uncache
- * lp->cache
- * lp->thin
* lp->keep_mimages
- * lp->snapshot
* --type mirror|raid lp->mirrorlog lp->corelog
* --type raid0|striped
*/
switch(lp->conv_type) {
- case CONV_MERGE: /* Snapshot or mirror merge */
case CONV_SPLIT:
- case CONV_SPLIT_CACHE:
case CONV_SPLIT_MIRRORS:
- case CONV_SPLIT_SNAPSHOT: /* Destroy snapshot retaining cow as separate LV */
- case CONV_CACHE:
- case CONV_UNCACHE:
- case CONV_THIN:
break;
- case CONV_SNAPSHOT: /* Snapshot creation from pre-existing cow */
- if (!argc) {
- log_error("Please provide logical volume path for snapshot origin.");
- return 0;
- }
- lp->origin_name = argv[0];
- argv++, argc--;
-
- if (arg_is_set(cmd, regionsize_ARG)) {
- log_error("--regionsize is only available with mirrors");
- return 0;
- }
-
- if (arg_is_set(cmd, stripesize_ARG) || arg_is_set(cmd, stripes_long_ARG)) {
- log_error("--stripes and --stripesize are only available with striped mirrors");
- return 0;
- }
-
- if (arg_is_set(cmd, chunksize_ARG) &&
- (arg_sign_value(cmd, chunksize_ARG, SIGN_NONE) == SIGN_MINUS)) {
- log_error("Negative chunk size is invalid.");
- return 0;
- }
-
- lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8);
- if (lp->chunk_size < 8 || lp->chunk_size > 1024 ||
- !is_power_of_2(lp->chunk_size)) {
- log_error("Chunk size must be a power of 2 in the "
- "range 4K to 512K");
- return 0;
- }
- log_verbose("Setting chunk size to %s.", display_size(cmd, lp->chunk_size));
-
- lp->type_str = SEG_TYPE_NAME_SNAPSHOT;
- break;
case CONV_OTHER:
if (_mirror_or_raid_type_requested(cmd, lp->type_str) ||
@@ -803,15 +387,10 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
lp->force = arg_count(cmd, force_ARG);
lp->yes = arg_count(cmd, yes_ARG);
- if (!_lvconvert_name_params(lp, cmd, &argc, &argv))
- return_0;
-
- lp->pv_count = argc;
- lp->pvs = argv;
-
return 1;
}
+
static struct poll_functions _lvconvert_mirror_fns = {
.poll_progress = poll_mirror_progress,
.finish_copy = lvconvert_mirror_finish,
@@ -1256,22 +835,6 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd,
}
/*
- * Collapsing a stack of mirrors:
- *
- * If called with no argument, try collapsing the resync layers
- */
- if (!lp->mirrors_supplied && !lp->mirrorlog &&
- !lp->corelog && !arg_is_set(cmd, regionsize_ARG) &&
- !lp->keep_mimages) {
- *new_mimage_count = *old_mimage_count;
- *new_log_count = *old_log_count;
-
- if (find_temporary_mirror(lv) || lv_is_converting(lv))
- lp->need_polling = 1;
- return 1;
- }
-
- /*
* Adjusting mimage count?
*/
if (!lp->mirrors_supplied && !lp->keep_mimages)
@@ -4416,7 +3979,7 @@ static int _convert_cache_volume_thin_pool(struct cmd_context *cmd, struct logic
static int _convert_cache_volume_snapshot(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
- return _lvconvert_snapshot(cmd, lv, lp);
+ return _lvconvert_snapshot(cmd, lv, lp->origin_name);
}
/*
@@ -4954,79 +4517,21 @@ static int _convert_mirror(struct cmd_context *cmd, struct logical_volume *lv,
if (segtype_is_raid(lp->segtype))
return _convert_mirror_raid(cmd, lv, lp);
- /*
- * FIXME: this is here to preserve old behavior, but an
- * explicit option should be added to enable this case,
- * rather than making it the result of an ambiguous
- * "lvconvert vg/lv" command.
- * Add 'lvconvert --poll-mirror vg/lv' for this case.
- *
- * Old behavior was described as:
- * "Collapsing a stack of mirrors.
- * If called with no argument, try collapsing the resync layers"
- */
- log_debug("Checking if LV %s is converting.", display_lvname(lv));
- if (lv_is_converting(lv)) {
- lp->need_polling = 1;
- return 1;
- }
-
- log_error("Operation not permitted on mirror LV %s.", display_lvname(lv));
- log_error("Operations permitted on a mirror LV are:\n"
- " --mirrors\n"
- " --splitmirrors\n"
- " --mirrorlog\n"
- " --repair\n"
- " --type linear\n"
- " --type raid*\n");
-
+ log_error("Unknown operation on mirror LV %s.", display_lvname(lv));
return 0;
}
static int _convert_raid(struct cmd_context *cmd, struct logical_volume *lv,
struct lvconvert_params *lp)
{
- /* Permitted convert options on visible or hidden RaidLVs */
- /* The --thinpool alternative for --type thin-pool is not preferred, so not shown. */
- const char *permitted_options = lv_is_visible(lv) ?
- " --mirrors\n"
- " --splitmirrors\n"
- " --merge\n"
- " --repair\n"
- " --replace\n"
- " --type snapshot\n"
- " --type thin\n"
- " --type cache\n"
- " --type thin-pool\n"
- " --type cache-pool\n"
- " --type raid*\n"
- " --type mirror\n"
- " --type striped\n"
- " --type linear\n"
- :
- " --mirrors\n"
- " --splitmirrors\n"
- " --repair\n"
- " --replace\n"
- " --type raid*\n"
- " --type mirror\n"
- " --type striped\n"
- " --type linear\n";
-
- /* Applicable to any hidden _or_ visible LVs. */
if (arg_is_set(cmd, mirrors_ARG))
return _convert_raid_number(cmd, lv, lp);
if (arg_is_set(cmd, splitmirrors_ARG))
return _convert_raid_splitmirrors(cmd, lv, lp);
- if (segtype_is_raid(lp->segtype)) {
- /* Only --type allowed on hidden RaidLV. */
- if (!lv_is_visible(lv) && !arg_is_set(cmd, type_ARG))
- goto out;
-
+ if (segtype_is_raid(lp->segtype))
return _convert_raid_raid(cmd, lv, lp);
- }
if (segtype_is_mirror(lp->segtype))
return _convert_raid_mirror(cmd, lv, lp);
@@ -5037,33 +4542,7 @@ static int _convert_raid(struct cmd_context *cmd, struct logical_volume *lv,
if (_linear_type_requested(lp->type_str))
return _convert_raid_linear(cmd, lv, lp);
- /* Applicable to visible LVs only. */
- if (lv_is_visible(lv)) {
- if (lp->merge)
- return _convert_raid_merge(cmd, lv, lp);
-
- if (!strcmp(lp->type_str, SEG_TYPE_NAME_SNAPSHOT) || arg_is_set(cmd, snapshot_ARG))
- return _convert_raid_snapshot(cmd, lv, lp);
-
- if (lp->thin)
- return _convert_raid_thin(cmd, lv, lp);
-
- if (lp->cache)
- return _convert_raid_cache(cmd, lv, lp);
-
- if (!strcmp(lp->type_str, SEG_TYPE_NAME_THIN_POOL) ||
- arg_is_set(cmd, thinpool_ARG))
- return _convert_raid_thin_pool(cmd, lv, lp);
-
- if (!strcmp(lp->type_str, SEG_TYPE_NAME_CACHE_POOL) ||
- arg_is_set(cmd, cachepool_ARG))
- return _convert_raid_cache_pool(cmd, lv, lp);
- }
-
-out:
- log_error("Operation not permitted on raid LV %s.", display_lvname(lv));
- log_error("Operations permitted on a raid LV are:\n%s", permitted_options);
-
+ log_error("Unknown operation on raid LV %s.", display_lvname(lv));
return 0;
}
@@ -5072,27 +4551,6 @@ static int _convert_striped(struct cmd_context *cmd, struct logical_volume *lv,
{
const char *mirrors_type = find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL);
- /* FIXME: add --merge-mirror to make this distinct from --merge-snapshot. */
- if (lp->merge)
- return _convert_striped_merge(cmd, lv, lp);
-
- if (lp->snapshot || !strcmp(lp->type_str, SEG_TYPE_NAME_SNAPSHOT))
- return _convert_striped_snapshot(cmd, lv, lp);
-
- if (lp->thin)
- return _convert_striped_thin(cmd, lv, lp);
-
- if (lp->cache)
- return _convert_striped_cache(cmd, lv, lp);
-
- if (!strcmp(lp->type_str, SEG_TYPE_NAME_THIN_POOL) ||
- arg_is_set(cmd, thinpool_ARG))
- return _convert_striped_thin_pool(cmd, lv, lp);
-
- if (!strcmp(lp->type_str, SEG_TYPE_NAME_CACHE_POOL) ||
- arg_is_set(cmd, cachepool_ARG))
- return _convert_striped_cache_pool(cmd, lv, lp);
-
if (!strcmp(lp->type_str, SEG_TYPE_NAME_MIRROR))
return _convert_striped_mirror(cmd, lv, lp);
@@ -5107,19 +4565,7 @@ static int _convert_striped(struct cmd_context *cmd, struct logical_volume *lv,
if (arg_is_set(cmd, mirrors_ARG) && mirrors_type && !strcmp(mirrors_type, SEG_TYPE_NAME_RAID1))
return _convert_striped_raid(cmd, lv, lp);
- /* The --thinpool alternative for --type thin-pool is not preferred, so not shown. */
-
- log_error("Operation not permitted on striped or linear LV %s.", display_lvname(lv));
- log_error("Operations permitted on a striped or linear LV are:\n"
- " --merge\n"
- " --type snapshot\n"
- " --type thin\n"
- " --type cache\n"
- " --type thin-pool\n"
- " --type cache-pool\n"
- " --type mirror\n"
- " --type raid*\n");
-
+ log_error("Unknown operation on striped or linear LV %s.", display_lvname(lv));
return 0;
}
@@ -5148,39 +4594,6 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
struct lv_segment *seg = first_seg(lv);
int ret = 0;
- /*
- * Check some conditions that can never be processed.
- */
-
- if (lv_is_locked(lv)) {
- log_error("Cannot convert locked LV %s.", display_lvname(lv));
- goto out;
- }
-
- if (lv_is_pvmove(lv)) {
- log_error("Cannot convert pvmove LV %s.", display_lvname(lv));
- goto out;
- }
-
- if (!lv_is_visible(lv)) {
- /*
- * FIXME: there are some exceptions to the rule of only
- * operating on visible LVs. These should be fixed by running
- * the command on the visible LV with an option indicating
- * which sub LV is intended rather than naming the !visible LV.
- */
- if (!lv_is_cache_pool_metadata(lv) &&
- !lv_is_cache_pool_data(lv) &&
- !lv_is_thin_pool_metadata(lv) &&
- !lv_is_thin_pool_data(lv) &&
- !lv_is_used_cache_pool(lv) &&
- !lv_is_mirrored(lv) &&
- !lv_is_raid(lv)) {
- log_error("Cannot convert internal LV %s.", display_lvname(lv));
- goto out;
- }
- }
-
/* Set up segtype either from type_str or else to match the existing one. */
if (!*lp->type_str)
lp->segtype = seg->segtype;
@@ -5217,37 +4630,8 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
lp->stripes = 0;
}
- if (lp->snapshot)
- lp->zero = (lp->segtype->flags & SEG_CANNOT_BE_ZEROED) ? 0 : arg_int_value(cmd, zero_ARG, 1);
-
- /*
- * Each LV type that can be converted.
- * (The existing type of the LV, not a requested type.)
- */
- if (lv_is_cow(lv)) {
- ret = _convert_cow_snapshot(cmd, lv, lp);
- goto out;
- }
-
- if (lv_is_thin_volume(lv)) {
- ret = _convert_thin_volume(cmd, lv, lp);
- goto out;
- }
-
- if (lv_is_thin_pool(lv)) {
- ret = _convert_thin_pool(cmd, lv, lp);
- goto out;
- }
-
- if (lv_is_cache(lv)) {
- ret = _convert_cache_volume(cmd, lv, lp);
- goto out;
- }
-
- if (lv_is_cache_pool(lv)) {
- ret = _convert_cache_pool(cmd, lv, lp);
- goto out;
- }
+ if (lv_is_cache(lv))
+ lv = seg_lv(first_seg(lv), 0);
if (lv_is_mirror(lv)) {
ret = _convert_mirror(cmd, lv, lp);
@@ -5300,149 +4684,6 @@ static struct convert_poll_id_list* _convert_poll_id_list_create(struct cmd_cont
return idl;
}
-static int _lvconvert_and_add_to_poll_list(struct cmd_context *cmd,
- struct lvconvert_params *lp,
- struct logical_volume *lv)
-{
- int ret;
- struct lvinfo info;
- struct convert_poll_id_list *idl;
-
- /* _lvconvert() call may alter the reference in lp->lv_to_poll */
- if ((ret = _lvconvert(cmd, lv, lp)) != ECMD_PROCESSED)
- stack;
- else if (lp->need_polling) {
- if (!lv_info(cmd, lp->lv_to_poll, 0, &info, 0, 0) || !info.exists)
- log_print_unless_silent("Conversion starts after activation.");
- else {
- if (!(idl = _convert_poll_id_list_create(cmd, lp->lv_to_poll)))
- return_ECMD_FAILED;
- dm_list_add(&lp->idls, &idl->list);
- }
- }
-
- return ret;
-}
-
-static int _lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
- struct processing_handle *handle)
-{
- struct lvconvert_params *lp = (struct lvconvert_params *) handle->custom_handle;
- struct volume_group *vg = lv->vg;
-
- if (test_mode() && is_lockd_type(vg->lock_type)) {
- log_error("Test mode is not yet supported with lock type %s.",
- vg->lock_type);
- return ECMD_FAILED;
- }
-
- /*
- * lp->pvh holds the list of PVs available for allocation or removal
- */
- if (lp->pv_count) {
- if (!(lp->pvh = create_pv_list(cmd->mem, vg, lp->pv_count, lp->pvs, 0)))
- return_ECMD_FAILED;
- } else
- lp->pvh = &vg->pvs;
-
- lp->lv_to_poll = lv;
-
- return _lvconvert_and_add_to_poll_list(cmd, lp, lv);
-}
-
-static int _lvconvert_merge_single(struct cmd_context *cmd, struct logical_volume *lv,
- struct processing_handle *handle)
-{
- struct lvconvert_params *lp = (struct lvconvert_params *) handle->custom_handle;
-
- lp->lv_to_poll = lv;
-
- return _lvconvert_and_add_to_poll_list(cmd, lp, lv);
-}
-
-int lvconvert(struct cmd_context * cmd, int argc, char **argv)
-{
- int poll_ret, ret;
- struct convert_poll_id_list *idl;
- struct lvconvert_params lp = {
- .conv_type = CONV_OTHER,
- .target_attr = ~0,
- .idls = DM_LIST_HEAD_INIT(lp.idls),
- };
- struct processing_handle *handle = init_processing_handle(cmd, NULL);
-
- cmd->command->flags &= ~GET_VGNAME_FROM_OPTIONS;
-
- if (!handle) {
- log_error("Failed to initialize processing handle.");
- return ECMD_FAILED;
- }
-
- handle->custom_handle = &lp;
-
- if (!_read_params(cmd, argc, argv, &lp)) {
- ret = EINVALID_CMD_LINE;
- goto_out;
- }
-
- if (lp.merge) {
- ret = process_each_lv(cmd, argc, argv, NULL, NULL,
- READ_FOR_UPDATE, handle, NULL, &_lvconvert_merge_single);
- } else {
- int saved_ignore_suspended_devices = ignore_suspended_devices();
-
- if (lp.uncache) {
- init_ignore_suspended_devices(1);
- cmd->handles_missing_pvs = 1;
- }
-
- ret = process_each_lv(cmd, 0, NULL, lp.vg_name, lp.lv_name,
- READ_FOR_UPDATE, handle, NULL, &_lvconvert_single);
-
- init_ignore_suspended_devices(saved_ignore_suspended_devices);
- }
-
- dm_list_iterate_items(idl, &lp.idls) {
- poll_ret = _lvconvert_poll_by_id(cmd, idl->id,
- lp.wait_completion ? 0 : 1U,
- idl->is_merging_origin,
- idl->is_merging_origin_thin);
- if (poll_ret > ret)
- ret = poll_ret;
- }
-
-out:
- if (lp.policy_settings)
- dm_config_destroy(lp.policy_settings);
-
- destroy_processing_handle(cmd, handle);
-
- return ret;
-}
-
-/*
- * Below is code that has transitioned to using command defs.
- * ----------------------------------------------------------
- *
- * This code does not use read_params (or any other param reading
- * functions associated with it), or the lp struct. Those have
- * been primary vehicles for entangling all the lvconvert operations,
- * so avoiding them is important for untangling. They were also
- * heavily used for trying to figure out what the lvconvert operation
- * was meant to be doing, and that is no longer needed since the
- * command def provides it.
- *
- * All input data is already available from cmd->arg_values and
- * cmd->position_argv (the --option args in the former, the position
- * args in the later.) There is no need to copy these values into
- * another redundant struct of input values which just obfuscates.
- *
- * The new lvconvert_result struct, passed via custom_handle, is
- * used for *returning* data from processing, not for passing data
- * into processing.
- */
-
-
/*
* Data/results accumulated during processing.
*/
@@ -6360,9 +5601,274 @@ int lvconvert_split_cachepool_cmd(struct cmd_context *cmd, int argc, char **argv
NULL, NULL, &_lvconvert_split_cachepool_single);
}
+static int _lvconvert_raid_types_single(struct cmd_context *cmd, struct logical_volume *lv,
+ struct processing_handle *handle)
+{
+ struct lvconvert_params *lp = (struct lvconvert_params *) handle->custom_handle;
+ struct dm_list *use_pvh;
+ struct convert_poll_id_list *idl;
+ struct lvinfo info;
+ int ret;
+
+ if (cmd->position_argc > 1) {
+ /* First pos arg is required LV, remaining are optional PVs. */
+ if (!(use_pvh = create_pv_list(cmd->mem, lv->vg, cmd->position_argc - 1, cmd->position_argv + 1, 0)))
+ return_ECMD_FAILED;
+ lp->pv_count = cmd->position_argc - 1;
+ } else
+ use_pvh = &lv->vg->pvs;
+
+ lp->pvh = use_pvh;
+
+ lp->lv_to_poll = lv;
+
+ ret = _lvconvert(cmd, lv, lp);
+
+ if (ret != ECMD_PROCESSED)
+ return_ECMD_FAILED;
+
+ if (lp->need_polling) {
+ /* _lvconvert() call may alter the reference in lp->lv_to_poll */
+ if (!lv_info(cmd, lp->lv_to_poll, 0, &info, 0, 0) || !info.exists)
+ log_print_unless_silent("Conversion starts after activation.");
+ else {
+ if (!(idl = _convert_poll_id_list_create(cmd, lp->lv_to_poll)))
+ return_ECMD_FAILED;
+ dm_list_add(&lp->idls, &idl->list);
+ }
+ }
+
+ return ECMD_PROCESSED;
+}
+
+static int _lvconvert_raid_types_check(struct cmd_context *cmd, struct logical_volume *lv,
+ struct processing_handle *handle,
+ int lv_is_named_arg)
+{
+ int lvt_enum = get_lvt_enum(lv);
+ struct lv_types *lvtype = get_lv_type(lvt_enum);
+
+ if (!lv_is_visible(lv)) {
+ if (!lv_is_cache_pool_metadata(lv) &&
+ !lv_is_cache_pool_data(lv) &&
+ !lv_is_thin_pool_metadata(lv) &&
+ !lv_is_thin_pool_data(lv) &&
+ !lv_is_used_cache_pool(lv) &&
+ !lv_is_mirrored(lv) &&
+ !lv_is_raid(lv))
+ goto fail_hidden;
+ }
+
+ /*
+ * FIXME: this validation could be done by command defs.
+ *
+ * Outside the standard linear/striped/mirror/raid LV
+ * types, cache is the only special LV type that is handled
+ * (the command is redirected to origin).
+ */
+ switch (lvt_enum) {
+ case thin_LVT:
+ case thinpool_LVT:
+ case cachepool_LVT:
+ case snapshot_LVT:
+ log_error("Operation not permitted (%s %d) on LV %s type %s.",
+ cmd->command->command_line_id, cmd->command->command_line_enum,
+ display_lvname(lv), lvtype ? lvtype->name : "unknown");
+ return 0;
+ }
+
+ return 1;
+
+ fail_hidden:
+ log_error("Operation not permitted (%s %d) on hidden LV %s.",
+ cmd->command->command_line_id, cmd->command->command_line_enum,
+ display_lvname(lv));
+ return 0;
+}
+
+int lvconvert_raid_types_cmd(struct cmd_context * cmd, int argc, char **argv)
+{
+ int poll_ret, ret;
+ int saved_ignore_suspended_devices;
+ struct processing_handle *handle;
+ struct convert_poll_id_list *idl;
+ struct lvconvert_params lp = {
+ .conv_type = CONV_OTHER,
+ .target_attr = ~0,
+ .idls = DM_LIST_HEAD_INIT(lp.idls),
+ };
+
+ if (!(handle = init_processing_handle(cmd, NULL))) {
+ log_error("Failed to initialize processing handle.");
+ return ECMD_FAILED;
+ }
+
+ handle->custom_handle = &lp;
+
+ if (!_read_params(cmd, &lp)) {
+ ret = EINVALID_CMD_LINE;
+ goto_out;
+ }
+
+ saved_ignore_suspended_devices = ignore_suspended_devices();
+
+ ret = process_each_lv(cmd, 1, cmd->position_argv, NULL, NULL, READ_FOR_UPDATE,
+ handle, &_lvconvert_raid_types_check, &_lvconvert_raid_types_single);
+
+ init_ignore_suspended_devices(saved_ignore_suspended_devices);
+
+ dm_list_iterate_items(idl, &lp.idls) {
+ poll_ret = _lvconvert_poll_by_id(cmd, idl->id,
+ lp.wait_completion ? 0 : 1U,
+ idl->is_merging_origin,
+ idl->is_merging_origin_thin);
+ if (poll_ret > ret)
+ ret = poll_ret;
+ }
+
+out:
+ destroy_processing_handle(cmd, handle);
+
+ return ret;
+}
+
+/*
+ * change mirror log
+ */
+
+static int _lvconvert_visible_check(struct cmd_context *cmd, struct logical_volume *lv,
+ struct processing_handle *handle,
+ int lv_is_named_arg)
+{
+ if (!lv_is_visible(lv)) {
+ log_error("Operation not permitted (%s %d) on hidden LV %s.",
+ cmd->command->command_line_id, cmd->command->command_line_enum,
+ display_lvname(lv));
+ return 0;
+ }
+
+ return 1;
+}
+
+static int _lvconvert_change_mirrorlog_single(struct cmd_context *cmd, struct logical_volume *lv,
+ struct processing_handle *handle)
+{
+ struct lvconvert_params *lp = (struct lvconvert_params *) handle->custom_handle;
+ struct dm_list *use_pvh;
+
+ if (cmd->position_argc > 1) {
+ /* First pos arg is required LV, remaining are optional PVs. */
+ if (!(use_pvh = create_pv_list(cmd->mem, lv->vg, cmd->position_argc - 1, cmd->position_argv + 1, 0)))
+ return_ECMD_FAILED;
+ lp->pv_count = cmd->position_argc - 1;
+ } else
+ use_pvh = &lv->vg->pvs;
+
+ lp->pvh = use_pvh;
+
+ /* FIXME: extract the mirrorlog functionality out of _lvconvert()? */
+ return _lvconvert(cmd, lv, lp);
+}
+
+int lvconvert_change_mirrorlog_cmd(struct cmd_context * cmd, int argc, char **argv)
+{
+ struct processing_handle *handle;
+ struct lvconvert_params lp = {
+ .conv_type = CONV_OTHER,
+ .target_attr = ~0,
+ .idls = DM_LIST_HEAD_INIT(lp.idls),
+ };
+ int ret;
+
+ if (!(handle = init_processing_handle(cmd, NULL))) {
+ log_error("Failed to initialize processing handle.");
+ return ECMD_FAILED;
+ }
+
+ handle->custom_handle = &lp;
+
+ /* FIXME: extract the relevant bits of read_params and put here. */
+ if (!_read_params(cmd, &lp)) {
+ ret = EINVALID_CMD_LINE;
+ goto_out;
+ }
+
+ ret = process_each_lv(cmd, 1, cmd->position_argv, NULL, NULL, READ_FOR_UPDATE,
+ handle, &_lvconvert_visible_check, &_lvconvert_change_mirrorlog_single);
+
+out:
+ destroy_processing_handle(cmd, handle);
+
+ return ret;
+}
+
+/*
+ * split mirror images
+ */
+
+static int _lvconvert_split_mirror_images_single(struct cmd_context *cmd, struct logical_volume *lv,
+ struct processing_handle *handle)
+{
+ struct lvconvert_params *lp = (struct lvconvert_params *) handle->custom_handle;
+ struct dm_list *use_pvh;
+
+ if (cmd->position_argc > 1) {
+ /* First pos arg is required LV, remaining are optional PVs. */
+ if (!(use_pvh = create_pv_list(cmd->mem, lv->vg, cmd->position_argc - 1, cmd->position_argv + 1, 0)))
+ return_ECMD_FAILED;
+ lp->pv_count = cmd->position_argc - 1;
+ } else
+ use_pvh = &lv->vg->pvs;
+
+ lp->pvh = use_pvh;
+
+ /* FIXME: extract the split functionality out of _lvconvert()? */
+ return _lvconvert(cmd, lv, lp);
+}
+
+int lvconvert_split_mirror_images_cmd(struct cmd_context * cmd, int argc, char **argv)
+{
+ struct processing_handle *handle;
+ struct lvconvert_params lp = {
+ .conv_type = CONV_OTHER,
+ .target_attr = ~0,
+ .idls = DM_LIST_HEAD_INIT(lp.idls),
+ };
+ int ret;
+
+ if (!(handle = init_processing_handle(cmd, NULL))) {
+ log_error("Failed to initialize processing handle.");
+ return ECMD_FAILED;
+ }
+
+ handle->custom_handle = &lp;
+
+ /* FIXME: extract the relevant bits of read_params and put here. */
+ if (!_read_params(cmd, &lp)) {
+ ret = EINVALID_CMD_LINE;
+ goto_out;
+ }
+
+ /* FIXME: are there any hidden LVs that should be disallowed? */
+
+ ret = process_each_lv(cmd, 1, cmd->position_argv, NULL, NULL, READ_FOR_UPDATE,
+ handle, NULL, &_lvconvert_split_mirror_images_single);
+
+out:
+ destroy_processing_handle(cmd, handle);
+
+ return ret;
+}
+
+/*
+ * merge mirror images
+ *
+ * Called from both lvconvert --mergemirrors and lvconvert --merge.
+ */
+
static int _lvconvert_merge_mirror_images_single(struct cmd_context *cmd,
- struct logical_volume *lv,
- struct processing_handle *handle)
+ struct logical_volume *lv,
+ struct processing_handle *handle)
{
if (!lv_raid_merge(lv))
return ECMD_FAILED;
@@ -6372,10 +5878,11 @@ static int _lvconvert_merge_mirror_images_single(struct cmd_context *cmd,
int lvconvert_merge_mirror_images_cmd(struct cmd_context *cmd, int argc, char **argv)
{
+ /* arg can be a VG name, which is the standard option usage */
cmd->command->flags &= ~GET_VGNAME_FROM_OPTIONS;
return process_each_lv(cmd, cmd->position_argc, cmd->position_argv, NULL, NULL, READ_FOR_UPDATE,
- NULL, NULL, &_lvconvert_merge_mirror_images_single);
+ NULL, &_lvconvert_visible_check, &_lvconvert_merge_mirror_images_single);
}
static int _lvconvert_merge_generic_single(struct cmd_context *cmd,
@@ -6432,3 +5939,15 @@ int lvconvert_merge_cmd(struct cmd_context *cmd, int argc, char **argv)
return ret;
}
+/*
+ * All lvconvert command defs have their own function,
+ * so the generic function name is unused.
+ */
+
+int lvconvert(struct cmd_context *cmd, int argc, char **argv)
+{
+ log_error(INTERNAL_ERROR "Missing function for command definition %s.",
+ cmd->command->command_line_id);
+ return ECMD_FAILED;
+}
+
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 12e1a10d8..3538951f4 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -147,20 +147,17 @@ struct command_function command_functions[COMMAND_ID_COUNT] = {
{ lvconvert_split_and_keep_cachepool_CMD, lvconvert_split_cachepool_cmd },
{ lvconvert_split_and_remove_cachepool_CMD, lvconvert_split_cachepool_cmd },
+ /* lvconvert raid-related type conversions */
+ { lvconvert_raid_types_CMD, lvconvert_raid_types_cmd },
+
/* lvconvert utilities for raid/mirror */
- { lvconvert_merge_mirror_images_CMD, lvconvert_merge_mirror_images_cmd },
-#if 0
- { lvconvert_split_mirror_images_CMD, lvconvert_split_mirror_images_cmd },
+ { lvconvert_split_mirror_images_CMD, lvconvert_split_mirror_images_cmd},
{ lvconvert_change_mirrorlog_CMD, lvconvert_change_mirrorlog_cmd },
-#endif
+ { lvconvert_merge_mirror_images_CMD, lvconvert_merge_mirror_images_cmd },
/* redirected to merge_snapshot/merge_thin/merge_mirrors */
{ lvconvert_merge_CMD, lvconvert_merge_cmd },
-#if 0
- /* all raid-related type conversions */
- { lvconvert_raid_types_CMD, lvconvert_raid_types_cmd },
-#endif
};
diff --git a/tools/tools.h b/tools/tools.h
index e165a4dda..9f4666f65 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -270,7 +270,10 @@ int lvconvert_swap_pool_metadata_cmd(struct cmd_context *cmd, int argc, char **a
int lvconvert_merge_thin_cmd(struct cmd_context *cmd, int argc, char **argv);
int lvconvert_split_cachepool_cmd(struct cmd_context *cmd, int argc, char **argv);
+int lvconvert_raid_types_cmd(struct cmd_context * cmd, int argc, char **argv);
+int lvconvert_split_mirror_images_cmd(struct cmd_context * cmd, int argc, char **argv);
int lvconvert_merge_mirror_images_cmd(struct cmd_context *cmd, int argc, char **argv);
+int lvconvert_change_mirrorlog_cmd(struct cmd_context * cmd, int argc, char **argv);
int lvconvert_merge_cmd(struct cmd_context *cmd, int argc, char **argv);