1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-02 01:18:26 +03:00

lvconvert: Refactor argument handling code.

Begin disentangling the different lvconvert modes of operation
from each other.
This commit is contained in:
Alasdair G Kergon 2016-06-22 18:40:22 +01:00
parent 7e671e5dd0
commit dfc516f9bf
4 changed files with 206 additions and 107 deletions

View File

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

View File

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

View File

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

View File

@ -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,13 +126,23 @@ 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;
}
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) {
if (lp->cache) {
log_error("Logical volume name for caching is missing.");
@ -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
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;