mirror of
git://sourceware.org/git/lvm2.git
synced 2025-09-28 09:44:18 +03:00
Compare commits
19 Commits
v2_02_163
...
dev-dct-cm
Author | SHA1 | Date | |
---|---|---|---|
|
9d326f4ffb | ||
|
8c71fc1cc2 | ||
|
0336b41828 | ||
|
c0a0eedf2e | ||
|
73df2aedf9 | ||
|
114db6f745 | ||
|
d83f2d766d | ||
|
8e9d5d12ae | ||
|
c7bd33d951 | ||
|
8297276967 | ||
|
2ff893cd85 | ||
|
9c9b9b276a | ||
|
6d52b17dfc | ||
|
0973d6e331 | ||
|
a185a2bea2 | ||
|
93b61c07eb | ||
|
e30fb19030 | ||
|
2fed8d8515 | ||
|
480c1c9599 |
@@ -1 +1 @@
|
||||
1.02.133-git (2016-08-10)
|
||||
1.02.134-git (2016-08-15)
|
||||
|
12
WHATS_NEW
12
WHATS_NEW
@@ -1,3 +1,15 @@
|
||||
Version 2.02.165 -
|
||||
===================================
|
||||
Suppress some unnecessary --stripesize parameter warnings.
|
||||
Fix 'pvmove -n name ...' to prohibit collocation of RAID SubLVs
|
||||
|
||||
Version 2.02.164 - 15th August 2016
|
||||
===================================
|
||||
Fix selection of PVs when allocating raid0_meta.
|
||||
Fix sdbus socket leak leading to hang in lvmnotify.
|
||||
Specify max stripes for raid LV types: raid0:64; 1:10; 4,5:63; 6:62; 10:32.
|
||||
Avoid double suffix when naming _rmeta LV paired with _rimage LV.
|
||||
|
||||
Version 2.02.163 - 10th August 2016
|
||||
===================================
|
||||
Add profile for lvmdbusd which uses lvm shell json report output.
|
||||
|
@@ -1,3 +1,6 @@
|
||||
Version 1.02.134 -
|
||||
===================================
|
||||
|
||||
Version 1.02.133 - 10th August 2016
|
||||
===================================
|
||||
Add dm_report_destroy_rows/dm_report_group_output_and_pop_all for lvm shell.
|
||||
|
@@ -23,6 +23,11 @@
|
||||
* - define a configuration array of one or more types:
|
||||
* cfg_array(id, name, parent, flags, types, default_value, since_version, unconfigured_default_value, deprecated_since_version, deprecation_comment, comment)
|
||||
*
|
||||
* - define a configuration setting where the default value is evaluated in runtime
|
||||
* cfg_runtime(id, name, parent, flags, type, since_version, deprecated_since_version, deprecation_comment, comment)
|
||||
* (for each cfg_runtime, you need to define 'get_default_<name>(struct cmd_context *cmd, struct profile *profile)' function
|
||||
* to get the default value in runtime - usually, these functions are placed in config.[ch] file)
|
||||
*
|
||||
*
|
||||
* If default value can't be assigned statically because it depends on some
|
||||
* run-time checks or if it depends on other settings already defined,
|
||||
|
@@ -66,8 +66,13 @@
|
||||
#define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"
|
||||
#define DEFAULT_MIRROR_IMAGE_FAULT_POLICY "remove"
|
||||
#define DEFAULT_MIRROR_MAX_IMAGES 8 /* limited by kernel DM_KCOPYD_MAX_REGIONS */
|
||||
// FIXME Increase this to 64
|
||||
#define DEFAULT_RAID_MAX_IMAGES 8 /* limited by kernel failed devices bitfield in superblock (raid4/5/6 max 253) */
|
||||
/* Limited by kernel failed devices bitfield in superblock (raid4/5/6 MD max 253) */
|
||||
/*
|
||||
* FIXME: Increase these to 64 and further to the MD maximum
|
||||
* once the SubLVs split and name shift got enhanced
|
||||
*/
|
||||
#define DEFAULT_RAID1_MAX_IMAGES 10
|
||||
#define DEFAULT_RAID_MAX_IMAGES 64
|
||||
#define DEFAULT_ALLOCATION_STRIPE_ALL_DEVICES 0 /* Don't stripe across all devices if not -i/--stripes given */
|
||||
|
||||
#define DEFAULT_RAID_FAULT_POLICY "warn"
|
||||
|
@@ -261,10 +261,17 @@ static void _check_raid_seg(struct lv_segment *seg, int *error_count)
|
||||
if (seg->extents_copied > seg->area_len)
|
||||
raid_seg_error_val("extents_copied too large", seg->extents_copied);
|
||||
|
||||
/* Default still 8, change! */
|
||||
if (seg->area_count > DEFAULT_RAID_MAX_IMAGES) {
|
||||
/* Default < 10, change once raid1 split shift and rename SubLVs works! */
|
||||
if (seg_is_raid1(seg)) {
|
||||
if (seg->area_count > DEFAULT_RAID1_MAX_IMAGES) {
|
||||
log_error("LV %s invalid: maximum supported areas %u (is %u) for %s segment",
|
||||
seg->lv->name, DEFAULT_RAID1_MAX_IMAGES, seg->area_count, lvseg_name(seg));
|
||||
if ((*error_count)++ > ERROR_MAX)
|
||||
return;
|
||||
}
|
||||
} else if (seg->area_count > DEFAULT_RAID_MAX_IMAGES) {
|
||||
log_error("LV %s invalid: maximum supported areas %u (is %u) for %s segment",
|
||||
seg->lv->name, DEFAULT_RAID_MAX_IMAGES, seg->area_count, lvseg_name(seg));
|
||||
seg->lv->name, DEFAULT_RAID_MAX_IMAGES, seg->area_count, lvseg_name(seg));
|
||||
if ((*error_count)++ > ERROR_MAX)
|
||||
return;
|
||||
}
|
||||
|
@@ -1272,6 +1272,7 @@ uint32_t find_free_lvnum(struct logical_volume *lv);
|
||||
dm_percent_t copy_percent(const struct logical_volume *lv_mirr);
|
||||
char *generate_lv_name(struct volume_group *vg, const char *format,
|
||||
char *buffer, size_t len);
|
||||
char *top_level_lv_name(struct volume_group *vg, const char *lv_name);
|
||||
|
||||
struct generic_logical_volume *get_or_create_glv(struct dm_pool *mem, struct logical_volume *lv, int *glv_created);
|
||||
struct glv_list *get_or_create_glvl(struct dm_pool *mem, struct logical_volume *lv, int *glv_created);
|
||||
|
@@ -108,6 +108,23 @@ static void _check_and_adjust_region_size(const struct logical_volume *lv)
|
||||
return _ensure_min_region_size(lv);
|
||||
}
|
||||
|
||||
/* Strip any raid suffix off LV name */
|
||||
char *top_level_lv_name(struct volume_group *vg, const char *lv_name)
|
||||
{
|
||||
char *new_lv_name, *suffix;
|
||||
|
||||
if (!(new_lv_name = dm_pool_strdup(vg->vgmem, lv_name))) {
|
||||
log_error("Failed to allocate string for new LV name.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((suffix = first_substring(new_lv_name, "_rimage_", "_rmeta_",
|
||||
"_mimage_", "_mlog_", NULL)))
|
||||
*suffix = '\0';
|
||||
|
||||
return new_lv_name;
|
||||
}
|
||||
|
||||
static int _lv_is_raid_with_tracking(const struct logical_volume *lv,
|
||||
struct logical_volume **tracking)
|
||||
{
|
||||
@@ -160,14 +177,22 @@ static int _activate_sublv_preserving_excl(struct logical_volume *top_lv,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* HM Helper: prohibit allocation on @pv if @lv already has segments allocated on it */
|
||||
static int _avoid_pv_of_lv(struct logical_volume *lv, struct physical_volume *pv)
|
||||
{
|
||||
if (!lv_is_partial(lv) && lv_is_on_pv(lv, pv))
|
||||
pv->status |= PV_ALLOCATION_PROHIBITED;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _avoid_pvs_of_lv(struct logical_volume *lv, void *data)
|
||||
{
|
||||
struct dm_list *allocate_pvs = (struct dm_list *) data;
|
||||
struct pv_list *pvl;
|
||||
|
||||
dm_list_iterate_items(pvl, allocate_pvs)
|
||||
if (!lv_is_partial(lv) && lv_is_on_pv(lv, pvl->pv))
|
||||
pvl->pv->status |= PV_ALLOCATION_PROHIBITED;
|
||||
_avoid_pv_of_lv(lv, pvl->pv);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -179,7 +204,15 @@ static int _avoid_pvs_of_lv(struct logical_volume *lv, void *data)
|
||||
*/
|
||||
static int _avoid_pvs_with_other_images_of_lv(struct logical_volume *lv, struct dm_list *allocate_pvs)
|
||||
{
|
||||
return for_each_sub_lv(lv, _avoid_pvs_of_lv, allocate_pvs);
|
||||
/* HM FIXME: check fails in case we will ever have mixed AREA_PV/AREA_LV segments */
|
||||
if ((seg_type(first_seg(lv), 0) == AREA_PV ? _avoid_pvs_of_lv(lv, allocate_pvs):
|
||||
for_each_sub_lv(lv, _avoid_pvs_of_lv, allocate_pvs)))
|
||||
return 1;
|
||||
|
||||
log_error("Failed to prevent PVs holding image components "
|
||||
"from LV %s being used for allocation.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _clear_allocation_prohibited(struct dm_list *pvs)
|
||||
@@ -679,7 +712,7 @@ static int _alloc_rmeta_for_lv(struct logical_volume *data_lv,
|
||||
struct dm_list allocatable_pvs;
|
||||
struct alloc_handle *ah;
|
||||
struct lv_segment *seg = first_seg(data_lv);
|
||||
char *p, base_name[NAME_LEN];
|
||||
char *base_name;
|
||||
|
||||
dm_list_init(&allocatable_pvs);
|
||||
|
||||
@@ -699,9 +732,8 @@ static int _alloc_rmeta_for_lv(struct logical_volume *data_lv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void) dm_strncpy(base_name, data_lv->name, sizeof(base_name));
|
||||
if ((p = strstr(base_name, "_mimage_")))
|
||||
*p = '\0';
|
||||
if (!(base_name = top_level_lv_name(data_lv->vg, data_lv->name)))
|
||||
return_0;
|
||||
|
||||
if (!(ah = allocate_extents(data_lv->vg, NULL, seg->segtype, 0, 1, 0,
|
||||
seg->region_size,
|
||||
@@ -1573,14 +1605,25 @@ static int _alloc_rmeta_devs_for_rimage_devs(struct logical_volume *lv,
|
||||
dm_list_iterate_items(lvl, new_data_lvs) {
|
||||
log_debug_metadata("Allocating new metadata LV for %s", lvl->lv->name);
|
||||
|
||||
if (!_alloc_rmeta_for_lv(lvl->lv, &lvl_array[a].lv, allocate_pvs)) {
|
||||
log_error("Failed to allocate metadata LV for %s in %s",
|
||||
lvl->lv->name, lv->vg->name);
|
||||
return 0;
|
||||
/*
|
||||
* Try to collocate with DataLV first and
|
||||
* if that fails allocate on different PV.
|
||||
*/
|
||||
if (!_alloc_rmeta_for_lv(lvl->lv, &lvl_array[a].lv,
|
||||
allocate_pvs != &lv->vg->pvs ? allocate_pvs : NULL)) {
|
||||
dm_list_iterate_items(lvl1, new_meta_lvs)
|
||||
if (!_avoid_pvs_with_other_images_of_lv(lvl1->lv, allocate_pvs))
|
||||
return_0;
|
||||
|
||||
if (!_alloc_rmeta_for_lv(lvl->lv, &lvl_array[a].lv, allocate_pvs)) {
|
||||
log_error("Failed to allocate metadata LV for %s in %s",
|
||||
lvl->lv->name, lv->vg->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
dm_list_add(new_meta_lvs, &lvl_array[a++].list);
|
||||
|
||||
|
||||
dm_list_iterate_items(lvl1, new_meta_lvs)
|
||||
if (!_avoid_pvs_with_other_images_of_lv(lvl1->lv, allocate_pvs))
|
||||
return_0;
|
||||
|
@@ -73,7 +73,7 @@ void lvmnotify_send(struct cmd_context *cmd)
|
||||
out:
|
||||
sd_bus_error_free(&error);
|
||||
sd_bus_message_unref(m);
|
||||
sd_bus_unref(bus);
|
||||
sd_bus_flush_close_unref(bus);
|
||||
}
|
||||
|
||||
void set_vg_notify(struct cmd_context *cmd)
|
||||
|
@@ -611,6 +611,9 @@ VG/ThinPoolLV
|
||||
Convert the data portion of ThinPoolLV to type cache.
|
||||
.br
|
||||
\[bu]
|
||||
Requires \-\-cachepool to specify the cache pool to use.
|
||||
.br
|
||||
\[bu]
|
||||
Operates on the data sub LV of the thin pool LV.
|
||||
.br
|
||||
\[bu]
|
||||
@@ -805,6 +808,8 @@ Specifies the number mirror images in addition to the original LV image,
|
||||
e.g. \fB\-\-mirrors 1\fP means two copies of the data, the original and
|
||||
one mirror image.
|
||||
|
||||
The current maximum is 9 providing 10 raid1 images.
|
||||
|
||||
This option is required when converting an LV to a \fBraid1\fP or
|
||||
\fBmirror\fP LV.
|
||||
|
||||
|
@@ -399,6 +399,9 @@ to configure default mirror segment type.
|
||||
The options
|
||||
\fB\-\-mirrorlog\fP and \fB\-\-corelog\fP apply
|
||||
to the legacy "\fImirror\fP" segment type only.
|
||||
|
||||
Note the current maxima for mirrors are 7 for "mirror" providing
|
||||
8 mirror legs and 9 for "raid1" providing 10 legs.
|
||||
.
|
||||
.HP
|
||||
.BR \-\-mirrorlog
|
||||
@@ -633,8 +636,12 @@ section of \fBlvm.conf (5)\fP or add
|
||||
\fB\-\-config allocation/raid_stripe_all_devices=1\fP
|
||||
.br
|
||||
to the command.
|
||||
.br
|
||||
Note the current limitation of 8 stripes total in any RaidLV including parity devices.
|
||||
|
||||
Note the current maxima for stripes depend on the created RAID type.
|
||||
For raid10, the maximum of stripes is 32,
|
||||
for raid0, it is 64,
|
||||
for raid4/5, it is 63
|
||||
and for raid6 it is 62.
|
||||
|
||||
See the \fB\-\-nosync\fP option to optionally avoid initial syncrhonization of RaidLVs.
|
||||
|
||||
|
800
scripts/command-lines.in
Normal file
800
scripts/command-lines.in
Normal file
@@ -0,0 +1,800 @@
|
||||
#
|
||||
# A new command has a unique combination of:
|
||||
# command name, required option args and required
|
||||
# positional args.
|
||||
#
|
||||
# To define a new command, begin a single line with a
|
||||
# command name, followed by required options/args,
|
||||
# (e.g. --foo, or --foo val), followed by required
|
||||
# positional args, (e.g. VG)
|
||||
#
|
||||
# After the single line of required elements are lines
|
||||
# of optional elements:
|
||||
# . optional options/args are on new line that begins OO:
|
||||
# . optional positional args are on a new line that begins OP:
|
||||
#
|
||||
# command_name required_opt_arg ... required_pos_arg ...
|
||||
# OO: optional_opt_arg, ...
|
||||
# OP: optional_pos_arg ...
|
||||
#
|
||||
# required_opt_arg/optional_opt_arg must begin with the
|
||||
# long form option name, e.g. --foo. If the option name
|
||||
# takes a value, then the type of value is specified,
|
||||
# e.g. --foo String.
|
||||
#
|
||||
# Possible option names are listed in args.h
|
||||
#
|
||||
# Use --foo_long to specify that only the long form of
|
||||
# --foo is accepted by the command. (This is uncommon.)
|
||||
#
|
||||
# Possible option arg types that can follow --opt are:
|
||||
# Bool, Number, String, PV, VG, LV, Tag, Select.
|
||||
#
|
||||
# Option args outside the list of types are treated as literal
|
||||
# (non-variable) strings or numbers.
|
||||
#
|
||||
# required_pos_arg/optional_pos_arg can be one of the following:
|
||||
# PV, VG, LV, Tag, Select.
|
||||
#
|
||||
# required_pos_arg/optional_pos_arg can be multiple types
|
||||
# separated by |, e.g. VG|LV|Tag
|
||||
#
|
||||
# If the required_pos_arg/optional_pos_arg is repeatable,
|
||||
# it is followed by ..., e.g. VG|LV|Tag ...
|
||||
#
|
||||
# LV can have a suffix indicating the LV type, e.g. LV_linear, LV_thinpool.
|
||||
# LV_raid represents any raidN.
|
||||
#
|
||||
# VG, LV can have the suffix _new, indicating the named VG or LV
|
||||
# does not yet exist.
|
||||
#
|
||||
# If Select is included in pos_arg, it means that the pos_arg
|
||||
# may be empty if the --select option is used.
|
||||
#
|
||||
# To define a common set of options:
|
||||
# OO_NAME: --foo, --bar String
|
||||
#
|
||||
# To use this set of options, include it on the OO: line, e.g.
|
||||
# OO: --example, OO_NAME
|
||||
#
|
||||
# which is expaneded to
|
||||
# OO: --example, --foo, --bar String
|
||||
#
|
||||
# Including OO_NAME after a command name on the required line
|
||||
# means that any one of the options is required and the rest
|
||||
# are optional. The usage syntax for this case is printed as:
|
||||
# command (--foo A, --bar B)
|
||||
#
|
||||
|
||||
#
|
||||
# OO_ALL is included in every command automatically.
|
||||
# FIXME: add --force and --test to OO_ALL so that all commands will
|
||||
# accept them even if they are not used?
|
||||
#
|
||||
OO_ALL: --commandprofile String, --config String, --debug,
|
||||
--driverloaded Bool, --help, --profile String, --quiet,
|
||||
--verbose, --version, --yes
|
||||
|
||||
#
|
||||
# pvs, lvs, vgs, fullreport
|
||||
#
|
||||
OO_REPORT: --aligned, --all, --binary, --configreport String, --foreign,
|
||||
--ignorelockingfailure, --ignoreskippedcluster, --logonly,
|
||||
--nameprefixes, --noheadings, --nolocking, --nosuffix,
|
||||
--options String, --partial, --readonly, --reportformat String, --rows,
|
||||
--select String, --separator String, --shared, --sort String,
|
||||
--trustcache, --unbuffered, --units String, --unquoted
|
||||
|
||||
#
|
||||
# config, dumpconfig, lvmconfig
|
||||
#
|
||||
OO_CONFIG: --atversion String, --configtype String, --file String, --ignoreadvanced,
|
||||
--ignoreunsupported, --ignorelocal, --list, --mergedconfig, --metadataprofile String,
|
||||
--sinceversion String, --showdeprecated, --showunsupported, --validate, --withsummary,
|
||||
--withcomments, --withspaces, --unconfigured, --withversions
|
||||
|
||||
|
||||
config
|
||||
OO: OO_CONFIG
|
||||
OP: String ...
|
||||
|
||||
devtypes
|
||||
OO: --aligned, --binary, --nameprefixes, --noheadings,
|
||||
--nosuffix, --options String, --reportformat String, --rows,
|
||||
--select String, --separator String, --sort String, --unbuffered, --unquoted
|
||||
|
||||
dumpconfig
|
||||
OO: OO_CONFIG
|
||||
OP: String ...
|
||||
|
||||
formats
|
||||
|
||||
help
|
||||
|
||||
fullreport
|
||||
OO: OO_REPORT
|
||||
OP: VG ...
|
||||
|
||||
lastlog
|
||||
OO: --reportformat String, --select String
|
||||
|
||||
|
||||
#
|
||||
# None of these can function as a required option for lvchange.
|
||||
#
|
||||
OO_LVCHANGE: --autobackup Bool, --force, --ignorelockingfailure,
|
||||
--ignoremonitoring, --ignoreskippedcluster, --noudevsync,
|
||||
--reportformat String, --sysinit, --test, --select String
|
||||
|
||||
#
|
||||
# Any of these can function as a required option for lvchange.
|
||||
# profile is also part of OO_ALL, but is repeated in OO_LVCHANGE_META
|
||||
# because it can function as a required opt.
|
||||
#
|
||||
OO_LVCHANGE_META: --addtag Tag, --deltag Tag,
|
||||
--alloc String, --contiguous Bool,
|
||||
--detachprofile, --metadataprofile String, --profile String,
|
||||
--permission, --readahead Number|String, --setactivationskip Bool,
|
||||
--errorwhenfull Bool, --discards String, --zero Bool,
|
||||
--cachemode String, --cachepolicy String, --cachesettings String,
|
||||
--minrecoveryrate Number, --maxrecoveryrate Number,
|
||||
--writebehind Number, --writemostly PV
|
||||
|
||||
lvchange OO_LVCHANGE_META VG|LV|Tag|Select ...
|
||||
OO: OO_LVCHANGE
|
||||
|
||||
lvchange --resync VG|LV|Tag|Select ...
|
||||
OO: OO_LVCHANGE_META, OO_LVCHANGE
|
||||
|
||||
lvchange --syncaction String VG|LV|Tag|Select ...
|
||||
OO: OO_LVCHANGE_META, OO_LVCHANGE
|
||||
|
||||
lvchange --rebuild PV VG|LV|Tag|Select ...
|
||||
OO: OO_LVCHANGE_META, OO_LVCHANGE
|
||||
|
||||
lvchange --activate String VG|LV|Tag|Select ...
|
||||
OO: --activationmode String, --partial, --ignoreactivationskip, OO_LVCHANGE_META, OO_LVCHANGE
|
||||
|
||||
lvchange --refresh VG|LV|Tag|Select ...
|
||||
OO: OO_LVCHANGE_META, OO_LVCHANGE
|
||||
|
||||
lvchange --monitor Bool VG|LV|Tag|Select ...
|
||||
OO: --poll Bool, OO_LVCHANGE_META, OO_LVCHANGE
|
||||
|
||||
lvchange --poll Bool VG|LV|Tag|Select ...
|
||||
OO: --monitor Bool, OO_LVCHANGE_META, OO_LVCHANGE
|
||||
|
||||
lvchange --persistent Bool VG|LV|Tag|Select ...
|
||||
OO: --minor Number, --major Number, OO_LVCHANGE_META, OO_LVCHANGE
|
||||
|
||||
|
||||
OO_LVCONVERT_RAID: --mirrors Number, --stripes_long Number,
|
||||
--stripesize Number, --regionsize Number
|
||||
|
||||
OO_LVCONVERT_POOL: --poolmetadata LV, --poolmetadatasize Number,
|
||||
--poolmetadataspare Bool, --readahead Number|String, --chunksize Number
|
||||
|
||||
OO_LVCONVERT: --alloc String, --background, --force, --noudevsync,
|
||||
--test, --usepolicies
|
||||
|
||||
# FIXME: use different option names for different operations
|
||||
lvconvert --merge LV_linear|LV_striped|LV_raid|LV_thin|LV_snapshot|VG|Tag ...
|
||||
OO: --background, --interval Number
|
||||
DESC: Merge LV that was previously split from a mirror.
|
||||
DESC: Merge thin LV into its origin LV.
|
||||
DESC: Merge COW snapshot LV into its origin.
|
||||
|
||||
lvconvert --type snapshot LV_linear|LV_striped|LV_raid LV_snapshot
|
||||
OO: --chunksize Number, --zero Bool, OO_LVCONVERT
|
||||
DESC: Combine LV with a previously split snapshot LV.
|
||||
|
||||
lvconvert --type thin --thinpool LV LV_linear|LV_striped|LV_raid
|
||||
OO: --originname LV_new, OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||
DESC: Convert LV to type thin with an external origin.
|
||||
|
||||
# alternate form of lvconvert --type thin
|
||||
lvconvert --thin --thinpool LV LV_linear|LV_striped|LV_raid
|
||||
OO: --type thin, --originname LV_new, OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||
DESC: Convert LV to type thin with an external origin (infers --type thin).
|
||||
|
||||
lvconvert --type cache --cachepool LV LV_linear|LV_striped|LV_raid|LV_thinpool
|
||||
OO: --cachepolicy String, --cachesettings String, OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||
DESC: Convert LV to type cache.
|
||||
|
||||
# alternate form of lvconvert --type cache
|
||||
lvconvert --cache --cachepool LV LV_linear|LV_striped|LV_raid|LV_thinpool
|
||||
OO: --type cache, --cachepolicy String, --cachesettings String, OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||
DESC: Convert LV to type cache (infers --type cache).
|
||||
|
||||
lvconvert --type thin-pool LV_linear|LV_striped|LV_raid|LV_cache
|
||||
OO: --discards String, --zero Bool, OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||
DESC: Convert LV to type thin-pool.
|
||||
|
||||
lvconvert --type cache-pool LV_linear|LV_striped|LV_raid
|
||||
OO: OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||
DESC: Convert LV to type cache-pool.
|
||||
|
||||
lvconvert --type mirror LV_linear|LV_striped|LV_raid
|
||||
OO: OO_LVCONVERT_RAID, OO_LVCONVERT
|
||||
OP: PV ...
|
||||
DESC: Convert LV to type mirror.
|
||||
|
||||
lvconvert --type raid LV_linear|LV_striped|LV_mirror|LV_raid
|
||||
OO: OO_LVCONVERT_RAID, OO_LVCONVERT
|
||||
OP: PV ...
|
||||
DESC: Convert LV to type raid.
|
||||
DESC: Change LV raid type.
|
||||
|
||||
lvconvert --mirrors Number LV_raid|LV_mirror
|
||||
OO: OO_LVCONVERT
|
||||
OP: PV ...
|
||||
DESC: Change the number of mirror images in the LV.
|
||||
|
||||
lvconvert --mirrors Number LV_linear|LV_striped
|
||||
OO: OO_LVCONVERT_RAID, OO_LVCONVERT
|
||||
OP: PV ...
|
||||
DESC: Alternate form to convert LV to type raid1 or mirror (use --type raid1|mirror).
|
||||
|
||||
lvconvert --splitmirrors Number --name LV_new LV_raid|LV_mirror|LV_cache
|
||||
OO: OO_LVCONVERT
|
||||
DESC: Split images from a raid1 or mirror LV and use them to create a new LV.
|
||||
|
||||
lvconvert --splitmirrors Number --trackchanges LV_raid|LV_cache
|
||||
OO: OO_LVCONVERT
|
||||
DESC: Split images from a raid1 LV and use them to create a new LV.
|
||||
|
||||
lvconvert --repair LV_raid|LV_mirror|LV_thinpool
|
||||
OO: OO_LVCONVERT
|
||||
DESC: Replace failed PVs in a mirror or raid LV.
|
||||
DESC: Repair a thin pool.
|
||||
|
||||
lvconvert --replace PV LV_raid
|
||||
OO: OO_LVCONVERT
|
||||
OP: PV ...
|
||||
DESC: Replace specific PV(s) in a raid* LV with another PV.
|
||||
|
||||
lvconvert --type striped LV_raid
|
||||
OO: OO_LVCONVERT_RAID, OO_LVCONVERT
|
||||
OP: PV ...
|
||||
DESC: Convert LV to type striped.
|
||||
|
||||
lvconvert --type linear LV_raid|LV_mirror
|
||||
OO: OO_LVCONVERT
|
||||
DESC: Convert LV to type linear.
|
||||
|
||||
lvconvert --mirrorlog String LV_mirror
|
||||
OO: OO_LVCONVERT
|
||||
DESC: Change the type of log used by LV.
|
||||
|
||||
lvconvert --splitcache LV_cachepool|LV_cache|LV_thinpool
|
||||
OO: OO_LVCONVERT
|
||||
DESC: Separate and preserve a cache pool from a cache LV.
|
||||
|
||||
lvconvert --uncache LV_cache|LV_thinpool
|
||||
OO: OO_LVCONVERT
|
||||
DESC: Separate and remove a cache pool from a cache LV.
|
||||
|
||||
lvconvert --splitsnapshot LV_snapshot
|
||||
OO: OO_LVCONVERT
|
||||
DESC: Separate a COW snapshot from its origin LV.
|
||||
|
||||
# deprecated because of non-standard syntax
|
||||
lvconvert --thinpool LV
|
||||
OO: OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||
DESC: Alternate form to convert LV to type thin-pool (use --type thin-pool).
|
||||
|
||||
# deprecated because of non-standard syntax
|
||||
lvconvert --cachepool LV
|
||||
OO: OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||
DESC: Alternate form to convert LV to type cache-pool (use --type cache-pool).
|
||||
|
||||
# FIXME: add a new option defining this operation, e.g. --poll-mirror
|
||||
# The function of this command is not entirely clear.
|
||||
lvconvert LV_mirror
|
||||
DESC: Poll LV to collapse resync layers.
|
||||
|
||||
# FIXME: add a new option defining this operation, e.g. --swapmetadata
|
||||
lvconvert --poolmetadata LV LV_thinpool|LV_cachepool
|
||||
DESC: Swap metadata LV in a thin pool or cache pool (temporary command).
|
||||
|
||||
|
||||
# --extents or --size are interchangable
|
||||
|
||||
OO_LVCREATE: --addtag Tag, --alloc String, --autobackup Bool, --activate String,
|
||||
--contiguous Bool, --ignoreactivationskip, --ignoremonitoring, --major Number,
|
||||
--metadataprofile String, --minor Number, --monitor Bool, --name String, --nosync,
|
||||
--noudevsync, --permission, --persistent Bool, --readahead Number|String,
|
||||
--reportformat String, --setactivationskip Bool, --test, --wipesignatures Bool,
|
||||
--zero Bool
|
||||
|
||||
OO_LVCREATE_CACHE: --cachemode String, --cachepolicy String, --cachesettings String
|
||||
|
||||
OO_LVCREATE_POOL: --poolmetadatasize Number, --poolmetadataspare Bool, --chunksize Number
|
||||
|
||||
OO_LVCREATE_THIN: --discards String, --errorwhenfull Bool
|
||||
|
||||
OO_LVCREATE_RAID: --mirrors Number, --stripes Number, --stripesize Number,
|
||||
--regionsize Number, --minrecoveryrate Number, --maxrecoveryrate Number
|
||||
|
||||
lvcreate --type error --size Number VG
|
||||
OO: OO_LVCREATE
|
||||
DESC: Create an LV that returns errors when used.
|
||||
|
||||
lvcreate --type zero --size Number VG
|
||||
OO: OO_LVCREATE
|
||||
DESC: Create an LV that returns zeros when read.
|
||||
|
||||
lvcreate --type linear --size Number VG
|
||||
OO: OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a linear LV.
|
||||
|
||||
lvcreate --type striped --size Number VG
|
||||
OO: --stripes Number, --stripesize Number, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a striped LV.
|
||||
|
||||
lvcreate --type mirror --size Number VG
|
||||
OO: --mirrors Number, --mirrorlog String, --corelog, --regionsize Number, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a mirror LV.
|
||||
|
||||
lvcreate --type raid --size Number VG
|
||||
OO: OO_LVCREATE_RAID, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a raid LV (a specific raid level must be used, e.g. raid1).
|
||||
|
||||
lvcreate --type snapshot --size Number LV
|
||||
OO: OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a COW snapshot from an origin LV.
|
||||
|
||||
lvcreate --type snapshot --size Number --virtualsize Number VG
|
||||
OO: --virtualoriginsize Number, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a sparse COW snapshot LV of a virtual origin LV.
|
||||
|
||||
lvcreate --type thin-pool --size Number VG
|
||||
OO: OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a thin pool.
|
||||
|
||||
lvcreate --type cache-pool --size Number VG
|
||||
OO: OO_LVCREATE_POOL, OO_LVCREATE_CACHE, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a cache pool.
|
||||
|
||||
lvcreate --type thin --virtualsize Number --thinpool LV_thinpool
|
||||
OO: OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
DESC: Create a thin LV in a thin pool.
|
||||
|
||||
lvcreate --type thin --snapshot LV_thin
|
||||
OO: OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
DESC: Create a thin LV that is a snapshot of an existing thin LV.
|
||||
|
||||
lvcreate --type thin --snapshot --thinpool LV_thinpool LV
|
||||
OO: OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
DESC: Create a thin LV that is a snapshot of an external origin LV named in arg pos 1.
|
||||
|
||||
lvcreate --type thin --virtualsize Number --size Number --thinpool LV_new
|
||||
OO: OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a thin LV, first creating a thin pool for it, where the new thin pool is named by the --thinpool arg.
|
||||
|
||||
lvcreate --type thin --virtualsize Number --size Number LV_new
|
||||
OO: OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a thin LV, first creating a thin pool for it, where the new thin pool is named in arg pos 1.
|
||||
|
||||
lvcreate --type thin --virtualsize Number --size Number VG
|
||||
OO: OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a thin LV, first creating a thin pool for it.
|
||||
|
||||
# FIXME: this should be done by lvconvert, and this command deprecated
|
||||
lvcreate --type cache --size Number LV
|
||||
OO: OO_LVCREATE_POOL, OO_LVCREATE_CACHE, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Convert the specified LV to type cache after creating a new cache pool LV to use.
|
||||
|
||||
lvcreate --type cache --size Number --cachepool LV_cachepool
|
||||
OO: OO_LVCREATE_POOL, OO_LVCREATE_CACHE, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a cache LV, first creating a new origin LV, then combining it with the existing cache pool in arg pos 1.
|
||||
|
||||
lvcreate --size Number VG
|
||||
OO: --type linear, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a linear LV. (default --type linear)
|
||||
|
||||
lvcreate --stripes Number --size Number VG
|
||||
OO: --type striped, --stripesize Number, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a striped LV. (infers --type striped)
|
||||
|
||||
lvcreate --mirrors Number --size Number VG
|
||||
OO: --type raid1|mirror, --mirrorlog String, --corelog, OO_LVCREATE_RAID, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a raid1 or mirror LV. (infers --type raid1|mirror)
|
||||
|
||||
lvcreate --snapshot --size Number LV
|
||||
OO: --type snapshot, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a COW snapshot LV of the origin LV in arg pos 1. (infers --type snapshot)
|
||||
|
||||
lvcreate --thin --size Number VG
|
||||
OO: --type thin-pool, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a thin pool. (infers --type thin-pool)
|
||||
|
||||
lvcreate --cache --size Number VG
|
||||
OO: --type cache-pool, OO_LVCREATE_POOL, OO_LVCREATE_CACHE, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a cache pool. (infers --type cache-pool)
|
||||
|
||||
lvcreate --snapshot LV_thin
|
||||
OO: --type thin, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
DESC: Create a thin LV that is a snapshot of an existing thin LV. (infers --type thin)
|
||||
|
||||
lvcreate --snapshot --thinpool LV_thinpool LV
|
||||
OO: --type thin, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
DESC: Create a thin LV that is a snapshot of an external origin LV. (infers --type thin)
|
||||
|
||||
lvcreate --virtualsize Number --thinpool LV_thinpool
|
||||
OO: --type thin, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
DESC: Create a thin LV in a thin pool. (infers --type thin)
|
||||
|
||||
lvcreate --size Number --cachepool LV_cachepool
|
||||
OO: --type cache, OO_LVCREATE_CACHE, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a new origin LV, combining it with an existing cache pool to create a new cache LV. (infers --type cache)
|
||||
|
||||
lvcreate --thin --virtualsize Number --size Number --thinpool LV_new
|
||||
OO: --type thin, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a thin LV, first creating a thin pool for it, where the new thin pool is named by the --thinpool arg. (infers --type thin)
|
||||
|
||||
lvcreate --thin --virtualsize Number --size Number LV_new
|
||||
OO: --type thin, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a thin LV, first creating a thin pool for it, where the new thin pool is named in arg pos 1. (infers --type thin)
|
||||
|
||||
lvcreate --size Number --virtualsize Number VG
|
||||
OO: --type thin, --type snapshot, --thin, --snapshot,
|
||||
--virtualoriginsize Number, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
|
||||
OP: PV ...
|
||||
DESC: Create a thin LV, first creating a thin pool for it. (infers --type thin)
|
||||
DESC: Create a sparse snapshot of a virtual origin LV. (infers --type snapshot)
|
||||
DESC: (infers --type thin or --type snapshot according to sparse_segtype_default)
|
||||
|
||||
lvdisplay
|
||||
OO: --aligned, --all, --binary, --colon, --columns,
|
||||
--configreport String, --foreign, --history, --ignorelockingfailure,
|
||||
--ignoreskippedcluster, --logonly, --maps, --noheadings,
|
||||
--nosuffix, --options String, --sort String, --partial, --readonly,
|
||||
--reportformat String, --segments, --select String, --separator String,
|
||||
--shared, --unbuffered, --units String
|
||||
OP: VG|LV|Tag ...
|
||||
|
||||
# --extents or --size are interchangable
|
||||
lvextend --size Number LV
|
||||
OO: --alloc String, --autobackup Bool, --force, --mirrors Number,
|
||||
--nofsck, --nosync, --noudevsync, --reportformat String, --resizefs,
|
||||
--stripes Number, --stripesize Number, --test, --poolmetadatasize Number
|
||||
OP: PV ...
|
||||
|
||||
lvextend LV PV ...
|
||||
OO: --alloc String, --autobackup Bool, --force, --mirrors Number,
|
||||
--nofsck, --nosync, --noudevsync,
|
||||
--reportformat String, --resizefs, --stripes Number, --stripesize Number,
|
||||
--test
|
||||
|
||||
lvextend --poolmetadatasize Number LV_thinpool
|
||||
OO: --alloc String, --autobackup Bool, --force, --mirrors Number,
|
||||
--nofsck, --nosync, --noudevsync,
|
||||
--reportformat String, --stripes Number, --stripesize Number,
|
||||
--test
|
||||
OP: PV ...
|
||||
|
||||
lvextend --usepolicies LV_thinpool|LV_snapshot
|
||||
OO: --alloc String, --autobackup Bool, --force, --mirrors Number,
|
||||
--nofsck, --nosync, --noudevsync,
|
||||
--reportformat String, --resizefs,
|
||||
--test
|
||||
|
||||
lvmchange
|
||||
|
||||
lvmconfig
|
||||
OO: OO_CONFIG
|
||||
|
||||
lvmdiskscan
|
||||
OO: --lvmpartition, --readonly
|
||||
|
||||
lvmsadc
|
||||
|
||||
lvmsar
|
||||
OO: --full, --stdin
|
||||
|
||||
# --extents or --size are interchangable
|
||||
lvreduce --size Number LV
|
||||
OO: --autobackup Bool, --force, --nofsck, --noudevsync,
|
||||
--reportformat String, --resizefs, --test
|
||||
|
||||
lvremove VG|LV|Tag|Select ...
|
||||
OO: --autobackup Bool, --force, --nohistory, --noudevsync,
|
||||
--reportformat String, --select String, --test
|
||||
|
||||
lvrename VG LV LV_new
|
||||
OO: --autobackup Bool, --noudevsync, --reportformat String, --test
|
||||
|
||||
lvrename LV LV_new
|
||||
OO: --autobackup Bool, --noudevsync, --reportformat String, --test
|
||||
|
||||
# --extents or --size are interchangable
|
||||
lvresize --size Number LV
|
||||
OO: --alloc String, --autobackup Bool, --force,
|
||||
--nofsck, --nosync, --noudevsync, --reportformat String, --resizefs,
|
||||
--stripes Number, --stripesize Number, --test, --poolmetadatasize Number
|
||||
OP: PV ...
|
||||
|
||||
lvresize LV PV ...
|
||||
OO: --alloc String, --autobackup Bool, --force,
|
||||
--nofsck, --nosync, --noudevsync,
|
||||
--reportformat String, --resizefs, --stripes Number, --stripesize Number,
|
||||
--test
|
||||
|
||||
lvresize --poolmetadatasize Number LV_thinpool
|
||||
OO: --alloc String, --autobackup Bool, --force,
|
||||
--nofsck, --nosync, --noudevsync,
|
||||
--reportformat String, --stripes Number, --stripesize Number,
|
||||
--test
|
||||
OP: PV ...
|
||||
|
||||
lvs
|
||||
OO: --history, --segments, OO_REPORT
|
||||
OP: VG|LV|Tag ...
|
||||
|
||||
lvscan
|
||||
OO: --all, --blockdevice, --ignorelockingfailure, --partial,
|
||||
--readonly, --reportformat String, --cache_long
|
||||
|
||||
|
||||
#
|
||||
# None of these can function as a required option for pvchange.
|
||||
#
|
||||
OO_PVCHANGE: --autobackup Bool, --force, --ignoreskippedcluster,
|
||||
--reportformat String, --test, --uuid
|
||||
|
||||
#
|
||||
# Any of these can function as a required option for pvchange.
|
||||
#
|
||||
OO_PVCHANGE_META: --allocatable Bool, --addtag Tag, --deltag Tag,
|
||||
--uuid, --metadataignore Bool
|
||||
|
||||
pvchange OO_PVCHANGE_META --all
|
||||
OO: OO_PVCHANGE
|
||||
|
||||
pvchange OO_PVCHANGE_META PV|Select ...
|
||||
OO: --select String, OO_PVCHANGE
|
||||
|
||||
pvresize PV ...
|
||||
OO: --setphysicalvolumesize Number, --reportformat String, --test
|
||||
|
||||
pvck PV ...
|
||||
OO: --labelsector Number
|
||||
|
||||
#
|
||||
# Use --uuidstr here which will be converted to uuidstr_ARG
|
||||
# which is actually --uuid string on the command line.
|
||||
#
|
||||
pvcreate PV ...
|
||||
OO: --dataalignment Number, --dataalignmentoffset Number, --bootloaderareasize Number,
|
||||
--force, --test, --labelsector Number, --metadatatype String,
|
||||
--pvmetadatacopies Number, --metadatasize Number, --metadataignore Bool,
|
||||
--norestorefile, --setphysicalvolumesize Number,
|
||||
--reportformat String, --restorefile String, --uuidstr String, --zero Bool
|
||||
|
||||
pvdata
|
||||
|
||||
pvdisplay
|
||||
OO: --aligned, --all, --binary, --colon, --columns, --configreport String,
|
||||
--foreign, --ignorelockingfailure, --ignoreskippedcluster,
|
||||
--logonly, --maps, --noheadings, --nosuffix, --options String,
|
||||
--readonly, --reportformat String, --select String, --separator String, --shared,
|
||||
--short, --sort String, --unbuffered, --units String
|
||||
OP: PV|Tag ...
|
||||
|
||||
pvmove PV
|
||||
OO: --abort, --alloc String, --atomic, --autobackup Bool, --background,
|
||||
--interval Number, --name LV, --noudevsync, --reportformat String, --test
|
||||
OP: PV ...
|
||||
|
||||
pvmove
|
||||
OO: --abort, --background, --test
|
||||
|
||||
lvpoll --polloperation String LV ...
|
||||
OO: --abort, --autobackup Bool, --handlemissingpvs, --interval Number, --test
|
||||
|
||||
pvremove PV ...
|
||||
OO: --force, --reportformat String, --test
|
||||
|
||||
pvs
|
||||
OO: --segments, OO_REPORT
|
||||
OP: PV|Tag ...
|
||||
|
||||
pvscan
|
||||
OO: --ignorelockingfailure, --reportformat String, --exported, --novolumegroup,
|
||||
--short, --uuid
|
||||
|
||||
pvscan --cache
|
||||
OO: --ignorelockingfailure, --reportformat String, --background,
|
||||
--activate String, --major Number, --minor Number,
|
||||
OP: PV|String ...
|
||||
|
||||
segtypes
|
||||
|
||||
systemid
|
||||
|
||||
tags
|
||||
|
||||
vgcfgbackup
|
||||
OO: --file String, --foreign, --ignorelockingfailure, --partial, --readonly,
|
||||
--reportformat String
|
||||
|
||||
vgcfgrestore VG
|
||||
OO: --file String, --force_long, --list, --metadatatype String, --test
|
||||
|
||||
vgcfgrestore --list --file String
|
||||
|
||||
#
|
||||
# None of these can function as a required option for vgchange.
|
||||
#
|
||||
OO_VGCHANGE: --autobackup Bool, --ignoremonitoring, --ignoreskippedcluster,
|
||||
--noudevsync, --reportformat String, --select String, --test, --force
|
||||
|
||||
#
|
||||
# Any of these can function as a required option for vgchange.
|
||||
# profile is also part of OO_ALL, but is repeated in OO_VGCHANGE_META
|
||||
# because it can function as a required opt.
|
||||
#
|
||||
OO_VGCHANGE_META: --addtag Tag, --deltag Tag,
|
||||
--logicalvolume Number, --maxphysicalvolumes Number, --alloc String, --uuid,
|
||||
--clustered Bool, --metadatacopies Number, --vgmetadatacopies Number|String,
|
||||
--physicalextentsize Number, --resizeable Bool, --systemid String, --locktype String,
|
||||
--profile String, --detachprofile, --metadataprofile String,
|
||||
|
||||
vgchange OO_VGCHANGE_META
|
||||
OO: OO_VGCHANGE
|
||||
OP: VG|Tag ...
|
||||
|
||||
vgchange --monitor Bool
|
||||
OO: --sysinit, --ignorelockingfailure, --poll Bool, OO_VGCHANGE_META, OO_VGCHANGE
|
||||
OP: VG|Tag ...
|
||||
|
||||
vgchange --poll Bool
|
||||
OO: --ignorelockingfailure, OO_VGCHANGE_META, OO_VGCHANGE
|
||||
OP: VG|Tag ...
|
||||
|
||||
vgchange --activate String
|
||||
OO: --activationmode String, --ignoreactivationskip, --partial, --sysinit,
|
||||
--ignorelockingfailure, --monitor Bool, --poll Bool, OO_VGCHANGE_META, OO_VGCHANGE
|
||||
OP: VG|Tag ...
|
||||
|
||||
vgchange --refresh
|
||||
OO: --sysinit, --ignorelockingfailure, --monitor Bool, --poll Bool, OO_VGCHANGE_META, OO_VGCHANGE
|
||||
OP: VG|Tag ...
|
||||
|
||||
vgchange --lockstart
|
||||
OO: --lockopt String, OO_VGCHANGE_META, OO_VGCHANGE
|
||||
OP: VG|Tag ...
|
||||
|
||||
vgchange --lockstop
|
||||
OO: --lockopt String, OO_VGCHANGE_META, OO_VGCHANGE
|
||||
OP: VG|Tag ...
|
||||
|
||||
vgck
|
||||
OO: --reportformat String
|
||||
OP: VG|Tag ...
|
||||
|
||||
vgconvert VG ...
|
||||
OO: --force, --test, --labelsector Number, --bootloaderareasize Number,
|
||||
--metadatatype String, --pvmetadatacopies Number,
|
||||
--metadatasize Number, --reportformat String
|
||||
|
||||
vgcreate VG_new PV ...
|
||||
OO: --addtag Tag, --alloc String, --autobackup Bool, --clustered Bool, --maxlogicalvolumes Number,
|
||||
--maxphysicalvolumes Number, --metadataprofile String, --metadatatype String,
|
||||
--physicalextentsize Number, --test, --force, --zero Bool, --labelsector Number,
|
||||
--metadatasize Number, --pvmetadatacopies Number, --reportformat String, --metadatacopies Number,
|
||||
--vgmetadatacopies Number|String, --dataalignment Number, --dataalignmentoffset Number,
|
||||
--shared, --systemid String, --locktype String, --lockopt String
|
||||
|
||||
vgdisplay
|
||||
OO: --activevolumegroups, --aligned, --binary, --colon, --columns,
|
||||
--configreport String, --foreign, --ignorelockingfailure,
|
||||
--ignoreskippedcluster, --logonly, --noheadings, --nosuffix,
|
||||
--options String, --partial, --readonly, --reportformat String, --select String,
|
||||
--shared, --short, --separator String, --sort String, --unbuffered, --units String
|
||||
OP: VG|Tag ...
|
||||
|
||||
OO_VGEXPORT: --reportformat String, --test
|
||||
|
||||
vgexport VG|Tag|Select ...
|
||||
OO: --select String, OO_VGEXPORT
|
||||
|
||||
vgexport --all
|
||||
OO: OO_VGEXPORT
|
||||
|
||||
vgextend VG PV ...
|
||||
OO: --autobackup Bool, --test,
|
||||
--force, --zero Bool, --labelsector Number, --metadatatype String,
|
||||
--metadatasize Number, --pvmetadatacopies Number,
|
||||
--metadataignore Bool, --dataalignment Number, --dataalignmentoffset Number,
|
||||
--reportformat String, --restoremissing
|
||||
|
||||
OO_VGIMPORT: --force, --reportformat String, --test
|
||||
|
||||
vgimport VG|Tag|Select ...
|
||||
OO: --select String, OO_VGIMPORT
|
||||
|
||||
vgimport --all
|
||||
OO: OO_VGIMPORT
|
||||
|
||||
vgimportclone PV ...
|
||||
OO: --basevgname VG, --test, --import
|
||||
|
||||
vgmerge VG VG
|
||||
OO: --autobackup Bool, --list, --test
|
||||
|
||||
vgmknodes
|
||||
OO: --ignorelockingfailure, --refresh, --reportformat String
|
||||
OP: VG|LV|Tag ...
|
||||
|
||||
OO_VGREDUCE: --autobackup Bool, --force, --reportformat String, --test
|
||||
|
||||
vgreduce VG PV ...
|
||||
OO: OO_VGREDUCE
|
||||
|
||||
vgreduce --all VG
|
||||
OO: OO_VGREDUCE
|
||||
|
||||
vgreduce --removemissing VG
|
||||
OO: --mirrorsonly, OO_VGREDUCE
|
||||
|
||||
vgremove VG|Tag|Select ...
|
||||
OO: --force, --noudevsync, --reportformat String, --select String, --test
|
||||
|
||||
vgrename VG VG_new
|
||||
OO: --autobackup Bool, --force, --reportformat String, --test
|
||||
|
||||
vgrename String VG_new
|
||||
OO: --autobackup Bool, --force, --reportformat String, --test
|
||||
|
||||
vgs
|
||||
OO: OO_REPORT
|
||||
OP: VG|Tag ...
|
||||
|
||||
vgscan
|
||||
OO: --cache_long, --ignorelockingfailure, --mknodes, --notifydbus,
|
||||
--partial, --reportformat String
|
||||
|
||||
OO_VGSPLIT: --autobackup Bool, --test
|
||||
|
||||
OO_VGSPLIT_NEW: --alloc String, --clustered Bool,
|
||||
--maxlogicalvolumes Number, --maxphysicalvolumes Number,
|
||||
--metadatatype String, --vgmetadatacopies Number|String
|
||||
|
||||
vgsplit VG VG PV ...
|
||||
OO: OO_VGSPLIT
|
||||
|
||||
vgsplit --name LV VG VG
|
||||
OO: OO_VGSPLIT
|
||||
|
||||
vgsplit VG VG_new PV ...
|
||||
OO: OO_VGSPLIT, OO_VGSPLIT_NEW
|
||||
|
||||
vgsplit --name LV VG VG_new
|
||||
OO: OO_VGSPLIT, OO_VGSPLIT_NEW
|
||||
|
||||
version
|
||||
|
1534
scripts/create-commands.c
Normal file
1534
scripts/create-commands.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -115,6 +115,7 @@ fi
|
||||
%{_mandir}/man8/lvmconfig.8.gz
|
||||
%{_mandir}/man8/lvmdiskscan.8.gz
|
||||
%{_mandir}/man8/lvmdump.8.gz
|
||||
%{_mandir}/man8/lvm-fullreport.8.gz
|
||||
%{_mandir}/man8/lvmsadc.8.gz
|
||||
%{_mandir}/man8/lvmsar.8.gz
|
||||
%{_mandir}/man8/lvreduce.8.gz
|
||||
@@ -179,6 +180,7 @@ fi
|
||||
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/profile/thin-performance.profile
|
||||
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/profile/cache-mq.profile
|
||||
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/profile/cache-smq.profile
|
||||
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/profile/lvmdbusd.profile
|
||||
%dir %{_sysconfdir}/lvm/backup
|
||||
%dir %{_sysconfdir}/lvm/cache
|
||||
%dir %{_sysconfdir}/lvm/archive
|
||||
|
@@ -53,6 +53,15 @@ lvcreate -l 4 --type raid10 -i 2 -m 1 -n $lv1 $vg \
|
||||
check lv_tree_on $vg ${lv1}_foo "$dev1"
|
||||
check lv_tree_on $vg $lv1 "$dev1" "$dev2" "$dev3" "$dev4"
|
||||
aux mkdev_md5sum $vg $lv1
|
||||
|
||||
# Check collocation of SubLVs is prohibited
|
||||
not pvmove $mode -n ${lv1}_rimage_0 "$dev1" "$dev2"
|
||||
check lv_tree_on $vg $lv1 "$dev1" "$dev2" "$dev3" "$dev4"
|
||||
not pvmove $mode -n ${lv1}_rimage_1 "$dev2" "$dev1"
|
||||
check lv_tree_on $vg $lv1 "$dev1" "$dev2" "$dev3" "$dev4"
|
||||
not pvmove $mode -n ${lv1}_rmeta_0 "$dev1" "$dev3"
|
||||
check lv_tree_on $vg $lv1 "$dev1" "$dev2" "$dev3" "$dev4"
|
||||
|
||||
pvmove $mode "$dev1" "$dev5"
|
||||
check lv_tree_on $vg ${lv1}_foo "$dev5"
|
||||
check lv_tree_on $vg $lv1 "$dev2" "$dev3" "$dev4" "$dev5"
|
||||
|
@@ -32,7 +32,7 @@ arg(cachepool_ARG, '\0', "cachepool", string_arg, 0, 0)
|
||||
arg(commandprofile_ARG, '\0', "commandprofile", string_arg, 0, 0)
|
||||
arg(config_ARG, '\0', "config", string_arg, 0, 0)
|
||||
arg(configreport_ARG, '\0', "configreport", string_arg, ARG_GROUPABLE, 1)
|
||||
arg(configtype_ARG, '\0', "type", string_arg, 0, 0)
|
||||
arg(configtype_ARG, '\0', "configtype", string_arg, 0, 0)
|
||||
arg(corelog_ARG, '\0', "corelog", NULL, 0, 0)
|
||||
arg(dataalignment_ARG, '\0', "dataalignment", size_kb_arg, 0, 0)
|
||||
arg(dataalignmentoffset_ARG, '\0', "dataalignmentoffset", size_kb_arg, 0, 0)
|
||||
|
200
tools/command.h
Normal file
200
tools/command.h
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU Lesser General Public License v.2.1.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_COMMAND_H
|
||||
#define _LVM_COMMAND_H
|
||||
|
||||
struct cmd_context;
|
||||
|
||||
/* command functions */
|
||||
typedef int (*command_fn) (struct cmd_context * cmd, int argc, char **argv);
|
||||
|
||||
/*
|
||||
* Command defintion
|
||||
*
|
||||
* A command is defined in terms of a command name,
|
||||
* required options (+args), optional options (+args),
|
||||
* required positional args, optional positional args.
|
||||
*
|
||||
* A positional arg always has non-zero pos_arg.def.types.
|
||||
* The first positional arg has pos_arg.pos of 1.
|
||||
*/
|
||||
|
||||
/* Number of string constants accepted after an option. */
|
||||
#define MAX_STR_SET 16
|
||||
|
||||
/* arg_def flags */
|
||||
#define ARG_DEF_FLAG_NEW 1
|
||||
#define ARG_DEF_FLAG_MAY_REPEAT 2
|
||||
|
||||
/* arg_def types, can be multiple */
|
||||
enum {
|
||||
ARG_DEF_TYPE_NONE = 0,
|
||||
ARG_DEF_TYPE_BOOL = 1 << 0,
|
||||
ARG_DEF_TYPE_NUM_ANY = 1 << 1,
|
||||
ARG_DEF_TYPE_STR_ANY = 1 << 2,
|
||||
ARG_DEF_TYPE_NUM_CONST = 1 << 3,
|
||||
ARG_DEF_TYPE_STR_CONST = 1 << 4,
|
||||
ARG_DEF_TYPE_STR_SET = 1 << 5, /* a set of specific accepted string values */
|
||||
ARG_DEF_TYPE_NAME_ANY = 1 << 6,
|
||||
ARG_DEF_TYPE_NAME_PV = 1 << 7,
|
||||
ARG_DEF_TYPE_NAME_VG = 1 << 8,
|
||||
ARG_DEF_TYPE_NAME_LV = 1 << 9,
|
||||
ARG_DEF_TYPE_TAG = 1 << 10,
|
||||
ARG_DEF_TYPE_SELECT = 1 << 11,
|
||||
};
|
||||
|
||||
#define ARG_DEF_TYPES 16
|
||||
struct arg_def_type {
|
||||
const char *name;
|
||||
int flag;
|
||||
};
|
||||
|
||||
/* The names used for arg_def types in command-lines.in */
|
||||
static struct arg_def_type arg_def_types[ARG_DEF_TYPES] = {
|
||||
{ "None", ARG_DEF_TYPE_NONE},
|
||||
{ "Bool", ARG_DEF_TYPE_BOOL},
|
||||
{ "Number", ARG_DEF_TYPE_NUM_ANY},
|
||||
{ "String", ARG_DEF_TYPE_STR_ANY},
|
||||
{ "Name", ARG_DEF_TYPE_NAME_ANY},
|
||||
{ "PV", ARG_DEF_TYPE_NAME_PV},
|
||||
{ "VG", ARG_DEF_TYPE_NAME_VG},
|
||||
{ "LV", ARG_DEF_TYPE_NAME_LV},
|
||||
{ "Tag", ARG_DEF_TYPE_TAG},
|
||||
{ "Select", ARG_DEF_TYPE_SELECT},
|
||||
};
|
||||
|
||||
/* arg_def lv_types, can be multiple */
|
||||
enum {
|
||||
ARG_DEF_LV_ANY = 0,
|
||||
ARG_DEF_LV_LINEAR = 1 << 0,
|
||||
ARG_DEF_LV_STRIPED = 1 << 1,
|
||||
ARG_DEF_LV_SNAPSHOT = 1 << 2,
|
||||
ARG_DEF_LV_MIRROR = 1 << 3,
|
||||
ARG_DEF_LV_RAID = 1 << 4,
|
||||
ARG_DEF_LV_RAID0 = 1 << 5,
|
||||
ARG_DEF_LV_RAID1 = 1 << 6,
|
||||
ARG_DEF_LV_RAID4 = 1 << 7,
|
||||
ARG_DEF_LV_RAID5 = 1 << 8,
|
||||
ARG_DEF_LV_RAID6 = 1 << 9,
|
||||
ARG_DEF_LV_RAID10 = 1 << 10,
|
||||
ARG_DEF_LV_THIN = 1 << 11,
|
||||
ARG_DEF_LV_THINPOOL = 1 << 12,
|
||||
ARG_DEF_LV_CACHE = 1 << 13,
|
||||
ARG_DEF_LV_CACHEPOOL = 1 << 14,
|
||||
};
|
||||
|
||||
#define ARG_DEF_LVS 64
|
||||
struct arg_def_lv {
|
||||
const char *name;
|
||||
int flag;
|
||||
};
|
||||
|
||||
/* The names used for arg_def lv_types in command-lines.in */
|
||||
static struct arg_def_lv arg_def_lvs[ARG_DEF_LVS] = {
|
||||
{ "LV", ARG_DEF_LV_ANY},
|
||||
{ "LV_linear", ARG_DEF_LV_LINEAR},
|
||||
{ "LV_striped", ARG_DEF_LV_STRIPED},
|
||||
{ "LV_snapshot", ARG_DEF_LV_SNAPSHOT},
|
||||
{ "LV_mirror", ARG_DEF_LV_MIRROR},
|
||||
{ "LV_raid", ARG_DEF_LV_RAID},
|
||||
{ "LV_raid0", ARG_DEF_LV_RAID0},
|
||||
{ "LV_raid1", ARG_DEF_LV_RAID1},
|
||||
{ "LV_raid4", ARG_DEF_LV_RAID4},
|
||||
{ "LV_raid5", ARG_DEF_LV_RAID5},
|
||||
{ "LV_raid6", ARG_DEF_LV_RAID6},
|
||||
{ "LV_raid10", ARG_DEF_LV_RAID10},
|
||||
{ "LV_thin", ARG_DEF_LV_THIN},
|
||||
{ "LV_thinpool", ARG_DEF_LV_THINPOOL},
|
||||
{ "LV_cache", ARG_DEF_LV_CACHE},
|
||||
{ "LV_cachepool", ARG_DEF_LV_CACHEPOOL},
|
||||
};
|
||||
|
||||
/* Description a value that follows an option or exists in a position. */
|
||||
|
||||
struct arg_def {
|
||||
uint32_t types; /* ARG_DEF_TYPE_, can be multiple */
|
||||
uint32_t lv_types; /* ARG_DEF_LV_, can be multiple */
|
||||
uint64_t num; /* a literal number for ARG_DEF_TYPE_NUM_CONST */
|
||||
const char *str; /* a literal string for ARG_DEF_TYPE_STR_CONST */
|
||||
const char *str_set[MAX_STR_SET]; /* literal strings for ARG_DEF_TYPE_STR_SET */
|
||||
uint32_t flags; /* ARG_DEF_FLAG_ */
|
||||
};
|
||||
|
||||
/* Description of an option and the value that follows it. */
|
||||
|
||||
struct opt_arg {
|
||||
int opt; /* option, e.g. foo_ARG */
|
||||
struct arg_def def; /* defines accepted values */
|
||||
};
|
||||
|
||||
/* Description of a position and the value that exists there. */
|
||||
|
||||
struct pos_arg {
|
||||
int pos; /* position, e.g. first is 1 */
|
||||
struct arg_def def; /* defines accepted values */
|
||||
};
|
||||
|
||||
/*
|
||||
* CMD_RO_ARGS needs to accomodate a list of options,
|
||||
* of which one is required after which the rest are
|
||||
* optional.
|
||||
*/
|
||||
#define CMD_RO_ARGS 32 /* required opt args */
|
||||
#define CMD_OO_ARGS ARG_COUNT /* optional opt args */
|
||||
#define CMD_RP_ARGS 8 /* required positional args */
|
||||
#define CMD_OP_ARGS 8 /* optional positional args */
|
||||
|
||||
/*
|
||||
* one or more from required_opt_args is required,
|
||||
* then the rest are optional.
|
||||
*/
|
||||
#define CMD_FLAG_ONE_REQUIRED_OPT 1
|
||||
|
||||
/* a register of the lvm commands */
|
||||
struct command {
|
||||
const char *name;
|
||||
const char *desc;
|
||||
const char *usage;
|
||||
command_fn fn;
|
||||
|
||||
unsigned int flags;
|
||||
|
||||
unsigned int cmd_flags; /* CMD_FLAG_ */
|
||||
|
||||
/* definitions of opt/pos args */
|
||||
|
||||
/* required args following an --opt */
|
||||
struct opt_arg required_opt_args[CMD_RO_ARGS];
|
||||
|
||||
/* optional args following an --opt */
|
||||
struct opt_arg optional_opt_args[CMD_OO_ARGS];
|
||||
|
||||
/* required positional args */
|
||||
struct pos_arg required_pos_args[CMD_RP_ARGS];
|
||||
|
||||
/* optional positional args */
|
||||
struct pos_arg optional_pos_args[CMD_OP_ARGS];
|
||||
|
||||
int ro_count;
|
||||
int oo_count;
|
||||
int rp_count;
|
||||
int op_count;
|
||||
|
||||
/* used for processing current position */
|
||||
int pos_count;
|
||||
};
|
||||
|
||||
#endif
|
1428
tools/commands.h
1428
tools/commands.h
File diff suppressed because it is too large
Load Diff
@@ -1910,6 +1910,11 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
|
||||
if (lp->mirrors_supplied) {
|
||||
if (!*lp->type_str || !strcmp(lp->type_str, SEG_TYPE_NAME_RAID1) || !strcmp(lp->type_str, SEG_TYPE_NAME_LINEAR) ||
|
||||
(!strcmp(lp->type_str, SEG_TYPE_NAME_STRIPED) && image_count == 1)) {
|
||||
if (image_count > DEFAULT_RAID1_MAX_IMAGES) {
|
||||
log_error("Only up to %u mirrors in %s LV %s supported currently.",
|
||||
DEFAULT_RAID1_MAX_IMAGES, lp->segtype->name, display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
if (!lv_raid_change_image_count(lv, image_count, lp->pvh))
|
||||
return_0;
|
||||
|
||||
|
@@ -527,8 +527,21 @@ static int _read_mirror_and_raid_params(struct cmd_context *cmd,
|
||||
struct lvcreate_params *lp)
|
||||
{
|
||||
int pagesize = lvm_getpagesize();
|
||||
unsigned max_images = segtype_is_raid(lp->segtype) ? DEFAULT_RAID_MAX_IMAGES :
|
||||
DEFAULT_MIRROR_MAX_IMAGES;
|
||||
unsigned max_images;
|
||||
|
||||
if (seg_is_raid(lp)) {
|
||||
if (seg_is_raid1(lp))
|
||||
max_images = DEFAULT_RAID1_MAX_IMAGES;
|
||||
else {
|
||||
max_images = DEFAULT_RAID_MAX_IMAGES;
|
||||
if (seg_is_raid4(lp) ||
|
||||
seg_is_any_raid5(lp))
|
||||
max_images--;
|
||||
else if (seg_is_any_raid6(lp))
|
||||
max_images -= 2;
|
||||
}
|
||||
} else
|
||||
max_images = DEFAULT_MIRROR_MAX_IMAGES;
|
||||
|
||||
/* Common mirror and raid params */
|
||||
if (arg_is_set(cmd, mirrors_ARG)) {
|
||||
@@ -556,8 +569,19 @@ static int _read_mirror_and_raid_params(struct cmd_context *cmd,
|
||||
/* Default to 2 mirrored areas if '--type mirror|raid1|raid10' */
|
||||
lp->mirrors = seg_is_mirrored(lp) ? 2 : 1;
|
||||
|
||||
if (max(lp->mirrors, lp->stripes) > max_images) {
|
||||
log_error("Only up to %u images in %s supported currently.",
|
||||
/* FIMXE: raid10 check has to change once we support data copies and odd numbers of stripes */
|
||||
if (seg_is_raid10(lp) && lp->mirrors * lp->stripes > max_images) {
|
||||
log_error("Only up to %u stripes in %s supported currently.",
|
||||
max_images, lp->segtype->name);
|
||||
return 0;
|
||||
} else if (seg_is_mirrored(lp)) {
|
||||
if (lp->mirrors > max_images) {
|
||||
log_error("Only up to %u mirrors in %s supported currently.",
|
||||
max_images, lp->segtype->name);
|
||||
return 0;
|
||||
}
|
||||
} else if (lp->stripes > max_images) {
|
||||
log_error("Only up to %u stripes in %s supported currently.",
|
||||
max_images, lp->segtype->name);
|
||||
return 0;
|
||||
}
|
||||
@@ -1231,10 +1255,17 @@ static int _check_raid_parameters(struct volume_group *vg,
|
||||
struct lvcreate_cmdline_params *lcp)
|
||||
{
|
||||
unsigned devs = lcp->pv_count ? : dm_list_size(&vg->pvs);
|
||||
uint64_t page_sectors = lvm_getpagesize() >> SECTOR_SHIFT;
|
||||
struct cmd_context *cmd = vg->cmd;
|
||||
int old_stripes = !arg_is_set(cmd, stripes_ARG) &&
|
||||
find_config_tree_bool(cmd, allocation_raid_stripe_all_devices_CFG, NULL);
|
||||
|
||||
if (vg->extent_size < page_sectors) {
|
||||
log_error("Unable to create RAID LV: requires minimum VG extent size %s",
|
||||
display_size(vg->cmd, page_sectors));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we requested the previous behaviour by setting
|
||||
* "allocation/raid_stripe_all_devices = 1" and the
|
||||
|
@@ -57,7 +57,7 @@ int lvm2_run(void *handle, const char *cmdline)
|
||||
|
||||
cmd = (struct cmd_context *) handle;
|
||||
|
||||
cmd->argv = argv;
|
||||
cmd->pos_arg_values = argv;
|
||||
|
||||
if (!(cmdcopy = dm_strdup(cmdline))) {
|
||||
log_error("Cmdline copy failed.");
|
||||
|
@@ -49,6 +49,11 @@ extern char *optarg;
|
||||
# define OPTIND_INIT 1
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include "command-lines-count.h" /* #define COMMAND_COUNT, generated from command-lines.in */
|
||||
#endif
|
||||
#define COMMAND_COUNT 128
|
||||
|
||||
/*
|
||||
* Table of valid switches
|
||||
*/
|
||||
@@ -58,12 +63,32 @@ static struct arg_props _arg_props[ARG_COUNT + 1] = {
|
||||
#undef arg
|
||||
};
|
||||
|
||||
/*
|
||||
* Table of valid command names
|
||||
*/
|
||||
#define MAX_COMMAND_NAMES 64
|
||||
struct command_name {
|
||||
const char *name;
|
||||
const char *desc;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
struct command_name command_names[MAX_COMMAND_NAMES] = {
|
||||
#define xx(a, b, c...) { # a, b, c }
|
||||
#include "commands.h"
|
||||
#undef xx
|
||||
}
|
||||
|
||||
/*
|
||||
* Table of valid command lines
|
||||
*/
|
||||
static struct command commands[COMMAND_COUNT];
|
||||
static struct cmdline_context _cmdline;
|
||||
|
||||
/* Command line args */
|
||||
unsigned arg_count(const struct cmd_context *cmd, int a)
|
||||
{
|
||||
return cmd->arg_values ? cmd->arg_values[a].count : 0;
|
||||
return cmd->opt_arg_values ? cmd->opt_arg_values[a].count : 0;
|
||||
}
|
||||
|
||||
unsigned grouped_arg_count(const struct arg_values *av, int a)
|
||||
@@ -182,12 +207,12 @@ const char *arg_long_option_name(int a)
|
||||
|
||||
const char *arg_value(const struct cmd_context *cmd, int a)
|
||||
{
|
||||
return cmd->arg_values ? cmd->arg_values[a].value : NULL;
|
||||
return cmd->opt_arg_values ? cmd->opt_arg_values[a].value : NULL;
|
||||
}
|
||||
|
||||
const char *arg_str_value(const struct cmd_context *cmd, int a, const char *def)
|
||||
{
|
||||
return arg_is_set(cmd, a) ? cmd->arg_values[a].value : def;
|
||||
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].value : def;
|
||||
}
|
||||
|
||||
const char *grouped_arg_str_value(const struct arg_values *av, int a, const char *def)
|
||||
@@ -217,44 +242,44 @@ int32_t first_grouped_arg_int_value(const struct cmd_context *cmd, int a, const
|
||||
int32_t arg_int_value(const struct cmd_context *cmd, int a, const int32_t def)
|
||||
{
|
||||
return (_cmdline.arg_props[a].flags & ARG_GROUPABLE) ?
|
||||
first_grouped_arg_int_value(cmd, a, def) : (arg_is_set(cmd, a) ? cmd->arg_values[a].i_value : def);
|
||||
first_grouped_arg_int_value(cmd, a, def) : (arg_is_set(cmd, a) ? cmd->opt_arg_values[a].i_value : def);
|
||||
}
|
||||
|
||||
uint32_t arg_uint_value(const struct cmd_context *cmd, int a, const uint32_t def)
|
||||
{
|
||||
return arg_is_set(cmd, a) ? cmd->arg_values[a].ui_value : def;
|
||||
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].ui_value : def;
|
||||
}
|
||||
|
||||
int64_t arg_int64_value(const struct cmd_context *cmd, int a, const int64_t def)
|
||||
{
|
||||
return arg_is_set(cmd, a) ? cmd->arg_values[a].i64_value : def;
|
||||
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].i64_value : def;
|
||||
}
|
||||
|
||||
uint64_t arg_uint64_value(const struct cmd_context *cmd, int a, const uint64_t def)
|
||||
{
|
||||
return arg_is_set(cmd, a) ? cmd->arg_values[a].ui64_value : def;
|
||||
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].ui64_value : def;
|
||||
}
|
||||
|
||||
/* No longer used.
|
||||
const void *arg_ptr_value(struct cmd_context *cmd, int a, const void *def)
|
||||
{
|
||||
return arg_is_set(cmd, a) ? cmd->arg_values[a].ptr : def;
|
||||
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].ptr : def;
|
||||
}
|
||||
*/
|
||||
|
||||
sign_t arg_sign_value(const struct cmd_context *cmd, int a, const sign_t def)
|
||||
{
|
||||
return arg_is_set(cmd, a) ? cmd->arg_values[a].sign : def;
|
||||
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].sign : def;
|
||||
}
|
||||
|
||||
percent_type_t arg_percent_value(const struct cmd_context *cmd, int a, const percent_type_t def)
|
||||
{
|
||||
return arg_is_set(cmd, a) ? cmd->arg_values[a].percent : def;
|
||||
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].percent : def;
|
||||
}
|
||||
|
||||
int arg_count_increment(struct cmd_context *cmd, int a)
|
||||
{
|
||||
return cmd->arg_values[a].count++;
|
||||
return cmd->opt_arg_values[a].count++;
|
||||
}
|
||||
|
||||
int yes_no_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
|
||||
@@ -709,104 +734,227 @@ int metadatacopies_arg(struct cmd_context *cmd, struct arg_values *av)
|
||||
return int_arg(cmd, av);
|
||||
}
|
||||
|
||||
static void __alloc(int size)
|
||||
static struct command_name *_find_command_name(char *name)
|
||||
{
|
||||
if (!(_cmdline.commands = dm_realloc(_cmdline.commands, sizeof(*_cmdline.commands) * size))) {
|
||||
log_fatal("Couldn't allocate memory.");
|
||||
exit(ECMD_FAILED);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_COMMAND_NAMES; i++) {
|
||||
if (!command_names[i].name)
|
||||
break;
|
||||
if (!strcmp(command_names[i].name, name))
|
||||
return &command_names[i];
|
||||
}
|
||||
|
||||
_cmdline.commands_size = size;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _alloc_command(void)
|
||||
void _define_commands(void)
|
||||
{
|
||||
if (!_cmdline.commands_size)
|
||||
__alloc(32);
|
||||
|
||||
if (_cmdline.commands_size <= _cmdline.num_commands)
|
||||
__alloc(2 * _cmdline.commands_size);
|
||||
}
|
||||
|
||||
static void _create_new_command(const char *name, command_fn command,
|
||||
unsigned flags,
|
||||
const char *desc, const char *usagestr,
|
||||
int nargs, int *args)
|
||||
{
|
||||
struct command *nc;
|
||||
|
||||
_alloc_command();
|
||||
|
||||
nc = _cmdline.commands + _cmdline.num_commands++;
|
||||
|
||||
nc->name = name;
|
||||
nc->desc = desc;
|
||||
nc->usage = usagestr;
|
||||
nc->fn = command;
|
||||
nc->flags = flags;
|
||||
nc->num_args = nargs;
|
||||
nc->valid_args = args;
|
||||
}
|
||||
|
||||
static void _register_command(const char *name, command_fn fn, const char *desc,
|
||||
unsigned flags, const char *usagestr, ...)
|
||||
{
|
||||
int nargs = 0, i;
|
||||
int *args;
|
||||
va_list ap;
|
||||
|
||||
/* count how many arguments we have */
|
||||
va_start(ap, usagestr);
|
||||
while (va_arg(ap, int) >= 0)
|
||||
nargs++;
|
||||
va_end(ap);
|
||||
|
||||
/* allocate space for them */
|
||||
if (!(args = dm_malloc(sizeof(*args) * nargs))) {
|
||||
log_fatal("Out of memory.");
|
||||
exit(ECMD_FAILED);
|
||||
}
|
||||
|
||||
/* fill them in */
|
||||
va_start(ap, usagestr);
|
||||
for (i = 0; i < nargs; i++)
|
||||
args[i] = va_arg(ap, int);
|
||||
va_end(ap);
|
||||
|
||||
/* enter the command in the register */
|
||||
_create_new_command(name, fn, flags, desc, usagestr, nargs, args);
|
||||
/* command-lines.h defines command[] structs, generated from command-lines.in */
|
||||
#include "command-lines.h" /* generated from command-lines.in */
|
||||
}
|
||||
|
||||
void lvm_register_commands(void)
|
||||
{
|
||||
#define xx(a, b, c, d...) _register_command(# a, a, b, c, ## d, \
|
||||
driverloaded_ARG, \
|
||||
debug_ARG, help_ARG, help2_ARG, \
|
||||
version_ARG, verbose_ARG, \
|
||||
yes_ARG, \
|
||||
quiet_ARG, config_ARG, \
|
||||
commandprofile_ARG, \
|
||||
profile_ARG, -1);
|
||||
#include "commands.h"
|
||||
#undef xx
|
||||
struct command_name *cname;
|
||||
int i;
|
||||
|
||||
_define_commands();
|
||||
|
||||
_cmdline.commands = &commands;
|
||||
_cmdline.num_commands = COMMAND_COUNT;
|
||||
|
||||
for (i = 0; i < COMMAND_COUNT; i++) {
|
||||
if (!(cname = _find_command_name(commands[i].name)))
|
||||
log_error(INTERNAL_ERROR "Failed to find command name %s.", commands[i].name);
|
||||
commands[i].flags = cname->flags;
|
||||
}
|
||||
}
|
||||
|
||||
static struct command *_find_command(const char *name)
|
||||
/*
|
||||
* Match what the user typed with a one specific command definition/prototype
|
||||
* from commands[]. If nothing matches, it's not a valid command. The match
|
||||
* is based on command name, required opt args and required pos args.
|
||||
*
|
||||
* Find an entry in the commands array that matches based the arg values.
|
||||
*
|
||||
* If the cmd has opt or pos args set that are not accepted by command,
|
||||
* we can: silently ignore them, warn they are not being used, or fail.
|
||||
* Default should probably be to warn and continue.
|
||||
*
|
||||
* For each command[i], check how many required opt/pos args cmd matches.
|
||||
* Save the command[i] that matches the most.
|
||||
*
|
||||
* commands[i].cmd_flags & CMD_FLAG_ONE_REQUIRED_OPT means
|
||||
* any one item from commands[i].required_opt_args needs to be
|
||||
* set to match.
|
||||
*
|
||||
* required_pos_args[0].flags & ARG_DEF_TYPE_SELECT means
|
||||
* cmd->pos_arg_values[0] can be NULL if arg_is_set(select_ARG)
|
||||
*/
|
||||
|
||||
static int _opt_equivalent_is_set(struct cmd_context *cmd, int opt)
|
||||
{
|
||||
int i;
|
||||
const char *base;
|
||||
if ((opt == mirrorlog_ARG) && arg_is_set(cmd, corelog_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
base = last_path_component(name);
|
||||
if ((opt == resizeable_ARG) && arg_is_set(cmd, resizable_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
for (i = 0; i < _cmdline.num_commands; i++) {
|
||||
if (!strcmp(base, _cmdline.commands[i].name))
|
||||
break;
|
||||
if ((opt == allocatable_ARG) && arg_is_set(cmd, allocation_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == resizeable_ARG) && arg_is_set(cmd, allocation_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == activate_ARG) && arg_is_set(cmd, available_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == rebuild_ARG) && arg_is_set(cmd, raidrebuild_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == syncaction_ARG) && arg_is_set(cmd, raidsyncaction_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == writemostly_ARG) && arg_is_set(cmd, raidwritemostly_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == minrecoveryrate_ARG) && arg_is_set(cmd, raidminrecoveryrate_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == maxrecoveryrate_ARG) && arg_is_set(cmd, raidmaxrecoveryrate_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
if ((opt == writebehind_ARG) && arg_is_set(cmd, raidwritebehind_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _command_required_opt_matches(struct cmd_context *cmd, int ci, int ro)
|
||||
{
|
||||
if (arg_is_set(cmd, commands[ci].required_opt_args[ro].opt, NULL))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* For some commands, --size and --extents are interchanable,
|
||||
* but command[] definitions use only --size.
|
||||
*/
|
||||
if ((commands[ci].required_opt_args[ro].opt == size_ARG) && arg_is_set(cmd, extents_ARG, NULL)) {
|
||||
if (!strcmp(commands[i].name, "lvcreate") ||
|
||||
!strcmp(commands[i].name, "lvresize")
|
||||
!strcmp(commands[i].name, "lvextend")
|
||||
!strcmp(commands[i].name, "lvreduce"))
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (i >= _cmdline.num_commands)
|
||||
return 0;
|
||||
/* TODO: for lvmconfig, recognize --type in place of --typeconfig? */
|
||||
|
||||
return _cmdline.commands + i;
|
||||
if (_opt_equivalent_is_set(cmd, commands[ci].required_opt_args[ro].opt))
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _command_required_pos_matches(struct cmd_context *cmd, int ci, int rp)
|
||||
{
|
||||
if (cmd->pos_arg_values[rp]) {
|
||||
/* FIXME: can we match object type better than just checking something exists? */
|
||||
/* Some cases could be validated by looking at defs.types and at the value. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If Select is specified as a pos arg, then that pos arg can be
|
||||
* empty if --select is used.
|
||||
*/
|
||||
if ((commands[ci].required_pos_args[rp].def.types & ARG_DEF_TYPE_SELECT) &&
|
||||
arg_is_set(cmd, select_ARG, NULL))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct command *_find_command(struct cmd_context *cmd, const char *path)
|
||||
{
|
||||
const char *name;
|
||||
int ro, rp;
|
||||
int found = 0;
|
||||
int i;
|
||||
|
||||
name = last_path_component(path);
|
||||
|
||||
for (i = 0; i < COMMAND_COUNT; i++) {
|
||||
if (strcmp(name, commands[i].name))
|
||||
continue;
|
||||
|
||||
match_count = 1; /* for command name matching */
|
||||
mismatch_count = 0;
|
||||
|
||||
/* match required_opt_args */
|
||||
|
||||
for (ro = 0; ro < commands[i].ro_count; ro++) {
|
||||
if (_command_required_opt_matches(cmd, i, ro))
|
||||
match_count++;
|
||||
else
|
||||
mismatch_count++;
|
||||
}
|
||||
|
||||
/*
|
||||
* One item in required_opt_args must be set for
|
||||
* a match, and the rest are optional (don't count
|
||||
* as mismatches).
|
||||
*/
|
||||
if (cmd->cmd_flags & CMD_FLAG_ONE_REQUIRED_OPT) {
|
||||
if (match_count >= 2) {
|
||||
match_count = 2;
|
||||
mismatch_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* match required_pos_args */
|
||||
|
||||
for (rp = 0; rp < commands[i].rp_count; rp++) {
|
||||
if (_command_required_pos_matches(cmd, i, rp))
|
||||
match_count++;
|
||||
else
|
||||
mismatch_count++;
|
||||
}
|
||||
|
||||
if (mismatch_count) {
|
||||
/* save i/match_count for "closest" command that doesn't match */
|
||||
if (!closest_count || (match_count > closest_count)) {
|
||||
closest_i = i;
|
||||
closest_count = match_count;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!best_match_count || (match_count > best_match_count)) {
|
||||
best_match_i = i;
|
||||
best_match_count = match_count;
|
||||
}
|
||||
}
|
||||
|
||||
if (!best_match_count) {
|
||||
/* nothing matches */
|
||||
/* TODO: report closest matching command and report missing required opt/pos args for that? */
|
||||
log_error("Failed to find a matching command definition.");
|
||||
if (closest_count) {
|
||||
log_warn("Closest command usage is:");
|
||||
log_warn("%s", commands[closest_i].usage);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if all arg_is_set values from cmd are accepted as
|
||||
* optional_opt_args, and warn (or fail per config?) if options are set
|
||||
* in cmd that are not accepted by the chosen command[i].
|
||||
*
|
||||
* Same for pos args.
|
||||
*/
|
||||
|
||||
log_debug("matched command usage: %.80s ...", commands[best_match_i].usage);
|
||||
|
||||
return &commands[best_match_i];
|
||||
}
|
||||
|
||||
static void _short_usage(const char *name)
|
||||
@@ -816,14 +964,16 @@ static void _short_usage(const char *name)
|
||||
|
||||
static int _usage(const char *name)
|
||||
{
|
||||
struct command *com = _find_command(name);
|
||||
struct command_name *cname = _find_command_name(name);
|
||||
|
||||
if (!com) {
|
||||
if (!cname) {
|
||||
log_print("%s: no such command.", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_print("%s: %s\n\n%s", com->name, com->desc, com->usage);
|
||||
/* FIXME: print usage strings from matching commands[] entries? */
|
||||
|
||||
log_print("%s: %s", cname->name, cname->desc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -890,7 +1040,7 @@ static int _process_command_line(struct cmd_context *cmd, int *argc,
|
||||
struct arg_values *av;
|
||||
struct arg_value_group_list *current_group = NULL;
|
||||
|
||||
if (!(cmd->arg_values = dm_pool_zalloc(cmd->mem, sizeof(*cmd->arg_values) * ARG_COUNT))) {
|
||||
if (!(cmd->opt_arg_values = dm_pool_zalloc(cmd->mem, sizeof(*cmd->opt_arg_values) * ARG_COUNT))) {
|
||||
log_fatal("Unable to allocate memory for command line arguments.");
|
||||
return 0;
|
||||
}
|
||||
@@ -917,7 +1067,7 @@ static int _process_command_line(struct cmd_context *cmd, int *argc,
|
||||
|
||||
a = _cmdline.arg_props + arg;
|
||||
|
||||
av = &cmd->arg_values[arg];
|
||||
av = &cmd->opt_arg_values[arg];
|
||||
|
||||
if (a->flags & ARG_GROUPABLE) {
|
||||
/*
|
||||
@@ -930,7 +1080,7 @@ static int _process_command_line(struct cmd_context *cmd, int *argc,
|
||||
(current_group->arg_values[arg].count && !(a->flags & ARG_COUNTABLE)) ||
|
||||
(current_group->prio < a->prio)) {
|
||||
/* FIXME Reduce size including only groupable args */
|
||||
if (!(current_group = dm_pool_zalloc(cmd->mem, sizeof(struct arg_value_group_list) + sizeof(*cmd->arg_values) * ARG_COUNT))) {
|
||||
if (!(current_group = dm_pool_zalloc(cmd->mem, sizeof(struct arg_value_group_list) + sizeof(*cmd->opt_arg_values) * ARG_COUNT))) {
|
||||
log_fatal("Unable to allocate memory for command line arguments.");
|
||||
return 0;
|
||||
}
|
||||
@@ -1002,12 +1152,12 @@ static int _merge_synonym(struct cmd_context *cmd, int oldarg, int newarg)
|
||||
/* Not groupable? */
|
||||
if (!(_cmdline.arg_props[oldarg].flags & ARG_GROUPABLE)) {
|
||||
if (arg_is_set(cmd, oldarg))
|
||||
_copy_arg_values(cmd->arg_values, oldarg, newarg);
|
||||
_copy_arg_values(cmd->opt_arg_values, oldarg, newarg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (arg_is_set(cmd, oldarg))
|
||||
cmd->arg_values[newarg].count = cmd->arg_values[oldarg].count;
|
||||
cmd->opt_arg_values[newarg].count = cmd->opt_arg_values[oldarg].count;
|
||||
|
||||
/* Groupable */
|
||||
dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
|
||||
@@ -1431,7 +1581,7 @@ static int _prepare_profiles(struct cmd_context *cmd)
|
||||
log_debug(_setting_global_profile_msg, _command_profile_source_name, profile->name);
|
||||
cmd->profile_params->global_command_profile = profile;
|
||||
|
||||
if (!cmd->arg_values)
|
||||
if (!cmd->opt_arg_values)
|
||||
cmd->profile_params->shell_profile = profile;
|
||||
}
|
||||
|
||||
@@ -1553,14 +1703,14 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
|
||||
|
||||
log_debug("Parsing: %s", cmd->cmd_line);
|
||||
|
||||
if (!(cmd->command = _find_command(argv[0])))
|
||||
return ENO_SUCH_CMD;
|
||||
|
||||
if (!_process_command_line(cmd, &argc, &argv)) {
|
||||
log_error("Error during parsing of command line.");
|
||||
return EINVALID_CMD_LINE;
|
||||
}
|
||||
|
||||
if (!(cmd->command = _find_command(cmd, argv[0])))
|
||||
return ENO_SUCH_CMD;
|
||||
|
||||
set_cmd_name(cmd->command->name);
|
||||
|
||||
if (arg_is_set(cmd, backgroundfork_ARG)) {
|
||||
@@ -1853,7 +2003,7 @@ static int _do_get_custom_fd(const char *env_var_name, int *fd)
|
||||
{
|
||||
const char *str;
|
||||
char *endptr;
|
||||
int tmp_fd;
|
||||
long int tmp_fd;
|
||||
|
||||
*fd = -1;
|
||||
|
||||
@@ -2040,23 +2190,8 @@ struct cmd_context *init_lvm(unsigned set_connections, unsigned set_filters)
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static void _fin_commands(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < _cmdline.num_commands; i++)
|
||||
dm_free(_cmdline.commands[i].valid_args);
|
||||
|
||||
dm_free(_cmdline.commands);
|
||||
|
||||
_cmdline.commands = NULL;
|
||||
_cmdline.num_commands = 0;
|
||||
_cmdline.commands_size = 0;
|
||||
}
|
||||
|
||||
void lvm_fin(struct cmd_context *cmd)
|
||||
{
|
||||
_fin_commands();
|
||||
destroy_toolcontext(cmd);
|
||||
udev_fin_library_context();
|
||||
}
|
||||
@@ -2202,7 +2337,8 @@ int lvm2_main(int argc, char **argv)
|
||||
if (!(cmd = init_lvm(0, 0)))
|
||||
return -1;
|
||||
|
||||
cmd->argv = argv;
|
||||
cmd->pos_arg_values = argv;
|
||||
|
||||
lvm_register_commands();
|
||||
|
||||
if (_lvm1_fallback(cmd)) {
|
||||
|
@@ -144,6 +144,75 @@ static struct dm_list *_get_allocatable_pvs(struct cmd_context *cmd, int argc,
|
||||
return allocatable_pvs;
|
||||
}
|
||||
|
||||
/*
|
||||
* If @lv_name's a RAID SubLV, check for any PVs
|
||||
* on @trim_list holding it's sibling (rimage/rmeta)
|
||||
* and remove it from the @trim_list in order to allow
|
||||
* for pvmove collocation of DataLV/MetaLV pairs.
|
||||
*/
|
||||
static int _remove_sibling_pvs_from_trim_list(struct logical_volume *lv,
|
||||
const char *lv_name,
|
||||
struct dm_list *trim_list)
|
||||
{
|
||||
char *idx, *suffix, *sublv_name;
|
||||
size_t len;
|
||||
struct logical_volume *sublv;
|
||||
struct dm_list untrim_list, *pvh1, *pvh2;
|
||||
struct pv_list *pvl1, *pvl2;
|
||||
|
||||
/* Give up with success unless @lv_name _and_ valid raid segment type */
|
||||
if (!lv_name || !*lv_name ||
|
||||
!seg_is_raid(first_seg(lv)) ||
|
||||
seg_is_raid0(first_seg(lv)) ||
|
||||
!strcmp(lv->name, lv_name))
|
||||
return 1;
|
||||
|
||||
dm_list_init(&untrim_list);
|
||||
|
||||
if (!(suffix = first_substring(lv_name, "_rimage_", "_rmeta_", NULL)))
|
||||
return 0;
|
||||
|
||||
if (!(idx = strstr(suffix + 1, "_")))
|
||||
return 0;
|
||||
idx++;
|
||||
|
||||
/* + 2 for the longer rimage string */
|
||||
if (!(sublv_name = dm_pool_alloc(lv->vg->cmd->mem, strlen(lv_name + 2))))
|
||||
return_0;
|
||||
|
||||
/* Create the siblings name (e.g. "raidlv_rmeta_N" -> "raidlv_rimage_N" */
|
||||
len = suffix - lv_name;
|
||||
strncpy(sublv_name, lv_name, len);
|
||||
sprintf(sublv_name + len, strstr(suffix, "_rimage_") ? "_rmeta_%s" : "_rimage_%s", idx);
|
||||
|
||||
if (!(sublv = find_lv(lv->vg, sublv_name))) {
|
||||
log_error("Can't find sub LV %s?", sublv_name);
|
||||
return_0;
|
||||
}
|
||||
|
||||
if (!get_pv_list_for_lv(lv->vg->cmd->mem, sublv, &untrim_list)) {
|
||||
log_error("Can't find PVs for sub LV %s?", sublv_name);
|
||||
return_0;
|
||||
}
|
||||
|
||||
dm_list_iterate(pvh1, &untrim_list) {
|
||||
pvl1 = dm_list_item(pvh1, struct pv_list);
|
||||
|
||||
dm_list_iterate(pvh2, trim_list) {
|
||||
pvl2 = dm_list_item(pvh2, struct pv_list);
|
||||
|
||||
if (pvl1->pv == pvl2->pv) {
|
||||
log_debug("Removing PV %s from trim list",
|
||||
pvl2->pv->dev->pvid);
|
||||
dm_list_del(&pvl2->list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* _trim_allocatable_pvs
|
||||
* @alloc_list
|
||||
@@ -324,7 +393,7 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
|
||||
if (lv == lv_mirr)
|
||||
continue;
|
||||
|
||||
if (lv_name && strcmp(lv->name, lv_name))
|
||||
if (lv_name && strcmp(lv->name, top_level_lv_name(vg, lv_name)))
|
||||
continue;
|
||||
|
||||
/*
|
||||
@@ -334,7 +403,7 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
|
||||
*
|
||||
* Allow clustered mirror, but not raid mirror.
|
||||
*/
|
||||
if (vg_is_clustered(lv->vg) && !lv_is_mirror_type(lv))
|
||||
if (vg_is_clustered(vg) && !lv_is_mirror_type(lv))
|
||||
continue;
|
||||
|
||||
if (!lv_is_on_pvs(lv, source_pvl))
|
||||
@@ -351,8 +420,18 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
|
||||
seg_is_mirrored(first_seg(lv))) {
|
||||
dm_list_init(&trim_list);
|
||||
|
||||
if (!get_pv_list_for_lv(lv->vg->cmd->mem,
|
||||
lv, &trim_list))
|
||||
if (!get_pv_list_for_lv(vg->cmd->mem, lv, &trim_list))
|
||||
return_NULL;
|
||||
|
||||
/*
|
||||
* Remove any PVs holding SubLV siblings to allow
|
||||
* for collocation (e.g. *rmeta_0 -> *rimage_0).
|
||||
*
|
||||
* Callee checks for lv_name and valid raid segment type.
|
||||
*
|
||||
* FIXME: don't rely on namespace
|
||||
*/
|
||||
if (!_remove_sibling_pvs_from_trim_list(lv, lv_name, &trim_list))
|
||||
return_NULL;
|
||||
|
||||
if (!_trim_allocatable_pvs(allocatable_pvs,
|
||||
@@ -370,6 +449,7 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
|
||||
lv = lvl->lv;
|
||||
if (lv == lv_mirr)
|
||||
continue;
|
||||
|
||||
if (lv_name) {
|
||||
if (strcmp(lv->name, lv_name) && !sub_lv_of(lv, lv_name))
|
||||
continue;
|
||||
|
@@ -105,7 +105,7 @@ int become_daemon(struct cmd_context *cmd, int skip_lvm)
|
||||
init_verbose(VERBOSE_BASE_LEVEL);
|
||||
#endif /* DEBUG_CHILD */
|
||||
|
||||
strncpy(*cmd->argv, "(lvm2)", strlen(*cmd->argv));
|
||||
strncpy(*cmd->pos_arg_values, "(lvm2)", strlen(*cmd->pos_arg_values));
|
||||
|
||||
lvmetad_disconnect();
|
||||
|
||||
@@ -1281,10 +1281,12 @@ static int _validate_stripe_params(struct cmd_context *cmd, const struct segment
|
||||
if (!stripe_size_required && *stripe_size) {
|
||||
log_print_unless_silent("Ignoring stripesize argument for %s devices.", segtype->name);
|
||||
*stripe_size = 0;
|
||||
} else if (segtype_is_striped(segtype) && *stripes == 1 && *stripe_size) {
|
||||
log_print_unless_silent("Ignoring stripesize argument with single stripe.");
|
||||
} else if (*stripes == 1 && (segtype_is_striped(segtype) || segtype_is_mirror(segtype))) {
|
||||
stripe_size_required = 0;
|
||||
*stripe_size = 0;
|
||||
if (*stripe_size) {
|
||||
log_print_unless_silent("Ignoring stripesize argument with single stripe.");
|
||||
*stripe_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (stripe_size_required) {
|
||||
|
@@ -44,6 +44,8 @@
|
||||
#include "toollib.h"
|
||||
#include "lvmnotify.h"
|
||||
|
||||
#include "command.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -51,8 +53,6 @@
|
||||
#define MAX_ARGS 64
|
||||
|
||||
/* command functions */
|
||||
typedef int (*command_fn) (struct cmd_context * cmd, int argc, char **argv);
|
||||
|
||||
#define xx(a, b...) int a(struct cmd_context *cmd, int argc, char **argv);
|
||||
#include "commands.h"
|
||||
#undef xx
|
||||
@@ -118,19 +118,6 @@ struct arg_value_group_list {
|
||||
#define ENABLE_DUPLICATE_DEVS 0x00000400
|
||||
/* Command does not accept tags as args. */
|
||||
#define DISALLOW_TAG_ARGS 0x00000800
|
||||
|
||||
/* a register of the lvm commands */
|
||||
struct command {
|
||||
const char *name;
|
||||
const char *desc;
|
||||
const char *usage;
|
||||
command_fn fn;
|
||||
|
||||
unsigned flags;
|
||||
|
||||
int num_args;
|
||||
int *valid_args;
|
||||
};
|
||||
|
||||
void usage(const char *name);
|
||||
|
||||
|
@@ -331,7 +331,7 @@ static int _move_thins(struct volume_group *vg_from,
|
||||
data_lv = seg_lv(first_seg(seg->pool_lv), 0);
|
||||
|
||||
/* Ignore, if no allocations on PVs of @vg_to */
|
||||
if (!lv_is_on_pvs(data_lv, &vg_to->pvs) ||
|
||||
if (!lv_is_on_pvs(data_lv, &vg_to->pvs) &&
|
||||
(seg->external_lv && !lv_is_on_pvs(seg->external_lv, &vg_to->pvs)))
|
||||
continue;
|
||||
|
||||
|
Reference in New Issue
Block a user