1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-11-01 00:23:49 +03:00

Compare commits

..

23 Commits

Author SHA1 Message Date
Heinz Mauelshagen
74210f8662 raid: fixup some size issues; allow for striped -> raid4 conversion 2016-08-26 14:35:07 +02:00
Heinz Mauelshagen
ddb3826523 Adjust region and stripe sizes on small VG extents 2016-08-26 12:35:08 +02:00
Heinz Mauelshagen
2aeb71cb37 Fix bogus metadata device size on conversion from striped/raid0 -> raid4 2016-08-26 12:32:03 +02:00
Alasdair G Kergon
c3d821b647 alloc: Avoid PV tags too when avoiding parallel PV allocation.
Also add debug messages for parallel PVs.
2016-08-26 12:22:32 +02:00
Heinz Mauelshagen
2e9cb73706 Support tiny VG extent sizes... 2016-08-25 01:36:56 +02:00
Heinz Mauelshagen
9a4acf93cd test: delay writes to all test PVs in lvchange-rebuild-raid.sh to avoid race 2016-08-25 01:36:13 +02:00
Heinz Mauelshagen
bff470f83f test: add missing lvchange-rebuild-raid.sh 2016-08-24 18:22:34 +02:00
Alasdair G Kergon
40a4f5f38f alloc: Record PV tags of parallel PVs in log. 2016-08-24 15:49:34 +01:00
Alasdair G Kergon
68adf2c199 alloc: Move _log_parallel_areas. 2016-08-24 15:47:38 +01:00
Alasdair G Kergon
7837fbc1c1 lvconvert: Disallow raid10 mirror conversions. 2016-08-23 23:40:16 +01:00
Alasdair G Kergon
2d65ce9711 dmeventd: Add fixed timeout when unmonitoring. 2016-08-23 16:09:18 +01:00
Peter Rajnoha
db0e34535c libdm: add some comments about DM_UDEV_DISABLE_LIBRARY_FALLBACK flag 2016-08-23 15:58:03 +02:00
Alasdair G Kergon
b975532433 dmeventd: Simplify replacement unmonitor code. 2016-08-23 12:16:39 +01:00
Alasdair G Kergon
97ee5a1cd3 dmeventd: Start merging back replacement unmonitor code. 2016-08-23 11:30:34 +01:00
Alasdair G Kergon
952e413328 dmeventd: Fix unmonitoring when segtype changes.
When the segment type is being changed, unmonitoring an LV requires
the existing dso to be specified as a parameter, not the new one.
2016-08-23 02:26:14 +01:00
Alasdair G Kergon
7646741ec6 raid: Don't monitor raid0 or raid0_meta LVs. 2016-08-20 02:14:33 +01:00
Alasdair G Kergon
896912b14d lvcreate: Never treat raid0 as linear.
raid0 and raid0_meta require, or default to, at least 2 stripes.
2016-08-19 23:57:30 +01:00
Alasdair G Kergon
88e6abc5a0 lvconvert: Don't allow --repair on raid0 LVs. 2016-08-19 23:42:01 +01:00
David Teigland
bf0eaafa6b libdaemon: add errno to error message 2016-08-19 10:59:46 -05:00
Alasdair G Kergon
e192fde687 lvcreate: Drop warning messages for number of raid stripes.
It's now just setting a default, not adjusting the user's parameter.
2016-08-19 14:53:33 +01:00
Alasdair G Kergon
ea0f604e70 lvcreate: No longer adjust --stripes for raid types.
If the number of stripes requested is incompatible with the requested
type of raid, give an error instead of adjusting it.

If no stripes argument is supplied, continue to use an appropriate
default.
2016-08-19 14:19:51 +01:00
Alasdair G Kergon
c1a0a2c712 toollib: Record whether or not stripes/stripe_size args supplied. 2016-08-19 13:51:43 +01:00
Alasdair G Kergon
c27963c566 lib: Move lcm and gcd to lib/misc for wider use. 2016-08-18 14:06:13 +01:00
36 changed files with 2500 additions and 11574 deletions

View File

@@ -1,5 +1,11 @@
Version 2.02.165 -
===================================
Avoid PV tags when checking allocation against parallel PVs.
Disallow mirror conversions of raid10 volumes.
Fix dmeventd unmonitoring when segment type (and dso) changes.
Don't allow lvconvert --repair on raid0 devices or attempt to monitor them.
No longer adjust incorrect number of raid stripes supplied to lvcreate.
Move lcm and gcd to lib/misc.
Suppress some unnecessary --stripesize parameter warnings.
Fix 'pvmove -n name ...' to prohibit collocation of RAID SubLVs

View File

@@ -50,6 +50,7 @@
@top_srcdir@/lib/misc/lvm-file.h
@top_srcdir@/lib/misc/lvm-flock.h
@top_srcdir@/lib/misc/lvm-globals.h
@top_srcdir@/lib/misc/lvm-maths.h
@top_srcdir@/lib/misc/lvm-percent.h
@top_srcdir@/lib/misc/lvm-signal.h
@top_srcdir@/lib/misc/lvm-string.h

View File

@@ -112,6 +112,7 @@ SOURCES =\
misc/lvm-file.c \
misc/lvm-flock.c \
misc/lvm-globals.c \
misc/lvm-maths.c \
misc/lvm-signal.c \
misc/lvm-string.c \
misc/lvm-wrappers.c \

View File

@@ -1548,7 +1548,7 @@ static struct dm_event_handler *_create_dm_event_handler(struct cmd_context *cmd
if (dm_event_handler_set_dmeventd_path(dmevh, find_config_tree_str(cmd, dmeventd_executable_CFG, NULL)))
goto_bad;
if (dm_event_handler_set_dso(dmevh, dso))
if (dso && dm_event_handler_set_dso(dmevh, dso))
goto_bad;
if (dm_event_handler_set_uuid(dmevh, dmuuid))
@@ -1592,6 +1592,39 @@ static char *_build_target_uuid(struct cmd_context *cmd, const struct logical_vo
return build_dm_uuid(cmd->mem, lv, layer);
}
static int _device_registered_with_dmeventd(struct cmd_context *cmd, const struct logical_volume *lv, int *pending, const char **dso)
{
char *uuid;
enum dm_event_mask evmask = 0;
struct dm_event_handler *dmevh;
*pending = 0;
if (!(uuid = _build_target_uuid(cmd, lv)))
return_0;
if (!(dmevh = _create_dm_event_handler(cmd, uuid, NULL, 0, DM_EVENT_ALL_ERRORS)))
return_0;
if (dm_event_get_registered_device(dmevh, 0)) {
dm_event_handler_destroy(dmevh);
return 0;
}
evmask = dm_event_handler_get_event_mask(dmevh);
if (evmask & DM_EVENT_REGISTRATION_PENDING) {
*pending = 1;
evmask &= ~DM_EVENT_REGISTRATION_PENDING;
}
if (dso && (*dso = dm_event_handler_get_dso(dmevh)) && !(*dso = dm_pool_strdup(cmd->mem, *dso)))
log_error("Failed to duplicate dso name.");
dm_event_handler_destroy(dmevh);
return evmask;
}
int target_registered_with_dmeventd(struct cmd_context *cmd, const char *dso,
const struct logical_volume *lv, int *pending)
{
@@ -1674,6 +1707,8 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
uint32_t s;
static const struct lv_activate_opts zlaopts = { 0 };
struct lvinfo info;
const char *dso;
int new_unmonitor;
if (!laopts)
laopts = &zlaopts;
@@ -1781,42 +1816,58 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
!seg->segtype->ops->target_monitored) /* doesn't support registration */
continue;
monitored = seg->segtype->ops->target_monitored(seg, &pending);
if (!monitor)
/* When unmonitoring, obtain existing dso being used. */
monitored = _device_registered_with_dmeventd(cmd, seg->lv, &pending, &dso);
else
monitored = seg->segtype->ops->target_monitored(seg, &pending);
/* FIXME: We should really try again if pending */
monitored = (pending) ? 0 : monitored;
monitor_fn = NULL;
new_unmonitor = 0;
if (monitor) {
if (monitored)
log_verbose("%s already monitored.", display_lvname(lv));
else if (seg->segtype->ops->target_monitor_events)
else if (seg->segtype->ops->target_monitor_events) {
log_verbose("Monitoring %s%s", display_lvname(lv), test_mode() ? " [Test mode: skipping this]" : "");
monitor_fn = seg->segtype->ops->target_monitor_events;
}
} else {
if (!monitored)
log_verbose("%s already not monitored.", display_lvname(lv));
else if (seg->segtype->ops->target_unmonitor_events)
monitor_fn = seg->segtype->ops->target_unmonitor_events;
else if (*dso) {
/*
* Divert unmonitor away from code that depends on the new segment
* type instead of the existing one if it's changing.
*/
log_verbose("Not monitoring %s with %s%s", display_lvname(lv), dso, test_mode() ? " [Test mode: skipping this]" : "");
new_unmonitor = 1;
}
}
/* Do [un]monitor */
if (!monitor_fn)
continue;
log_verbose("%sonitoring %s%s", monitor ? "M" : "Not m", display_lvname(lv),
test_mode() ? " [Test mode: skipping this]" : "");
/* FIXME Test mode should really continue a bit further. */
if (test_mode())
continue;
/* FIXME specify events */
if (!monitor_fn(seg, 0)) {
log_error("%s: %s segment monitoring function failed.",
display_lvname(lv), seg->segtype->name);
return 0;
}
if (new_unmonitor) {
if (!target_register_events(cmd, dso, lv, 0, 0, 10)) {
log_error("%s: segment unmonitoring failed.",
display_lvname(lv));
return 0;
}
} else if (monitor_fn) {
/* FIXME specify events */
if (!monitor_fn(seg, 0)) {
log_error("%s: %s segment monitoring function failed.",
display_lvname(lv), seg->segtype->name);
return 0;
}
} else
continue;
/* Check [un]monitor results */
/* Try a couple times if pending, but not forever... */

View File

@@ -90,7 +90,7 @@ struct cmd_context {
const char *cmd_line;
struct command *command;
char **argv;
struct arg_values *opt_arg_values;
struct arg_values *arg_values;
struct dm_list arg_value_groups;
/*

View File

@@ -391,7 +391,7 @@ static int _read_segment(struct logical_volume *lv, const struct dm_config_node
if (!(seg = alloc_lv_segment(segtype, lv, start_extent,
extent_count, 0, 0, NULL, area_count,
extent_count, 0, 0, 0, NULL))) {
segtype->parity_devs ? (extent_count / (area_count - segtype->parity_devs)) : extent_count, 0, 0, 0, NULL))) {
log_error("Segment allocation failed");
return 0;
}

View File

@@ -38,9 +38,6 @@ typedef enum {
NEXT_AREA
} area_use_t;
/* FIXME: remove RAID_METADATA_AREA_LEN macro after defining 'raid_log_extents'*/
#define RAID_METADATA_AREA_LEN 1
/* FIXME These ended up getting used differently from first intended. Refactor. */
/* Only one of A_CONTIGUOUS_TO_LVSEG, A_CLING_TO_LVSEG, A_CLING_TO_ALLOCED may be set */
#define A_CONTIGUOUS_TO_LVSEG 0x01 /* Must be contiguous to an existing segment */
@@ -878,22 +875,51 @@ dm_percent_t copy_percent(const struct logical_volume *lv)
return denominator ? dm_make_percent(numerator, denominator) : DM_PERCENT_100;
}
/* Round up extents to next stripe boundary for number of stripes */
static uint32_t _round_to_stripe_boundary(struct volume_group *vg, uint32_t extents,
uint32_t stripes, int extend)
/* Round any tiny extents to multiples of 4K */
#define MINIMUM_ALLOCATION_SECTORS 8
static uint32_t _round_extents(uint32_t extents, uint32_t extent_size, int extend)
{
uint64_t size = (uint64_t) extents * extent_size;
uint64_t rest = size % MINIMUM_ALLOCATION_SECTORS;
if (!rest)
return extents;
if (!size)
return 0;
rest = MINIMUM_ALLOCATION_SECTORS - rest;
return (size + (extend ? rest : -(MINIMUM_ALLOCATION_SECTORS - rest))) / extent_size;
}
/* Round up extents to next stripe boundary for number of stripes and ensure minimum sizes */
static uint32_t _round_extents_to_boundary(struct volume_group *vg, uint32_t extents,
uint32_t stripes, uint32_t stripe_size, int extend)
{
uint32_t size_rest, new_extents = extents;
if (!stripes)
return extents;
if (stripes < 2)
return _round_extents(extents, vg->extent_size, extend);
redo:
/* Round up extents to stripe divisible amount */
if ((size_rest = extents % stripes)) {
if ((size_rest = new_extents % stripes))
new_extents += extend ? stripes - size_rest : -size_rest;
log_print_unless_silent("Rounding size %s (%d extents) up to stripe boundary size %s (%d extents).",
if (stripes > 1 && stripe_size > 1) {
uint32_t tmp = new_extents;
if ((new_extents = _round_extents(tmp / stripes, vg->extent_size, extend) * stripes) != tmp)
goto redo;
}
log_debug("Adjusted allocation request of %" PRIu32 " to %" PRIu32 " logical extents.", extents, new_extents);
if (new_extents != extents)
log_print_unless_silent("Rounding size %s (%d extents) up to boundary size %s (%d extents).",
display_size(vg->cmd, (uint64_t) extents * vg->extent_size), extents,
display_size(vg->cmd, (uint64_t) new_extents * vg->extent_size), new_extents);
}
return new_extents;
}
@@ -1203,6 +1229,8 @@ static uint32_t _calc_area_multiple(const struct segment_type *segtype,
}
/*
* FIXME:
*
* RAID10 - only has 2-way mirror right now.
* If we are to move beyond 2-way RAID10, then
* the 'stripes' argument will always need to
@@ -1230,14 +1258,14 @@ static int _lv_segment_reduce(struct lv_segment *seg, uint32_t reduction)
uint32_t area_reduction, s;
/* Caller must ensure exact divisibility */
if (seg_is_striped(seg)) {
if (reduction % seg->area_count) {
if (seg_is_striped(seg) || (seg_is_raid(seg) && !seg_is_raid1(seg))) {
if (reduction % (seg->area_count - seg->segtype->parity_devs)) {
log_error("Segment extent reduction %" PRIu32
" not divisible by #stripes %" PRIu32,
reduction, seg->area_count);
return 0;
}
area_reduction = (reduction / seg->area_count);
area_reduction = reduction / (seg->area_count - seg->segtype->parity_devs);
} else
area_reduction = reduction;
@@ -1581,11 +1609,13 @@ static uint32_t _mirror_log_extents(uint32_t region_size, uint32_t pe_size, uint
/* Is there enough total space or should we give up immediately? */
static int _sufficient_pes_free(struct alloc_handle *ah, struct dm_list *pvms,
uint32_t allocated, uint32_t extents_still_needed)
uint32_t allocated, uint32_t extents_still_needed,
uint32_t extent_size)
{
uint32_t area_extents_needed = (extents_still_needed - allocated) * ah->area_count / ah->area_multiple;
uint32_t parity_extents_needed = (extents_still_needed - allocated) * ah->parity_count / ah->area_multiple;
uint32_t metadata_extents_needed = ah->alloc_and_split_meta ? 0 : ah->metadata_area_count * RAID_METADATA_AREA_LEN; /* One each */
uint32_t metadata_extents_needed = ah->alloc_and_split_meta ? 0 :
ah->metadata_area_count * lv_raid_metadata_area_len(ah->region_size, extent_size);
uint32_t total_extents_needed = area_extents_needed + parity_extents_needed + metadata_extents_needed;
uint32_t free_pes = pv_maps_size(pvms);
@@ -1674,49 +1704,6 @@ static void _init_alloc_parms(struct alloc_handle *ah,
alloc_parms->flags |= A_CAN_SPLIT;
}
static int _log_parallel_areas(struct dm_pool *mem, struct dm_list *parallel_areas)
{
struct seg_pvs *spvs;
struct pv_list *pvl;
char *pvnames;
if (!parallel_areas)
return 1;
dm_list_iterate_items(spvs, parallel_areas) {
if (!dm_pool_begin_object(mem, 256)) {
log_error("dm_pool_begin_object failed");
return 0;
}
dm_list_iterate_items(pvl, &spvs->pvs) {
if (!dm_pool_grow_object(mem, pv_dev_name(pvl->pv), strlen(pv_dev_name(pvl->pv)))) {
log_error("dm_pool_grow_object failed");
dm_pool_abandon_object(mem);
return 0;
}
if (!dm_pool_grow_object(mem, " ", 1)) {
log_error("dm_pool_grow_object failed");
dm_pool_abandon_object(mem);
return 0;
}
}
if (!dm_pool_grow_object(mem, "\0", 1)) {
log_error("dm_pool_grow_object failed");
dm_pool_abandon_object(mem);
return 0;
}
pvnames = dm_pool_end_object(mem);
log_debug_alloc("Parallel PVs at LE %" PRIu32 " length %" PRIu32 ": %s",
spvs->le, spvs->len, pvnames);
dm_pool_free(mem, pvnames);
}
return 1;
}
/* Handles also stacking */
static int _setup_lv_size(struct logical_volume *lv, uint32_t extents)
{
@@ -2030,25 +2017,20 @@ static int _is_same_pv(struct pv_match *pvmatch __attribute((unused)), struct pv
/*
* Does PV area have a tag listed in allocation/cling_tag_list that
* matches EITHER a tag of the PV of the existing segment OR a tag in pv_tags?
* If tags_list_str is set, then instead we generate a list of matching tags for printing.
* If mem is set, then instead we append a list of matching tags for printing to the object there.
*/
static int _match_pv_tags(const struct dm_config_node *cling_tag_list_cn,
struct physical_volume *pv1, uint32_t pv1_start_pe, uint32_t area_num,
struct physical_volume *pv2, struct dm_list *pv_tags, unsigned validate_only,
struct dm_pool *mem, const char **tags_list_str)
struct dm_pool *mem, unsigned parallel_pv)
{
const struct dm_config_value *cv;
const char *str;
const char *tag_matched;
struct dm_list *tags_to_match = tags_list_str ? NULL : pv_tags ? : &pv2->tags;
struct dm_list *tags_to_match = mem ? NULL : pv_tags ? : &pv2->tags;
struct dm_str_list *sl;
unsigned first_tag = 1;
if (tags_list_str && !dm_pool_begin_object(mem, 256)) {
log_error("PV tags string allocation failed");
return 0;
}
for (cv = cling_tag_list_cn->v; cv; cv = cv->next) {
if (cv->type != DM_CFG_STRING) {
if (validate_only)
@@ -2085,16 +2067,14 @@ static int _match_pv_tags(const struct dm_config_node *cling_tag_list_cn,
/* Wildcard matches any tag against any tag. */
if (!strcmp(str, "*")) {
if (tags_list_str) {
if (mem) {
dm_list_iterate_items(sl, &pv1->tags) {
if (!first_tag && !dm_pool_grow_object(mem, ",", 0)) {
dm_pool_abandon_object(mem);
log_error("PV tags string extension failed.");
return 0;
}
first_tag = 0;
if (!dm_pool_grow_object(mem, sl->str, 0)) {
dm_pool_abandon_object(mem);
log_error("PV tags string extension failed.");
return 0;
}
@@ -2104,10 +2084,14 @@ static int _match_pv_tags(const struct dm_config_node *cling_tag_list_cn,
if (!str_list_match_list(&pv1->tags, tags_to_match, &tag_matched))
continue;
else {
if (!pv_tags)
log_debug_alloc("Matched allocation PV tag %s on existing %s with free space on %s.",
tag_matched, pv_dev_name(pv1), pv2 ? pv_dev_name(pv2) : "-");
else
if (!pv_tags) {
if (parallel_pv)
log_debug_alloc("Not using free space on %s: Matched allocation PV tag %s on existing parallel PV %s.",
pv_dev_name(pv1), tag_matched, pv2 ? pv_dev_name(pv2) : "-");
else
log_debug_alloc("Matched allocation PV tag %s on existing %s with free space on %s.",
tag_matched, pv_dev_name(pv1), pv2 ? pv_dev_name(pv2) : "-");
} else
log_debug_alloc("Eliminating allocation area %" PRIu32 " at PV %s start PE %" PRIu32
" from consideration: PV tag %s already used.",
area_num, pv_dev_name(pv1), pv1_start_pe, tag_matched);
@@ -2119,24 +2103,26 @@ static int _match_pv_tags(const struct dm_config_node *cling_tag_list_cn,
(tags_to_match && !str_list_match_item(tags_to_match, str)))
continue;
else {
if (tags_list_str) {
if (mem) {
if (!first_tag && !dm_pool_grow_object(mem, ",", 0)) {
dm_pool_abandon_object(mem);
log_error("PV tags string extension failed.");
return 0;
}
first_tag = 0;
if (!dm_pool_grow_object(mem, str, 0)) {
dm_pool_abandon_object(mem);
log_error("PV tags string extension failed.");
return 0;
}
continue;
}
if (!pv_tags)
log_debug_alloc("Matched allocation PV tag %s on existing %s with free space on %s.",
str, pv_dev_name(pv1), pv2 ? pv_dev_name(pv2) : "-");
else
if (!pv_tags) {
if (parallel_pv)
log_debug_alloc("Not using free space on %s: Matched allocation PV tag %s on existing parallel PV %s.",
pv2 ? pv_dev_name(pv2) : "-", str, pv_dev_name(pv1));
else
log_debug_alloc("Matched allocation PV tag %s on existing %s with free space on %s.",
str, pv_dev_name(pv1), pv2 ? pv_dev_name(pv2) : "-");
} else
log_debug_alloc("Eliminating allocation area %" PRIu32 " at PV %s start PE %" PRIu32
" from consideration: PV tag %s already used.",
area_num, pv_dev_name(pv1), pv1_start_pe, str);
@@ -2144,32 +2130,25 @@ static int _match_pv_tags(const struct dm_config_node *cling_tag_list_cn,
}
}
if (tags_list_str) {
if (!dm_pool_grow_object(mem, "\0", 1)) {
dm_pool_abandon_object(mem);
log_error("PV tags string extension failed.");
return 0;
}
*tags_list_str = dm_pool_end_object(mem);
if (mem)
return 1;
}
return 0;
}
static int _validate_tag_list(const struct dm_config_node *cling_tag_list_cn)
{
return _match_pv_tags(cling_tag_list_cn, NULL, 0, 0, NULL, NULL, 1, NULL, NULL);
return _match_pv_tags(cling_tag_list_cn, NULL, 0, 0, NULL, NULL, 1, NULL, 0);
}
static const char *_tags_list_str(struct alloc_handle *ah, struct physical_volume *pv1)
static int _tags_list_str(struct dm_pool *mem, struct physical_volume *pv1, const struct dm_config_node *cling_tag_list_cn)
{
const char *tags_list_str;
if (!_match_pv_tags(cling_tag_list_cn, pv1, 0, 0, NULL, NULL, 0, mem, 0)) {
dm_pool_abandon_object(mem);
return_0;
}
if (!_match_pv_tags(ah->cling_tag_list_cn, pv1, 0, 0, NULL, NULL, 0, ah->mem, &tags_list_str))
return_NULL;
return tags_list_str;
return 1;
}
/*
@@ -2180,7 +2159,7 @@ static int _pv_has_matching_tag(const struct dm_config_node *cling_tag_list_cn,
struct physical_volume *pv1, uint32_t pv1_start_pe, uint32_t area_num,
struct dm_list *pv_tags)
{
return _match_pv_tags(cling_tag_list_cn, pv1, pv1_start_pe, area_num, NULL, pv_tags, 0, NULL, NULL);
return _match_pv_tags(cling_tag_list_cn, pv1, pv1_start_pe, area_num, NULL, pv_tags, 0, NULL, 0);
}
/*
@@ -2188,14 +2167,82 @@ static int _pv_has_matching_tag(const struct dm_config_node *cling_tag_list_cn,
* matches a tag of the PV of the existing segment?
*/
static int _pvs_have_matching_tag(const struct dm_config_node *cling_tag_list_cn,
struct physical_volume *pv1, struct physical_volume *pv2)
struct physical_volume *pv1, struct physical_volume *pv2,
unsigned parallel_pv)
{
return _match_pv_tags(cling_tag_list_cn, pv1, 0, 0, pv2, NULL, 0, NULL, NULL);
return _match_pv_tags(cling_tag_list_cn, pv1, 0, 0, pv2, NULL, 0, NULL, parallel_pv);
}
static int _has_matching_pv_tag(struct pv_match *pvmatch, struct pv_segment *pvseg, struct pv_area *pva)
{
return _pvs_have_matching_tag(pvmatch->cling_tag_list_cn, pvseg->pv, pva->map->pv);
return _pvs_have_matching_tag(pvmatch->cling_tag_list_cn, pvseg->pv, pva->map->pv, 0);
}
static int _log_parallel_areas(struct dm_pool *mem, struct dm_list *parallel_areas,
const struct dm_config_node *cling_tag_list_cn)
{
struct seg_pvs *spvs;
struct pv_list *pvl;
char *pvnames;
unsigned first;
if (!parallel_areas)
return 1;
dm_list_iterate_items(spvs, parallel_areas) {
first = 1;
if (!dm_pool_begin_object(mem, 256)) {
log_error("dm_pool_begin_object failed");
return 0;
}
dm_list_iterate_items(pvl, &spvs->pvs) {
if (!first && !dm_pool_grow_object(mem, " ", 1)) {
log_error("dm_pool_grow_object failed");
dm_pool_abandon_object(mem);
return 0;
}
if (!dm_pool_grow_object(mem, pv_dev_name(pvl->pv), strlen(pv_dev_name(pvl->pv)))) {
log_error("dm_pool_grow_object failed");
dm_pool_abandon_object(mem);
return 0;
}
if (cling_tag_list_cn) {
if (!dm_pool_grow_object(mem, "(", 1)) {
log_error("dm_pool_grow_object failed");
dm_pool_abandon_object(mem);
return 0;
}
if (!_tags_list_str(mem, pvl->pv, cling_tag_list_cn)) {
dm_pool_abandon_object(mem);
return_0;
}
if (!dm_pool_grow_object(mem, ")", 1)) {
log_error("dm_pool_grow_object failed");
dm_pool_abandon_object(mem);
return 0;
}
}
first = 0;
}
if (!dm_pool_grow_object(mem, "\0", 1)) {
log_error("dm_pool_grow_object failed");
dm_pool_abandon_object(mem);
return 0;
}
pvnames = dm_pool_end_object(mem);
log_debug_alloc("Parallel PVs at LE %" PRIu32 " length %" PRIu32 ": %s",
spvs->le, spvs->len, pvnames);
dm_pool_free(mem, pvnames);
}
return 1;
}
/*
@@ -2218,8 +2265,17 @@ static void _reserve_area(struct alloc_handle *ah, struct alloc_state *alloc_sta
struct pv_area_used *area_used = &alloc_state->areas[ix_pva];
const char *pv_tag_list = NULL;
if (ah->cling_tag_list_cn)
pv_tag_list = _tags_list_str(ah, pva->map->pv);
if (ah->cling_tag_list_cn) {
if (!dm_pool_begin_object(ah->mem, 256))
log_error("PV tags string allocation failed");
else if (!_tags_list_str(ah->mem, pva->map->pv, ah->cling_tag_list_cn))
dm_pool_abandon_object(ah->mem);
else if (!dm_pool_grow_object(ah->mem, "\0", 1)) {
dm_pool_abandon_object(ah->mem);
log_error("PV tags string extension failed.");
} else
pv_tag_list = dm_pool_end_object(ah->mem);
}
log_debug_alloc("%s allocation area %" PRIu32 " %s %s start PE %" PRIu32
" length %" PRIu32 " leaving %" PRIu32 "%s%s.",
@@ -2378,7 +2434,7 @@ static int _check_cling_to_alloced(struct alloc_handle *ah, const struct dm_conf
continue; /* Area already assigned */
dm_list_iterate_items(aa, &ah->alloced_areas[s]) {
if ((!cling_tag_list_cn && (pva->map->pv == aa[0].pv)) ||
(cling_tag_list_cn && _pvs_have_matching_tag(cling_tag_list_cn, pva->map->pv, aa[0].pv))) {
(cling_tag_list_cn && _pvs_have_matching_tag(cling_tag_list_cn, pva->map->pv, aa[0].pv, 0))) {
if (positional)
_reserve_required_area(ah, alloc_state, pva, pva->count, s, 0);
return 1;
@@ -2389,13 +2445,20 @@ static int _check_cling_to_alloced(struct alloc_handle *ah, const struct dm_conf
return 0;
}
static int _pv_is_parallel(struct physical_volume *pv, struct dm_list *parallel_pvs)
static int _pv_is_parallel(struct physical_volume *pv, struct dm_list *parallel_pvs, const struct dm_config_node *cling_tag_list_cn)
{
struct pv_list *pvl;
dm_list_iterate_items(pvl, parallel_pvs)
if (pv == pvl->pv)
dm_list_iterate_items(pvl, parallel_pvs) {
if (pv == pvl->pv) {
log_debug_alloc("Not using free space on existing parallel PV %s.",
pv_dev_name(pvl->pv));
return 1;
}
if (cling_tag_list_cn && _pvs_have_matching_tag(cling_tag_list_cn, pvl->pv, pv, 1))
return 1;
}
return 0;
}
@@ -2683,7 +2746,7 @@ static int _find_some_parallel_space(struct alloc_handle *ah,
/* FIXME Split into log and non-log parallel_pvs and only check the log ones if log_iteration? */
/* (I've temporatily disabled the check.) */
/* Avoid PVs used by existing parallel areas */
if (!log_iteration_count && parallel_pvs && _pv_is_parallel(pvm->pv, parallel_pvs))
if (!log_iteration_count && parallel_pvs && _pv_is_parallel(pvm->pv, parallel_pvs, ah->cling_tag_list_cn))
goto next_pv;
/*
@@ -3001,7 +3064,7 @@ static int _allocate(struct alloc_handle *ah,
if (!(pvms = create_pv_maps(ah->mem, vg, allocatable_pvs)))
return_0;
if (!_log_parallel_areas(ah->mem, ah->parallel_areas))
if (!_log_parallel_areas(ah->mem, ah->parallel_areas, ah->cling_tag_list_cn))
stack;
alloc_state.areas_size = dm_list_size(pvms);
@@ -3042,7 +3105,7 @@ static int _allocate(struct alloc_handle *ah,
old_allocated = alloc_state.allocated;
log_debug_alloc("Trying allocation using %s policy.", get_alloc_string(alloc));
if (!ah->approx_alloc && !_sufficient_pes_free(ah, pvms, alloc_state.allocated, ah->new_extents))
if (!ah->approx_alloc && !_sufficient_pes_free(ah, pvms, alloc_state.allocated, ah->new_extents, vg->extent_size))
goto_out;
_init_alloc_parms(ah, &alloc_parms, alloc, prev_lvseg,
@@ -3235,7 +3298,7 @@ static struct alloc_handle *_alloc_init(struct cmd_context *cmd,
ah->metadata_area_count = area_count;
ah->alloc_and_split_meta = 1;
ah->log_len = RAID_METADATA_AREA_LEN;
ah->log_len = lv_raid_metadata_area_len(ah->region_size, extent_size);
/*
* We need 'log_len' extents for each
@@ -3814,8 +3877,7 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
if (seg_is_raid(seg)) {
stripes = 1;
stripe_size = 0;
if (seg_is_any_raid0(seg))
area_multiple = seg->area_count;
area_multiple = _calc_area_multiple(seg->segtype, seg->area_count, seg_is_raid1(seg) ? 1 : seg->area_count - seg->segtype->parity_devs);
}
for (fa = first_area, s = 0; s < seg->area_count; s++) {
@@ -3938,6 +4000,82 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
return 1;
}
/* Adjust region and stripe size on very small LVs */
void lv_adjust_region_and_stripe_size(struct logical_volume *lv)
{
uint32_t size;
uint64_t area_size;
struct lv_segment *seg = first_seg(lv);
if (!seg)
return;
area_size = (uint64_t) seg->area_len * lv->vg->extent_size;
if (seg->region_size > area_size) {
size = _round_down_pow2(seg_lv(seg, 0)->size);
log_warn("Region size %s too large for LV %s size %s, rounded down to %s",
display_size(lv->vg->cmd, seg->region_size),
display_lvname(lv),
display_size(lv->vg->cmd, lv->size),
display_size(lv->vg->cmd, size));
seg->region_size = size;
}
if (seg->stripe_size > area_size) {
size = _round_down_pow2(seg_lv(seg, 0)->size);
log_warn("Stripe size %s too large for LV %s size %s, rounded down to %s",
display_size(lv->vg->cmd, seg->stripe_size),
display_lvname(lv),
display_size(lv->vg->cmd, lv->size),
display_size(lv->vg->cmd, size));
seg->stripe_size = size;
}
}
/* Check MetaLV size is sufficient fro RaidLV @lv size */
#define RAID_SUPERBLOCKS_SIZE (2 * 4096) /* dm-raid superblock and bitmap superblock */
static int _raid_rmeta_size_sufficient(struct logical_volume *lv)
{
uint32_t area_multiple;
uint64_t max_rimage_size;
uint64_t mlv_bytes; /* dm-raid superblock and bitmap superblock */
struct lv_segment *seg = first_seg(lv);
struct logical_volume *mlv;
if (!seg ||
!seg_is_raid(seg) ||
!seg->region_size ||
!seg->meta_areas ||
!(mlv = seg_metalv(seg, 0)))
return 1;
mlv_bytes = mlv->size << SECTOR_SHIFT;
if (mlv_bytes < RAID_SUPERBLOCKS_SIZE) {
log_error("Metadata LV %s too small to even hold the RAID headers",
display_lvname(mlv));
return 0;
}
/*
* Subtract space for 2 headers (superblock and bitmap)
* and calculate max image size in sectors
*/
max_rimage_size = (mlv_bytes - RAID_SUPERBLOCKS_SIZE) * 8 * seg->region_size;
/* Calculate the maximum possible LV size */
/* FIXME: area_multiple needs to change once we support odd number of stripes in raid10 */
area_multiple = _calc_area_multiple(seg->segtype, seg->area_count, 0);
if (max_rimage_size * area_multiple < lv->size) {
log_error("Can't extend LV %s larger than %s because of MetaLV size",
display_lvname(lv),
display_size(lv->vg->cmd, max_rimage_size * area_multiple));
return 0;
}
return 1;
}
/*
* Entry point for single-step LV allocation + extension.
* Extents is the number of logical extents to append to the LV unless
@@ -3955,7 +4093,7 @@ int lv_extend(struct logical_volume *lv,
struct dm_list *allocatable_pvs, alloc_policy_t alloc,
int approx_alloc)
{
int r = 1;
int r = 1, empty = 0;
int log_count = 0;
struct alloc_handle *ah;
uint32_t sub_lv_count;
@@ -3968,6 +4106,8 @@ int lv_extend(struct logical_volume *lv,
return lv_add_virtual_segment(lv, 0u, extents, segtype);
if (!lv->le_count) {
empty = 1;
if (segtype_is_pool(segtype))
/*
* Pool allocations treat the metadata device like a mirror log.
@@ -3998,6 +4138,8 @@ int lv_extend(struct logical_volume *lv,
if (!(r = lv_add_segment(ah, 0, ah->area_count, lv, segtype,
stripe_size, 0u, 0)))
stack;
if (empty)
lv_adjust_region_and_stripe_size(lv);
} else {
/*
* For RAID, all the devices are AREA_LV.
@@ -4023,6 +4165,17 @@ int lv_extend(struct logical_volume *lv,
stripes, stripe_size)))
goto_out;
if (empty)
lv_adjust_region_and_stripe_size(lv);
if (!(r = _raid_rmeta_size_sufficient(lv))) {
if (!old_extents &&
(!lv_remove(lv) || !vg_write(lv->vg) || !vg_commit(lv->vg)))
return_0;
goto_out;
}
/*
* If we are expanding an existing mirror, we can skip the
* resync of the extension if the LV is currently in-sync
@@ -4333,6 +4486,7 @@ static int _validate_stripesize(const struct volume_group *vg,
return 0;
}
/* Limit stripe size to extent size for non-RAID */
if (lp->stripe_size > vg->extent_size) {
log_print_unless_silent("Reducing stripe size %s to maximum, "
"physical extent size %s.",
@@ -4826,6 +4980,10 @@ static int _lvresize_adjust_extents(struct logical_volume *lv,
(lp->sign == SIGN_NONE && (lp->extents < existing_extents)))
reducing = 1;
lp->extents = _round_extents_to_boundary(lv->vg, lp->extents,
seg_is_mirrored(seg_last) ? 1 : seg_last->area_count - seg_last->segtype->parity_devs,
seg_last->stripe_size, !reducing);
/* If extending, find properties of last segment */
if (!reducing) {
seg_mirrors = seg_is_mirrored(seg_last) ? lv_mirror_count(lv) : 0;
@@ -7084,6 +7242,17 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
}
}
#if 1
/* FIXME: minimum 1K extent size??? */
if (lp->stripe_size > vg->extent_size &&
!seg_is_raid(lp)) {
log_print_unless_silent("Reducing requested stripe size %s to maximum, "
"physical extent size %s.",
display_size(cmd, (uint64_t) lp->stripe_size),
display_size(cmd, (uint64_t) vg->extent_size));
lp->stripe_size = vg->extent_size;
}
#else
if (lp->stripe_size > vg->extent_size) {
if (seg_is_raid(lp) && (vg->extent_size < STRIPE_SIZE_MIN)) {
/*
@@ -7105,8 +7274,9 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
display_size(cmd, (uint64_t) vg->extent_size));
lp->stripe_size = vg->extent_size;
}
#endif
lp->extents = _round_to_stripe_boundary(vg, lp->extents, lp->stripes, 1);
lp->extents = _round_extents_to_boundary(vg, lp->extents, lp->stripes, lp->stripe_size, 1);
if (!lp->extents && !seg_is_thin_volume(lp)) {
log_error(INTERNAL_ERROR "Unable to create new logical volume with no extents.");
@@ -7258,6 +7428,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
status |= LV_NOTSYNCED;
}
if (!seg_is_raid(lp))
lp->region_size = adjusted_mirror_region_size(vg->extent_size,
lp->extents,
lp->region_size, 0,

View File

@@ -413,9 +413,8 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
inc_error_count;
}
area_multiplier = segtype_is_striped(seg->segtype) ?
seg->area_count : 1;
area_multiplier = (segtype_is_striped(seg->segtype) || (seg_is_raid(seg) && !seg_is_raid1(seg))) ?
(seg->area_count - seg->segtype->parity_devs) : 1;
if (seg->area_len * area_multiplier != seg->len) {
log_error("LV %s: segment %u has inconsistent "
"area_len %u",

View File

@@ -30,10 +30,11 @@
#define MAX_STRIPES 128U
#define SECTOR_SHIFT 9L
#define SECTOR_SIZE ( 1L << SECTOR_SHIFT )
#define STRIPE_SIZE_MIN ( (unsigned) lvm_getpagesize() >> SECTOR_SHIFT) /* PAGESIZE in sectors */
#define STRIPE_SIZE_MIN 8 /* 8 sectors minimum to allow for raid takover of striped */
#define STRIPE_SIZE_MAX ( 512L * 1024L >> SECTOR_SHIFT) /* 512 KB in sectors */
#define STRIPE_SIZE_LIMIT ((UINT_MAX >> 2) + 1)
#define MAX_RESTRICTED_LVS 255 /* Used by FMT_RESTRICTED_LVIDS */
#define MIN_EXTENT_SIZE 8 /* 8 sectors minimum to allow for raid takover of striped */
#define MAX_EXTENT_SIZE ((uint32_t) -1)
#define MIN_NON_POWER2_EXTENT_SIZE (128U * 2U) /* 128KB in sectors */
@@ -825,6 +826,7 @@ int lv_rename_update(struct cmd_context *cmd, struct logical_volume *lv,
/* Updates and reloads metadata for given lv */
int lv_update_and_reload(struct logical_volume *lv);
int lv_update_and_reload_origin(struct logical_volume *lv);
void lv_adjust_region_and_stripe_size(struct logical_volume *lv);
uint32_t extents_from_size(struct cmd_context *cmd, uint64_t size,
uint32_t extent_size);
@@ -945,6 +947,9 @@ struct lvcreate_params {
uint32_t chunk_size; /* snapshot */
uint32_t region_size; /* mirror */
unsigned stripes_supplied; /* striped */
unsigned stripe_size_supplied; /* striped */
uint32_t mirrors; /* mirror */
uint32_t min_recovery_rate; /* RAID */
@@ -1209,6 +1214,7 @@ 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);
int partial_raid_lv_supports_degraded_activation(const struct logical_volume *lv);
uint32_t lv_raid_metadata_area_len(uint32_t region_size, uint32_t extent_size);
/* -- metadata/raid_manip.c */
/* ++ metadata/cache_manip.c */

View File

@@ -1008,6 +1008,11 @@ int vgcreate_params_validate(struct cmd_context *cmd,
return 0;
}
if (vp->extent_size < MIN_EXTENT_SIZE) {
log_error("Physical extent size < 4 KiB restricts RAID use.");
return 0;
}
if (!(cmd->fmt->features & FMT_UNLIMITED_VOLS)) {
if (!vp->max_lv)
vp->max_lv = 255;

View File

@@ -430,28 +430,6 @@ int validate_pool_chunk_size(struct cmd_context *cmd,
return r;
}
/* Greatest common divisor */
static unsigned long _gcd(unsigned long n1, unsigned long n2)
{
unsigned long remainder;
do {
remainder = n1 % n2;
n1 = n2;
n2 = remainder;
} while (n2);
return n1;
}
/* Least common multiple */
static unsigned long _lcm(unsigned long n1, unsigned long n2)
{
if (!n1 || !n2)
return 0;
return (n1 * n2) / _gcd(n1, n2);
}
int recalculate_pool_chunk_size_with_dev_hints(struct logical_volume *pool_lv,
int passed_args,
int chunk_size_calc_policy)
@@ -497,7 +475,7 @@ int recalculate_pool_chunk_size_with_dev_hints(struct logical_volume *pool_lv,
continue;
if (previous_hint)
hint = _lcm(previous_hint, hint);
hint = lcm(previous_hint, hint);
previous_hint = hint;
break;
case AREA_LV:

View File

@@ -151,6 +151,26 @@ int lv_is_raid_with_tracking(const struct logical_volume *lv)
return _lv_is_raid_with_tracking(lv, &tracking);
}
/* FIXME: remove lv_raid_metadata_area_len() after defining 'lv_raid_rmeta_extents'*/
uint32_t lv_raid_metadata_area_len(uint32_t region_size, uint32_t extent_size)
{
uint32_t r;
uint64_t max_lv_size;
if (!region_size)
region_size++;
/* Ensure senseful minimum metadata device size until we get dynamic rmeta resizing... */
max_lv_size = UINT32_MAX / 2;
max_lv_size *= extent_size;
max_lv_size = min(max_lv_size, (uint64_t) 2048 * 1024 * 1024 * 128);
r = (max_lv_size / region_size / (8*2048*extent_size) ?: 1);
if (r * extent_size < 2 * 12)
r = 2 * 12;
return r;
}
uint32_t lv_raid_image_count(const struct logical_volume *lv)
{
struct lv_segment *seg = first_seg(lv);
@@ -628,6 +648,9 @@ static int _alloc_image_components(struct logical_volume *lv,
else
region_size = seg->region_size;
if (!region_size)
region_size = get_default_region_size(lv->vg->cmd);
if (seg_is_raid(seg))
segtype = seg->segtype;
else if (!(segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_RAID1)))
@@ -709,6 +732,7 @@ static int _alloc_rmeta_for_lv(struct logical_volume *data_lv,
struct logical_volume **meta_lv,
struct dm_list *allocate_pvs)
{
uint32_t region_size;
struct dm_list allocatable_pvs;
struct alloc_handle *ah;
struct lv_segment *seg = first_seg(data_lv);
@@ -735,9 +759,10 @@ static int _alloc_rmeta_for_lv(struct logical_volume *data_lv,
if (!(base_name = top_level_lv_name(data_lv->vg, data_lv->name)))
return_0;
region_size = seg->region_size ?: get_default_region_size(data_lv->vg->cmd);
if (!(ah = allocate_extents(data_lv->vg, NULL, seg->segtype, 0, 1, 0,
seg->region_size,
1 /*RAID_METADATA_AREA_LEN*/,
lv_raid_metadata_area_len(region_size, data_lv->vg->extent_size),
allocate_pvs, data_lv->alloc, 0, NULL)))
return_0;
@@ -845,7 +870,9 @@ static int _raid_add_images_without_commit(struct logical_volume *lv,
lv->status |= RAID;
seg = first_seg(lv);
seg_lv(seg, 0)->status |= RAID_IMAGE | LVM_READ | LVM_WRITE;
seg->region_size = get_default_region_size(lv->vg->cmd);
if (!seg->region_size)
seg->region_size = get_default_region_size(lv->vg->cmd);
seg->stripe_size = 0;
/* MD's bitmap is limited to tracking 2^21 regions */
while (seg->region_size < (lv->size / (1 << 21))) {
@@ -2520,7 +2547,7 @@ static struct possible_takeover_reshape_type _possible_takeover_reshape_types[]
.current_areas = 1,
.options = ALLOW_STRIPE_SIZE },
{ .current_types = SEG_STRIPED_TARGET, /* striped, i.e. seg->area_count > 1 */
.possible_types = SEG_RAID0|SEG_RAID0_META,
.possible_types = SEG_RAID0|SEG_RAID0_META|SEG_RAID4,
.current_areas = ~0U,
.options = ALLOW_NONE },
/* raid0* -> */
@@ -2886,7 +2913,7 @@ static int _raid456_to_raid0_or_striped_wrapper(TAKEOVER_FN_ARGS)
return_0;
/* FIXME Hard-coded raid4 to raid0 */
seg->area_len = seg->extents_copied = seg->area_len / seg->area_count;
seg->area_len = seg->extents_copied = seg->len / (seg->area_count - seg->segtype->parity_devs);
if (segtype_is_striped_target(new_segtype)) {
if (!_convert_raid0_to_striped(lv, 0, &removal_lvs))
@@ -2972,10 +2999,13 @@ static int _striped_or_raid0_to_raid45610_wrapper(TAKEOVER_FN_ARGS)
seg->segtype = new_segtype;
seg->region_size = new_region_size;
/* FIXME Hard-coded raid0 to raid4 */
seg->area_len = seg->len;
/* FIXME Hard-coded raid0 -> raid4 */
if (seg_is_any_raid0(seg))
seg->area_len = seg->extents_copied = seg->len / (seg->area_count - seg->segtype->parity_devs);
_check_and_adjust_region_size(lv);
lv_adjust_region_and_stripe_size(lv);
log_debug_metadata("Updating VG metadata and reloading %s LV %s",
lvseg_name(seg), display_lvname(lv));
@@ -3065,7 +3095,7 @@ static int _takeover_from_raid0_to_raid10(TAKEOVER_FN_ARGS)
static int _takeover_from_raid0_to_raid45(TAKEOVER_FN_ARGS)
{
return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1, 1 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1, 2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
}
static int _takeover_from_raid0_to_raid6(TAKEOVER_FN_ARGS)
@@ -3111,7 +3141,7 @@ static int _takeover_from_raid0_meta_to_raid10(TAKEOVER_FN_ARGS)
static int _takeover_from_raid0_meta_to_raid45(TAKEOVER_FN_ARGS)
{
return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1, 1 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
return _striped_or_raid0_to_raid45610_wrapper(lv, new_segtype, yes, force, first_seg(lv)->area_count + 1, 2 /* data_copies */, 0, 0, new_region_size, allocate_pvs);
}
static int _takeover_from_raid0_meta_to_raid6(TAKEOVER_FN_ARGS)
@@ -3384,12 +3414,6 @@ static int _set_convenient_raid456_segtype_to(const struct lv_segment *seg_from,
!segtype_is_raid5_n(*segtype)) {
log_error("Conversion to raid5_n not yet supported.");
return 0;
/* If this is any raid6 conversion request -> enforce raid6_n_6, because we convert from striped */
} else if (segtype_is_any_raid6(*segtype) &&
!segtype_is_raid6_n_6(*segtype)) {
log_error("Conversion to raid6_n_6 not yet supported.");
return 0;
}
/* Got to do check for raid5 -> raid6 ... */

View File

@@ -145,7 +145,7 @@ struct dev_manager;
#define segtype_is_unknown(segtype) ((segtype)->flags & SEG_UNKNOWN ? 1 : 0)
#define segtype_supports_stripe_size(segtype) \
((segtype_is_striped(segtype) || segtype_is_mirror(segtype) || \
((segtype_is_striped(segtype) || \
segtype_is_cache(segtype) || segtype_is_cache_pool(segtype) || \
segtype_is_thin(segtype) || segtype_is_snapshot(segtype) || \
(segtype_is_raid(segtype) && !segtype_is_raid1(segtype))) ? 1 : 0)

View File

@@ -89,6 +89,7 @@
# include "lvm-logging.h"
# include "lvm-globals.h"
# include "lvm-wrappers.h"
# include "lvm-maths.h"
#endif
#include <unistd.h>

38
lib/misc/lvm-maths.c Normal file
View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2016 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
*/
#include "lib.h"
/* Greatest common divisor */
unsigned long gcd(unsigned long n1, unsigned long n2)
{
unsigned long remainder;
do {
remainder = n1 % n2;
n1 = n2;
n2 = remainder;
} while (n2);
return n1;
}
/* Least common multiple */
unsigned long lcm(unsigned long n1, unsigned long n2)
{
if (!n1 || !n2)
return 0;
return (n1 * n2) / gcd(n1, n2);
}

24
lib/misc/lvm-maths.h Normal file
View File

@@ -0,0 +1,24 @@
/*
* Copyright (C) 2016 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_MATH_H
#define _LVM_MATH_H
/* Greatest common divisor */
unsigned long gcd(unsigned long n1, unsigned long n2);
/* Least common multiple */
unsigned long lcm(unsigned long n1, unsigned long n2);
#endif

View File

@@ -499,7 +499,12 @@ static struct segment_type *_init_raid_segtype(struct cmd_context *cmd,
segtype->ops = &_raid_ops;
segtype->name = rt->name;
segtype->flags = SEG_RAID | SEG_ONLY_EXCLUSIVE | rt->extra_flags | monitored;
segtype->flags = SEG_RAID | SEG_ONLY_EXCLUSIVE | rt->extra_flags;
/* Never monitor raid0 or raid0_meta LVs */
if (!segtype_is_any_raid0(segtype))
segtype->flags |= monitored;
segtype->parity_devs = rt->parity;
log_very_verbose("Initialised segtype: %s", segtype->name);

View File

@@ -491,7 +491,7 @@ static int handle_connect(daemon_state s)
client.socket_fd = accept(s.socket_fd, (struct sockaddr *) &sockaddr, &sl);
if (client.socket_fd < 0) {
ERROR(&s, "Failed to accept connection.");
ERROR(&s, "Failed to accept connection errno %d.", errno);
return 0;
}
@@ -513,7 +513,7 @@ static int handle_connect(daemon_state s)
ts->client = client;
if (pthread_create(&ts->client.thread_id, NULL, _client_thread, ts)) {
ERROR(&s, "Failed to create client thread.");
ERROR(&s, "Failed to create client thread errno %d.", errno);
return 0;
}

View File

@@ -216,6 +216,7 @@ int dm_task_set_major_minor(struct dm_task *dmt, int major, int minor, int allow
int dm_task_set_uid(struct dm_task *dmt, uid_t uid);
int dm_task_set_gid(struct dm_task *dmt, gid_t gid);
int dm_task_set_mode(struct dm_task *dmt, mode_t mode);
/* See also description for DM_UDEV_DISABLE_LIBRARY_FALLBACK flag! */
int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags);
int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr);
int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads, const char *sectors, const char *start);
@@ -3496,7 +3497,18 @@ struct dm_pool *dm_config_memory(struct dm_config_tree *cft);
* DM_UDEV_DISABLE_LIBRARY_FALLBACK is set in case we need to disable
* libdevmapper's node management. We will rely on udev completely
* and there will be no fallback action provided by libdevmapper if
* udev does something improperly.
* udev does something improperly. Using the library fallback code has
* a consequence that you need to take into account: any device node
* or symlink created without udev is not recorded in udev database
* which other applications may read to get complete list of devices.
* For this reason, use of DM_UDEV_DISABLE_LIBRARY_FALLBACK is
* recommended on systems where udev is used. Keep library fallback
* enabled just for exceptional cases where you need to debug udev-related
* problems. If you hit such problems, please contact us through upstream
* LVM2 development mailing list (see also README file). This flag is
* currently not set by default in libdevmapper so you need to set it
* explicitly if you're sure that udev is behaving correctly on your
* setups.
*/
#define DM_UDEV_DISABLE_LIBRARY_FALLBACK 0x0020
/*

View File

@@ -1,844 +0,0 @@
#
# When this file is changed, tools/command-lines.h
# and tools/command-lines-count.h must be regenerated
# with:
#
# scripts/create-commands --output count scripts/command-lines.in > tools/command-lines-count.h
# scripts/create-commands --output struct scripts/command-lines.in > tools/command-lines.h
#
#
# Syntax
#
# 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.
#
# 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. LV_type1_type2_type3 when the LV is
# limited to multiple specific types.
#
# 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.
#
# --size and --extents are interchangable, but only --size is used
# in these definitions to keep them simpler. Either --size or
# --extents will be recognized when matching a command to one of
# these definitions.
#
# Some options have multiple names, but only one form of the name
# is used in these definitions. Synonyms will be recognized when
# matching a command to a command definition.
#
# used in definitions below (equivalent but not used in definitions)
# mirrorlog core (corelog)
# resizeable (resizable)
# allocatable (allocation)
# resizeable (allocation)
# activate (available)
# rebuild (raidrebuild)
# syncaction (raidsyncaction)
# writemostly (raidwritemostly)
# minrecoveryrate (raidminrecoveryrate)
# maxrecoveryrate (raidmaxrecoveryrate)
# writebehind (raidwritebehind)
#
# DESC: describe what the command does, with a separate
# sentence ending in '.' for each unique operation.
# A new line is printed after each '.' so be careful
# about where '.' is used.
#
#
# For efficiency, sets of options can be defined and reused
# in multiple command definitions.
#
# 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 Units, --unquoted
#
# config, dumpconfig, lvmconfig
#
OO_CONFIG: --atversion String, --typeconfig 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 Alloc, --contiguous Bool,
--detachprofile, --metadataprofile String, --profile String,
--permission Permission, --readahead Readahead, --setactivationskip Bool,
--errorwhenfull Bool, --discards Discards, --zero Bool,
--cachemode CacheMode, --cachepolicy String, --cachesettings String,
--minrecoveryrate SizeKB, --maxrecoveryrate SizeKB,
--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 Active VG|LV|Tag|Select ...
OO: --activationmode ActivationMode, --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 SNumber, --stripes_long Number,
--stripesize SizeKB, --regionsize SizeMB
OO_LVCONVERT_POOL: --poolmetadata LV, --poolmetadatasize SizeMB,
--poolmetadataspare Bool, --readahead Readahead, --chunksize SizeKB
OO_LVCONVERT: --alloc Alloc, --background, --force, --noudevsync,
--test, --usepolicies
# FIXME: use different option names for different operations
lvconvert --merge LV_linear_striped_raid_thin_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_striped_raid LV_snapshot
OO: --chunksize SizeKB, --zero Bool, OO_LVCONVERT
DESC: Combine LV with a previously split snapshot LV.
lvconvert --type thin --thinpool LV LV_linear_striped_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_striped_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_striped_raid_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_striped_raid_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_striped_raid_cache
OO: --discards Discards, --zero Bool, OO_LVCONVERT_POOL, OO_LVCONVERT
DESC: Convert LV to type thin-pool.
lvconvert --type cache-pool LV_linear_striped_raid
OO: OO_LVCONVERT_POOL, OO_LVCONVERT
DESC: Convert LV to type cache-pool.
lvconvert --type mirror LV_linear_striped_raid
OO: OO_LVCONVERT_RAID, OO_LVCONVERT
OP: PV ...
DESC: Convert LV to type mirror.
lvconvert --type raid LV_linear_striped_mirror_raid
OO: OO_LVCONVERT_RAID, OO_LVCONVERT
OP: PV ...
DESC: Convert LV to type raid.
DESC: Change LV raid type.
lvconvert --mirrors SNumber LV_raid_mirror
OO: OO_LVCONVERT
OP: PV ...
DESC: Change the number of mirror images in the LV.
lvconvert --mirrors SNumber LV_linear_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_raid1_mirror_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_raid1_cache
OO: OO_LVCONVERT
DESC: Split images from a raid1 LV and use them to create a new LV.
lvconvert --repair LV_raid_mirror_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_mirror
OO: OO_LVCONVERT
DESC: Convert LV to type linear.
lvconvert --mirrorlog MirrorLog LV_mirror
OO: OO_LVCONVERT
DESC: Change the type of log used by LV.
lvconvert --splitcache LV_cachepool_cache_thinpool
OO: OO_LVCONVERT
DESC: Separate and preserve a cache pool from a cache LV.
lvconvert --uncache LV_cache_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_cachepool
DESC: Swap metadata LV in a thin pool or cache pool (temporary command).
# --extents or --size are interchangable
OO_LVCREATE: --addtag Tag, --alloc Alloc, --autobackup Bool, --activate Active,
--contiguous Bool, --ignoreactivationskip, --ignoremonitoring, --major Number,
--metadataprofile String, --minor Number, --monitor Bool, --name String, --nosync,
--noudevsync, --permission Permission, --persistent Bool, --readahead Readahead,
--reportformat String, --setactivationskip Bool, --test, --wipesignatures Bool,
--zero Bool
OO_LVCREATE_CACHE: --cachemode CacheMode, --cachepolicy String, --cachesettings String
OO_LVCREATE_POOL: --poolmetadatasize SizeMB, --poolmetadataspare Bool, --chunksize SizeKB
OO_LVCREATE_THIN: --discards Discards, --errorwhenfull Bool
OO_LVCREATE_RAID: --mirrors SNumber, --stripes Number, --stripesize SizeKB,
--regionsize SizeMB, --minrecoveryrate SizeKB, --maxrecoveryrate SizeKB
lvcreate --type error --size SizeMB VG
OO: OO_LVCREATE
DESC: Create an LV that returns errors when used.
lvcreate --type zero --size SizeMB VG
OO: OO_LVCREATE
DESC: Create an LV that returns zeros when read.
lvcreate --type linear --size SizeMB VG
OO: OO_LVCREATE
OP: PV ...
DESC: Create a linear LV.
lvcreate --type striped --size SizeMB VG
OO: --stripes Number, --stripesize SizeKB, OO_LVCREATE
OP: PV ...
DESC: Create a striped LV.
lvcreate --type mirror --size SizeMB VG
OO: --mirrors SNumber, --mirrorlog MirrorLog, --corelog, --regionsize SizeMB, OO_LVCREATE
OP: PV ...
DESC: Create a mirror LV.
lvcreate --type raid --size SizeMB VG
OO: OO_LVCREATE_RAID, OO_LVCREATE
OP: PV ...
DESC: Create a raid LV (a specific raid level must be used, for example, raid1).
lvcreate --type snapshot --size SizeMB LV
OO: OO_LVCREATE
OP: PV ...
DESC: Create a COW snapshot from an origin LV.
lvcreate --type snapshot --size SizeMB --virtualsize SizeMB VG
OO: --virtualoriginsize SizeMB, OO_LVCREATE
OP: PV ...
DESC: Create a sparse COW snapshot LV of a virtual origin LV.
lvcreate --type thin-pool --size SizeMB VG
OO: OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
OP: PV ...
DESC: Create a thin pool.
lvcreate --type cache-pool --size SizeMB VG
OO: OO_LVCREATE_POOL, OO_LVCREATE_CACHE, OO_LVCREATE
OP: PV ...
DESC: Create a cache pool.
lvcreate --type thin --virtualsize SizeMB --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 SizeMB --size SizeMB --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 SizeMB --size SizeMB 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 SizeMB --size SizeMB 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 SizeMB 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 SizeMB --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 SizeMB VG
OO: --type linear, OO_LVCREATE
OP: PV ...
DESC: Create a linear LV, --name is usually specified (default --type linear).
lvcreate --stripes Number --size SizeMB VG
OO: --type striped, --stripesize SizeKB, OO_LVCREATE
OP: PV ...
DESC: Create a striped LV (infers --type striped).
lvcreate --mirrors SNumber --size SizeMB VG
OO: --type raid1, --type mirror, --mirrorlog MirrorLog, --corelog, OO_LVCREATE_RAID, OO_LVCREATE
OP: PV ...
DESC: Create a raid1 or mirror LV (infers --type raid1|mirror).
lvcreate --snapshot --size SizeMB 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 SizeMB 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 SizeMB 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 SizeMB --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 SizeMB --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 SizeMB --size SizeMB --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 SizeMB --size SizeMB 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 SizeMB --virtualsize SizeMB VG
OO: --type thin, --type snapshot, --thin, --snapshot,
--virtualoriginsize SizeMB, 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 Units
OP: VG|LV|Tag ...
# --extents or --size are interchangable
lvextend --size SizeMB LV
OO: --alloc Alloc, --autobackup Bool, --force, --mirrors SNumber,
--nofsck, --nosync, --noudevsync, --reportformat String, --resizefs,
--stripes Number, --stripesize SizeKB, --test, --poolmetadatasize SizeMB
OP: PV ...
lvextend LV PV ...
OO: --alloc Alloc, --autobackup Bool, --force, --mirrors SNumber,
--nofsck, --nosync, --noudevsync,
--reportformat String, --resizefs, --stripes Number, --stripesize SizeKB,
--test
lvextend --poolmetadatasize SizeMB LV_thinpool
OO: --alloc Alloc, --autobackup Bool, --force, --mirrors SNumber,
--nofsck, --nosync, --noudevsync,
--reportformat String, --stripes Number, --stripesize SizeKB,
--test
OP: PV ...
lvextend --usepolicies LV_thinpool_snapshot
OO: --alloc Alloc, --autobackup Bool, --force, --mirrors SNumber,
--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 SizeMB 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 SizeMB LV
OO: --alloc Alloc, --autobackup Bool, --force,
--nofsck, --nosync, --noudevsync, --reportformat String, --resizefs,
--stripes Number, --stripesize SizeKB, --test, --poolmetadatasize SizeMB
OP: PV ...
lvresize LV PV ...
OO: --alloc Alloc, --autobackup Bool, --force,
--nofsck, --nosync, --noudevsync,
--reportformat String, --resizefs, --stripes Number, --stripesize SizeKB,
--test
lvresize --poolmetadatasize SizeMB LV_thinpool
OO: --alloc Alloc, --autobackup Bool, --force,
--nofsck, --nosync, --noudevsync,
--reportformat String, --stripes Number, --stripesize SizeKB,
--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 SizeMB, --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 SizeKB, --dataalignmentoffset SizeKB, --bootloaderareasize SizeMB,
--force, --test, --labelsector Number, --metadatatype MetadataType,
--pvmetadatacopies Number, --metadatasize SizeMB, --metadataignore Bool,
--norestorefile, --setphysicalvolumesize SizeMB,
--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 Units
OP: PV|Tag ...
pvmove PV
OO: --abort, --alloc Alloc, --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_long
OO: --ignorelockingfailure, --reportformat String, --background,
--activate Active, --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 MetadataType, --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 Alloc, --uuid,
--clustered Bool, --metadatacopies MetadataCopies, --vgmetadatacopies MetadataCopies,
--physicalextentsize SizeMB, --resizeable Bool, --systemid String, --locktype LockType,
--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 Active
OO: --activationmode ActivationMode, --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 SizeMB,
--metadatatype MetadataType, --pvmetadatacopies Number,
--metadatasize SizeMB, --reportformat String
vgcreate VG_new PV ...
OO: --addtag Tag, --alloc Alloc, --autobackup Bool, --clustered Bool, --maxlogicalvolumes Number,
--maxphysicalvolumes Number, --metadataprofile String, --metadatatype MetadataType,
--physicalextentsize SizeMB, --test, --force, --zero Bool, --labelsector Number,
--metadatasize SizeMB, --pvmetadatacopies Number, --reportformat String, --metadatacopies MetadataCopies,
--vgmetadatacopies MetadataCopies, --dataalignment SizeKB, --dataalignmentoffset SizeKB,
--shared, --systemid String, --locktype LockType, --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 Units
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 MetadataType,
--metadatasize SizeMB, --pvmetadatacopies Number,
--metadataignore Bool, --dataalignment SizeKB, --dataalignmentoffset SizeKB,
--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 Alloc, --clustered Bool,
--maxlogicalvolumes Number, --maxphysicalvolumes Number,
--metadatatype MetadataType, --vgmetadatacopies MetadataCopies
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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,128 @@
#!/bin/bash
# Copyright (C) 2016 Red Hat, Inc. All rights reserved.
#
# 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 General Public License v.2.
#
# You should have received a copy of the GNU 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
SKIP_WITH_LVMLOCKD=1
SKIP_WITH_LVMPOLLD=1
. lib/inittest
aux have_raid 1 3 2 || skip
aux prepare_vg 8
# Delay 1st leg so that rebuilding status characters can be read
for d in "$dev1" "$dev2" "$dev3" "$dev4" "$dev5" "$dev6" "$dev7" "$dev8"
do
aux delay_dev $d 0 3
done
# rhbz 1064592
##############################################
# Create an 8-way striped raid10 with 4 mirror
# groups and rebuild selected PVs.
lvcreate --type raid10 -m 1 -i 4 -l 2 -n $lv1 $vg
aux wait_for_sync $vg $lv1
# Rebuild 1st and 2nd device would rebuild a
# whole mirror group and needs to be rejected.
not lvchange --yes --rebuild "$dev1" --rebuild "$dev2" $vg/$lv1
not aux check_status_chars $vg $lv1 "aAaAAAAA"
aux wait_for_sync $vg $lv1
# Rebuild 1st and 3nd device from different mirror groups is fine.
lvchange --yes --rebuild "$dev1" --rebuild "$dev3" $vg/$lv1
aux check_status_chars $vg $lv1 "aAaAAAAA"
aux wait_for_sync $vg $lv1
# Rebuild devices 1, 3, 6 from different mirror groups is fine.
lvchange --yes --rebuild "$dev1" --rebuild "$dev3" --rebuild "$dev6" $vg/$lv1
aux check_status_chars $vg $lv1 "aAaAAaAA"
aux wait_for_sync $vg $lv1
# Rebuild devices 1, 3, 5 and 6 with 5+6 being
# being a whole mirror group needs to be rejected.
not lvchange --yes --rebuild "$dev1" --rebuild "$dev3" --rebuild "$dev6" --rebuild "$dev5" $vg/$lv1
not aux check_status_chars $vg $lv1 "aAaAaaAA"
aux wait_for_sync $vg $lv1
# Rebuild devices 1, 3, 5 and 7 from different mirror groups is fine.
lvchange --yes --rebuild "$dev1" --rebuild "$dev3" --rebuild "$dev5" --rebuild "$dev7" $vg/$lv1
aux check_status_chars $vg $lv1 "aAaAaAaA"
aux wait_for_sync $vg $lv1
# Rebuild devices 2, 4, 6 and 8 from different mirror groups is fine.
lvchange --yes --rebuild "$dev2" --rebuild "$dev4" --rebuild "$dev6" --rebuild "$dev8" $vg/$lv1
aux check_status_chars $vg $lv1 "AaAaAaAa"
aux wait_for_sync $vg $lv1
##############################################
# Create an 8-legged raid1 and rebuild selected PVs
lvremove --yes $vg/$lv1
lvcreate --yes --type raid1 -m 7 -l 2 -n $lv1 $vg
aux wait_for_sync $vg $lv1
# Rebuilding all raid1 legs needs to be rejected.
not lvchange --yes --rebuild "$dev1" --rebuild "$dev2" --rebuild "$dev3" --rebuild "$dev4" \
--rebuild "$dev5" --rebuild "$dev6" --rebuild "$dev7" --rebuild "$dev8" $vg/$lv1
not aux check_status_chars $vg $lv1 "aaaaaaaa"
aux wait_for_sync $vg $lv1
# Rebuilding all but the raid1 master leg is fine.
lvchange --yes --rebuild "$dev2" --rebuild "$dev3" --rebuild "$dev4" \
--rebuild "$dev5" --rebuild "$dev6" --rebuild "$dev7" --rebuild "$dev8" $vg/$lv1
aux check_status_chars $vg $lv1 "Aaaaaaaa"
aux wait_for_sync $vg $lv1
# Rebuilding the raid1 master leg is fine.
lvchange --yes --rebuild "$dev1" $vg/$lv1
aux check_status_chars $vg $lv1 "aAAAAAAA"
aux wait_for_sync $vg $lv1
# Rebuild legs on devices 2, 4, 6 and 8 is fine.
lvchange --yes --rebuild "$dev2" --rebuild "$dev4" --rebuild "$dev6" --rebuild "$dev8" $vg/$lv1
aux check_status_chars $vg $lv1 "AaAaAaAa"
aux wait_for_sync $vg $lv1
##############################################
# Create an 6-legged raid6 and rebuild selected PVs
lvremove --yes $vg/$lv1
lvcreate --yes --type raid6 -i 4 -l 2 -n $lv1 $vg
aux wait_for_sync $vg $lv1
# Rebuilding all raid6 stripes needs to be rejected.
not lvchange --yes --rebuild "$dev1" --rebuild "$dev2" --rebuild "$dev3" \
--rebuild "$dev4" --rebuild "$dev5" --rebuild "$dev6" $vg/$lv1
not aux check_status_chars $vg $lv1 "aaaaaa"
aux wait_for_sync $vg $lv1
# Rebuilding more than 2 raid6 stripes needs to be rejected.
not lvchange --yes --rebuild "$dev2" --rebuild "$dev4" --rebuild "$dev6" $vg/$lv1
not aux check_status_chars $vg $lv1 "AaAaAa"
aux wait_for_sync $vg $lv1
# Rebuilding any 1 raid6 stripe is fine.
lvchange --yes --rebuild "$dev2" $vg/$lv1
aux check_status_chars $vg $lv1 "AaAAAA"
aux wait_for_sync $vg $lv1
lvchange --yes --rebuild "$dev5" $vg/$lv1
aux check_status_chars $vg $lv1 "AAAAaA"
aux wait_for_sync $vg $lv1
# Rebuilding any 2 raid6 stripes is fine.
lvchange --yes --rebuild "$dev2" --rebuild "$dev4" $vg/$lv1
aux check_status_chars $vg $lv1 "AaAaAA"
aux wait_for_sync $vg $lv1
lvchange --yes --rebuild "$dev1" --rebuild "$dev5" $vg/$lv1
aux check_status_chars $vg $lv1 "aAAAaA"
aux wait_for_sync $vg $lv1
vgremove -ff $vg

View File

@@ -17,214 +17,215 @@
* Put all long args that don't have a corresponding short option first.
*/
/* *INDENT-OFF* */
arg(abort_ARG, '\0', "abort", 0, 0, 0)
arg(activationmode_ARG, '\0', "activationmode", activationmode_VAL, 0, 0)
arg(addtag_ARG, '\0', "addtag", tag_VAL, ARG_GROUPABLE, 0)
arg(aligned_ARG, '\0', "aligned", 0, 0, 0)
arg(alloc_ARG, '\0', "alloc", alloc_VAL, 0, 0)
arg(atomic_ARG, '\0', "atomic", 0, 0, 0)
arg(atversion_ARG, '\0', "atversion", string_VAL, 0, 0)
arg(binary_ARG, '\0', "binary", 0, 0, 0)
arg(bootloaderareasize_ARG, '\0', "bootloaderareasize", sizemb_VAL, 0, 0)
arg(cache_long_ARG, '\0', "cache", 0, 0, 0)
arg(cachemode_ARG, '\0', "cachemode", cachemode_VAL, 0, 0)
arg(cachepool_ARG, '\0', "cachepool", lv_VAL, 0, 0)
arg(commandprofile_ARG, '\0', "commandprofile", string_VAL, 0, 0)
arg(config_ARG, '\0', "config", string_VAL, 0, 0)
arg(configreport_ARG, '\0', "configreport", string_VAL, ARG_GROUPABLE, 1)
arg(configtype_ARG, '\0', "typeconfig", string_VAL, 0, 0)
arg(corelog_ARG, '\0', "corelog", 0, 0, 0)
arg(dataalignment_ARG, '\0', "dataalignment", sizekb_VAL, 0, 0)
arg(dataalignmentoffset_ARG, '\0', "dataalignmentoffset", sizekb_VAL, 0, 0)
arg(deltag_ARG, '\0', "deltag", tag_VAL, ARG_GROUPABLE, 0)
arg(detachprofile_ARG, '\0', "detachprofile", 0, 0, 0)
arg(discards_ARG, '\0', "discards", discards_VAL, 0, 0)
arg(driverloaded_ARG, '\0', "driverloaded", bool_VAL, 0, 0)
arg(errorwhenfull_ARG, '\0', "errorwhenfull", bool_VAL, 0, 0)
arg(force_long_ARG, '\0', "force", 0, ARG_COUNTABLE, 0)
arg(foreign_ARG, '\0', "foreign", 0, 0, 0)
arg(handlemissingpvs_ARG, '\0', "handlemissingpvs", 0, 0, 0)
arg(ignoreadvanced_ARG, '\0', "ignoreadvanced", 0, 0, 0)
arg(ignorelocal_ARG, '\0', "ignorelocal", 0, 0, 0)
arg(ignorelockingfailure_ARG, '\0', "ignorelockingfailure", 0, 0, 0)
arg(ignoremonitoring_ARG, '\0', "ignoremonitoring", 0, 0, 0)
arg(ignoreskippedcluster_ARG, '\0', "ignoreskippedcluster", 0, 0, 0)
arg(ignoreunsupported_ARG, '\0', "ignoreunsupported", 0, 0, 0)
arg(labelsector_ARG, '\0', "labelsector", number_VAL, 0, 0)
arg(lockopt_ARG, '\0', "lockopt", string_VAL, 0, 0)
arg(lockstart_ARG, '\0', "lockstart", 0, 0, 0)
arg(lockstop_ARG, '\0', "lockstop", 0, 0, 0)
arg(locktype_ARG, '\0', "locktype", locktype_VAL, 0, 0)
arg(logonly_ARG, '\0', "logonly", 0, 0, 0)
arg(maxrecoveryrate_ARG, '\0', "maxrecoveryrate", sizekb_VAL, 0, 0)
arg(merge_ARG, '\0', "merge", 0, 0, 0)
arg(mergedconfig_ARG, '\0', "mergedconfig", 0, 0, 0)
arg(metadatacopies_ARG, '\0', "metadatacopies", metadatacopies_VAL, 0, 0)
arg(metadataignore_ARG, '\0', "metadataignore", bool_VAL, 0, 0)
arg(metadataprofile_ARG, '\0', "metadataprofile", string_VAL, 0, 0)
arg(metadatasize_ARG, '\0', "metadatasize", sizemb_VAL, 0, 0)
arg(minor_ARG, '\0', "minor", number_VAL, ARG_GROUPABLE, 0)
arg(minrecoveryrate_ARG, '\0', "minrecoveryrate", sizekb_VAL, 0, 0)
arg(mirrorlog_ARG, '\0', "mirrorlog", mirrorlog_VAL, 0, 0)
arg(mirrorsonly_ARG, '\0', "mirrorsonly", 0, 0, 0)
arg(mknodes_ARG, '\0', "mknodes", 0, 0, 0)
arg(monitor_ARG, '\0', "monitor", bool_VAL, 0, 0)
arg(nameprefixes_ARG, '\0', "nameprefixes", 0, 0, 0)
arg(noheadings_ARG, '\0', "noheadings", 0, 0, 0)
arg(nohistory_ARG, '\0', "nohistory", 0, 0, 0)
arg(nolocking_ARG, '\0', "nolocking", 0, 0, 0)
arg(norestorefile_ARG, '\0', "norestorefile", 0, 0, 0)
arg(nosuffix_ARG, '\0', "nosuffix", 0, 0, 0)
arg(nosync_ARG, '\0', "nosync", 0, 0, 0)
arg(notifydbus_ARG, '\0', "notifydbus", 0, 0, 0)
arg(noudevsync_ARG, '\0', "noudevsync", 0, 0, 0)
arg(originname_ARG, '\0', "originname", lv_VAL, 0, 0)
arg(physicalvolumesize_ARG, '\0', "setphysicalvolumesize", sizemb_VAL, 0, 0)
arg(poll_ARG, '\0', "poll", bool_VAL, 0, 0)
arg(polloperation_ARG, '\0', "polloperation", string_VAL, 0, 0)
arg(pooldatasize_ARG, '\0', "pooldatasize", sizemb_VAL, 0, 0)
arg(poolmetadata_ARG, '\0', "poolmetadata", lv_VAL, 0, 0)
arg(poolmetadatasize_ARG, '\0', "poolmetadatasize", sizemb_VAL, 0, 0)
arg(poolmetadataspare_ARG, '\0', "poolmetadataspare", bool_VAL, 0, 0)
arg(profile_ARG, '\0', "profile", string_VAL, 0, 0)
arg(pvmetadatacopies_ARG, '\0', "pvmetadatacopies", number_VAL, 0, 0)
arg(raidrebuild_ARG, '\0', "raidrebuild", string_VAL, ARG_GROUPABLE, 0)
arg(raidmaxrecoveryrate_ARG, '\0', "raidmaxrecoveryrate", sizekb_VAL, 0, 0)
arg(raidminrecoveryrate_ARG, '\0', "raidminrecoveryrate", sizekb_VAL, 0, 0)
arg(raidsyncaction_ARG, '\0', "raidsyncaction", string_VAL, 0, 0)
arg(raidwritebehind_ARG, '\0', "raidwritebehind", number_VAL, 0, 0)
arg(raidwritemostly_ARG, '\0', "raidwritemostly", string_VAL, ARG_GROUPABLE, 0)
arg(readonly_ARG, '\0', "readonly", 0, 0, 0)
arg(refresh_ARG, '\0', "refresh", 0, 0, 0)
arg(removemissing_ARG, '\0', "removemissing", 0, 0, 0)
arg(rebuild_ARG, '\0', "rebuild", pv_VAL, ARG_GROUPABLE, 0)
arg(repair_ARG, '\0', "repair", 0, 0, 0)
arg(replace_ARG, '\0', "replace", pv_VAL, ARG_GROUPABLE, 0)
arg(reportformat_ARG, '\0', "reportformat", string_VAL, 0, 0)
arg(restorefile_ARG, '\0', "restorefile", string_VAL, 0, 0)
arg(restoremissing_ARG, '\0', "restoremissing", 0, 0, 0)
arg(resync_ARG, '\0', "resync", 0, 0, 0)
arg(rows_ARG, '\0', "rows", 0, 0, 0)
arg(segments_ARG, '\0', "segments", 0, 0, 0)
arg(separator_ARG, '\0', "separator", string_VAL, 0, 0)
arg(shared_ARG, '\0', "shared", 0, 0, 0)
arg(sinceversion_ARG, '\0', "sinceversion", string_VAL, 0, 0)
arg(split_ARG, '\0', "split", 0, 0, 0)
arg(splitcache_ARG, '\0', "splitcache", 0, 0, 0)
arg(splitmirrors_ARG, '\0', "splitmirrors", number_VAL, 0, 0)
arg(splitsnapshot_ARG, '\0', "splitsnapshot", 0, 0, 0)
arg(showdeprecated_ARG, '\0', "showdeprecated", 0, 0, 0)
arg(showunsupported_ARG, '\0', "showunsupported", 0, 0, 0)
arg(stripes_long_ARG, '\0', "stripes", number_VAL, 0, 0)
arg(syncaction_ARG, '\0', "syncaction", string_VAL, 0, 0) /* FIXME Use custom VAL */
arg(sysinit_ARG, '\0', "sysinit", 0, 0, 0)
arg(systemid_ARG, '\0', "systemid", string_VAL, 0, 0)
arg(thinpool_ARG, '\0', "thinpool", lv_VAL, 0, 0)
arg(trackchanges_ARG, '\0', "trackchanges", 0, 0, 0)
arg(trustcache_ARG, '\0', "trustcache", 0, 0, 0)
arg(type_ARG, '\0', "type", segtype_VAL, 0, 0)
arg(unbuffered_ARG, '\0', "unbuffered", 0, 0, 0)
arg(uncache_ARG, '\0', "uncache", 0, 0, 0)
arg(cachepolicy_ARG, '\0', "cachepolicy", string_VAL, 0, 0)
arg(cachesettings_ARG, '\0', "cachesettings", string_VAL, ARG_GROUPABLE, 0)
arg(unconfigured_ARG, '\0', "unconfigured", 0, 0, 0)
arg(units_ARG, '\0', "units", units_VAL, 0, 0)
arg(unquoted_ARG, '\0', "unquoted", 0, 0, 0)
arg(usepolicies_ARG, '\0', "usepolicies", 0, 0, 0)
arg(validate_ARG, '\0', "validate", 0, 0, 0)
arg(version_ARG, '\0', "version", 0, 0, 0)
arg(vgmetadatacopies_ARG, '\0', "vgmetadatacopies", metadatacopies_VAL, 0, 0)
arg(virtualoriginsize_ARG, '\0', "virtualoriginsize", sizemb_VAL, 0, 0)
arg(withsummary_ARG, '\0', "withsummary", 0, 0, 0)
arg(withcomments_ARG, '\0', "withcomments", 0, 0, 0)
arg(withspaces_ARG, '\0', "withspaces", 0, 0, 0)
arg(withversions_ARG, '\0', "withversions", 0, 0, 0)
arg(writebehind_ARG, '\0', "writebehind", number_VAL, 0, 0)
arg(writemostly_ARG, '\0', "writemostly", string_VAL, ARG_GROUPABLE, 0)
arg(abort_ARG, '\0', "abort", NULL, 0, 0)
arg(activationmode_ARG, '\0', "activationmode", string_arg, 0, 0)
arg(addtag_ARG, '\0', "addtag", tag_arg, ARG_GROUPABLE, 0)
arg(aligned_ARG, '\0', "aligned", NULL, 0, 0)
arg(alloc_ARG, '\0', "alloc", alloc_arg, 0, 0)
arg(atomic_ARG, '\0', "atomic", NULL, 0, 0)
arg(atversion_ARG, '\0', "atversion", string_arg, 0, 0)
arg(binary_ARG, '\0', "binary", NULL, 0, 0)
arg(bootloaderareasize_ARG, '\0', "bootloaderareasize", size_mb_arg, 0, 0)
arg(cache_long_ARG, '\0', "cache", NULL, 0, 0)
arg(cachemode_ARG, '\0', "cachemode", cachemode_arg, 0, 0)
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(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)
arg(deltag_ARG, '\0', "deltag", tag_arg, ARG_GROUPABLE, 0)
arg(detachprofile_ARG, '\0', "detachprofile", NULL, 0, 0)
arg(discards_ARG, '\0', "discards", discards_arg, 0, 0)
arg(driverloaded_ARG, '\0', "driverloaded", yes_no_arg, 0, 0)
arg(errorwhenfull_ARG, '\0', "errorwhenfull", yes_no_arg, 0, 0)
arg(force_long_ARG, '\0', "force", NULL, ARG_COUNTABLE, 0)
arg(foreign_ARG, '\0', "foreign", NULL, 0, 0)
arg(handlemissingpvs_ARG, '\0', "handlemissingpvs", NULL, 0, 0)
arg(ignoreadvanced_ARG, '\0', "ignoreadvanced", NULL, 0, 0)
arg(ignorelocal_ARG, '\0', "ignorelocal", NULL, 0, 0)
arg(ignorelockingfailure_ARG, '\0', "ignorelockingfailure", NULL, 0, 0)
arg(ignoremonitoring_ARG, '\0', "ignoremonitoring", NULL, 0, 0)
arg(ignoreskippedcluster_ARG, '\0', "ignoreskippedcluster", NULL, 0, 0)
arg(ignoreunsupported_ARG, '\0', "ignoreunsupported", NULL, 0, 0)
arg(labelsector_ARG, '\0', "labelsector", int_arg, 0, 0)
arg(lockopt_ARG, '\0', "lockopt", string_arg, 0, 0)
arg(lockstart_ARG, '\0', "lockstart", NULL, 0, 0)
arg(lockstop_ARG, '\0', "lockstop", NULL, 0, 0)
arg(locktype_ARG, '\0', "locktype", locktype_arg, 0, 0)
arg(logonly_ARG, '\0', "logonly", NULL, 0, 0)
arg(maxrecoveryrate_ARG, '\0', "maxrecoveryrate", size_kb_arg, 0, 0)
arg(merge_ARG, '\0', "merge", NULL, 0, 0)
arg(mergedconfig_ARG, '\0', "mergedconfig", NULL, 0, 0)
arg(metadatacopies_ARG, '\0', "metadatacopies", metadatacopies_arg, 0, 0)
arg(metadataignore_ARG, '\0', "metadataignore", yes_no_arg, 0, 0)
arg(metadataprofile_ARG, '\0', "metadataprofile", string_arg, 0, 0)
arg(metadatasize_ARG, '\0', "metadatasize", size_mb_arg, 0, 0)
arg(minor_ARG, '\0', "minor", int_arg, ARG_GROUPABLE, 0)
arg(minrecoveryrate_ARG, '\0', "minrecoveryrate", size_kb_arg, 0, 0)
arg(mirrorlog_ARG, '\0', "mirrorlog", mirrorlog_arg, 0, 0)
arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL, 0, 0)
arg(mknodes_ARG, '\0', "mknodes", NULL, 0, 0)
arg(monitor_ARG, '\0', "monitor", yes_no_arg, 0, 0)
arg(nameprefixes_ARG, '\0', "nameprefixes", NULL, 0, 0)
arg(noheadings_ARG, '\0', "noheadings", NULL, 0, 0)
arg(nohistory_ARG, '\0', "nohistory", NULL, 0, 0)
arg(nolocking_ARG, '\0', "nolocking", NULL, 0, 0)
arg(norestorefile_ARG, '\0', "norestorefile", NULL, 0, 0)
arg(nosuffix_ARG, '\0', "nosuffix", NULL, 0, 0)
arg(nosync_ARG, '\0', "nosync", NULL, 0, 0)
arg(notifydbus_ARG, '\0', "notifydbus", NULL, 0, 0)
arg(noudevsync_ARG, '\0', "noudevsync", NULL, 0, 0)
arg(originname_ARG, '\0', "originname", string_arg, 0, 0)
arg(physicalvolumesize_ARG, '\0', "setphysicalvolumesize", size_mb_arg, 0, 0)
arg(poll_ARG, '\0', "poll", yes_no_arg, 0, 0)
arg(polloperation_ARG, '\0', "polloperation", string_arg, 0, 0)
arg(pooldatasize_ARG, '\0', "pooldatasize", size_mb_arg, 0, 0)
arg(poolmetadata_ARG, '\0', "poolmetadata", string_arg, 0, 0)
arg(poolmetadatasize_ARG, '\0', "poolmetadatasize", size_mb_arg, 0, 0)
arg(poolmetadataspare_ARG, '\0', "poolmetadataspare", yes_no_arg, 0, 0)
arg(profile_ARG, '\0', "profile", string_arg, 0, 0)
arg(pvmetadatacopies_ARG, '\0', "pvmetadatacopies", int_arg, 0, 0)
arg(raidrebuild_ARG, '\0', "raidrebuild", string_arg, ARG_GROUPABLE, 0)
arg(raidmaxrecoveryrate_ARG, '\0', "raidmaxrecoveryrate", size_kb_arg, 0, 0)
arg(raidminrecoveryrate_ARG, '\0', "raidminrecoveryrate", size_kb_arg, 0, 0)
arg(raidsyncaction_ARG, '\0', "raidsyncaction", string_arg, 0, 0)
arg(raidwritebehind_ARG, '\0', "raidwritebehind", int_arg, 0, 0)
arg(raidwritemostly_ARG, '\0', "raidwritemostly", string_arg, ARG_GROUPABLE, 0)
arg(readonly_ARG, '\0', "readonly", NULL, 0, 0)
arg(refresh_ARG, '\0', "refresh", NULL, 0, 0)
arg(removemissing_ARG, '\0', "removemissing", NULL, 0, 0)
arg(rebuild_ARG, '\0', "rebuild", string_arg, ARG_GROUPABLE, 0)
arg(repair_ARG, '\0', "repair", NULL, 0, 0)
arg(replace_ARG, '\0', "replace", string_arg, ARG_GROUPABLE, 0)
arg(reportformat_ARG, '\0', "reportformat", string_arg, 0, 0)
arg(restorefile_ARG, '\0', "restorefile", string_arg, 0, 0)
arg(restoremissing_ARG, '\0', "restoremissing", NULL, 0, 0)
arg(resync_ARG, '\0', "resync", NULL, 0, 0)
arg(rows_ARG, '\0', "rows", NULL, 0, 0)
arg(segments_ARG, '\0', "segments", NULL, 0, 0)
arg(separator_ARG, '\0', "separator", string_arg, 0, 0)
arg(shared_ARG, '\0', "shared", NULL, 0, 0)
arg(sinceversion_ARG, '\0', "sinceversion", string_arg, 0, 0)
arg(split_ARG, '\0', "split", NULL, 0, 0)
arg(splitcache_ARG, '\0', "splitcache", NULL, 0, 0)
arg(splitmirrors_ARG, '\0', "splitmirrors", int_arg, 0, 0)
arg(splitsnapshot_ARG, '\0', "splitsnapshot", NULL, 0, 0)
arg(showdeprecated_ARG, '\0', "showdeprecated", NULL, 0, 0)
arg(showunsupported_ARG, '\0', "showunsupported", NULL, 0, 0)
arg(stripes_long_ARG, '\0', "stripes", int_arg, 0, 0)
arg(syncaction_ARG, '\0', "syncaction", string_arg, 0, 0) /* FIXME Use custom validation fn */
arg(sysinit_ARG, '\0', "sysinit", NULL, 0, 0)
arg(systemid_ARG, '\0', "systemid", string_arg, 0, 0)
arg(thinpool_ARG, '\0', "thinpool", string_arg, 0, 0)
arg(trackchanges_ARG, '\0', "trackchanges", NULL, 0, 0)
arg(trustcache_ARG, '\0', "trustcache", NULL, 0, 0)
arg(type_ARG, '\0', "type", segtype_arg, 0, 0)
arg(unbuffered_ARG, '\0', "unbuffered", NULL, 0, 0)
arg(uncache_ARG, '\0', "uncache", NULL, 0, 0)
arg(cachepolicy_ARG, '\0', "cachepolicy", string_arg, 0, 0)
arg(cachesettings_ARG, '\0', "cachesettings", string_arg, ARG_GROUPABLE, 0)
arg(unconfigured_ARG, '\0', "unconfigured", NULL, 0, 0)
arg(units_ARG, '\0', "units", string_arg, 0, 0)
arg(unquoted_ARG, '\0', "unquoted", NULL, 0, 0)
arg(usepolicies_ARG, '\0', "usepolicies", NULL, 0, 0)
arg(validate_ARG, '\0', "validate", NULL, 0, 0)
arg(version_ARG, '\0', "version", NULL, 0, 0)
arg(vgmetadatacopies_ARG, '\0', "vgmetadatacopies", metadatacopies_arg, 0, 0)
arg(virtualoriginsize_ARG, '\0', "virtualoriginsize", size_mb_arg, 0, 0)
arg(withsummary_ARG, '\0', "withsummary", NULL, 0, 0)
arg(withcomments_ARG, '\0', "withcomments", NULL, 0, 0)
arg(withspaces_ARG, '\0', "withspaces", NULL, 0, 0)
arg(withversions_ARG, '\0', "withversions", NULL, 0, 0)
arg(writebehind_ARG, '\0', "writebehind", int_arg, 0, 0)
arg(writemostly_ARG, '\0', "writemostly", string_arg, ARG_GROUPABLE, 0)
/* Allow some variations */
arg(allocation_ARG, '\0', "allocation", bool_VAL, 0, 0)
arg(available_ARG, '\0', "available", activation_VAL, 0, 0)
arg(resizable_ARG, '\0', "resizable", bool_VAL, 0, 0)
arg(allocation_ARG, '\0', "allocation", yes_no_arg, 0, 0)
arg(available_ARG, '\0', "available", activation_arg, 0, 0)
arg(resizable_ARG, '\0', "resizable", yes_no_arg, 0, 0)
/*
* ... and now the short args.
*/
arg(activate_ARG, 'a', "activate", activation_VAL, 0, 0)
arg(all_ARG, 'a', "all", 0, 0, 0)
arg(autobackup_ARG, 'A', "autobackup", bool_VAL, 0, 0)
arg(activevolumegroups_ARG, 'A', "activevolumegroups", 0, 0, 0)
arg(background_ARG, 'b', "background", 0, 0, 0)
arg(backgroundfork_ARG, 'b', "background", 0, 0, 0)
arg(basevgname_ARG, 'n', "basevgname", string_VAL, 0, 0)
arg(blockdevice_ARG, 'b', "blockdevice", 0, 0, 0)
arg(chunksize_ARG, 'c', "chunksize", sizekb_VAL, 0, 0)
arg(clustered_ARG, 'c', "clustered", bool_VAL, 0, 0)
arg(colon_ARG, 'c', "colon", 0, 0, 0)
arg(columns_ARG, 'C', "columns", 0, 0, 0)
arg(contiguous_ARG, 'C', "contiguous", bool_VAL, 0, 0)
arg(debug_ARG, 'd', "debug", 0, ARG_COUNTABLE, 0)
arg(exported_ARG, 'e', "exported", 0, 0, 0)
arg(physicalextent_ARG, 'E', "physicalextent", 0, 0, 0)
arg(file_ARG, 'f', "file", string_VAL, 0, 0)
arg(force_ARG, 'f', "force", 0, ARG_COUNTABLE, 0)
arg(full_ARG, 'f', "full", 0, 0, 0)
arg(help_ARG, 'h', "help", 0, ARG_COUNTABLE, 0)
arg(cache_ARG, 'H', "cache", 0, 0, 0)
arg(history_ARG, 'H', "history", 0, 0, 0)
arg(help2_ARG, '?', "", 0, 0, 0)
arg(import_ARG, 'i', "import", 0, 0, 0)
arg(interval_ARG, 'i', "interval", number_VAL, 0, 0)
arg(iop_version_ARG, 'i', "iop_version", 0, 0, 0)
arg(stripes_ARG, 'i', "stripes", number_VAL, 0, 0)
arg(stripesize_ARG, 'I', "stripesize", sizekb_VAL, 0, 0)
arg(logicalvolume_ARG, 'l', "logicalvolume", number_VAL, 0, 0)
arg(maxlogicalvolumes_ARG, 'l', "maxlogicalvolumes", number_VAL, 0, 0)
arg(extents_ARG, 'l', "extents", numsignedper_VAL, 0, 0)
arg(list_ARG, 'l', "list", 0, 0, 0)
arg(lvmpartition_ARG, 'l', "lvmpartition", 0, 0, 0)
arg(size_ARG, 'L', "size", sizemb_VAL, 0, 0)
arg(persistent_ARG, 'M', "persistent", bool_VAL, 0, 0)
arg(major_ARG, 'j', "major", number_VAL, ARG_GROUPABLE, 0)
arg(setactivationskip_ARG, 'k', "setactivationskip", bool_VAL, 0, 0)
arg(ignoreactivationskip_ARG, 'K', "ignoreactivationskip", 0, 0, 0)
arg(maps_ARG, 'm', "maps", 0, 0, 0)
arg(mirrors_ARG, 'm', "mirrors", numsigned_VAL, 0, 0)
arg(metadatatype_ARG, 'M', "metadatatype", metadatatype_VAL, 0, 0)
arg(name_ARG, 'n', "name", string_VAL, 0, 0)
arg(nofsck_ARG, 'n', "nofsck", 0, 0, 0)
arg(novolumegroup_ARG, 'n', "novolumegroup", 0, 0, 0)
arg(oldpath_ARG, 'n', "oldpath", 0, 0, 0)
arg(options_ARG, 'o', "options", string_VAL, ARG_GROUPABLE, 0)
arg(sort_ARG, 'O', "sort", string_VAL, ARG_GROUPABLE, 0)
arg(maxphysicalvolumes_ARG, 'p', "maxphysicalvolumes", number_VAL, 0, 0)
arg(permission_ARG, 'p', "permission", permission_VAL, 0, 0)
arg(partial_ARG, 'P', "partial", 0, 0, 0)
arg(physicalvolume_ARG, 'P', "physicalvolume", 0, 0, 0)
arg(quiet_ARG, 'q', "quiet", 0, ARG_COUNTABLE, 0)
arg(readahead_ARG, 'r', "readahead", readahead_VAL, 0, 0)
arg(resizefs_ARG, 'r', "resizefs", 0, 0, 0)
arg(reset_ARG, 'R', "reset", 0, 0, 0)
arg(regionsize_ARG, 'R', "regionsize", sizemb_VAL, 0, 0)
arg(physicalextentsize_ARG, 's', "physicalextentsize", sizemb_VAL, 0, 0)
arg(snapshot_ARG, 's', "snapshot", 0, 0, 0)
arg(short_ARG, 's', "short", 0, 0, 0)
arg(stdin_ARG, 's', "stdin", 0, 0, 0)
arg(select_ARG, 'S', "select", string_VAL, ARG_GROUPABLE, 0)
arg(test_ARG, 't', "test", 0, 0, 0)
arg(thin_ARG, 'T', "thin", 0, 0, 0)
arg(uuid_ARG, 'u', "uuid", 0, 0, 0)
arg(uuidstr_ARG, 'u', "uuid", string_VAL, 0, 0)
arg(uuidlist_ARG, 'U', "uuidlist", 0, 0, 0)
arg(verbose_ARG, 'v', "verbose", 0, ARG_COUNTABLE, 0)
arg(volumegroup_ARG, 'V', "volumegroup", 0, 0, 0)
arg(virtualsize_ARG, 'V', "virtualsize", sizemb_VAL, 0, 0)
arg(wipesignatures_ARG, 'W', "wipesignatures", bool_VAL, 0, 0)
arg(allocatable_ARG, 'x', "allocatable", bool_VAL, 0, 0)
arg(resizeable_ARG, 'x', "resizeable", bool_VAL, 0, 0)
arg(yes_ARG, 'y', "yes", 0, 0, 0)
arg(zero_ARG, 'Z', "zero", bool_VAL, 0, 0)
arg(activate_ARG, 'a', "activate", activation_arg, 0, 0)
arg(all_ARG, 'a', "all", NULL, 0, 0)
arg(autobackup_ARG, 'A', "autobackup", yes_no_arg, 0, 0)
arg(activevolumegroups_ARG, 'A', "activevolumegroups", NULL, 0, 0)
arg(background_ARG, 'b', "background", NULL, 0, 0)
arg(backgroundfork_ARG, 'b', "background", NULL, 0, 0)
arg(basevgname_ARG, 'n', "basevgname", string_arg, 0, 0)
arg(blockdevice_ARG, 'b', "blockdevice", NULL, 0, 0)
arg(chunksize_ARG, 'c', "chunksize", size_kb_arg, 0, 0)
arg(clustered_ARG, 'c', "clustered", yes_no_arg, 0, 0)
arg(colon_ARG, 'c', "colon", NULL, 0, 0)
arg(columns_ARG, 'C', "columns", NULL, 0, 0)
arg(contiguous_ARG, 'C', "contiguous", yes_no_arg, 0, 0)
arg(debug_ARG, 'd', "debug", NULL, ARG_COUNTABLE, 0)
arg(exported_ARG, 'e', "exported", NULL, 0, 0)
arg(physicalextent_ARG, 'E', "physicalextent", NULL, 0, 0)
arg(file_ARG, 'f', "file", string_arg, 0, 0)
arg(force_ARG, 'f', "force", NULL, ARG_COUNTABLE, 0)
arg(full_ARG, 'f', "full", NULL, 0, 0)
arg(help_ARG, 'h', "help", NULL, 0, 0)
arg(cache_ARG, 'H', "cache", NULL, 0, 0)
arg(history_ARG, 'H', "history", NULL, 0, 0)
arg(help2_ARG, '?', "", NULL, 0, 0)
arg(import_ARG, 'i', "import", NULL, 0, 0)
arg(interval_ARG, 'i', "interval", int_arg, 0, 0)
arg(iop_version_ARG, 'i', "iop_version", NULL, 0, 0)
arg(stripes_ARG, 'i', "stripes", int_arg, 0, 0)
arg(stripesize_ARG, 'I', "stripesize", size_kb_arg, 0, 0)
arg(logicalvolume_ARG, 'l', "logicalvolume", int_arg, 0, 0)
arg(maxlogicalvolumes_ARG, 'l', "maxlogicalvolumes", int_arg, 0, 0)
arg(extents_ARG, 'l', "extents", int_arg_with_sign_and_percent, 0, 0)
arg(list_ARG, 'l', "list", NULL, 0, 0)
arg(lvmpartition_ARG, 'l', "lvmpartition", NULL, 0, 0)
arg(logicalextent_ARG, 'L', "logicalextent", int_arg_with_sign, 0, 0)
arg(size_ARG, 'L', "size", size_mb_arg, 0, 0)
arg(persistent_ARG, 'M', "persistent", yes_no_arg, 0, 0)
arg(major_ARG, 'j', "major", int_arg, ARG_GROUPABLE, 0)
arg(setactivationskip_ARG, 'k', "setactivationskip", yes_no_arg, 0, 0)
arg(ignoreactivationskip_ARG, 'K', "ignoreactivationskip", NULL, 0, 0)
arg(maps_ARG, 'm', "maps", NULL, 0, 0)
arg(mirrors_ARG, 'm', "mirrors", int_arg_with_sign, 0, 0)
arg(metadatatype_ARG, 'M', "metadatatype", metadatatype_arg, 0, 0)
arg(name_ARG, 'n', "name", string_arg, 0, 0)
arg(nofsck_ARG, 'n', "nofsck", NULL, 0, 0)
arg(novolumegroup_ARG, 'n', "novolumegroup", NULL, 0, 0)
arg(oldpath_ARG, 'n', "oldpath", NULL, 0, 0)
arg(options_ARG, 'o', "options", string_arg, ARG_GROUPABLE, 0)
arg(sort_ARG, 'O', "sort", string_arg, ARG_GROUPABLE, 0)
arg(maxphysicalvolumes_ARG, 'p', "maxphysicalvolumes", int_arg, 0, 0)
arg(permission_ARG, 'p', "permission", permission_arg, 0, 0)
arg(partial_ARG, 'P', "partial", NULL, 0, 0)
arg(physicalvolume_ARG, 'P', "physicalvolume", NULL, 0, 0)
arg(quiet_ARG, 'q', "quiet", NULL, ARG_COUNTABLE, 0)
arg(readahead_ARG, 'r', "readahead", readahead_arg, 0, 0)
arg(resizefs_ARG, 'r', "resizefs", NULL, 0, 0)
arg(reset_ARG, 'R', "reset", NULL, 0, 0)
arg(regionsize_ARG, 'R', "regionsize", size_mb_arg, 0, 0)
arg(physicalextentsize_ARG, 's', "physicalextentsize", size_mb_arg, 0, 0)
arg(snapshot_ARG, 's', "snapshot", NULL, 0, 0)
arg(short_ARG, 's', "short", NULL, 0, 0)
arg(stdin_ARG, 's', "stdin", NULL, 0, 0)
arg(select_ARG, 'S', "select", string_arg, ARG_GROUPABLE, 0)
arg(test_ARG, 't', "test", NULL, 0, 0)
arg(thin_ARG, 'T', "thin", NULL, 0, 0)
arg(uuid_ARG, 'u', "uuid", NULL, 0, 0)
arg(uuidstr_ARG, 'u', "uuid", string_arg, 0, 0)
arg(uuidlist_ARG, 'U', "uuidlist", NULL, 0, 0)
arg(verbose_ARG, 'v', "verbose", NULL, ARG_COUNTABLE, 0)
arg(volumegroup_ARG, 'V', "volumegroup", NULL, 0, 0)
arg(virtualsize_ARG, 'V', "virtualsize", size_mb_arg, 0, 0)
arg(wipesignatures_ARG, 'W', "wipesignatures", yes_no_arg, 0, 0)
arg(allocatable_ARG, 'x', "allocatable", yes_no_arg, 0, 0)
arg(resizeable_ARG, 'x', "resizeable", yes_no_arg, 0, 0)
arg(yes_ARG, 'y', "yes", NULL, 0, 0)
arg(zero_ARG, 'Z', "zero", yes_no_arg, 0, 0)
/* this should always be last */
arg(ARG_COUNT, '-', "", 0, 0, 0)
arg(ARG_COUNT, '-', "", NULL, 0, 0)
/* *INDENT-ON* */

View File

@@ -1,3 +0,0 @@
/* Do not edit. This file is generated by scripts/create-commands */
/* using command definitions from scripts/command-lines.in */
#define COMMAND_COUNT 144

File diff suppressed because it is too large Load Diff

View File

@@ -1,156 +0,0 @@
/*
* 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.
*/
/* arg_def flags */
#define ARG_DEF_FLAG_NEW 1 << 0
#define ARG_DEF_FLAG_MAY_REPEAT 1 << 1
/* arg_def lv_types */
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,
ARG_DEF_LV_LAST = 1 << 15,
};
static inline int val_bit_is_set(uint64_t val_bits, int val_enum)
{
return (val_bits & (1 << val_enum)) ? 1 : 0;
}
static inline uint64_t val_enum_to_bit(int val_enum)
{
return 1 << val_enum;
}
/* Description a value that follows an option or exists in a position. */
struct arg_def {
uint64_t val_bits; /* bits of x_VAL, can be multiple for pos_arg */
uint64_t num; /* a literal number for conststr_VAL */
const char *str; /* a literal string for constnum_VAL */
uint32_t lv_types; /* ARG_DEF_LV_, for lv_VAL, can be multiple */
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 64 /* required opt args */
#define CMD_OO_ARGS 150 /* 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; /* specific command description from command-lines.h */
const char *usage;
struct command_name *cname;
command_fn fn;
unsigned int flags; /* copied from command_name.flags from commands.h */
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;
};
struct command_name {
const char *name;
const char *desc; /* general command description from commands.h */
unsigned int flags;
/* union of {required,optional}_opt_args for all commands with this name */
int valid_args[ARG_COUNT];
int num_args;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -86,7 +86,8 @@ struct lvconvert_params {
sign_t mirrors_sign;
uint32_t stripes;
uint32_t stripe_size;
uint32_t stripe_size_supplied;
unsigned stripes_supplied;
unsigned stripe_size_supplied;
uint32_t read_ahead;
cache_mode_t cache_mode; /* cache */
const char *policy_name; /* cache */
@@ -1848,6 +1849,11 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
lvseg_name(seg));
return 0;
}
if (seg_is_raid10(seg)) {
log_error("--mirrors/-m cannot be changed with %s.",
lvseg_name(seg));
return 0;
}
}
if (!_lvconvert_validate_thin(lv, lp))
@@ -1962,7 +1968,13 @@ static int _lvconvert_raid(struct logical_volume *lv, struct lvconvert_params *l
return 0;
}
if (!seg_is_striped(seg) && !lv_raid_percent(lv, &sync_percent)) {
if (seg_is_striped(seg)) {
log_error("Cannot repair LV %s of type raid0.",
display_lvname(lv));
return 0;
}
if (!lv_raid_percent(lv, &sync_percent)) {
log_error("Unable to determine sync status of %s.",
display_lvname(lv));
return 0;
@@ -3183,7 +3195,7 @@ static int _lvconvert_pool(struct cmd_context *cmd,
return_0;
if (!get_stripe_params(cmd, get_segtype_from_string(cmd, SEG_TYPE_NAME_STRIPED),
&lp->stripes, &lp->stripe_size))
&lp->stripes, &lp->stripe_size, &lp->stripes_supplied, &lp->stripe_size_supplied))
return_0;
if (!archive(vg))
@@ -4473,10 +4485,8 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
if (_mirror_or_raid_type_requested(cmd, lp->type_str) || _raid0_type_requested(lp->type_str) ||
_striped_type_requested(lp->type_str) || lp->repair || lp->mirrorlog || lp->corelog) {
/* FIXME Handle +/- adjustments too? */
if (!get_stripe_params(cmd, lp->segtype, &lp->stripes, &lp->stripe_size))
if (!get_stripe_params(cmd, lp->segtype, &lp->stripes, &lp->stripe_size, &lp->stripes_supplied, &lp->stripe_size_supplied))
return_0;
/* FIXME Move this into the get function */
lp->stripe_size_supplied = arg_is_set(cmd, stripesize_ARG);
if (_raid0_type_requested(lp->type_str) || _striped_type_requested(lp->type_str))
/* FIXME Shouldn't need to override get_stripe_params which defaults to 1 stripe (i.e. linear)! */

View File

@@ -464,8 +464,13 @@ static int _read_raid_params(struct cmd_context *cmd,
/*
* RAID10 needs at least 4 stripes
*/
log_warn("Adjusting stripes to the minimum of 2 for %s.",
lp->segtype->name);
if (lp->stripes_supplied) {
log_error("Minimum of 2 stripes required for %s.",
lp->segtype->name);
return 0;
}
log_verbose("Using 2 stripes for %s.", lp->segtype->name);
lp->stripes = 2;
}
@@ -480,14 +485,28 @@ static int _read_raid_params(struct cmd_context *cmd,
/*
* RAID1 does not take a stripe arg
*/
log_error("Stripe argument cannot be used with segment type, %s",
log_error("Stripes argument cannot be used with segment type, %s",
lp->segtype->name);
return 0;
}
} else if (lp->stripes < 2)
/* No stripes argument was given */
lp->stripes = seg_is_any_raid6(lp) ? 3 : 2;
} else if (seg_is_any_raid6(lp) && lp->stripes < 3) {
if (lp->stripes_supplied) {
log_error("Minimum of 3 stripes required for %s.", lp->segtype->name);
return 0;
}
log_verbose("Using 3 stripes for %s.", lp->segtype->name);
lp->stripes = 3;
} else if (lp->stripes < 2) {
if (lp->stripes_supplied) {
log_error("Minimum of 2 stripes required for %s.", lp->segtype->name);
return 0;
}
log_verbose("Using 2 stripes for %s.", lp->segtype->name);
lp->stripes = 2;
}
if (seg_is_raid1(lp)) {
if (lp->stripe_size) {
@@ -495,6 +514,8 @@ static int _read_raid_params(struct cmd_context *cmd,
lp->segtype->name);
return 0;
}
} else if (!lp->stripe_size) {
; // lp->stripe_size = find_config_tree_int(cmd, metadata_stripesize_CFG, NULL) * 2;
}
if (arg_is_set(cmd, mirrors_ARG) && segtype_is_raid(lp->segtype) &&
@@ -526,7 +547,6 @@ static int _read_raid_params(struct cmd_context *cmd,
static int _read_mirror_and_raid_params(struct cmd_context *cmd,
struct lvcreate_params *lp)
{
int pagesize = lvm_getpagesize();
unsigned max_images;
if (seg_is_raid(lp)) {
@@ -603,12 +623,20 @@ static int _read_mirror_and_raid_params(struct cmd_context *cmd,
return 0;
}
#if 1
if (lp->region_size && !is_power_of_2(lp->region_size)) {
log_error("Region size (%" PRIu32 ") must be power of 2",
lp->region_size);
return 0;
}
#else
if (lp->region_size % (pagesize >> SECTOR_SHIFT)) {
log_error("Region size (%" PRIu32 ") must be a multiple of "
"machine memory page size (%d)",
lp->region_size, pagesize >> SECTOR_SHIFT);
return 0;
}
#endif
if (seg_is_mirror(lp) && !_read_mirror_params(cmd, lp))
return_0;
@@ -1061,7 +1089,7 @@ static int _lvcreate_params(struct cmd_context *cmd,
if (!_lvcreate_name_params(cmd, &argc, &argv, lp) ||
!_read_size_params(cmd, lp, lcp) ||
!get_stripe_params(cmd, lp->segtype, &lp->stripes, &lp->stripe_size) ||
!get_stripe_params(cmd, lp->segtype, &lp->stripes, &lp->stripe_size, &lp->stripes_supplied, &lp->stripe_size_supplied) ||
(lp->create_pool &&
!get_pool_params(cmd, lp->segtype, &lp->passed_args,
&lp->pool_metadata_size, &lp->pool_metadata_spare,
@@ -1255,17 +1283,10 @@ 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

View File

@@ -45,9 +45,9 @@ static char *_list_cmds(const char *text, int state)
len = strlen(text);
}
while (i < _cmdline->num_command_names)
if (!strncmp(text, _cmdline->command_names[i++].name, len))
return strdup(_cmdline->command_names[i - 1].name);
while (i < _cmdline->num_commands)
if (!strncmp(text, _cmdline->commands[i++].name, len))
return strdup(_cmdline->commands[i - 1].name);
return NULL;
}
@@ -57,7 +57,7 @@ static char *_list_args(const char *text, int state)
{
static int match_no = 0;
static size_t len = 0;
static struct command_name *cname;
static struct command *com;
/* Initialise if this is a new completion attempt */
if (!state) {
@@ -65,40 +65,40 @@ static char *_list_args(const char *text, int state)
int j;
match_no = 0;
cname = NULL;
com = NULL;
len = strlen(text);
/* Find start of first word in line buffer */
while (isspace(*s))
s++;
/* Look for word in list of command names */
for (j = 0; j < _cmdline->num_command_names; j++) {
/* Look for word in list of commands */
for (j = 0; j < _cmdline->num_commands; j++) {
const char *p;
char *q = s;
p = _cmdline->command_names[j].name;
p = _cmdline->commands[j].name;
while (*p == *q) {
p++;
q++;
}
if ((!*p) && *q == ' ') {
cname = _cmdline->command_names + j;
com = _cmdline->commands + j;
break;
}
}
}
if (!cname)
if (!com)
return NULL;
/* Short form arguments */
if (len < 3) {
while (match_no < cname->num_args) {
while (match_no < com->num_args) {
char s[3];
char c;
if (!(c = (_cmdline->arg_props +
cname->valid_args[match_no++])->short_arg))
com->valid_args[match_no++])->short_arg))
continue;
sprintf(s, "-%c", c);
@@ -108,13 +108,13 @@ static char *_list_args(const char *text, int state)
}
/* Long form arguments */
if (match_no < cname->num_args)
match_no = cname->num_args;
if (match_no < com->num_args)
match_no = com->num_args;
while (match_no - cname->num_args < cname->num_args) {
while (match_no - com->num_args < com->num_args) {
const char *l;
l = (_cmdline->arg_props +
cname->valid_args[match_no++ - cname->num_args])->long_arg;
com->valid_args[match_no++ - com->num_args])->long_arg;
if (*(l + 2) && !strncmp(text, l, len))
return strdup(l);
}

View File

@@ -19,11 +19,10 @@
struct cmd_context;
struct cmdline_context {
struct arg_props *arg_props;
struct command *commands;
int num_commands;
struct command_name *command_names;
int num_command_names;
struct arg_props *arg_props;
struct command *commands;
int num_commands;
int commands_size;
};
int lvm2_main(int argc, char **argv);

File diff suppressed because it is too large Load Diff

View File

@@ -1278,16 +1278,31 @@ static int _validate_stripe_params(struct cmd_context *cmd, const struct segment
{
int stripe_size_required = segtype_supports_stripe_size(segtype);
#if 1
if (stripe_size_required) {
if (*stripes == 1 && segtype_is_mirror(segtype)) {
stripe_size_required = 0;
if (*stripe_size) {
log_print_unless_silent("Ignoring stripesize argument with single stripe.");
*stripe_size = 0;
}
}
} else if (*stripe_size) {
log_print_unless_silent("Ignoring stripesize argument for %s devices.", segtype->name);
*stripe_size = 0;
}
#else
if (!stripe_size_required && *stripe_size) {
log_print_unless_silent("Ignoring stripesize argument for %s devices.", segtype->name);
*stripe_size = 0;
} else if (*stripes == 1 && (segtype_is_striped(segtype) || segtype_is_mirror(segtype))) {
} else if (*stripes == 1 && (segtype_is_striped_target(segtype) || segtype_is_mirror(segtype))) {
stripe_size_required = 0;
if (*stripe_size) {
log_print_unless_silent("Ignoring stripesize argument with single stripe.");
*stripe_size = 0;
}
}
#endif
if (stripe_size_required) {
if (!*stripe_size) {
@@ -1318,13 +1333,17 @@ static int _validate_stripe_params(struct cmd_context *cmd, const struct segment
* power of 2, we must divide UINT_MAX by four and add 1 (to round it
* up to the power of 2)
*/
int get_stripe_params(struct cmd_context *cmd, const struct segment_type *segtype, uint32_t *stripes, uint32_t *stripe_size)
int get_stripe_params(struct cmd_context *cmd, const struct segment_type *segtype,
uint32_t *stripes, uint32_t *stripe_size,
unsigned *stripes_supplied, unsigned *stripe_size_supplied)
{
/* stripes_long_ARG takes precedence (for lvconvert) */
/* FIXME Cope with relative +/- changes for lvconvert. */
*stripes = arg_uint_value(cmd, arg_is_set(cmd, stripes_long_ARG) ? stripes_long_ARG : stripes_ARG, 1);
*stripes_supplied = arg_is_set(cmd, stripes_long_ARG) ? : arg_is_set(cmd, stripes_ARG);
*stripe_size = arg_uint_value(cmd, stripesize_ARG, 0);
*stripe_size_supplied = arg_is_set(cmd, stripesize_ARG);
if (*stripe_size) {
if (arg_sign_value(cmd, stripesize_ARG, SIGN_NONE) == SIGN_MINUS) {
log_error("Negative stripesize is invalid.");

View File

@@ -197,7 +197,8 @@ int get_pool_params(struct cmd_context *cmd,
int *zero);
int get_stripe_params(struct cmd_context *cmd, const struct segment_type *segtype,
uint32_t *stripes, uint32_t *stripe_size);
uint32_t *stripes, uint32_t *stripe_size,
unsigned *stripes_supplied, unsigned *stripe_size_supplied);
int get_cache_params(struct cmd_context *cmd,
cache_mode_t *cache_mode,

View File

@@ -50,27 +50,20 @@
#define CMD_LEN 256
#define MAX_ARGS 64
/* define the enums for the values accepted by command line --options */
enum {
#define val(a, b, c, d) a ,
#include "vals.h"
#undef val
};
/* command functions */
typedef int (*command_fn) (struct cmd_context * cmd, int argc, char **argv);
/* define the enums for the command line --options */
#define xx(a, b...) int a(struct cmd_context *cmd, int argc, char **argv);
#include "commands.h"
#undef xx
/* define the enums for the command line switches */
enum {
#define arg(a, b, c, d, e, f) a ,
#include "args.h"
#undef arg
};
/* command functions */
#define xx(a, b...) int a(struct cmd_context *cmd, int argc, char **argv);
#include "commands.h"
#undef xx
#include "command.h"
#define ARG_COUNTABLE 0x00000001 /* E.g. -vvvv */
#define ARG_GROUPABLE 0x00000002 /* E.g. --addtag */
@@ -86,13 +79,13 @@ struct arg_values {
/* void *ptr; // Currently not used. */
};
/* a global table of possible --option's */
/* a global table of possible arguments */
struct arg_props {
int arg_enum; /* foo_ARG from args.h */
const char short_arg;
char _padding[7];
const char *long_arg;
int val_enum; /* foo_VAL from vals.h */
int (*fn) (struct cmd_context *cmd, struct arg_values *av);
uint32_t flags;
uint32_t prio;
};
@@ -103,14 +96,6 @@ struct arg_value_group_list {
uint32_t prio;
};
/* a global table of possible --option values */
struct val_props {
int val_enum; /* foo_VAL from vals.h */
int (*fn) (struct cmd_context *cmd, struct arg_values *av);
const char *name;
const char *usage;
};
#define CACHE_VGMETADATA 0x00000001
#define PERMITTED_READ_ONLY 0x00000002
/* Process all VGs if none specified on the command line. */
@@ -133,6 +118,19 @@ struct val_props {
#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);

View File

@@ -1,135 +0,0 @@
/*
* Define value types which describe values accepted
* by the --option's in args.h, and can also describe
* the values accepted as positional args.
*
* Previously, accepted values were only "described"
* by identifying the parsing function to use.
*
* Some standard val types are used by many options,
* e.g. many options (aa_ARG, bb_ARG, cc_ARG) all
* accept a number_VAL.
*
* Other special val types are used by only one option,
* e.g. only mirrorlog_ARG accepts a mirrorlog_VAL.
* This typically means that there are some specific
* words that are recognized after the option.
*
* Some options currently take a standard val type,
* (esp string_VAL), but they could be given their
* own custom val type. The advantage of using a
* custom val type is the possibility of validating
* the value when parsing it with a custom parsing
* function, and the possibility of displaying the
* actual accepted values in the command usage.
* Without a custom val type, the code must do ad hoc
* validation of the string values, and the usage
* output for the option will only say "String"
* rather than giving the accepted string values.
* Even without a custom parsing function, there is
* reason to define a custom x_VAL enum so that a
* more descriptive usage string can be specified
* as opposed to just "String".
*
* Most of the val types defined here are used after
* --option's, and are referenced in foo_ARG entries
* in args.h. But, some val types are only used to
* represent positional values in command definitions,
* e.g. vg_VAL.
*
* val(a, b, c, d)
*
* a: foo_VAL enums
* b: the function to parse and set the value
* c: the name used to reference this value in command defs
* d: what to display in usage output for this value
*
* command defintions will use --option NAME, where NAME
* is shown in val() field c. NAME will be translated to
* foo_VAL enum in field a, which is used in commands[]
* structs.
*
* option definitions (arg.h) will reference foo_VAL enum
* in field a.
*
* FIXME: for specialized val types, the set of recognized
* words is not defined or stored in a consistent way,
* but is just whatever the parsing function happens to look
* for, so adding a new accepted value for the val type is
* often just making the parsing function recognize a new
* word. This new word should then also be added to the
* usage string for the val type here. It would be nice
* if the accepted values could be defined in a more
* consistent way, perhaps in struct val_props.
*
* The usage text for an option is not always the full
* set of words accepted for an option, but may be a
* subset. i.e. an outdated word that no longer does
* anything may not be shown, but may still be recognized
* and ignored, or an option that shouldn't be used in
* general isn't shown to avoid suggesting it.
* e.g. for --activate we show the most common "y|n|ay"
* without showing the lvmlockd variations "ey|sy" which
* are not applicable in general.
*
* FIXME: are there some specialized or irrelevant
* options included in the usage text below that should
* be removed? Should "lvm1" be removed?
*
* For Number args that take optional units, a full usage
* could be "Number[bBsSkKmMgGtTpPeE]" (with implied |),
* but repeating this full specification produces cluttered
* output, and doesn't indicate which unit is the default.
* "Number[units]" would be cleaner, as would a subset of
* common units, e.g. "Number[kmg...]", but neither helps
* with default. "Number[k|unit]" and "Number[m|unit]" show
* the default, and "unit" indicates that other units
* are possible without listing them all. This also
* suggests using the preferred lower case letters, because
* --size and other option args treat upper/lower letters
* the same, all as 1024 SI base. For this reason, we
* should avoid suggesting the upper case letters.
*/
val(none_VAL, NULL, "None", "") /* unused, for enum value 0 */
val(conststr_VAL, NULL, "ConstString", "") /* used only for command defs */
val(constnum_VAL, NULL, "ConstNumber", "") /* used only for command defs */
val(bool_VAL, yes_no_arg, "Bool", "y|n")
val(number_VAL, int_arg, "Number", NULL)
val(string_VAL, string_arg, "String", NULL)
val(vg_VAL, string_arg, "VG", NULL)
val(lv_VAL, string_arg, "LV", NULL)
val(pv_VAL, string_arg, "PV", NULL)
val(tag_VAL, tag_arg, "Tag", NULL)
val(select_VAL, NULL, "Select", NULL) /* used only for command defs */
val(activationmode_VAL, string_arg, "ActivationMode", "partial|degraded|complete")
val(activation_VAL, activation_arg, "Active", "y|n|ay")
val(cachemode_VAL, cachemode_arg, "CacheMode", "writethrough|writeback")
val(discards_VAL, discards_arg, "Discards", "passdown|nopassdown|ignore")
val(mirrorlog_VAL, mirrorlog_arg, "MirrorLog", "core|disk")
val(sizekb_VAL, size_kb_arg, "SizeKB", "Number[k|unit]")
val(sizemb_VAL, size_mb_arg, "SizeMB", "Number[m|unit]")
val(numsigned_VAL, int_arg_with_sign, "SNumber", "[+|-]Number")
val(numsignedper_VAL, int_arg_with_sign_and_percent, "SNumberP", "[+|-]Number[%{VG|PVS|FREE}]")
val(permission_VAL, permission_arg, "Permission", "rw|r")
val(metadatatype_VAL, metadatatype_arg, "MetadataType", "lvm2|lvm1")
val(units_VAL, string_arg, "Units", "hHbBsSkKmMgGtTpPeE")
val(segtype_VAL, segtype_arg, "SegType", "linear|striped|snapshot|mirror|raid*|thin|cache|thin-pool|cache-pool")
val(alloc_VAL, alloc_arg, "Alloc", "contiguous|cling|cling_by_tags|normal|anywhere|inherit")
val(locktype_VAL, locktype_arg, "LockType", "sanlock|dlm|none")
val(readahead_VAL, readahead_arg, "Readahead", "auto|none|NumberSectors")
val(metadatacopies_VAL, metadatacopies_arg, "MetadataCopies", "all|unmanaged|Number")
/* this should always be last */
val(VAL_COUNT, NULL, NULL, NULL)
/*
* I suspect many of the following are good candidates for a custom VAL enum
* for the benefit of custom parsing, or custom usage, or both:
*
* configreport_ARG, configtype_ARG, polloperation_ARG, raidrebuild_ARG,
* raidsyncaction_ARG, raidwritemostly_ARG, reportformat_ARG, syncaction_ARG,
* cachepolicy_ARG, cachesettings_ARG, writemostly_ARG
*/