From dfc516f9bfd35ec36c60165bd319a9b0008764a3 Mon Sep 17 00:00:00 2001 From: Alasdair G Kergon Date: Wed, 22 Jun 2016 18:40:22 +0100 Subject: [PATCH] lvconvert: Refactor argument handling code. Begin disentangling the different lvconvert modes of operation from each other. --- WHATS_NEW | 1 + lib/metadata/metadata-exported.h | 9 +- lib/metadata/raid_manip.c | 9 +- tools/lvconvert.c | 294 ++++++++++++++++++++----------- 4 files changed, 206 insertions(+), 107 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 86a53ce8b..ce77b6ca1 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.158 - ================================= + Refactor lvconvert argument handling code. Add --logonly option to report only cmd log for a command, not other reports. Add log/command_log_selection to configure default selection used on cmd log. Use 'orphan' object type in cmd log for groups to collect PVs not yet in VGs. diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h index a88ba1e25..5948404be 100644 --- a/lib/metadata/metadata-exported.h +++ b/lib/metadata/metadata-exported.h @@ -1202,8 +1202,13 @@ int lv_raid_split(struct logical_volume *lv, const char *split_name, int lv_raid_split_and_track(struct logical_volume *lv, struct dm_list *splittable_pvs); int lv_raid_merge(struct logical_volume *lv); -int lv_raid_reshape(struct logical_volume *lv, - const struct segment_type *new_segtype); +int lv_raid_convert(struct logical_volume *lv, + const struct segment_type *new_segtype, + int yes, int force, + const unsigned image_count, + const unsigned stripes, + const unsigned new_stripe_size, + struct dm_list *allocate_pvs); int lv_raid_replace(struct logical_volume *lv, struct dm_list *remove_pvs, struct dm_list *allocate_pvs); int lv_raid_remove_missing(struct logical_volume *lv); diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c index 739e1449d..132eef3bd 100644 --- a/lib/metadata/raid_manip.c +++ b/lib/metadata/raid_manip.c @@ -1469,8 +1469,13 @@ static int _convert_mirror_to_raid1(struct logical_volume *lv, * * Returns: 1 on success, 0 on failure */ -int lv_raid_reshape(struct logical_volume *lv, - const struct segment_type *new_segtype) +int lv_raid_convert(struct logical_volume *lv, + const struct segment_type *new_segtype, + int yes, int force, + unsigned new_image_count, + const unsigned new_stripes, + const unsigned new_stripe_size, + struct dm_list *allocate_pvs) { struct lv_segment *seg = first_seg(lv); diff --git a/tools/lvconvert.c b/tools/lvconvert.c index ae9b0528d..9c7f9c24f 100644 --- a/tools/lvconvert.c +++ b/tools/lvconvert.c @@ -19,18 +19,29 @@ #include "lvconvert_poll.h" struct lvconvert_params { + /* Exactly one of these options is chosen */ + int merge; /* Either merge_snapshot or merge_mirror is also set */ int cache; - int force; + int corelog; + int mirrorlog; + int mirrors_supplied; /* When type_str is not set, this may be set with keep_mimages for --splitmirrors */ + int repair; + int replace; int snapshot; int split; int splitcache; int splitsnapshot; - int merge; - int merge_mirror; - int poolmetadataspare; - int repair; int thin; int uncache; + const char *type_str; /* When this is set, mirrors_supplied may optionally also be set */ + + const struct segment_type *segtype; + + int merge_snapshot; /* merge is also set */ + int merge_mirror; /* merge is also set */ + + int poolmetadataspare; + int force; int yes; int zero; @@ -55,7 +66,6 @@ struct lvconvert_params { const char *policy_name; /* cache */ struct dm_config_tree *policy_settings; /* cache */ - const struct segment_type *segtype; unsigned target_attr; alloc_policy_t alloc; @@ -116,11 +126,21 @@ static int _lvconvert_name_params(struct lvconvert_params *lp, 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; } - return 1; + + if (!strstr((*pargv)[0], "_rimage_")) { /* Snapshot */ + if (!(lp->segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_SNAPSHOT))) + return_0; + lp->merge_snapshot = 1; + return 1; + } + + /* Mirror */ + lp->merge_mirror = 1; } if (!*pargc) { @@ -191,7 +211,7 @@ static int _lvconvert_name_params(struct lvconvert_params *lp, if (!lp->merge_mirror && !lp->repair && - !arg_is_set(cmd, splitmirrors_ARG) && + !lp->keep_mimages && !strstr(lp->lv_name, "_tdata") && !strstr(lp->lv_name, "_tmeta") && !strstr(lp->lv_name, "_cdata") && @@ -247,6 +267,7 @@ static int _check_conversion_type(struct cmd_context *cmd, const char *type_str) /* FIXME: Check thin-pool and thin more thoroughly! */ if (!strcmp(type_str, "snapshot") || + !strcmp(type_str, "striped") || !strncmp(type_str, "raid", 4) || !strcmp(type_str, "cache-pool") || !strcmp(type_str, "cache") || !strcmp(type_str, "thin-pool") || !strcmp(type_str, "thin")) @@ -257,43 +278,57 @@ static int _check_conversion_type(struct cmd_context *cmd, const char *type_str) } /* -s/--snapshot and --type snapshot are synonyms */ -static int _snapshot_type_requested(struct cmd_context *cmd, const char *type_str) { +static int _snapshot_type_requested(struct cmd_context *cmd, const char *type_str) +{ return (arg_is_set(cmd, snapshot_ARG) || !strcmp(type_str, "snapshot")); } + +static int _raid0_type_requested(struct cmd_context *cmd, const char *type_str) +{ + return (!strcmp(type_str, "raid0")); +} + /* mirror/raid* (1,10,4,5,6 and their variants) reshape */ -static int _mirror_or_raid_type_requested(struct cmd_context *cmd, const char *type_str) { - return (arg_is_set(cmd, mirrors_ARG) || !strncmp(type_str, "raid", 4) || !strcmp(type_str, "mirror")); +static int _mirror_or_raid_type_requested(struct cmd_context *cmd, const char *type_str) +{ + return (arg_is_set(cmd, mirrors_ARG) || !strcmp(type_str, "mirror") || + (!strncmp(type_str, "raid", 4) && !_raid0_type_requested(cmd, type_str))); +} + +static int _striped_type_requested(struct cmd_context *cmd, const char *type_str) +{ + return (!strcmp(type_str, "striped")); } static int _read_pool_params(struct cmd_context *cmd, int *pargc, char ***pargv, - const char *type_str, struct lvconvert_params *lp) + struct lvconvert_params *lp) { int cachepool = 0; int thinpool = 0; if ((lp->pool_data_name = arg_str_value(cmd, cachepool_ARG, NULL))) { - if (type_str[0] && - strcmp(type_str, "cache") && - strcmp(type_str, "cache-pool")) { + if (lp->type_str[0] && + strcmp(lp->type_str, "cache") && + strcmp(lp->type_str, "cache-pool")) { log_error("--cachepool argument is only valid with " " the cache or cache-pool segment type."); return 0; } cachepool = 1; - type_str = "cache-pool"; - } else if (!strcmp(type_str, "cache-pool")) + lp->type_str = "cache-pool"; + } else if (!strcmp(lp->type_str, "cache-pool")) cachepool = 1; else if ((lp->pool_data_name = arg_str_value(cmd, thinpool_ARG, NULL))) { - if (type_str[0] && - strcmp(type_str, "thin") && - strcmp(type_str, "thin-pool")) { + if (lp->type_str[0] && + strcmp(lp->type_str, "thin") && + strcmp(lp->type_str, "thin-pool")) { log_error("--thinpool argument is only valid with " " the thin or thin-pool segment type."); return 0; } thinpool = 1; - type_str = "thin-pool"; - } else if (!strcmp(type_str, "thin-pool")) + lp->type_str = "thin-pool"; + } else if (!strcmp(lp->type_str, "thin-pool")) thinpool = 1; if (lp->cache && !cachepool) { @@ -326,7 +361,7 @@ static int _read_pool_params(struct cmd_context *cmd, int *pargc, char ***pargv, splitmirrors_ARG, splitsnapshot_ARG, -1)) return_0; - if (!(lp->segtype = get_segtype_from_string(cmd, type_str))) + if (!(lp->segtype = get_segtype_from_string(cmd, lp->type_str))) return_0; if (!get_pool_params(cmd, lp->segtype, &lp->passed_args, @@ -374,11 +409,13 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv, struct arg_value_group_list *group; int region_size; int pagesize = lvm_getpagesize(); - const char *type_str = arg_str_value(cmd, type_ARG, ""); - if (!_check_conversion_type(cmd, type_str)) + lp->type_str = arg_str_value(cmd, type_ARG, ""); + + if (arg_is_set(cmd, type_ARG) && !_check_conversion_type(cmd, lp->type_str)) return_0; + /* If --repair, check for incompatible args. */ if (arg_is_set(cmd, repair_ARG)) { if (arg_outside_list_is_set(cmd, "cannot be used with --repair", repair_ARG, @@ -390,7 +427,12 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv, lp->repair = 1; } - if (arg_is_set(cmd, mirrorlog_ARG) && arg_is_set(cmd, corelog_ARG)) { + if (arg_is_set(cmd, mirrorlog_ARG)) + lp->mirrorlog = 1; + if (arg_is_set(cmd, corelog_ARG)) + lp->corelog = 1; + + if (lp->mirrorlog && lp->corelog) { log_error("--mirrorlog and --corelog are incompatible."); return 0; } @@ -432,57 +474,40 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv, lp->uncache = 1; } - if ((_snapshot_type_requested(cmd, type_str) || arg_is_set(cmd, merge_ARG)) && - (arg_is_set(cmd, mirrorlog_ARG) || _mirror_or_raid_type_requested(cmd, type_str) || - lp->repair || arg_is_set(cmd, thinpool_ARG))) { - log_error("--snapshot/--type snapshot or --merge argument " - "cannot be mixed with --mirrors/--type mirror/--type raid*, " - "--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, type_str) || - lp->repair || - arg_is_set(cmd, thinpool_ARG))) { - log_error("--stripes or --stripesize argument is only valid " - "with --mirrors/--type mirror/--type raid*, --repair and --thinpool"); - return 0; - } - if (arg_is_set(cmd, cache_ARG)) lp->cache = 1; - if (!strcmp(type_str, "cache")) + if (!strcmp(lp->type_str, "cache")) lp->cache = 1; else if (lp->cache) { - if (type_str[0]) { - log_error("--cache is incompatible with --type %s", type_str); + if (lp->type_str[0]) { + log_error("--cache is incompatible with --type %s", lp->type_str); return 0; } - type_str = "cache"; + lp->type_str = "cache"; } if (arg_is_set(cmd, thin_ARG)) lp->thin = 1; - if (!strcmp(type_str, "thin")) + if (!strcmp(lp->type_str, "thin")) lp->thin = 1; else if (lp->thin) { - if (type_str[0]) { - log_error("--thin is incompatible with --type %s", type_str); + if (lp->type_str[0]) { + log_error("--thin is incompatible with --type %s", lp->type_str); return 0; } - type_str = "thin"; + lp->type_str = "thin"; } - if (!_read_pool_params(cmd, &argc, &argv, type_str, lp)) + /* May set lp->segtype */ + if (!_read_pool_params(cmd, &argc, &argv, lp)) return_0; if (!arg_is_set(cmd, background_ARG)) lp->wait_completion = 1; - if (_snapshot_type_requested(cmd, type_str)) { + if (_snapshot_type_requested(cmd, lp->type_str)) { if (arg_is_set(cmd, merge_ARG)) { log_error("--snapshot and --merge are mutually exclusive."); return 0; @@ -493,6 +518,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv, if (lp->split) { lp->lv_split_name = arg_str_value(cmd, name_ARG, NULL); + /* * The '--splitmirrors n' argument is equivalent to '--mirrors -n' * (note the minus sign), except that it signifies the additional @@ -500,7 +526,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv, * discarding it. */ } else if (arg_is_set(cmd, splitmirrors_ARG)) { - if (_mirror_or_raid_type_requested(cmd, type_str)) { + if (_mirror_or_raid_type_requested(cmd, lp->type_str)) { log_error("--mirrors/--type mirror/--type raid* and --splitmirrors are " "mutually exclusive."); return 0; @@ -521,38 +547,84 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv, return 0; } - if (arg_is_set(cmd, merge_ARG)) { - if ((argc == 1) && strstr(argv[0], "_rimage_")) - lp->merge_mirror = 1; - else - lp->merge = 1; + if (arg_is_set(cmd, merge_ARG)) + lp->merge = 1; + + if (arg_is_set(cmd, replace_ARG)) + lp->replace = 1; + + /* If no other case was identified, then use of --stripes means --type striped */ + if (!arg_is_set(cmd, type_ARG) && !lp->merge && !lp->splitsnapshot && + !lp->splitcache && !lp->split && !lp->snapshot && !lp->uncache && !lp->cache && !lp->thin && + !lp->replace && !_mirror_or_raid_type_requested(cmd, lp->type_str) && + !lp->repair && !lp->mirrorlog && !lp->corelog && + (arg_is_set(cmd, stripes_long_ARG) || arg_is_set(cmd, stripesize_ARG))) + lp->type_str = "striped"; + + if ((_snapshot_type_requested(cmd, lp->type_str) || lp->merge) && + (lp->mirrorlog || _mirror_or_raid_type_requested(cmd, lp->type_str) || + lp->repair || arg_is_set(cmd, thinpool_ARG) || _raid0_type_requested(cmd, lp->type_str) || + _striped_type_requested(cmd, lp->type_str))) { + log_error("--snapshot/--type snapshot or --merge argument " + "cannot be mixed with --mirrors/--type mirror/--type raid*/--stripes/--type striped, " + "--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(cmd, lp->type_str) || + _raid0_type_requested(cmd, lp->type_str) || lp->repair || arg_is_set(cmd, thinpool_ARG))) { + log_error("--stripes or --stripesize argument is only valid " + "with --mirrors/--type mirror/--type raid*/--type striped, --repair and --thinpool"); + return 0; } if (arg_is_set(cmd, mirrors_ARG)) { /* - * --splitmirrors has been chosen as the mechanism for - * specifying the intent of detaching and keeping a mimage - * versus an additional qualifying argument being added here. + * --splitmirrors is the mechanism for detaching and keeping a mimage */ + lp->mirrors_supplied = 1; lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0); lp->mirrors_sign = arg_sign_value(cmd, mirrors_ARG, SIGN_NONE); } lp->alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, ALLOC_INHERIT); - /* There are six types of lvconvert. */ - if (lp->merge) { /* Snapshot merge */ + /* + * Final checking of each case: + * lp->merge + * lp->splitsnapshot + * lp->splitcache + * lp->split + * lp->uncache + * lp->cache + * lp->thin + * lp->snapshot + * lp->replace + * --type mirror|raid lp->repair lp->mirrorlog lp->corelog + * --type raid0|striped + */ + if (lp->merge) { /* Snapshot or mirror merge */ 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; - - if (!(lp->segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_SNAPSHOT))) - return_0; } else if (lp->splitsnapshot) /* Destroy snapshot retaining cow as separate LV */ ; + else if (lp->splitcache) + ; + else if (lp->split) + ; + else if (lp->uncache) + ; + else if (lp->cache) + ; + else if (lp->thin) + ; + else if (lp->keep_mimages) /* --splitmirrors */ + ; else if (lp->snapshot) { /* Snapshot creation from pre-existing cow */ if (!argc) { log_error("Please provide logical volume path for snapshot origin."); @@ -592,7 +664,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv, lp->zero = (lp->segtype->flags & SEG_CANNOT_BE_ZEROED) ? 0 : arg_int_value(cmd, zero_ARG, 1); - } else if (arg_is_set(cmd, replace_ARG)) { /* RAID device replacement */ + } else if (lp->replace) { /* RAID device replacement */ lp->replace_pv_count = arg_count(cmd, replace_ARG); lp->replace_pvs = dm_pool_alloc(cmd->mem, sizeof(char *) * lp->replace_pv_count); if (!lp->replace_pvs) @@ -612,10 +684,8 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv, tmp_str))) return_0; } - } else if (_mirror_or_raid_type_requested(cmd, type_str) || - arg_is_set(cmd, repair_ARG) || - arg_is_set(cmd, mirrorlog_ARG) || - arg_is_set(cmd, corelog_ARG)) { /* Mirrors (and some RAID functions) */ + } else if (_mirror_or_raid_type_requested(cmd, lp->type_str) || + lp->repair || lp->mirrorlog || lp->corelog) { /* Mirrors (and some RAID functions) */ if (arg_is_set(cmd, chunksize_ARG)) { log_error("--chunksize is only available with snapshots or pools."); return 0; @@ -630,7 +700,6 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv, * --regionsize is only valid if converting an LV into a mirror. * Checked when we know the state of the LV being converted. */ - if (arg_is_set(cmd, regionsize_ARG)) { if (arg_sign_value(cmd, regionsize_ARG, SIGN_NONE) == SIGN_MINUS) { @@ -671,7 +740,8 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv, if (!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size)) return_0; - if (arg_is_set(cmd, mirrors_ARG) && !lp->mirrors) { + /* FIXME man page says in one place that --type and --mirrors can't be mixed */ + if (lp->mirrors_supplied && !lp->mirrors) { /* down-converting to linear/stripe? */ if (!(lp->segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_STRIPED))) @@ -681,6 +751,17 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv, if (!(lp->segtype = get_segtype_from_string(cmd, arg_str_value(cmd, type_ARG, find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL))))) return_0; } /* else segtype will default to current type */ + } else if (_raid0_type_requested(cmd, lp->type_str) || _striped_type_requested(cmd, lp->type_str)) { /* striped or raid0 */ + if (arg_from_list_is_set(cmd, "cannot be used with --type raid0 or --type striped", + chunksize_ARG, corelog_ARG, mirrors_ARG, mirrorlog_ARG, regionsize_ARG, zero_ARG, + -1)) + return_0; + + if (!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size)) + return_0; + + if (!(lp->segtype = get_segtype_from_string(cmd, lp->type_str))) + return_0; } lp->force = arg_count(cmd, force_ARG); @@ -1139,7 +1220,7 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd, *old_mimage_count = lv_mirror_count(lv); *old_log_count = _get_log_count(lv); - if (is_lockd_type(lv->vg->lock_type) && arg_is_set(cmd, splitmirrors_ARG)) { + if (is_lockd_type(lv->vg->lock_type) && lp->keep_mimages) { /* FIXME: we need to create a lock for the new LV. */ log_error("Unable to split mirrors in VG with lock_type %s", lv->vg->lock_type); return 0; @@ -1150,9 +1231,9 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd, * * If called with no argument, try collapsing the resync layers */ - if (!arg_is_set(cmd, mirrors_ARG) && !arg_is_set(cmd, mirrorlog_ARG) && - !arg_is_set(cmd, corelog_ARG) && !arg_is_set(cmd, regionsize_ARG) && - !arg_is_set(cmd, splitmirrors_ARG) && !lp->repair) { + if (!lp->mirrors_supplied && !lp->mirrorlog && + !lp->corelog && !arg_is_set(cmd, regionsize_ARG) && + !lp->keep_mimages && !lp->repair) { *new_mimage_count = *old_mimage_count; *new_log_count = *old_log_count; @@ -1164,7 +1245,7 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd, /* * Adjusting mimage count? */ - if (!arg_is_set(cmd, mirrors_ARG) && !arg_is_set(cmd, splitmirrors_ARG)) + if (!lp->mirrors_supplied && !lp->keep_mimages) lp->mirrors = *old_mimage_count; else if (lp->mirrors_sign == SIGN_PLUS) lp->mirrors = *old_mimage_count + lp->mirrors; @@ -1207,11 +1288,10 @@ static int _lvconvert_mirrors_parse_params(struct cmd_context *cmd, * position that the user would like a 'disk' log. */ *new_log_count = (*old_mimage_count > 1) ? *old_log_count : 1; - if (!arg_is_set(cmd, corelog_ARG) && !arg_is_set(cmd, mirrorlog_ARG)) + if (!lp->corelog && !lp->mirrorlog) return 1; - *new_log_count = arg_int_value(cmd, mirrorlog_ARG, - arg_is_set(cmd, corelog_ARG) ? MIRROR_LOG_CORE : DEFAULT_MIRRORLOG); + *new_log_count = arg_int_value(cmd, mirrorlog_ARG, lp->corelog ? MIRROR_LOG_CORE : DEFAULT_MIRRORLOG); /* * No mirrored logs for cluster mirrors until @@ -1665,6 +1745,10 @@ static int _is_valid_raid_conversion(const struct segment_type *from_segtype, if (from_segtype == to_segtype) return 1; + /* Support raid0 <-> striped conversions */ + if (segtype_is_striped(from_segtype) && segtype_is_striped(to_segtype)) + return 1; + if (!segtype_is_raid(from_segtype) && !segtype_is_raid(to_segtype)) return_0; /* Not converting to or from RAID? */ @@ -1710,8 +1794,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l lp->segtype = seg->segtype; /* Can only change image count for raid1 and linear */ - if (arg_is_set(cmd, mirrors_ARG) && - !seg_is_mirrored(seg) && !seg_is_linear(seg)) { + if (lp->mirrors_supplied && !seg_is_mirrored(seg) && !seg_is_linear(seg)) { log_error("'--mirrors/-m' is not compatible with %s", lvseg_name(seg)); return 0; @@ -1727,13 +1810,13 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l return 0; } - if (seg_is_linear(seg) && !lp->merge_mirror && !arg_is_set(cmd, mirrors_ARG)) { + if (seg_is_linear(seg) && !lp->merge_mirror && !lp->mirrors_supplied) { log_error("Raid conversions require -m/--mirrors"); return 0; } /* Change number of RAID1 images */ - if (arg_is_set(cmd, mirrors_ARG) || arg_is_set(cmd, splitmirrors_ARG)) { + if (lp->mirrors_supplied || lp->keep_mimages) { image_count = lv_raid_image_count(lv); if (lp->mirrors_sign == SIGN_PLUS) image_count += lp->mirrors; @@ -1744,8 +1827,7 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l if (image_count < 1) { log_error("Unable to %s images by specified amount", - arg_is_set(cmd, splitmirrors_ARG) ? - "split" : "reduce"); + lp->keep_mimages ? "split" : "reduce"); return 0; } } @@ -1756,17 +1838,24 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l if (arg_is_set(cmd, trackchanges_ARG)) return lv_raid_split_and_track(lv, lp->pvh); - if (arg_is_set(cmd, splitmirrors_ARG)) + if (lp->keep_mimages) return lv_raid_split(lv, lp->lv_split_name, image_count, lp->pvh); - if (arg_is_set(cmd, mirrors_ARG)) + if (lp->mirrors_supplied) return lv_raid_change_image_count(lv, image_count, lp->pvh); - if (arg_is_set(cmd, type_ARG)) - return lv_raid_reshape(lv, lp->segtype); + if ((seg_is_linear(seg) || seg_is_striped(seg) || seg_is_mirrored(seg) || lv_is_raid(lv)) && + ((lp->type_str && lp->type_str[0]) || image_count)) { + if (segtype_is_any_raid0(lp->segtype) && + !(lp->target_attr & RAID_FEATURE_RAID0)) { + log_error("RAID module does not support RAID0."); + return 0; + } + return lv_raid_convert(lv, lp->segtype, lp->yes, lp->force, image_count, lp->stripes, lp->stripe_size, lp->pvh); + } - if (arg_is_set(cmd, replace_ARG)) + if (lp->replace) return lv_raid_replace(lv, lp->replace_pvh, lp->pvh); if (lp->repair) { @@ -1778,7 +1867,8 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l return 0; } - if (!lv_raid_percent(lv, &sync_percent)) { + if (!seg_is_striped(seg) && !seg_is_any_raid0(seg) && + !lv_raid_percent(lv, &sync_percent)) { log_error("Unable to determine sync status of %s/%s.", lv->vg->name, lv->name); return 0; @@ -3256,7 +3346,7 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv, return ECMD_FAILED; } - if (lv_is_cow(lv) && !lp->merge && !lp->splitsnapshot) { + if (lv_is_cow(lv) && !lp->merge_snapshot && !lp->splitsnapshot) { log_error("Cannot convert snapshot logical volume %s.", display_lvname(lv)); return ECMD_FAILED; @@ -3331,8 +3421,8 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv, /* forward splitmirror operations to the cache origin, which may be raid * or old-style mirror */ - if (arg_is_set(cmd, splitmirrors_ARG) && lv_is_cache_type(lv) - && (origin = seg_lv(first_seg(lv), 0)) && lv_is_cache_origin(origin)) { + if (lp->keep_mimages && lv_is_cache_type(lv) && + (origin = seg_lv(first_seg(lv), 0)) && lv_is_cache_origin(origin)) { log_warn("WARNING: Selected operation does not work with cache-type LVs."); log_warn("WARNING: Proceeding using the cache origin volume %s instead.", display_lvname(origin)); @@ -3348,12 +3438,12 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv, * the segtype was not specified, then we need * to consult the default. */ - if (arg_is_set(cmd, mirrors_ARG) && !lv_is_mirrored(lv)) { + if (lp->mirrors_supplied && !lv_is_mirrored(lv)) { if (!(lp->segtype = get_segtype_from_string(cmd, find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL)))) return_ECMD_FAILED; } } - if (lp->merge) { + if (lp->merge_snapshot) { if ((lv_is_thin_volume(lv) && !_lvconvert_merge_thin_snapshot(cmd, lv, lp)) || (!lv_is_thin_volume(lv) && !_lvconvert_merge_old_snapshot(cmd, lv, lp))) { log_print_unless_silent("Unable to merge volume %s into its origin.", @@ -3384,9 +3474,7 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv, /* If repairing and using policies, remove missing PVs from VG */ if (lp->repair && arg_is_set(cmd, usepolicies_ARG)) _remove_missing_empty_pv(lv->vg, failed_pvs); - } else if (arg_is_set(cmd, mirrors_ARG) || - arg_is_set(cmd, splitmirrors_ARG) || - lv_is_mirrored(lv)) { + } else if (lp->mirrors_supplied || lp->keep_mimages || lv_is_mirrored(lv)) { if (!archive(lv->vg)) return_ECMD_FAILED; -- 2.43.5