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:
parent
7e671e5dd0
commit
dfc516f9bf
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user