1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-09-26 01:44:19 +03:00

Compare commits

..

14 Commits

Author SHA1 Message Date
David Teigland
51dd97da82 lvconvert: remove unused code 2016-12-20 15:17:48 -06:00
David Teigland
f610e60388 lvconvert: use command defs for raid/mirror types
All lvconvert functionality has been moved out of the
previous monolithic lvconvert code, except conversions
related to raid/mirror/striped/linear.  This switches
that remaining code to be based on command defs, and
standard process_each_lv arg processing.  This final
switch results in quite a bit of dead code that is
also removed.
2016-12-20 14:22:55 -06:00
David Teigland
902f14c750 tests: use swapmetadata
and some other pool/cache/thin related changes
2016-12-20 14:22:55 -06:00
David Teigland
e511af33d1 lvconvert: use command defs for mergemirrors
and route the generic --merge to one of the
specific merge functions
2016-12-20 14:22:55 -06:00
David Teigland
5976c34c3b toollib: find VG name in option values when needed 2016-12-20 14:22:55 -06:00
David Teigland
c86166dac7 lvconvert: use command defs for thin/cache/pool creation
Everything related to thin and cache.
2016-12-20 14:22:51 -06:00
David Teigland
69530a6827 lvconvert: add startpoll command using command def
This is a new explicit version of 'lvconvert LV'
which has been an obscure way of triggering polling
to be restarted on an LV that was previously converted.
2016-12-20 14:14:52 -06:00
David Teigland
b5ba546e3c lvconvert: snapshot: use command definitions
Lift all the snapshot utilities (merge, split, combine)
out of the monolithic lvconvert implementation, using
the command definitions.  The old code associated with
these commands is now unused and will be removed separately.
2016-12-20 14:14:47 -06:00
David Teigland
75732b65a4 lvconvert: remove unused calls for repair and replace
repair and replace are no longer called from the
monolithic lvconvert code, so remove the unused code.
2016-12-19 15:18:28 -06:00
David Teigland
a4d1ceb6d4 lvconvert: repair and replace: use command definitions
This lifts the lvconvert --repair and --replace commands
out of the monolithic lvconvert implementation.  The
previous calls into repair/replace can no longer be
reached and will be removed in a separate commit.
2016-12-19 15:18:21 -06:00
David Teigland
b5e373866d lvchange: make use of command definitions
Reorganize the lvchange code to take advantage of
the command definition, and remove the validation
that is done by the command definintion rules.
2016-12-19 15:18:14 -06:00
David Teigland
d81e37acf5 process_each_lv: add check_single_lv function
The new check_single_lv() function is called prior to the
existing process_single_lv().  If the check function returns 0,
the LV will not be processed.

The check_single_lv function is meant to be a standard method
to validate the combination of specific command + specific LV,
and decide if the combination is allowed.  The check_single
function can be used by anything that calls process_each_lv.

As commands are migrated to take advantage of command
definitions, each command definition gets its own entry
point which calls process_each for itself, passing a
pair of check_single/process_single functions which can
be specific to the narrowly defined command def.
2016-12-19 15:18:08 -06:00
David Teigland
516068b8cc commands: new method for defining commands
. Define a prototype for every lvm command.
. Match every user command with one definition.
. Generate help text and man pages from them.

The new file command-lines.in defines a prototype for every
unique lvm command.  A unique lvm command is a unique
combination of: command name + required option args +
required positional args.  Each of these prototypes also
includes the optional option args and optional positional
args that the command will accept, a description, and a
unique string ID for the definition.  Any valid command
will match one of the prototypes.

Here's an example of the lvresize command definitions from
command-lines.in, there are three unique lvresize commands:

lvresize --size SizeMB LV
OO: --alloc Alloc, --autobackup Bool, --force,
--nofsck, --nosync, --noudevsync, --reportformat String, --resizefs,
--stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB
OP: PV ...
ID: lvresize_by_size
DESC: Resize an LV by a specified size.

lvresize LV PV ...
OO: --alloc Alloc, --autobackup Bool, --force,
--nofsck, --nosync, --noudevsync,
--reportformat String, --resizefs, --stripes Number, --stripesize SizeKB
ID: lvresize_by_pv
DESC: Resize an LV by specified PV extents.
FLAGS: SECONDARY_SYNTAX

lvresize --poolmetadatasize SizeMB LV_thinpool
OO: --alloc Alloc, --autobackup Bool, --force,
--nofsck, --nosync, --noudevsync,
--reportformat String, --stripes Number, --stripesize SizeKB
OP: PV ...
ID: lvresize_pool_metadata_by_size
DESC: Resize a pool metadata SubLV by a specified size.

The three commands have separate definitions because they have
different required parameters.  Required parameters are specified
on the first line of the definition.  Optional options are
listed after OO, and optional positional args are listed after OP.

This data is used to generate corresponding command definition
structures for lvm in command-lines.h.  usage/help output is also
auto generated, so it is always in sync with the definitions.

Example of the corresponding generated structure in
command-lines.h for the first lvresize prototype
(these structures are never edited directly):

commands[83].name = "lvresize";
commands[83].command_line_id = "lvresize_by_size";
commands[83].command_line_enum = lvresize_by_size_CMD;
commands[83].fn = lvresize;
commands[83].ro_count = 1;
commands[83].rp_count = 1;
commands[83].oo_count = 22;
commands[83].op_count = 1;
commands[83].cmd_flags = 0;
commands[83].desc = "DESC: Resize an LV by a specified size.";
commands[83].usage = "lvresize --size Number[m|unit] LV"
" [ --resizefs, --poolmetadatasize Number[m|unit], COMMON_OPTIONS ]"
" [ PV ... ]";
commands[83].usage_common =
" [ --alloc contiguous|cling|cling_by_tags|normal|anywhere|inherit, --nosync, --reportformat String, --autobackup y|n, --stripes Number, --stripesize Number[k|unit], --nofsck, --commandprofile String, --config String, --debug, --driverloaded y|n, --help, --profile String, --quiet, --verbose, --version, --yes, --test, --force, --noudevsync ]";
commands[83].required_opt_args[0].opt = size_ARG;
commands[83].required_opt_args[0].def.val_bits = val_enum_to_bit(sizemb_VAL);
commands[83].required_pos_args[0].pos = 1;
commands[83].required_pos_args[0].def.val_bits = val_enum_to_bit(lv_VAL);
commands[83].optional_opt_args[0].opt = commandprofile_ARG;
commands[83].optional_opt_args[0].def.val_bits = val_enum_to_bit(string_VAL);
commands[83].optional_opt_args[1].opt = config_ARG;
commands[83].optional_opt_args[1].def.val_bits = val_enum_to_bit(string_VAL);
commands[83].optional_opt_args[2].opt = debug_ARG;
commands[83].optional_opt_args[3].opt = driverloaded_ARG;
commands[83].optional_opt_args[3].def.val_bits = val_enum_to_bit(bool_VAL);
commands[83].optional_opt_args[4].opt = help_ARG;
commands[83].optional_opt_args[5].opt = profile_ARG;
commands[83].optional_opt_args[5].def.val_bits = val_enum_to_bit(string_VAL);
commands[83].optional_opt_args[6].opt = quiet_ARG;
commands[83].optional_opt_args[7].opt = verbose_ARG;
commands[83].optional_opt_args[8].opt = version_ARG;
commands[83].optional_opt_args[9].opt = yes_ARG;
commands[83].optional_opt_args[10].opt = test_ARG;
commands[83].optional_opt_args[11].opt = alloc_ARG;
commands[83].optional_opt_args[11].def.val_bits = val_enum_to_bit(alloc_VAL);
commands[83].optional_opt_args[12].opt = autobackup_ARG;
commands[83].optional_opt_args[12].def.val_bits = val_enum_to_bit(bool_VAL);
commands[83].optional_opt_args[13].opt = force_ARG;
commands[83].optional_opt_args[14].opt = nofsck_ARG;
commands[83].optional_opt_args[15].opt = nosync_ARG;
commands[83].optional_opt_args[16].opt = noudevsync_ARG;
commands[83].optional_opt_args[17].opt = reportformat_ARG;
commands[83].optional_opt_args[17].def.val_bits = val_enum_to_bit(string_VAL);
commands[83].optional_opt_args[18].opt = resizefs_ARG;
commands[83].optional_opt_args[19].opt = stripes_ARG;
commands[83].optional_opt_args[19].def.val_bits = val_enum_to_bit(number_VAL);
commands[83].optional_opt_args[20].opt = stripesize_ARG;
commands[83].optional_opt_args[20].def.val_bits = val_enum_to_bit(sizekb_VAL);
commands[83].optional_opt_args[21].opt = poolmetadatasize_ARG;
commands[83].optional_opt_args[21].def.val_bits = val_enum_to_bit(sizemb_VAL);
commands[83].optional_pos_args[0].pos = 2;
commands[83].optional_pos_args[0].def.val_bits = val_enum_to_bit(pv_VAL);
commands[83].optional_pos_args[0].def.flags = ARG_DEF_FLAG_MAY_REPEAT;

Every user-entered command is compared against the set of
command structures, and matched with one.  An error is
reported if an entered command does not have the required
parameters for any definition.  The closest match is printed
as a suggestion, and running lvresize --help will display
the usage for each possible lvresize command.

The prototype syntax used for help/man output includes
required --option and positional args on the first line,
and optional --option and positional args enclosed in [ ]
on subsequent lines.

  command_name <required_opt_args> <required_pos_args>
          [ <optional_opt_args> ]
          [ <optional_pos_args> ]

$ lvresize --help
  lvresize - Resize a logical volume

  Resize an LV by a specified size.
  lvresize --size Number[m|unit] LV
        [ --resizefs,
          --poolmetadatasize Number[m|unit],
          COMMON_OPTIONS ]
        [ PV ... ]

  Resize a pool metadata SubLV by a specified size.
  lvresize --poolmetadatasize Number[m|unit] LV_thinpool
        [ COMMON_OPTIONS ]
        [ PV ... ]

  Common options:
        [ --alloc contiguous|cling|cling_by_tags|normal|anywhere|inherit,
          --nosync,
          --reportformat String,
          --autobackup y|n,
          --stripes Number,
          --stripesize Number[k|unit],
          --nofsck,
          --commandprofile String,
          --config String,
          --debug,
          --driverloaded y|n,
          --help,
          --profile String,
          --quiet,
          --verbose,
          --version,
          --yes,
          --test,
          --force,
          --noudevsync ]

  (Use --help --help for usage notes.)

$ lvresize --poolmetadatasize 4
  Failed to find a matching command definition.
  Closest command usage is:
  lvresize --poolmetadatasize Number[m|unit] LV_thinpool

Command definitions that are not to be advertised/suggested
have the flag SECONDARY_SYNTAX.  These commands will not be
printed in the normal help output.

Man page prototypes are also generated from the same original
command definitions, and are always in sync with the code
and help text.

Very early in command execution, a matching command definition
is found.  lvm then knows the operation being done, and that
the provided args conform to the definition.  This will allow
lots of ad hoc checking/validation to be removed throughout
the code.

Each command definition can also be routed to a specific
function to implement it.  The function is associated with
an enum value for the command definition (generated from
the ID string.)  These per-command-definition implementation
functions have not yet been created, so all commands
currently fall back to the existing per-command-name
implementation functions.

Using per-command-definition functions will allow lots of
code to be removed which tries to figure out what the
command is meant to do.  This is currently based on ad hoc
and complicated option analysis.  When using the new
functions, what the command is doing is already known
from the associated command definition.

So, this first phase validates every user-entered command
against the set of command prototypes, then calls the existing
implementation.  The second phase can associate an implementation
function with each definition, and take further advantage of the
known operation to avoid the complicated option analysis.
2016-12-19 15:17:56 -06:00
David Teigland
95e00d2043 lvmlockd: test mode doesn't work
The --test option is not yet compatible with shared VGs
because changes are made in lvmlockd that cannot be
reversed or faked.
2016-12-19 15:17:42 -06:00
38 changed files with 747 additions and 1607 deletions

View File

@@ -1,11 +1,5 @@
Version 2.02.169 -
=====================================
Add missing udev sync when flushing dirty cache content.
vgchange -p accepts only uint32 numbers.
Report thin LV date for merged LV when the merge is in progress.
Detect if snapshot merge really started before polling for progress.
Checking LV for merging origin requires also it has merged snapshot.
Extend validation of metadata processing.
Enable usage of cached volumes as snapshot origin LV.
Fix displayed lv name when splitting snapshot (2.02.146).
Warn about command not making metadata backup just once per command.

View File

@@ -1,6 +1,5 @@
Version 1.02.138 -
=====================================
Thin dmeventd plugin reacts faster on lvextend failure path with umount.
Add dm_stats_bind_from_fd() to bind a stats handle from a file descriptor.
Do not try call callback when reverting activation on error path.
Fix file mapping for extents with physically adjacent extents.

View File

@@ -328,7 +328,6 @@ void process_event(struct dm_task *dmt,
char *params;
int needs_policy = 0;
int needs_umount = 0;
struct dm_task *new_dmt = NULL;
#if THIN_DEBUG
log_debug("Watch for tp-data:%.2f%% tp-metadata:%.2f%%.",
@@ -347,28 +346,6 @@ void process_event(struct dm_task *dmt,
goto out;
stack;
/*
* Rather update oldish status
* since after 'command' processing
* percentage info could have changed a lot.
* If we would get above UMOUNT_THRESH
* we would wait for next sigalarm.
*/
if (!(new_dmt = dm_task_create(DM_DEVICE_STATUS)))
goto_out;
if (!dm_task_set_uuid(new_dmt, dm_task_get_uuid(dmt)))
goto_out;
/* Non-blocking status read */
if (!dm_task_no_flush(new_dmt))
log_warn("WARNING: Can't set no_flush for dm status.");
if (!dm_task_run(new_dmt))
goto_out;
dmt = new_dmt;
}
dm_get_next_target(dmt, next, &start, &length, &target_type, &params);
@@ -456,9 +433,6 @@ out:
device, state->fails);
pthread_kill(pthread_self(), SIGALRM);
}
if (new_dmt)
dm_task_destroy(new_dmt);
}
int register_device(const char *device,

View File

@@ -618,7 +618,7 @@ class Lv(LvCommon):
rc, out, err = cmdhandler.activate_deactivate(
'lvchange', lv_name, activate, control_flags, options)
if rc == 0:
cfg.load()
dbo.refresh()
return '/'
else:
raise dbus.exceptions.DBusException(
@@ -667,7 +667,7 @@ class Lv(LvCommon):
rc, out, err = cmdhandler.lv_tag(
lv_name, tags_add, tags_del, tag_options)
if rc == 0:
cfg.load()
dbo.refresh()
return '/'
else:
raise dbus.exceptions.DBusException(

View File

@@ -19,6 +19,7 @@ from .utils import log_error, mt_async_result
class RequestEntry(object):
def __init__(self, tmo, method, arguments, cb, cb_error,
return_tuple=True, job_state=None):
self.tmo = tmo
self.method = method
self.arguments = arguments
self.cb = cb
@@ -34,38 +35,31 @@ class RequestEntry(object):
self._return_tuple = return_tuple
self._job_state = job_state
if tmo < 0:
if self.tmo < 0:
# Client is willing to block forever
pass
elif tmo == 0:
self._return_job()
else:
# Note: using 990 instead of 1000 for second to ms conversion to
# account for overhead. Goal is to return just before the
# timeout amount has expired. Better to be a little early than
# late.
self.timer_id = GLib.timeout_add(
tmo * 990, RequestEntry._request_timeout, self)
self.timer_id = GLib.timeout_add_seconds(
tmo, RequestEntry._request_timeout, self)
@staticmethod
def _request_timeout(r):
"""
Method which gets called when the timer runs out!
:param r: RequestEntry which timed out
:return: Result of timer_expired
:return: Nothing
"""
return r.timer_expired()
r.timer_expired()
def _return_job(self):
# Return job is only called when we create a request object or when
# we pop a timer. In both cases we are running in the correct context
# and do not need to schedule the call back in main context.
self._job = Job(self, self._job_state)
cfg.om.register_object(self._job, True)
if self._return_tuple:
self.cb(('/', self._job.dbus_object_path()))
mt_async_result(self.cb, ('/', self._job.dbus_object_path()))
else:
self.cb(self._job.dbus_object_path())
mt_async_result(self.cb, self._job.dbus_object_path())
def run_cmd(self):
try:

View File

@@ -727,7 +727,7 @@ class Vg(AutomatedProperties):
rc, out, err = cmdhandler.vg_tag(
vg_name, tags_add, tags_del, tag_options)
if rc == 0:
cfg.load()
dbo.refresh()
return '/'
else:
raise dbus.exceptions.DBusException(
@@ -780,7 +780,7 @@ class Vg(AutomatedProperties):
if dbo:
rc, out, err = method(vg_name, value, options)
if rc == 0:
cfg.load()
dbo.refresh()
return '/'
else:
raise dbus.exceptions.DBusException(

View File

@@ -358,10 +358,6 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
{
return 1;
}
int lv_deactivate_any_missing_subdevs(const struct logical_volume *lv)
{
return 1;
}
int pv_uses_vg(struct physical_volume *pv,
struct volume_group *vg)
{
@@ -1940,7 +1936,7 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
/* FIXME specify events */
if (!monitor_fn(seg, 0)) {
log_error("%s: %s segment monitoring function failed.",
display_lvname(lv), lvseg_name(seg));
display_lvname(lv), seg->segtype->name);
return 0;
}
} else
@@ -2577,77 +2573,6 @@ int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
return r;
}
/* Remove any existing, closed mapped device by @name */
static int _remove_dm_dev_by_name(const char *name)
{
int r = 0;
struct dm_task *dmt;
struct dm_info info;
if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
return_0;
/* Check, if the device exists. */
if (dm_task_set_name(dmt, name) && dm_task_run(dmt) && dm_task_get_info(dmt, &info)) {
dm_task_destroy(dmt);
/* Ignore non-existing or open dm devices */
if (!info.exists || info.open_count)
return 1;
if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
return_0;
if (dm_task_set_name(dmt, name))
r = dm_task_run(dmt);
}
dm_task_destroy(dmt);
return r;
}
/* Work all segments of @lv removing any existing, closed "*-missing_N_0" sub devices. */
static int _lv_remove_any_missing_subdevs(struct logical_volume *lv)
{
if (lv) {
uint32_t seg_no = 0;
char name[257];
struct lv_segment *seg;
dm_list_iterate_items(seg, &lv->segments) {
if (seg->area_count != 1)
return_0;
if (dm_snprintf(name, sizeof(name), "%s-%s-missing_%u_0", seg->lv->vg->name, seg->lv->name, seg_no) < 0)
return 0;
if (!_remove_dm_dev_by_name(name))
return 0;
seg_no++;
}
}
return 1;
}
/* Remove any "*-missing_*" sub devices added by the activation layer for an rmate/rimage missing PV mapping */
int lv_deactivate_any_missing_subdevs(const struct logical_volume *lv)
{
uint32_t s;
struct lv_segment *seg = first_seg(lv);
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) == AREA_LV &&
!_lv_remove_any_missing_subdevs(seg_lv(seg, s)))
return 0;
if (seg->meta_areas && seg_metatype(seg, s) == AREA_LV &&
!_lv_remove_any_missing_subdevs(seg_metalv(seg, s)))
return 0;
}
return 1;
}
/*
* Does PV use VG somewhere in its construction?
* Returns 1 on failure.

View File

@@ -124,8 +124,6 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logi
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
int lv_deactivate_any_missing_subdevs(const struct logical_volume *lv);
/*
* Returns 1 if info structure has been populated, else 0 on failure.
* When lvinfo* is NULL, it returns 1 if the device is locally active, 0 otherwise.

View File

@@ -2493,7 +2493,7 @@ static int _add_target_to_dtree(struct dev_manager *dm,
if (!seg->segtype->ops->add_target_line) {
log_error(INTERNAL_ERROR "_emit_target cannot handle "
"segment type %s.", lvseg_name(seg));
"segment type %s.", seg->segtype->name);
return 0;
}

View File

@@ -398,7 +398,7 @@ int export_extents(struct disk_list *dl, uint32_t lv_num,
if (!(seg->segtype->flags & SEG_FORMAT1_SUPPORT)) {
log_error("Segment type %s in LV %s: "
"unsupported by format1",
lvseg_name(seg), lv->name);
seg->segtype->name, lv->name);
return 0;
}
if (seg_type(seg, s) != AREA_PV) {

View File

@@ -326,7 +326,7 @@ int validate_lv_cache_create_origin(const struct logical_volume *origin_lv)
lv_is_cow(origin_lv) || lv_is_merging_cow(origin_lv) ||
lv_is_virtual(origin_lv)) {
log_error("Cache is not supported with %s segment type of the original logical volume %s.",
lvseg_name(first_seg(origin_lv)), display_lvname(origin_lv));
first_seg(origin_lv)->segtype->name, display_lvname(origin_lv));
return 0;
}
@@ -424,15 +424,9 @@ int lv_cache_wait_for_clean(struct logical_volume *cache_lv, int *is_clean)
/* Switch to cleaner policy to flush the cache */
cache_seg->cleaner_policy = 1;
/* Reload cache volume with "cleaner" policy */
/* Reaload kernel with "cleaner" policy */
if (!lv_update_and_reload_origin(cache_lv))
return_0;
if (!sync_local_dev_names(cache_lv->vg->cmd)) {
log_error("Failed to sync local devices when clearing cache volume %s.",
display_lvname(cache_lv));
return 0;
}
}
/*
@@ -442,12 +436,6 @@ int lv_cache_wait_for_clean(struct logical_volume *cache_lv, int *is_clean)
if (1) {
if (!lv_refresh_suspend_resume(lock_lv))
return_0;
if (!sync_local_dev_names(cache_lv->vg->cmd)) {
log_error("Failed to sync local devices after final clearing of cache %s.",
display_lvname(cache_lv));
return 0;
}
}
cache_seg->cleaner_policy = 0;

View File

@@ -1418,19 +1418,35 @@ static int _lv_refresh_suspend_resume(const struct logical_volume *lv)
int lv_refresh_suspend_resume(const struct logical_volume *lv)
{
if (!_lv_refresh_suspend_resume(lv))
return 0;
/*
* Remove any transiently activated error
* devices which arean't used any more.
* FIXME:
*
* in case of RAID, refresh the SubLVs before
* refreshing the top-level one in order to cope
* with transient failures of SubLVs.
*/
if (lv_is_raid(lv) && !lv_deactivate_any_missing_subdevs(lv)) {
log_error("Failed to remove temporary SubLVs from %s", display_lvname(lv));
return 0;
if (lv_is_raid(lv)) {
if (vg_is_clustered(lv->vg) &&
lv_is_active_remotely(lv)) {
if (!_lv_refresh_suspend_resume(lv))
return 0;
} else {
uint32_t s;
struct lv_segment *seg = first_seg(lv);
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) == AREA_LV &&
!_lv_refresh_suspend_resume(seg_lv(seg, s)))
return 0;
if (seg->meta_areas &&
seg_metatype(seg, s) == AREA_LV &&
!_lv_refresh_suspend_resume(seg_metalv(seg, s)))
return 0;
}
}
}
return 1;
return _lv_refresh_suspend_resume(lv);
}
/*
@@ -3466,7 +3482,7 @@ int lv_add_segment(struct alloc_handle *ah,
region_size))
return_0;
if (segtype_can_split(segtype) && !lv_merge_segments(lv)) {
if ((segtype->flags & SEG_CAN_SPLIT) && !lv_merge_segments(lv)) {
log_error("Couldn't merge segments after extending "
"logical volume.");
return 0;
@@ -4595,7 +4611,7 @@ static int _lvresize_adjust_policy(const struct logical_volume *lv,
if (!policy_amount) {
log_error("Can't extend %s with %s autoextend percent set to 0%%.",
display_lvname(lv), lvseg_name(first_seg(lv)));
display_lvname(lv), first_seg(lv)->segtype->name);
return 0;
}
@@ -7047,7 +7063,7 @@ static int _should_wipe_lv(struct lvcreate_params *lp,
struct logical_volume *lv, int warn)
{
/* Unzeroable segment */
if (seg_cannot_be_zeroed(first_seg(lv)))
if (first_seg(lv)->segtype->flags & SEG_CANNOT_BE_ZEROED)
return 0;
/* Thin snapshot need not to be zeroed */

View File

@@ -71,13 +71,6 @@ int lv_merge_segments(struct logical_volume *lv)
if (error_count++ > ERROR_MAX) \
goto out
#define seg_error(msg) { \
log_error("LV %s, segment %u invalid: %s for %s segment.", \
seg->lv->name, seg_count, (msg), lvseg_name(seg)); \
if ((*error_count)++ > ERROR_MAX) \
return; \
}
/*
* RAID segment property checks.
*
@@ -195,10 +188,44 @@ static void _check_non_raid_seg_members(struct lv_segment *seg, int *error_count
{
if (seg->origin) /* snap and thin */
raid_seg_error("non-zero origin LV");
if (seg->indirect_origin) /* thin */
raid_seg_error("non-zero indirect_origin LV");
if (seg->merge_lv) /* thin */
raid_seg_error("non-zero merge LV");
if (seg->cow) /* snap */
raid_seg_error("non-zero cow LV");
if (!dm_list_empty(&seg->origin_list)) /* snap */
raid_seg_error("non-zero origin_list");
if (seg->log_lv)
raid_seg_error("non-zero log LV");
if (seg->segtype_private)
raid_seg_error("non-zero segtype_private");
/* thin members */
if (seg->metadata_lv)
raid_seg_error("non-zero metadata LV");
if (seg->transaction_id)
raid_seg_error("non-zero transaction_id");
if (seg->zero_new_blocks)
raid_seg_error("non-zero zero_new_blocks");
if (seg->discards)
raid_seg_error("non-zero discards");
if (!dm_list_empty(&seg->thin_messages))
raid_seg_error("non-zero thin_messages list");
if (seg->external_lv)
raid_seg_error("non-zero external LV");
if (seg->pool_lv)
raid_seg_error("non-zero pool LV");
if (seg->device_id)
raid_seg_error("non-zero device_id");
/* cache members */
if (seg->cache_mode)
raid_seg_error("non-zero cache_mode");
if (seg->policy_name)
raid_seg_error("non-zero policy_name");
if (seg->policy_settings)
raid_seg_error("non-zero policy_settings");
if (seg->cleaner_policy)
raid_seg_error("non-zero cleaner_policy");
/* replicator members (deprecated) */
if (seg->replicator)
raid_seg_error("non-zero replicator");
@@ -222,6 +249,9 @@ static void _check_raid_seg(struct lv_segment *seg, int *error_count)
uint32_t area_len, s;
/* General checks applying to all RAIDs */
if (!seg_is_raid(seg))
raid_seg_error("erroneous RAID check");
if (!seg->area_count)
raid_seg_error("zero area count");
@@ -246,6 +276,9 @@ static void _check_raid_seg(struct lv_segment *seg, int *error_count)
return;
}
if (seg->chunk_size)
raid_seg_error_val("non-zero chunk_size", seg->chunk_size);
/* FIXME: should we check any non-RAID segment struct members at all? */
_check_non_raid_seg_members(seg, error_count);
@@ -296,169 +329,6 @@ static void _check_raid_seg(struct lv_segment *seg, int *error_count)
}
/* END: RAID segment property checks. */
static void _check_lv_segment(struct logical_volume *lv, struct lv_segment *seg,
unsigned seg_count, int *error_count)
{
struct lv_segment *seg2;
if (lv_is_mirror_image(lv) &&
(!(seg2 = find_mirror_seg(seg)) || !seg_is_mirrored(seg2)))
seg_error("mirror image is not mirrored");
if (seg_is_cache(seg)) {
if (!lv_is_cache(lv))
seg_error("is not flagged as cache LV");
if (!seg->pool_lv) {
seg_error("is missing cache pool LV");
} else if (!lv_is_cache_pool(seg->pool_lv))
seg_error("is not referencing cache pool LV");
} else { /* !cache */
if (seg->cleaner_policy)
seg_error("sets cleaner_policy");
}
if (seg_is_cache_pool(seg)) {
if (!dm_list_empty(&seg->lv->segs_using_this_lv)) {
switch (seg->cache_mode) {
case CACHE_MODE_WRITETHROUGH:
case CACHE_MODE_WRITEBACK:
case CACHE_MODE_PASSTHROUGH:
break;
default:
seg_error("has invalid cache's feature flag")
}
if (!seg->policy_name)
seg_error("is missing cache policy name");
}
} else { /* !cache_pool */
if (seg->cache_mode)
seg_error("sets cache mode");
if (seg->policy_name)
seg_error("sets policy name");
if (seg->policy_settings)
seg_error("sets policy settings");
}
if (!seg_can_error_when_full(seg) && lv_is_error_when_full(lv))
seg_error("does not support flag ERROR_WHEN_FULL.");
if (seg_is_mirrored(seg)) {
/* Check mirror log - which is attached to the mirrored seg */
if (seg->log_lv) {
if (!lv_is_mirror_log(seg->log_lv))
seg_error("log LV is not a mirror log");
if (!(seg2 = first_seg(seg->log_lv)) || (find_mirror_seg(seg2) != seg))
seg_error("log LV does not point back to mirror segment");
}
} else { /* !mirrored */
if (seg->log_lv) {
if (lv_is_raid_image(lv))
seg_error("log LV is not a mirror log or a RAID image");
}
}
if (seg_is_raid(seg))
_check_raid_seg(seg, error_count);
if (seg_is_pool(seg)) {
if ((seg->area_count != 1) || (seg_type(seg, 0) != AREA_LV)) {
seg_error("is missing a pool data LV");
} else if (!(seg2 = first_seg(seg_lv(seg, 0))) || (find_pool_seg(seg2) != seg))
seg_error("data LV does not refer back to pool LV");
if (!seg->metadata_lv) {
seg_error("is missing a pool metadata LV");
} else if (!(seg2 = first_seg(seg->metadata_lv)) || (find_pool_seg(seg2) != seg))
seg_error("metadata LV does not refer back to pool LV");
if (!validate_pool_chunk_size(lv->vg->cmd, seg->segtype, seg->chunk_size))
seg_error("has invalid chunk size.");
} else { /* !thin_pool && !cache_pool */
if (seg->metadata_lv)
seg_error("must not have pool metadata LV set");
}
if (seg_is_thin_pool(seg)) {
if (!lv_is_thin_pool(lv))
seg_error("is not flagged as thin pool LV");
if (lv_is_thin_volume(lv))
seg_error("is a thin volume that must not contain thin pool segment");
} else { /* !thin_pool */
if (seg->zero_new_blocks)
seg_error("sets zero_new_blocks");
if (seg->discards)
seg_error("sets discards");
if (!dm_list_empty(&seg->thin_messages))
seg_error("sets thin_messages list");
}
if (seg_is_thin_volume(seg)) {
if (!lv_is_thin_volume(lv))
seg_error("is not flagged as thin volume LV");
if (lv_is_thin_pool(lv))
seg_error("is a thin pool that must not contain thin volume segment");
if (!seg->pool_lv) {
seg_error("is missing thin pool LV");
} else if (!lv_is_thin_pool(seg->pool_lv))
seg_error("is not referencing thin pool LV");
if (seg->device_id > DM_THIN_MAX_DEVICE_ID)
seg_error("has too large device id");
if (seg->external_lv &&
!lv_is_external_origin(seg->external_lv))
seg_error("external LV is not flagged as a external origin LV");
if (seg->merge_lv) {
if (!lv_is_thin_volume(seg->merge_lv))
seg_error("merge LV is not flagged as a thin LV");
if (!lv_is_merging_origin(seg->merge_lv))
seg_error("merge LV is not flagged as merging");
}
} else { /* !thin */
if (seg->device_id)
seg_error("sets device_id");
if (seg->external_lv)
seg_error("sets external LV");
if (seg->merge_lv)
seg_error("sets merge LV");
if (seg->indirect_origin)
seg_error("sets indirect_origin LV");
}
/* Some multi-seg vars excluded here */
if (!seg_is_cache(seg) &&
!seg_is_thin_volume(seg)) {
if (seg->pool_lv)
seg_error("sets pool LV");
}
if (!seg_is_pool(seg) &&
/* FIXME: format_pool/import_export.c _add_linear_seg() sets chunk_size */
!seg_is_linear(seg) &&
!seg_is_snapshot(seg)) {
if (seg->chunk_size)
seg_error("sets chunk_size");
}
if (!seg_is_thin_pool(seg) &&
!seg_is_thin_volume(seg)) {
if (seg->transaction_id)
seg_error("sets transaction_id");
}
if (!seg_unknown(seg)) {
if (seg->segtype_private)
seg_error("set segtype_private");
}
}
/*
* Verify that an LV's segments are consecutive, complete and don't overlap.
*/
@@ -466,7 +336,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
{
struct lv_segment *seg, *seg2;
uint32_t le = 0;
unsigned seg_count = 0, seg_found, external_lv_found = 0;
unsigned seg_count = 0, seg_found;
uint32_t area_multiplier, s;
struct seg_list *sl;
struct glv_list *glvl;
@@ -474,15 +344,80 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
struct replicator_site *rsite;
struct replicator_device *rdev;
dm_list_iterate_items(seg, &lv->segments) {
seg_count++;
/* Check LV flags match first segment type */
if (complete_vg) {
if (lv_is_thin_volume(lv)) {
if (dm_list_size(&lv->segments) != 1) {
log_error("LV %s is thin volume without exactly one segment.",
lv->name);
inc_error_count;
} else if (!seg_is_thin_volume(first_seg(lv))) {
log_error("LV %s is thin volume without first thin volume segment.",
lv->name);
inc_error_count;
}
}
if (seg->lv != lv) {
log_error("LV %s invalid: segment %u is referencing different LV.",
lv->name, seg_count);
if (lv_is_thin_pool(lv)) {
if (dm_list_size(&lv->segments) != 1) {
log_error("LV %s is thin pool volume without exactly one segment.",
lv->name);
inc_error_count;
} else if (!seg_is_thin_pool(first_seg(lv))) {
log_error("LV %s is thin pool without first thin pool segment.",
lv->name);
inc_error_count;
}
}
if (lv_is_pool_data(lv) &&
(!(seg2 = first_seg(lv)) || !(seg2 = find_pool_seg(seg2)) ||
seg2->area_count != 1 || seg_type(seg2, 0) != AREA_LV ||
seg_lv(seg2, 0) != lv)) {
log_error("LV %s: segment 1 pool data LV does not point back to same LV",
lv->name);
inc_error_count;
}
if (lv_is_pool_metadata(lv)) {
if (!(seg2 = first_seg(lv)) || !(seg2 = find_pool_seg(seg2)) ||
seg2->metadata_lv != lv) {
log_error("LV %s: segment 1 pool metadata LV does not point back to same LV",
lv->name);
inc_error_count;
}
if (lv_is_thin_pool_metadata(lv) &&
!strstr(lv->name, "_tmeta")) {
log_error("LV %s: thin pool metadata LV does not use _tmeta",
lv->name);
inc_error_count;
} else if (lv_is_cache_pool_metadata(lv) &&
!strstr(lv->name, "_cmeta")) {
log_error("LV %s: cache pool metadata LV does not use _cmeta",
lv->name);
inc_error_count;
}
}
if (lv_is_external_origin(lv)) {
seg_found = 0;
dm_list_iterate_items(sl, &lv->segs_using_this_lv)
if (sl->seg->external_lv == lv)
seg_found++;
if (seg_found != lv->external_count) {
log_error("LV %s: external origin count does not match.",
lv->name);
inc_error_count;
}
}
}
dm_list_iterate_items(seg, &lv->segments) {
seg_count++;
if (complete_vg && seg_is_raid(seg))
_check_raid_seg(seg, &error_count);
if (seg->le != le) {
log_error("LV %s invalid: segment %u should begin at "
"LE %" PRIu32 " (found %" PRIu32 ").",
@@ -500,6 +435,186 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
inc_error_count;
}
if (lv_is_error_when_full(lv) &&
!seg_can_error_when_full(seg)) {
log_error("LV %s: segment %u (%s) does not support flag "
"ERROR_WHEN_FULL.", lv->name, seg_count, seg->segtype->name);
inc_error_count;
}
if (complete_vg && seg->log_lv &&
!seg_is_mirrored(seg) && lv_is_raid_image(lv)) {
log_error("LV %s: segment %u log LV %s is not a "
"mirror log or a RAID image",
lv->name, seg_count, seg->log_lv->name);
inc_error_count;
}
/*
* Check mirror log - which is attached to the mirrored seg
*/
if (complete_vg && seg->log_lv && seg_is_mirrored(seg)) {
if (!lv_is_mirror_log(seg->log_lv)) {
log_error("LV %s: segment %u log LV %s is not "
"a mirror log",
lv->name, seg_count, seg->log_lv->name);
inc_error_count;
}
if (!(seg2 = first_seg(seg->log_lv)) ||
find_mirror_seg(seg2) != seg) {
log_error("LV %s: segment %u log LV does not "
"point back to mirror segment",
lv->name, seg_count);
inc_error_count;
}
}
if (complete_vg && lv_is_mirror_image(lv)) {
if (!(seg2 = find_mirror_seg(seg)) ||
!seg_is_mirrored(seg2)) {
log_error("LV %s: segment %u mirror image "
"is not mirrored",
lv->name, seg_count);
inc_error_count;
}
}
/* Check the various thin segment types */
if (complete_vg) {
if (seg_is_thin_pool(seg)) {
if (!lv_is_thin_pool(lv)) {
log_error("LV %s is missing thin pool flag for segment %u",
lv->name, seg_count);
inc_error_count;
}
if (lv_is_thin_volume(lv)) {
log_error("LV %s is a thin volume that must not contain thin pool segment %u",
lv->name, seg_count);
inc_error_count;
}
}
if (seg_is_cache_pool(seg) &&
!dm_list_empty(&seg->lv->segs_using_this_lv)) {
switch (seg->cache_mode) {
case CACHE_MODE_WRITETHROUGH:
case CACHE_MODE_WRITEBACK:
case CACHE_MODE_PASSTHROUGH:
break;
default:
log_error("LV %s has invalid cache's feature flag.",
lv->name);
inc_error_count;
}
if (!seg->policy_name) {
log_error("LV %s is missing cache policy name.", lv->name);
inc_error_count;
}
}
if (seg_is_pool(seg)) {
if (seg->area_count != 1 ||
seg_type(seg, 0) != AREA_LV) {
log_error("LV %s: %s segment %u is missing a pool data LV",
lv->name, seg->segtype->name, seg_count);
inc_error_count;
} else if (!(seg2 = first_seg(seg_lv(seg, 0))) || find_pool_seg(seg2) != seg) {
log_error("LV %s: %s segment %u data LV does not refer back to pool LV",
lv->name, seg->segtype->name, seg_count);
inc_error_count;
}
if (!seg->metadata_lv) {
log_error("LV %s: %s segment %u is missing a pool metadata LV",
lv->name, seg->segtype->name, seg_count);
inc_error_count;
} else if (!(seg2 = first_seg(seg->metadata_lv)) ||
find_pool_seg(seg2) != seg) {
log_error("LV %s: %s segment %u metadata LV does not refer back to pool LV",
lv->name, seg->segtype->name, seg_count);
inc_error_count;
}
if (!validate_pool_chunk_size(lv->vg->cmd, seg->segtype, seg->chunk_size)) {
log_error("LV %s: %s segment %u has invalid chunk size %u.",
lv->name, seg->segtype->name, seg_count, seg->chunk_size);
inc_error_count;
}
} else {
if (seg->metadata_lv) {
log_error("LV %s: segment %u must not have pool metadata LV set",
lv->name, seg_count);
inc_error_count;
}
}
if (seg_is_thin_volume(seg)) {
if (!lv_is_thin_volume(lv)) {
log_error("LV %s is missing thin volume flag for segment %u",
lv->name, seg_count);
inc_error_count;
}
if (lv_is_thin_pool(lv)) {
log_error("LV %s is a thin pool that must not contain thin volume segment %u",
lv->name, seg_count);
inc_error_count;
}
if (!seg->pool_lv) {
log_error("LV %s: segment %u is missing thin pool LV",
lv->name, seg_count);
inc_error_count;
} else if (!lv_is_thin_pool(seg->pool_lv)) {
log_error("LV %s: thin volume segment %u pool LV is not flagged as a pool LV",
lv->name, seg_count);
inc_error_count;
}
if (seg->device_id > DM_THIN_MAX_DEVICE_ID) {
log_error("LV %s: thin volume segment %u has too large device id %u",
lv->name, seg_count, seg->device_id);
inc_error_count;
}
if (seg->external_lv && (seg->external_lv->status & LVM_WRITE)) {
log_error("LV %s: external origin %s is writable.",
lv->name, seg->external_lv->name);
inc_error_count;
}
if (seg->merge_lv) {
if (!lv_is_thin_volume(seg->merge_lv)) {
log_error("LV %s: thin volume segment %u merging LV %s is not flagged as a thin LV",
lv->name, seg_count, seg->merge_lv->name);
inc_error_count;
}
if (!lv_is_merging_origin(seg->merge_lv)) {
log_error("LV %s: merging LV %s is not flagged as merging.",
lv->name, seg->merge_lv->name);
inc_error_count;
}
}
} else if (seg_is_cache(seg)) {
if (!lv_is_cache(lv)) {
log_error("LV %s is missing cache flag for segment %u",
lv->name, seg_count);
inc_error_count;
}
if (!seg->pool_lv) {
log_error("LV %s: segment %u is missing cache_pool LV",
lv->name, seg_count);
inc_error_count;
}
} else {
if (seg->pool_lv) {
log_error("LV %s: segment %u must not have pool LV set",
lv->name, seg_count);
inc_error_count;
}
}
}
if (seg_is_snapshot(seg)) {
if (seg->cow && seg->cow == seg->origin) {
log_error("LV %s: segment %u has same LV %s for "
@@ -512,9 +627,6 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
if (seg_is_replicator(seg) && !check_replicator_segment(seg))
inc_error_count;
if (complete_vg)
_check_lv_segment(lv, seg, seg_count, &error_count);
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) == AREA_UNASSIGNED) {
log_error("LV %s: segment %u has unassigned "
@@ -596,12 +708,6 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
le += seg->len;
}
if (le != lv->le_count) {
log_error("LV %s: inconsistent LE count %u != %u",
lv->name, le, lv->le_count);
inc_error_count;
}
dm_list_iterate_items(sl, &lv->segs_using_this_lv) {
seg = sl->seg;
seg_found = 0;
@@ -662,10 +768,6 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
lv->name);
inc_error_count;
}
/* Validation of external origin counter */
if (seg->external_lv == lv)
external_lv_found++;
}
dm_list_iterate_items(glvl, &lv->indirect_glvs) {
@@ -687,51 +789,10 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
}
}
/* Check LV flags match first segment type */
if (complete_vg) {
if ((seg_count != 1) &&
(lv_is_cache(lv) ||
lv_is_cache_pool(lv) ||
lv_is_raid(lv) ||
lv_is_snapshot(lv) ||
lv_is_thin_pool(lv) ||
lv_is_thin_volume(lv))) {
log_error("LV %s must have exactly one segment.",
lv->name);
inc_error_count;
}
if (lv_is_pool_data(lv) &&
(!(seg2 = first_seg(lv)) || !(seg2 = find_pool_seg(seg2)) ||
seg2->area_count != 1 || seg_type(seg2, 0) != AREA_LV ||
seg_lv(seg2, 0) != lv)) {
log_error("LV %s: segment 1 pool data LV does not point back to same LV",
lv->name);
inc_error_count;
}
if (lv_is_thin_pool_metadata(lv) && !strstr(lv->name, "_tmeta")) {
log_error("LV %s: thin pool metadata LV does not use _tmeta.",
lv->name);
inc_error_count;
} else if (lv_is_cache_pool_metadata(lv) && !strstr(lv->name, "_cmeta")) {
log_error("LV %s: cache pool metadata LV does not use _cmeta.",
lv->name);
inc_error_count;
}
if (lv_is_external_origin(lv)) {
if (lv->external_count != external_lv_found) {
log_error("LV %s: external origin count does not match.",
lv->name);
inc_error_count;
}
if (lv->status & LVM_WRITE) {
log_error("LV %s: external origin cant't be writable.",
lv->name);
inc_error_count;
}
}
if (le != lv->le_count) {
log_error("LV %s: inconsistent LE count %u != %u",
lv->name, le, lv->le_count);
inc_error_count;
}
out:

View File

@@ -198,7 +198,7 @@
#define lv_is_partial(lv) (((lv)->status & PARTIAL_LV) ? 1 : 0)
#define lv_is_virtual(lv) (((lv)->status & VIRTUAL) ? 1 : 0)
#define lv_is_merging(lv) (((lv)->status & MERGING) ? 1 : 0)
#define lv_is_merging_origin(lv) (lv_is_merging(lv) && (lv)->snapshot)
#define lv_is_merging_origin(lv) (lv_is_merging(lv))
#define lv_is_snapshot(lv) (((lv)->status & SNAPSHOT) ? 1 : 0)
#define lv_is_converting(lv) (((lv)->status & CONVERTING) ? 1 : 0)
#define lv_is_external_origin(lv) (((lv)->external_count > 0) ? 1 : 0)

View File

@@ -5447,19 +5447,6 @@ int vg_flag_write_locked(struct volume_group *vg)
return 0;
}
static int _access_vg_clustered(struct cmd_context *cmd, const struct volume_group *vg)
{
if (vg_is_clustered(vg) && !locking_is_clustered()) {
if (!cmd->ignore_clustered_vgs)
log_error("Skipping clustered volume group %s", vg->name);
else
log_verbose("Skipping clustered volume group %s", vg->name);
return 0;
}
return 1;
}
/*
* Performs a set of checks against a VG according to bits set in status
* and returns FAILED_* bits for those that aren't acceptable.
@@ -5471,9 +5458,15 @@ static uint32_t _vg_bad_status_bits(const struct volume_group *vg,
{
uint32_t failure = 0;
if ((status & CLUSTERED) && !_access_vg_clustered(vg->cmd, vg))
if ((status & CLUSTERED) &&
(vg_is_clustered(vg)) && !locking_is_clustered()) {
if (!vg->cmd->ignore_clustered_vgs)
log_error("Skipping clustered volume group %s", vg->name);
else
log_verbose("Skipping clustered volume group %s", vg->name);
/* Return because other flags are considered undefined. */
return FAILED_CLUSTERED;
}
if ((status & EXPORTED_VG) &&
vg_is_exported(vg)) {
@@ -5562,6 +5555,19 @@ static int _allow_extra_system_id(struct cmd_context *cmd, const char *system_id
return 0;
}
static int _access_vg_clustered(struct cmd_context *cmd, struct volume_group *vg)
{
if (vg_is_clustered(vg) && !locking_is_clustered()) {
if (!cmd->ignore_clustered_vgs)
log_error("Skipping clustered volume group %s", vg->name);
else
log_verbose("Skipping clustered volume group %s", vg->name);
return 0;
}
return 1;
}
static int _access_vg_lock_type(struct cmd_context *cmd, struct volume_group *vg,
uint32_t lockd_state, uint32_t *failure)
{

View File

@@ -2724,6 +2724,15 @@ static const char *_get_segtype_alias(const struct segment_type *segtype)
return "";
}
/* Return "linear" for striped segtype with 1 area instead of "striped" */
static const char *_get_segtype_name(const struct segment_type *segtype, unsigned new_image_count)
{
if (!segtype || (segtype_is_striped(segtype) && new_image_count == 1))
return "linear";
return segtype->name;
}
static int _log_possible_conversion_types(const struct logical_volume *lv, const struct segment_type *new_segtype)
{
unsigned possible_conversions = 0;
@@ -2744,7 +2753,7 @@ static int _log_possible_conversion_types(const struct logical_volume *lv, const
log_error("Converting %s from %s%s%s%s is "
"directly possible to the following layout%s:",
display_lvname(lv), lvseg_name(seg),
display_lvname(lv), _get_segtype_name(seg->segtype, seg->area_count),
*alias ? " (same as " : "", alias, *alias ? ")" : "",
possible_conversions > 1 ? "s" : "");

View File

@@ -144,12 +144,6 @@ struct dev_manager;
#define segtype_is_virtual(segtype) ((segtype)->flags & SEG_VIRTUAL ? 1 : 0)
#define segtype_is_unknown(segtype) ((segtype)->flags & SEG_UNKNOWN ? 1 : 0)
#define segtype_can_split(segtype) ((segtype)->flags & SEG_CAN_SPLIT ? 1 : 0)
#define segtype_cannot_be_zeroed(segtype) ((segtype)->flags & SEG_CANNOT_BE_ZEROED ? 1 : 0)
#define segtype_monitored(segtype) ((segtype)->flags & SEG_MONITORED ? 1 : 0)
#define segtype_only_exclusive(segtype) ((segtype)->flags & SEG_ONLY_EXCLUSIVE ? 1 : 0)
#define segtype_can_error_when_full(segtype) ((segtype)->flags & SEG_CAN_ERROR_WHEN_FULL ? 1 : 0)
#define segtype_supports_stripe_size(segtype) \
((segtype_is_striped(segtype) || segtype_is_mirror(segtype) || \
segtype_is_cache(segtype) || segtype_is_cache_pool(segtype) || \
@@ -194,11 +188,11 @@ struct dev_manager;
#define seg_is_thin_volume(seg) segtype_is_thin_volume((seg)->segtype)
#define seg_is_virtual(seg) segtype_is_virtual((seg)->segtype)
#define seg_unknown(seg) segtype_is_unknown((seg)->segtype)
#define seg_can_split(seg) segtype_can_split((seg)->segtype)
#define seg_cannot_be_zeroed(seg) segtype_cannot_be_zeroed((seg)->segtype)
#define seg_monitored(seg) segtype_monitored((seg)->segtype)
#define seg_only_exclusive(seg) segtype_only_exclusive((seg)->segtype)
#define seg_can_error_when_full(seg) segtype_can_error_when_full((seg)->segtype)
#define seg_can_split(seg) ((seg)->segtype->flags & SEG_CAN_SPLIT ? 1 : 0)
#define seg_cannot_be_zeroed(seg) ((seg)->segtype->flags & SEG_CANNOT_BE_ZEROED ? 1 : 0)
#define seg_monitored(seg) ((seg)->segtype->flags & SEG_MONITORED ? 1 : 0)
#define seg_only_exclusive(seg) ((seg)->segtype->flags & SEG_ONLY_EXCLUSIVE ? 1 : 0)
#define seg_can_error_when_full(seg) ((seg)->segtype->flags & SEG_CAN_ERROR_WHEN_FULL ? 1 : 0)
struct segment_type {
struct dm_list list; /* Internal */

View File

@@ -878,7 +878,7 @@ Count of writes merged this interval.
.B write_sector_count
Count of 512 byte sectors written this interval.
.TP
.B write_time
.B write_nsecs
Accumulated duration of all write requests (ns).
.TP
.B in_progress_count

View File

@@ -16,7 +16,6 @@ from collections import OrderedDict
import dbus
import os
import sys
import time
BUS_NAME = os.getenv('LVM_DBUS_NAME', 'com.redhat.lvmdbus1')
BASE_INTERFACE = 'com.redhat.lvmdbus1'
@@ -189,15 +188,10 @@ class RemoteInterface(object):
def __init__(
self, dbus_object, interface, introspect,
properties=None, timelimit=-1):
properties=None):
self.dbus_object = dbus_object
self.interface = interface
self.introspect = introspect
self.tmo = 0
if timelimit >= 0:
self.tmo = float(timelimit)
self.tmo *= 1.10
self.dbus_interface = dbus.Interface(self.dbus_object, self.interface)
self._set_props(properties)
@@ -209,19 +203,7 @@ class RemoteInterface(object):
return functools.partial(self, item)
def _wrapper(self, _method_name, *args, **kwargs):
# Lets see how long a method takes to execute, in call cases we should
# return something when the time limit has been reached.
start = time.time()
result = getattr(self.dbus_interface, _method_name)(*args, **kwargs)
end = time.time()
diff = end - start
if self.tmo > 0.0:
if diff > self.tmo:
std_err_print("\n Time exceeded: %f > %f %s" %
(diff, self.tmo, _method_name))
if self.introspect:
if 'RETURN_VALUE' in self.introspect[
@@ -254,14 +236,13 @@ class ClientProxy(object):
short_name = ClientProxy._intf_short_name(interface)
self.short_interface_names.append(short_name)
ro = RemoteInterface(self.dbus_object, interface, introspect,
properties, timelimit=self.tmo)
properties)
setattr(self, short_name, ro)
def __init__(self, bus, object_path, interface_prop_hash=None,
interfaces=None, timelimit=-1):
interfaces=None):
self.object_path = object_path
self.short_interface_names = []
self.tmo = timelimit
self.dbus_object = bus.get_object(
BUS_NAME, self.object_path, introspect=False)

View File

@@ -1491,27 +1491,6 @@ wait_pvmove_lv_ready() {
fi
}
# Holds device open with sleep which automatically expires after given timeout
# Prints PID of running holding sleep process in background
hold_device_open() {
local vgname=$1
local lvname=$2
local sec=${3:-20} # default 20sec
sleep $sec < "$DM_DEV_DIR/$vgname/$lvname" >/dev/null 2>&1 &
SLEEP_PID=$!
# wait till device is openned
for i in $(seq 1 50) ; do
if test "$(dmsetup info --noheadings -c -o open $vgname-$lvname)" -ne 0 ; then
echo "$SLEEP_PID"
return
fi
sleep .1
done
die "$vgname-$lvname expected to be openned, but it's not!"
}
# return total memory size in kB units
total_mem() {
while IFS=":" read -r a b ; do

View File

@@ -1,69 +0,0 @@
#!/bin/sh
# 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 10 1 || skip
aux prepare_vg 6
#
# FIXME: add multi-segment leg tests
#
function _check_raid
{
local vg=$1
shift
local lv=$1
shift
local fail=$1
shift
local good=$1
shift
local devs=$*
aux wait_for_sync $vg $lv
aux disable_dev --error --silent $devs
mkfs.ext4 "$DM_DEV_DIR/$vg/$lv"
fsck.ext4 -fn "$DM_DEV_DIR/$vg/$lv"
check raid_leg_status $vg $lv "$fail"
aux enable_dev --silent $devs
lvs -a -o +devices $vg | tee out
not grep unknown out
lvchange --refresh $vg/$lv
fsck.ext4 -fn "$DM_DEV_DIR/$vg/$lv"
aux wait_for_sync $vg $lv
fsck.ext4 -fn "$DM_DEV_DIR/$vg/$lv"
check raid_leg_status $vg $lv "$good"
}
# raid1 with transiently failing devices
lv=4way
lvcreate -aey --type raid1 -m 3 --ignoremonitoring -L 1 -n $lv $vg
_check_raid $vg $lv "ADAD" "AAAA" $dev2 $dev4
lvremove -y $vg/$lv
# raid6 with transiently failing devices
lv=6way
lvcreate -aey --type raid6 -i 4 --ignoremonitoring -L 1 -n $lv $vg
_check_raid $vg $lv "ADADAA" "AAAAAA" $dev2 $dev4
lvremove -y $vg/$lv
# raid10 with transiently failing devices
lv=6way
lvcreate -aey --type raid10 -i 3 -m 1 --ignoremonitoring -L 1 -n $lv $vg
_check_raid $vg $lv "ADADDA" "AAAAAA" $dev2 $dev4 $dev5
lvremove -y $vg/$lv
vgremove -f $vg

View File

@@ -32,8 +32,7 @@ get_image_pvs() {
aux have_raid 1 3 0 || skip
aux prepare_pvs 9
# vgcreate -s 256k $vg $(cat DEVICES)
vgcreate -s 2m $vg $(cat DEVICES)
vgcreate -s 256k $vg $(cat DEVICES)
###########################################
# RAID1 convert tests
@@ -136,27 +135,15 @@ lvconvert --yes --splitmirrors 1 --name $lv2 $vg/$lv1 "$dev2"
lvremove -ff $vg
###########################################
# RAID1 split + trackchanges / merge with content check
# RAID1 split + trackchanges / merge
###########################################
# 3-way to 2-way/linear
lvcreate --type raid1 -m 2 -l 1 -n $lv1 $vg
mkfs.ext4 "$DM_DEV_DIR/$vg/$lv1"
fsck.ext4 -fn "$DM_DEV_DIR/$vg/$lv1"
lvcreate --type raid1 -m 2 -l 2 -n $lv1 $vg
aux wait_for_sync $vg $lv1
fsck.ext4 -fn "$DM_DEV_DIR/$vg/$lv1"
lvconvert --splitmirrors 1 --trackchanges $vg/$lv1
check lv_exists $vg $lv1
check linear $vg ${lv1}_rimage_2
fsck.ext4 -fn "$DM_DEV_DIR/mapper/$vg-${lv1}_rimage_2"
dd of="$DM_DEV_DIR/$vg/$lv1" if=/dev/zero bs=512 oflag=direct count=`blockdev --getsz "$DM_DEV_DIR/$vg/$lv1"`
not fsck.ext4 -fn "$DM_DEV_DIR/$vg/$lv1"
fsck.ext4 -fn "$DM_DEV_DIR/mapper/$vg-${lv1}_rimage_2"
# FIXME: needed on tiny loop but not on real block backend ?
lvchange --refresh $vg/$lv1
lvconvert --merge $vg/${lv1}_rimage_2
aux wait_for_sync $vg $lv1
lvconvert --splitmirrors 1 --trackchanges $vg/$lv1
not fsck.ext4 -fn "$DM_DEV_DIR/mapper/$vg-${lv1}_rimage_2"
# FIXME: ensure no residual devices
lvremove -ff $vg

View File

@@ -50,12 +50,6 @@ not lvconvert --thin --thinpool $vg/tpool $vg/$lv1
# Switch to 'writethrough' - this should be supported
lvchange --cachemode writethrough $vg/$lv1
# FIXME
# systemd on fc23 'strikes-in' and unmounts mnt
# ATM the reason is unclear (bug in systemd, bad udev rules?)
# as a workaround mount again and 'WARN' test
should not mount "$DM_DEV_DIR/$vg/$lv1" mnt
lvconvert --thin $vg/$lv1 --originname extorg --thinpool $vg/tpool
# check cache exist as extorg-real

View File

@@ -29,7 +29,9 @@ snap_and_merge() {
sync
lvs -a $vg
SLEEP_PID=$(aux hold_device_open $vg $lv1 20)
# keep device open to prevent instant merge
sleep 20 < "$DM_DEV_DIR/$vg/$lv1" &
SLEEP_PID=$!
# initiate background merge
lvconvert -b --mergesnapshot $vg/$lv2

View File

@@ -24,6 +24,16 @@ fill() {
die "Snapshot does not fit $1"
}
# Wait until device is opened
wait_for_open_() {
for i in $(seq 1 50) ; do
test $(dmsetup info --noheadings -c -o open $1) -ne 0 && return
sleep 0.1
done
die "$1 expected to be openned, but it's not!"
}
cleanup_tail()
{
test -z "$SLEEP_PID" || kill $SLEEP_PID || true
@@ -115,7 +125,10 @@ lvchange -ay $vg1
check lv_field $vg1/$lv1 lv_active "$CHECK_ACTIVE"
# Test removal of opened (but unmounted) snapshot (device busy) for a while
SLEEP_PID=$(aux hold_device_open $vg1 $lv1 60)
sleep 120 < "$DM_DEV_DIR/$vg1/$lv1" &
SLEEP_PID=$!
wait_for_open_ "$vg1-$lv1"
# Opened virtual snapshot device is not removable
# it should retry device removal for a few seconds

View File

@@ -72,18 +72,18 @@ touch "$mntusedir/file$$"
sync
# Running 'keeper' process sleep holds the block device still in use
sleep 60 < "$mntusedir/file$$" >/dev/null 2>&1 &
sleep 60 < "$mntusedir/file$$" &
PID_SLEEP=$!
lvs -a $vg
# Fill pool above 95% (to cause 'forced lazy umount)
dd if=/dev/zero of="$mntdir/file$$" bs=256K count=20 conv=fdatasync
sync
lvs -a $vg
# Could loop here for a few secs so dmeventd can do some work
# In the worst case check only happens every 10 seconds :(
# With low water mark it quickly discovers overflow and umounts $vg/$lv1
# With low water mark it should react way faster
for i in $(seq 1 12) ; do
is_lv_opened_ "$vg/$lv1" || break
test $i -lt 12 || die "$mntdir should have been unmounted by dmeventd!"

View File

@@ -1,5 +1,5 @@
#!/bin/sh
# Copyright (C) 2014-2016 Red Hat, Inc. All rights reserved.
# Copyright (C) 2014 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
@@ -37,24 +37,15 @@ check lv_field $vg/snap thin_id "3"
lvconvert --mergethin $vg/snap
umount mnt
check lv_field $vg/$lv1 thin_id "1"
check lv_field $vg/pool transaction_id "3"
vgchange -an $vg
# Check reboot case
vgchange -ay --sysinit $vg
# Check correct thin_id is shown after activation
# even when metadata were not yet physically modified.
# Merge take its place during activation,
# but pool transaction_id still needs metadata update.
check lv_field $vg/$lv1 thin_id "3"
# Metadata are still not updated (--poll n)
check lv_field $vg/$lv1 thin_id "1"
check lv_field $vg/pool transaction_id "3"
# Check the metadata are updated after refresh
#
vgchange --refresh $vg
check lv_field $vg/$lv1 thin_id "3"
check lv_field $vg/pool transaction_id "4"

View File

@@ -53,13 +53,6 @@ not vgchange -p 2 $vg 2>err
grep "MaxPhysicalVolumes is less than the current number $pv_count of PVs for" err
check vg_field $vg max_pv 128
# try some numbers around MAX limit (uint32)
vgchange -p 4294967295 $vg
invalid vgchange -p 4294967296 $vg
invalid vgchange -p 18446744073709551615 $vg
invalid vgchange -p 18446744073709551616 $vg
check vg_field $vg max_pv 4294967295
# vgchange -l MaxLogicalVolumes
check vg_field $vg max_lv 0
invalid vgchange -l -128 $vg

View File

@@ -17,522 +17,221 @@
* Put all long args that don't have a corresponding short option first.
*/
/* *INDENT-OFF* */
arg(ARG_UNUSED, '-', "", 0, 0, 0, NULL) /* place holder for unused 0 value */
arg(abort_ARG, '\0', "abort", 0, 0, 0,
"#pvmove\n"
"Abort any pvmove operations in progress. If a pvmove was started\n"
"with the --atomic option, then all LVs will remain on the source PV.\n"
"Otherwise, segments that have been moved will remain on the\n"
"destination PV, while unmoved segments will remain on the source PV.\n"
"#lvpoll\n"
"Stop processing a poll operation in lvmpolld.\n")
arg(activationmode_ARG, '\0', "activationmode", activationmode_VAL, 0, 0,
"Determines if LV activation is allowed when PVs are missing,\n"
"e.g. because of a device failure.\n"
"\\fBcomplete\\fP only allows LVs with no missing PVs to be activated,\n"
"and is the most restrictive mode.\n"
"\\fBdegraded\\fP allows RAID LVs with missing PVs to be activated.\n"
"(This does not include the \"mirror\" type, see \"raid1\" instead.)\n"
"\\fBpartial\\fP allows any LV with missing PVs to be activated, and\n"
"should only be used for recovery or repair.\n"
"For default, see lvm.conf/activation_mode.\n")
arg(addtag_ARG, '\0', "addtag", tag_VAL, ARG_GROUPABLE, 0,
"Adds a tag to a PV, VG or LV. This option can be repeated to add\n"
"multiple tags at once. See lvm(8) for information about tags.\n")
arg(aligned_ARG, '\0', "aligned", 0, 0, 0,
"Use with --separator to align the output columns\n")
arg(alloc_ARG, '\0', "alloc", alloc_VAL, 0, 0,
"Determines the allocation policy when a command needs to allocate\n"
"Physical Extents (PEs) from the VG. Each VG and LV has an allocation policy\n"
"which can be changed with vgchange/lvchange, or overriden on the\n"
"command line.\n"
"\\fBnormal\\fP applies common sense rules such as not placing parallel stripes\n"
"on the same PV.\n"
"\\fBinherit\\fP applies the VG policy to an LV.\n"
"\\fBcontiguous\\fP requires new PEs be placed adjacent to existing PEs.\n"
"\\fBcling\\fP places new PEs on the same PV as existing PEs in the same\n"
"stripe of the LV.\n"
"If there are sufficient PEs for an allocation, but normal does not\n"
"use them, \\fBanywhere\\fP will use them even if it reduces performance,\n"
"e.g. by placing two stripes on the same PV.\n"
"Optional positional PV args on the command line can also be used to limit\n"
"which PVs the command will use for allocation.\n")
arg(atomic_ARG, '\0', "atomic", 0, 0, 0,
"Makes a pvmove operation atomic, ensuring that all affected LVs are\n"
"moved to the destination PV, or none are if the operation is aborted.\n")
arg(atversion_ARG, '\0', "atversion", string_VAL, 0, 0,
"Specify an LVM version in x.y.z format where x is the major version,\n"
"the y is the minor version and z is the patchlevel (e.g. 2.2.106).\n"
"When configuration is displayed, the configuration settings recognized\n"
"at this LVM version will be considered only. This can be used\n"
"to display a configuration that a certain LVM version understands and\n"
"which does not contain any newer settings for which LVM would\n"
"issue a warning message when checking the configuration.\n")
arg(binary_ARG, '\0', "binary", 0, 0, 0,
"Use binary values \"0\" or \"1\" instead of descriptive literal values\n"
"for columns that have exactly two valid values to report (not counting\n"
"the \"unknown\" value which denotes that the value could not be determined).\n")
arg(bootloaderareasize_ARG, '\0', "bootloaderareasize", sizemb_VAL, 0, 0,
"Create a separate bootloader area of specified size besides PV's data\n"
"area. The bootloader area is an area of reserved space on the PV from\n"
"which LVM will not allocate any extents and it's kept untouched. This is\n"
"primarily aimed for use with bootloaders to embed their own data or metadata.\n"
"The start of the bootloader area is always aligned, see also --dataalignment\n"
"and --dataalignmentoffset. The bootloader area size may eventually\n"
"end up increased due to the alignment, but it's never less than the\n"
"size that is requested. To see the bootloader area start and size of\n"
"an existing PV use pvs -o +pv_ba_start,pv_ba_size.\n")
arg(cache_long_ARG, '\0', "cache", 0, 0, 0,
"#pvscan\n"
"Scan one or more devices and send the metadata to lvmetad.\n"
"#vgscan\n"
"Scan all devices and send the metadata to lvmetad.\n"
"#lvscan\n"
"Scan the devices used by an LV and send the metadata to lvmetad.\n")
arg(cachemode_ARG, '\0', "cachemode", cachemode_VAL, 0, 0,
"Specifies when writes to a cache LV should be considered complete.\n"
"\\fBwriteback\\fP considers a write complete as soon as it is\n"
"stored in the cache pool.\n"
"\\fBwritethough\\fP considers a write complete only when it has\n"
"been stored in both the cache pool and on the origin LV.\n"
"While writethrough may be slower for writes, it is more\n"
"resilient if something should happen to a device associated with the\n"
"cache pool LV. With writethrough, all reads are served\n"
"from the origin LV (all reads miss the cache) and all writes are\n"
"forwarded to the origin LV; additionally, write hits cause cache\n"
"block invalidates. See lvmcache(7) for more information.\n")
arg(cachepool_ARG, '\0', "cachepool", lv_VAL, 0, 0,
"The name of a cache pool LV.\n")
arg(commandprofile_ARG, '\0', "commandprofile", string_VAL, 0, 0,
"The command profile to use for command configuration.\n"
"See lvm.conf(5) for more information about profiles.\n")
arg(config_ARG, '\0', "config", string_VAL, 0, 0,
"Config settings for the command. These override lvm.conf settings.\n"
"The String arg uses the same format as lvm.conf,\n"
"or may use section/field syntax.\n"
"See lvm.conf(5) for more information about config.\n")
arg(configreport_ARG, '\0', "configreport", configreport_VAL, ARG_GROUPABLE, 1,
"See lvmreport(7).\n")
arg(configtype_ARG, '\0', "typeconfig", configtype_VAL, 0, 0,
"See lvmreport(7).\n")
arg(corelog_ARG, '\0', "corelog", 0, 0, 0,
"An alias for --mirrorlog core.\n")
arg(dataalignment_ARG, '\0', "dataalignment", sizekb_VAL, 0, 0,
"Align the start of the data to a multiple of this number.\n"
"Also specify an appropriate Physical Extent size when creating a VG.\n"
"To see the location of the first Physical Extent of an existing PV,\n"
"use pvs -o +pe_start. In addition, it may be shifted by an alignment offset.\n"
"See lvm.conf/data_alignment_offset_detection and --dataalignmentoffset.\n")
arg(dataalignmentoffset_ARG, '\0', "dataalignmentoffset", sizekb_VAL, 0, 0,
"Shift the start of the data area by this additional offset.\n")
arg(deltag_ARG, '\0', "deltag", tag_VAL, ARG_GROUPABLE, 0,
"Deletes a tag from a PV, VG or LV. This option can be repeated to delete\n"
"multiple tags at once. See lvm(8) for information about tags.\n")
arg(detachprofile_ARG, '\0', "detachprofile", 0, 0, 0,
"Detaches a metadata profile from a VG or LV.\n"
"See lvm.conf(5) for more information about profiles.\n")
arg(discards_ARG, '\0', "discards", discards_VAL, 0, 0,
"Specifies how the device-mapper thin pool layer in the kernel should\n"
"handle discards.\n"
"\\fBignore\\fP causes the thin pool to ignore discards.\n"
"\\fBnopassdown\\fP causes the thin pool to process discards itself to\n"
"allow reuse of unneeded extents in the thin pool.\n"
"\\fBpassdown\\fP causes the thin pool to process discards itself\n"
"(like nopassdown) and pass the discards to the underlying device.\n")
arg(driverloaded_ARG, '\0', "driverloaded", bool_VAL, 0, 0,
"If set to no, the command will not attempt to use device-mapper.\n"
"For testing and debugging.\n")
arg(errorwhenfull_ARG, '\0', "errorwhenfull", bool_VAL, 0, 0,
"Specifies thin pool behavior when data space is exhausted.\n"
"When yes, device-mapper will immediately return an error\n"
"when a thin pool is full and an I/O request requires space.\n"
"When no, device-mapper will queue these I/O requests for a\n"
"period of time to allow the thin pool to be extended.\n"
"Errors are returned if no space is available after the timeout.\n"
"(Also see dm-thin-pool kernel module option no_space_timeout.)\n")
arg(force_long_ARG, '\0', "force", 0, ARG_COUNTABLE, 0, NULL)
arg(foreign_ARG, '\0', "foreign", 0, 0, 0,
"Report foreign VGs that would otherwise be skipped.\n"
"See lvmsystemid(7) for more information about foreign VGs.\n")
arg(handlemissingpvs_ARG, '\0', "handlemissingpvs", 0, 0, 0,
"Allows a polling operation to continue when PVs are missing,\n"
"e.g. for repairs due to faulty devices.\n")
arg(ignoreadvanced_ARG, '\0', "ignoreadvanced", 0, 0, 0,
"Exclude advanced configuration settings from the output.\n")
arg(ignorelocal_ARG, '\0', "ignorelocal", 0, 0, 0,
"Ignore local section.\n")
arg(ignorelockingfailure_ARG, '\0', "ignorelockingfailure", 0, 0, 0,
"Allows a command to continue with read-only metadata\n"
"operations after locking failures.\n")
arg(ignoremonitoring_ARG, '\0', "ignoremonitoring", 0, 0, 0,
"Do not interact with dmeventd unless --monitor is specified.\n"
"Do not use this if dmeventd is already monitoring a device.\n")
arg(ignoreskippedcluster_ARG, '\0', "ignoreskippedcluster", 0, 0, 0,
"Use to avoid exiting with an non-zero status code if the command is run\n"
"without clustered locking and clustered VGs are skipped.\n")
arg(ignoreunsupported_ARG, '\0', "ignoreunsupported", 0, 0, 0,
"Exclude unsupported configuration settings from the output. These settings are\n"
"either used for debugging and development purposes only or their support is not\n"
"yet complete and they are not meant to be used in production. The \\fBcurrent\\fP\n"
"and \\fBdiff\\fP types include unsupported settings in their output by default,\n"
"all the other types ignore unsupported settings.\n")
arg(labelsector_ARG, '\0', "labelsector", number_VAL, 0, 0,
"By default the PV is labelled with an LVM2 identifier in its second\n"
"sector (sector 1). This lets you use a different sector near the\n"
"start of the disk (between 0 and 3 inclusive - see LABEL_SCAN_SECTORS\n"
"in the source). Use with care.\n")
arg(lockopt_ARG, '\0', "lockopt", string_VAL, 0, 0,
"Used to pass options for special cases to lvmlockd.\n"
"See lvmlockd(8) for more information.\n")
arg(lockstart_ARG, '\0', "lockstart", 0, 0, 0,
"Start the lockspace of a shared VG in lvmlockd.\n"
"lvmlockd locks becomes available for the VG, allowing LVM to use the VG.\n"
"See lvmlockd(8) for more information.\n")
arg(lockstop_ARG, '\0', "lockstop", 0, 0, 0,
"Stop the lockspace of a shared VG in lvmlockd.\n"
"lvmlockd locks become unavailable for the VG, preventing LVM from using the VG.\n"
"See lvmlockd(8) for more information.\n")
arg(locktype_ARG, '\0', "locktype", locktype_VAL, 0, 0,
"#vgchange\n"
"Change the VG lock type to or from a shared lock type used with lvmlockd.\n"
"See lvmlockd(8) for more information.\n"
"#vgcreate\n"
"Specify the VG lock type directly in place of using --shared.\n"
"See lvmlockd(8) for more information.\n")
arg(logonly_ARG, '\0', "logonly", 0, 0, 0,
"Suppress command report and display only log report.\n")
arg(maxrecoveryrate_ARG, '\0', "maxrecoveryrate", sizekb_VAL, 0, 0,
"Sets the maximum recovery rate for a RAID LV. The rate value\n"
"is an amount of data per second for each device in the array.\n"
"Setting the rate to 0 means it will be unbounded.\n")
arg(merge_ARG, '\0', "merge", 0, 0, 0,
"An alias for --mergethin, --mergemirrors, or --mergesnapshot,\n"
"depending on the type of LV.\n")
arg(mergemirrors_ARG, '\0', "mergemirrors", 0, 0, 0,
"Merge LV images that were split from a raid1 LV.\n"
"See --splitmirrors with --trackchanges.\n")
arg(mergesnapshot_ARG, '\0', "mergesnapshot", 0, 0, 0,
"Merge COW snapshot LV into its origin.\n"
"When merging a snapshot, if both the origin and snapshot LVs are not open,\n"
"the merge will start immediately. Otherwise, the merge will start the\n"
"first time either the origin or snapshot LV are activated and both are\n"
"closed. Merging a snapshot into an origin that cannot be closed, for\n"
"example a root filesystem, is deferred until the next time the origin\n"
"volume is activated. When merging starts, the resulting LV will have the\n"
"origin's name, minor number and UUID. While the merge is in progress,\n"
"reads or writes to the origin appear as being directed to the snapshot\n"
"being merged. When the merge finishes, the merged snapshot is removed.\n"
"Multiple snapshots may be specified on the command line or a @tag may be\n"
"used to specify multiple snapshots be merged to their respective origin.\n")
arg(mergethin_ARG, '\0', "mergethin", 0, 0, 0,
"Merge thin LV into its origin LV.\n"
"The origin thin LV takes the content of the thin snapshot,\n"
"and the thin snapshot LV is removed.\n")
arg(mergedconfig_ARG, '\0', "mergedconfig", 0, 0, 0,
"When the command is run with --config\n"
"and/or --commandprofile (or using LVM_COMMAND_PROFILE\n"
"environment variable), --profile, or --metadataprofile,\n"
"merge all the contents of the \"config cascade\" before displaying it.\n"
"Without merging, only the configuration at the front of the\n"
"cascade is displayed.\n"
"See lvm.conf(5) for more information about config.\n")
arg(metadatacopies_ARG, '\0', "metadatacopies", metadatacopies_VAL, 0, 0,
"For commands starting with 'pv', this is an alias for --pvmetadatacopies.\n"
"For commands starting with 'vg', this is an alias for --vgmetadatacopies.\n")
arg(metadataignore_ARG, '\0', "metadataignore", bool_VAL, 0, 0,
"Specifies the metadataignore property of a PV.\n"
"If yes, metadata areas on the PV are ignored, and lvm will\n"
"not store metadata in the metadata areas of the PV.\n"
"If no, lvm will store metadata on the PV.\n")
arg(metadataprofile_ARG, '\0', "metadataprofile", string_VAL, 0, 0,
"The metadata profile to use for command configuration.\n"
"See lvm.conf(5) for more information about profiles.\n")
arg(metadatasize_ARG, '\0', "metadatasize", sizemb_VAL, 0, 0,
"The approximate amount of space used for each VG metadata area.\n"
"The size may be rounded.\n")
arg(minor_ARG, '\0', "minor", number_VAL, ARG_GROUPABLE, 0,
"A block device minor number.\n")
arg(minrecoveryrate_ARG, '\0', "minrecoveryrate", sizekb_VAL, 0, 0,
"Sets the minimum recovery rate for a RAID LV. The rate value\n"
"is an amount of data per second for each device in the array.\n"
"Setting the rate to 0 means it will be unbounded.\n")
arg(mirrorlog_ARG, '\0', "mirrorlog", mirrorlog_VAL, 0, 0,
"Specifies the type of mirror log for LVs with the \"mirror\" type\n"
"(does not apply to the \"raid1\" type.)\n"
"\\fBdisk\\fP is a persistent log and requires a small amount of\n"
"storage space, usually on a separate device from the data being mirrored.\n"
"\\fBcore\\fP is not persistent; the log is kept only in memory.\n"
"In this case, the mirror must be synchronized (by copying LV data from\n"
"the first device to others) each time the LV is activated, e.g. after reboot.\n"
"\\fBmirrored\\fP is a persistent log that is itself mirrored.\n")
arg(mirrorsonly_ARG, '\0', "mirrorsonly", 0, 0, 0, NULL)
arg(mknodes_ARG, '\0', "mknodes", 0, 0, 0,
"Also checks the LVM special files in /dev that are needed for active\n"
"LVs and creates any missing ones and removes unused ones.\n")
arg(monitor_ARG, '\0', "monitor", bool_VAL, 0, 0,
"Start (yes) or stop (no) monitoring an LV with dmeventd.\n"
"dmeventd monitors kernel events for an LV, and performs\n"
"automated maintenance for the LV in reponse to specific events.\n"
"See dmeventd(8) for more information.\n")
arg(nameprefixes_ARG, '\0', "nameprefixes", 0, 0, 0,
"Add an \"LVM2_\" prefix plus the field name to the output. Useful\n"
"with --noheadings to produce a list of field=value pairs that can\n"
"be used to set environment variables (for example, in udev rules).\n")
arg(noheadings_ARG, '\0', "noheadings", 0, 0, 0,
"Suppress the headings line that is normally the first line of output.\n"
"Useful if grepping the output.\n")
arg(nohistory_ARG, '\0', "nohistory", 0, 0, 0,
"Do not record history of LVs being removed.\n"
"This has no effect unless the configuration setting\n"
"metadata/record_lvs_history is enabled.\n")
arg(nolocking_ARG, '\0', "nolocking", 0, 0, 0,
"Disable locking.\n")
arg(norestorefile_ARG, '\0', "norestorefile", 0, 0, 0,
"In conjunction with --uuid, this allows a uuid to be specified\n"
"without also requiring that a backup of the metadata be provided.\n")
arg(nosuffix_ARG, '\0', "nosuffix", 0, 0, 0,
"Suppress the suffix on output sizes. Use with --units\n"
"(except h and H) if processing the output.\n")
arg(nosync_ARG, '\0', "nosync", 0, 0, 0,
"Causes the creation of mirror, raid1, raid4, raid5 and raid10 to skip the\n"
"initial synchronization. In case of mirror, raid1 and raid10, any data\n"
"written afterwards will be mirrored, but the original contents will not be\n"
"copied. In case of raid4 and raid5, no parity blocks will be written,\n"
"though any data written afterwards will cause parity blocks to be stored.\n"
"This is useful for skipping a potentially long and resource intensive initial\n"
"sync of an empty mirror/raid1/raid4/raid5 and raid10 LV.\n"
"This option is not valid for raid6, because raid6 relies on proper parity\n"
"(P and Q Syndromes) being created during initial synchronization in order\n"
"to reconstruct proper user date in case of device failures.\n"
"raid0 and raid0_meta do not provide any data copies or parity support\n"
"and thus do not support initial synchronization.\n")
arg(notifydbus_ARG, '\0', "notifydbus", 0, 0, 0,
"Send a notification to D-Bus. The command will exit with an error\n"
"if LVM is not built with support for D-Bus notification, or if the\n"
"notify_dbus config setting is disabled.\n")
arg(noudevsync_ARG, '\0', "noudevsync", 0, 0, 0,
"Disables udev synchronisation. The process will not wait for notification\n"
"from udev. It will continue irrespective of any possible udev processing\n"
"in the background. Only use this if udev is not running or has rules that\n"
"ignore the devices LVM creates.\n)
arg(originname_ARG, '\0', "originname", lv_VAL, 0, 0, NULL)
arg(physicalvolumesize_ARG, '\0', "setphysicalvolumesize", sizemb_VAL, 0, 0, NULL)
arg(poll_ARG, '\0', "poll", bool_VAL, 0, 0, NULL)
arg(polloperation_ARG, '\0', "polloperation", polloperation_VAL, 0, 0, NULL)
arg(pooldatasize_ARG, '\0', "pooldatasize", sizemb_VAL, 0, 0, NULL)
arg(poolmetadata_ARG, '\0', "poolmetadata", lv_VAL, 0, 0, NULL)
arg(poolmetadatasize_ARG, '\0', "poolmetadatasize", sizemb_VAL, 0, 0, NULL)
arg(poolmetadataspare_ARG, '\0', "poolmetadataspare", bool_VAL, 0, 0, NULL)
arg(profile_ARG, '\0', "profile", string_VAL, 0, 0,
"An alias for --commandprofile or --metadataprofile, depending\n"
"on the command.\n")
arg(pvmetadatacopies_ARG, '\0', "pvmetadatacopies", pvmetadatacopies_VAL, 0, 0, NULL)
arg(raidrebuild_ARG, '\0', "raidrebuild", pv_VAL, ARG_GROUPABLE, 0, NULL)
arg(raidmaxrecoveryrate_ARG, '\0', "raidmaxrecoveryrate", sizekb_VAL, 0, 0, NULL)
arg(raidminrecoveryrate_ARG, '\0', "raidminrecoveryrate", sizekb_VAL, 0, 0, NULL)
arg(raidsyncaction_ARG, '\0', "raidsyncaction", syncaction_VAL, 0, 0, NULL)
arg(raidwritebehind_ARG, '\0', "raidwritebehind", number_VAL, 0, 0, NULL)
arg(raidwritemostly_ARG, '\0', "raidwritemostly", writemostly_VAL, ARG_GROUPABLE, 0, NULL)
arg(readonly_ARG, '\0', "readonly", 0, 0, 0, NULL)
arg(refresh_ARG, '\0', "refresh", 0, 0, 0, NULL)
arg(removemissing_ARG, '\0', "removemissing", 0, 0, 0, NULL)
arg(rebuild_ARG, '\0', "rebuild", pv_VAL, ARG_GROUPABLE, 0, NULL)
arg(repair_ARG, '\0', "repair", 0, 0, 0, NULL)
arg(replace_ARG, '\0', "replace", pv_VAL, ARG_GROUPABLE, 0, NULL)
arg(reportformat_ARG, '\0', "reportformat", reportformat_VAL, 0, 0, NULL)
arg(restorefile_ARG, '\0', "restorefile", string_VAL, 0, 0, NULL)
arg(restoremissing_ARG, '\0', "restoremissing", 0, 0, 0, NULL)
arg(resync_ARG, '\0', "resync", 0, 0, 0, NULL)
arg(rows_ARG, '\0', "rows", 0, 0, 0, NULL)
arg(segments_ARG, '\0', "segments", 0, 0, 0, NULL)
arg(separator_ARG, '\0', "separator", string_VAL, 0, 0, NULL)
arg(shared_ARG, '\0', "shared", 0, 0, 0, NULL)
arg(sinceversion_ARG, '\0', "sinceversion", string_VAL, 0, 0, NULL)
arg(split_ARG, '\0', "split", 0, 0, 0, NULL)
arg(splitcache_ARG, '\0', "splitcache", 0, 0, 0, NULL)
arg(splitmirrors_ARG, '\0', "splitmirrors", number_VAL, 0, 0, NULL)
arg(splitsnapshot_ARG, '\0', "splitsnapshot", 0, 0, 0, NULL)
arg(showdeprecated_ARG, '\0', "showdeprecated", 0, 0, 0, NULL)
arg(showunsupported_ARG, '\0', "showunsupported", 0, 0, 0, NULL)
arg(startpoll_ARG, '\0', "startpoll", 0, 0, 0, NULL)
arg(stripes_long_ARG, '\0', "stripes", number_VAL, 0, 0, NULL)
arg(swapmetadata_ARG, '\0', "swapmetadata", 0, 0, 0, NULL)
arg(syncaction_ARG, '\0', "syncaction", syncaction_VAL, 0, 0, NULL)
arg(sysinit_ARG, '\0', "sysinit", 0, 0, 0, NULL)
arg(systemid_ARG, '\0', "systemid", string_VAL, 0, 0, NULL)
arg(thinpool_ARG, '\0', "thinpool", lv_VAL, 0, 0, NULL)
arg(trackchanges_ARG, '\0', "trackchanges", 0, 0, 0, NULL)
arg(trustcache_ARG, '\0', "trustcache", 0, 0, 0, NULL)
arg(type_ARG, '\0', "type", segtype_VAL, 0, 0, NULL)
arg(unbuffered_ARG, '\0', "unbuffered", 0, 0, 0, NULL)
arg(uncache_ARG, '\0', "uncache", 0, 0, 0, NULL)
arg(cachepolicy_ARG, '\0', "cachepolicy", string_VAL, 0, 0, NULL)
arg(cachesettings_ARG, '\0', "cachesettings", string_VAL, ARG_GROUPABLE, 0, NULL)
arg(unconfigured_ARG, '\0', "unconfigured", 0, 0, 0, NULL)
arg(units_ARG, '\0', "units", units_VAL, 0, 0, NULL)
arg(unquoted_ARG, '\0', "unquoted", 0, 0, 0, NULL)
arg(usepolicies_ARG, '\0', "usepolicies", 0, 0, 0, NULL)
arg(validate_ARG, '\0', "validate", 0, 0, 0, NULL)
arg(version_ARG, '\0', "version", 0, 0, 0, NULL)
arg(vgmetadatacopies_ARG, '\0', "vgmetadatacopies", vgmetadatacopies_VAL, 0, 0, NULL)
arg(virtualoriginsize_ARG, '\0', "virtualoriginsize", sizemb_VAL, 0, 0, NULL)
arg(withsummary_ARG, '\0', "withsummary", 0, 0, 0, NULL)
arg(withcomments_ARG, '\0', "withcomments", 0, 0, 0, NULL)
arg(withspaces_ARG, '\0', "withspaces", 0, 0, 0, NULL)
arg(withversions_ARG, '\0', "withversions", 0, 0, 0, NULL)
arg(writebehind_ARG, '\0', "writebehind", number_VAL, 0, 0, NULL)
arg(writemostly_ARG, '\0', "writemostly", writemostly_VAL, ARG_GROUPABLE, 0, NULL)
arg(ARG_UNUSED, '-', "", 0, 0, 0) /* place holder for unused 0 value */
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", configreport_VAL, ARG_GROUPABLE, 1)
arg(configtype_ARG, '\0', "typeconfig", configtype_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(mergemirrors_ARG, '\0', "mergemirrors", 0, 0, 0)
arg(mergesnapshot_ARG, '\0', "mergesnapshot", 0, 0, 0)
arg(mergethin_ARG, '\0', "mergethin", 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", polloperation_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", pvmetadatacopies_VAL, 0, 0)
arg(raidrebuild_ARG, '\0', "raidrebuild", pv_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", syncaction_VAL, 0, 0)
arg(raidwritebehind_ARG, '\0', "raidwritebehind", number_VAL, 0, 0)
arg(raidwritemostly_ARG, '\0', "raidwritemostly", writemostly_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", reportformat_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(startpoll_ARG, '\0', "startpoll", 0, 0, 0)
arg(stripes_long_ARG, '\0', "stripes", number_VAL, 0, 0)
arg(swapmetadata_ARG, '\0', "swapmetadata", 0, 0, 0)
arg(syncaction_ARG, '\0', "syncaction", syncaction_VAL, 0, 0)
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", vgmetadatacopies_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", writemostly_VAL, ARG_GROUPABLE, 0)
/* Allow some variations */
arg(allocation_ARG, '\0', "allocation", bool_VAL, 0, 0, NULL)
arg(available_ARG, '\0', "available", activation_VAL, 0, 0, NULL)
arg(resizable_ARG, '\0', "resizable", bool_VAL, 0, 0, NULL)
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)
/*
* ... and now the short args.
*/
arg(activate_ARG, 'a', "activate", activation_VAL, 0, 0, NULL)
arg(all_ARG, 'a', "all", 0, 0, 0, NULL)
arg(autobackup_ARG, 'A', "autobackup", bool_VAL, 0, 0, NULL)
arg(activevolumegroups_ARG, 'A', "activevolumegroups", 0, 0, 0, NULL)
arg(background_ARG, 'b', "background", 0, 0, 0, NULL)
arg(backgroundfork_ARG, 'b', "background", 0, 0, 0, NULL)
arg(basevgname_ARG, 'n', "basevgname", string_VAL, 0, 0, NULL)
arg(blockdevice_ARG, 'b', "blockdevice", 0, 0, 0, NULL)
arg(chunksize_ARG, 'c', "chunksize", sizekb_VAL, 0, 0, NULL)
arg(clustered_ARG, 'c', "clustered", bool_VAL, 0, 0, NULL)
arg(colon_ARG, 'c', "colon", 0, 0, 0, NULL)
arg(columns_ARG, 'C', "columns", 0, 0, 0, NULL)
arg(contiguous_ARG, 'C', "contiguous", bool_VAL, 0, 0, NULL)
arg(debug_ARG, 'd', "debug", 0, ARG_COUNTABLE, 0, NULL)
arg(exported_ARG, 'e', "exported", 0, 0, 0, NULL)
arg(physicalextent_ARG, 'E', "physicalextent", 0, 0, 0, NULL)
arg(file_ARG, 'f', "file", string_VAL, 0, 0, NULL)
arg(force_ARG, 'f', "force", 0, ARG_COUNTABLE, 0, NULL)
arg(full_ARG, 'f', "full", 0, 0, 0, NULL)
arg(help_ARG, 'h', "help", 0, ARG_COUNTABLE, 0, NULL)
arg(cache_ARG, 'H', "cache", 0, 0, 0, NULL)
arg(history_ARG, 'H', "history", 0, 0, 0, NULL)
arg(help2_ARG, '?', "", 0, 0, 0, NULL)
arg(import_ARG, 'i', "import", 0, 0, 0, NULL)
arg(interval_ARG, 'i', "interval", number_VAL, 0, 0, NULL)
arg(iop_version_ARG, 'i', "iop_version", 0, 0, 0, NULL)
arg(stripes_ARG, 'i', "stripes", number_VAL, 0, 0, NULL)
arg(stripesize_ARG, 'I', "stripesize", sizekb_VAL, 0, 0, NULL)
arg(logicalvolume_ARG, 'l', "logicalvolume", number_VAL, 0, 0, NULL)
arg(maxlogicalvolumes_ARG, 'l', "maxlogicalvolumes", number_VAL, 0, 0, NULL)
arg(extents_ARG, 'l', "extents", numsignedper_VAL, 0, 0, NULL)
arg(list_ARG, 'l', "list", 0, 0, 0, NULL)
arg(lvmpartition_ARG, 'l', "lvmpartition", 0, 0, 0, NULL)
arg(size_ARG, 'L', "size", sizemb_VAL, 0, 0, NULL)
arg(persistent_ARG, 'M', "persistent", bool_VAL, 0, 0, NULL)
arg(major_ARG, 'j', "major", number_VAL, ARG_GROUPABLE, 0, NULL)
arg(setactivationskip_ARG, 'k', "setactivationskip", bool_VAL, 0, 0, NULL)
arg(ignoreactivationskip_ARG, 'K', "ignoreactivationskip", 0, 0, 0, NULL)
arg(maps_ARG, 'm', "maps", 0, 0, 0, NULL)
arg(mirrors_ARG, 'm', "mirrors", numsigned_VAL, 0, 0, NULL)
arg(metadatatype_ARG, 'M', "metadatatype", metadatatype_VAL, 0, 0, NULL)
arg(name_ARG, 'n', "name", string_VAL, 0, 0, NULL)
arg(nofsck_ARG, 'n', "nofsck", 0, 0, 0, NULL)
arg(novolumegroup_ARG, 'n', "novolumegroup", 0, 0, 0, NULL)
arg(oldpath_ARG, 'n', "oldpath", 0, 0, 0, NULL)
arg(options_ARG, 'o', "options", string_VAL, ARG_GROUPABLE, 0, NULL)
arg(sort_ARG, 'O', "sort", string_VAL, ARG_GROUPABLE, 0, NULL)
arg(maxphysicalvolumes_ARG, 'p', "maxphysicalvolumes", uint32_VAL, 0, 0, NULL)
arg(permission_ARG, 'p', "permission", permission_VAL, 0, 0, NULL)
arg(partial_ARG, 'P', "partial", 0, 0, 0, NULL)
arg(physicalvolume_ARG, 'P', "physicalvolume", 0, 0, 0, NULL)
arg(quiet_ARG, 'q', "quiet", 0, ARG_COUNTABLE, 0, NULL)
arg(readahead_ARG, 'r', "readahead", readahead_VAL, 0, 0, NULL)
arg(resizefs_ARG, 'r', "resizefs", 0, 0, 0, NULL)
arg(reset_ARG, 'R', "reset", 0, 0, 0, NULL)
arg(regionsize_ARG, 'R', "regionsize", sizemb_VAL, 0, 0, NULL)
arg(physicalextentsize_ARG, 's', "physicalextentsize", sizemb_VAL, 0, 0, NULL)
arg(snapshot_ARG, 's', "snapshot", 0, 0, 0, NULL)
arg(short_ARG, 's', "short", 0, 0, 0, NULL)
arg(stdin_ARG, 's', "stdin", 0, 0, 0, NULL)
arg(select_ARG, 'S', "select", string_VAL, ARG_GROUPABLE, 0, NULL)
arg(test_ARG, 't', "test", 0, 0, 0, NULL)
arg(thin_ARG, 'T', "thin", 0, 0, 0, NULL)
arg(uuid_ARG, 'u', "uuid", 0, 0, 0, NULL)
arg(uuidstr_ARG, 'u', "uuid", string_VAL, 0, 0, NULL)
arg(uuidlist_ARG, 'U', "uuidlist", 0, 0, 0, NULL)
arg(verbose_ARG, 'v', "verbose", 0, ARG_COUNTABLE, 0, NULL)
arg(volumegroup_ARG, 'V', "volumegroup", 0, 0, 0, NULL)
arg(virtualsize_ARG, 'V', "virtualsize", sizemb_VAL, 0, 0, NULL)
arg(wipesignatures_ARG, 'W', "wipesignatures", bool_VAL, 0, 0, NULL)
arg(allocatable_ARG, 'x', "allocatable", bool_VAL, 0, 0, NULL)
arg(resizeable_ARG, 'x', "resizeable", bool_VAL, 0, 0, NULL)
arg(yes_ARG, 'y', "yes", 0, 0, 0, NULL)
arg(zero_ARG, 'Z', "zero", bool_VAL, 0, 0, NULL)
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)
/* this should always be last */
arg(ARG_COUNT, '-', "", 0, 0, 0, NULL)
arg(ARG_COUNT, '-', "", 0, 0, 0)
/* *INDENT-ON* */

View File

@@ -264,7 +264,7 @@ RULE: --alloc --discards --zero --cachemode --cachepolicy --cachesettings not lv
# like above, it was previouly allowed in combination.
lvchange --resync VG|LV_raid_mirror|Tag|Select ...
OO: --activate Active, OO_LVCHANGE
OO: --activate Activate, OO_LVCHANGE
ID: lvchange_resync
DESC: Resyncronize a mirror or raid LV.
RULE: all not lv_is_pvmove lv_is_locked
@@ -517,15 +517,6 @@ FLAGS: SECONDARY_SYNTAX
---
lvconvert --mergethin LV_thin ...
OO: OO_LVCONVERT
ID: lvconvert_merge_thin
DESC: Merge thin LV into its origin LV.
RULE: all not lv_is_locked lv_is_pvmove lv_is_merging_origin lv_is_virtual_origin lv_is_external_origin lv_is_merging_cow
RULE: all and lv_is_visible
---
# lvconvert snapshot-related utilities
# Create a new command set for these and migrate them out of lvconvert?
@@ -641,7 +632,12 @@ OO_LVCREATE_CACHE: --cachemode CacheMode, --cachepolicy String, --cachesettings
OO_LVCREATE_POOL: --poolmetadatasize SizeMB, --poolmetadataspare Bool, --chunksize SizeKB
OO_LVCREATE_THIN: --discards Discards, --errorwhenfull Bool
# FIXME: it's silly to include --mirrors 0 here. Fix the tests to not use
# --mirrors 0 in commands that do not accept any non-zero --mirrors
# option, and then remove this. Accepting an option, only so that the
# option's value can invalidate the use of the option is not advisable.
OO_LVCREATE_THIN: --discards Discards, --errorwhenfull Bool, --mirrors 0
OO_LVCREATE_RAID: --mirrors SNumber, --stripes Number, --stripesize SizeKB,
--regionsize SizeMB, --minrecoveryrate SizeKB, --maxrecoveryrate SizeKB
@@ -664,10 +660,15 @@ FLAGS: SECONDARY_SYNTAX
---
# FIXME: consider removing the --mirrors 0, --stripes 1 options
# and just reporting an error (or ignoring) if mirrors or stripes
# options are given. Same reasoning as above: it's confusing to
# advertise an option when the only value accepted for the option
# makes the option do nothing.
lvcreate --type linear --size SizeMB VG
OO: OO_LVCREATE
OO: --mirrors 0, --stripes 1, OO_LVCREATE
OP: PV ...
IO: --mirrors 0, --stripes 1
ID: lvcreate_linear
DESC: Create a linear LV.
FLAGS: SECONDARY_SYNTAX
@@ -677,9 +678,8 @@ FLAGS: SECONDARY_SYNTAX
# to people to not see the name parameter.
lvcreate --size SizeMB VG
OO: --type linear, OO_LVCREATE
OO: --type linear, --mirrors 0, --stripes 1, OO_LVCREATE
OP: PV ...
IO: --mirrors 0, --stripes 1
ID: lvcreate_linear
DESC: Create a linear LV (default --type linear).
DESC: When --name is omitted, the name is generated.
@@ -769,7 +769,6 @@ lvcreate --type thin-pool --size SizeMB VG
OO: --thinpool LV_new, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE,
--stripes Number, --stripesize SizeKB
OP: PV ...
IO: --mirrors 0
ID: lvcreate_thinpool
DESC: Create a thin pool.
@@ -778,7 +777,6 @@ lvcreate --thin --size SizeMB VG
OO: --type thin-pool, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE,
--stripes Number, --stripesize SizeKB
OP: PV ...
IO: --mirrors 0
ID: lvcreate_thinpool
DESC: Create a thin pool (variant, infers --type thin-pool).
FLAGS: SECONDARY_SYNTAX
@@ -788,7 +786,6 @@ lvcreate --size SizeMB --thinpool LV_new VG
OO: --thin, --type thin-pool, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE,
--stripes Number, --stripesize SizeKB
OP: PV ...
IO: --mirrors 0
ID: lvcreate_thinpool
DESC: Create a thin pool named by the --thinpool arg
DESC: (variant, infers --type thin-pool).
@@ -820,14 +817,12 @@ FLAGS: SECONDARY_SYNTAX
lvcreate --type thin --virtualsize SizeMB --thinpool LV_thinpool VG
OO: --thin, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_vol
DESC: Create a thin LV in a thin pool.
# alternate form of lvcreate --type thin
lvcreate --type thin --virtualsize SizeMB LV_thinpool
OO: --thin, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_vol
DESC: Create a thin LV in a thin pool named in the first arg
DESC: (variant, also see --thinpool for naming pool).
@@ -839,7 +834,6 @@ FLAGS: SECONDARY_SYNTAX
# alternate form of lvcreate --type thin
lvcreate --virtualsize SizeMB --thinpool LV_thinpool VG
OO: --type thin, --thin, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_vol
DESC: Create a thin LV in a thin pool (variant, infers --type thin).
FLAGS: SECONDARY_SYNTAX
@@ -847,7 +841,6 @@ FLAGS: SECONDARY_SYNTAX
# alternate form of lvcreate --type thin
lvcreate --virtualsize SizeMB LV_thinpool
OO: --type thin, --thin, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_vol
DESC: Create a thin LV in the thin pool named in the first arg
DESC: (variant, infers --type thin, also see --thinpool for
@@ -858,14 +851,12 @@ FLAGS: SECONDARY_SYNTAX
lvcreate --type thin LV_thin
OO: --thin, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_snapshot
DESC: Create a thin LV that is a snapshot of an existing thin LV.
# alternate form of lvcreate --type thin
lvcreate --thin LV_thin
OO: --type thin, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_snapshot
DESC: Create a thin LV that is a snapshot of an existing thin LV
DESC: (infers --type thin).
@@ -874,27 +865,33 @@ FLAGS: SECONDARY_SYNTAX
# alternate form of lvcreate --type thin
lvcreate --snapshot LV_thin
OO: --type thin, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_snapshot
DESC: Create a thin LV that is a snapshot of an existing thin LV
DESC: (infers --type thin).
lvcreate --type thin --thinpool LV_thinpool LV
OO: --thin, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_snapshot_of_external
DESC: Create a thin LV that is a snapshot of an external origin LV.
# alternate form of lvcreate --type thin --thinpool LV_thinpool LV
lvcreate --snapshot --thinpool LV_thinpool LV
OO: --type thin, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_snapshot_of_external
DESC: Create a thin LV that is a snapshot of an external origin LV
DESC: (infers --type thin).
---
lvconvert --mergethin LV_thin ...
OO: OO_LVCONVERT
ID: lvconvert_merge_thin
DESC: Merge thin LV into its origin LV.
RULE: all not lv_is_locked lv_is_pvmove lv_is_merging_origin lv_is_virtual_origin lv_is_external_origin lv_is_merging_cow
RULE: all and lv_is_visible
---
# stripes option is not intuitive when creating a thin LV,
# but here it applies to creating the new thin pool that
# is used for the thin LV
@@ -915,7 +912,6 @@ lvcreate --type thin --virtualsize SizeMB --size SizeMB --thinpool LV_new
OO: --thin, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE,
--stripes Number, --stripesize SizeKB
OP: PV ...
IO: --mirrors 0
ID: lvcreate_thin_vol_and_thinpool
DESC: Create a thin LV, first creating a thin pool for it,
DESC: where the new thin pool is named by the --thinpool arg.
@@ -925,7 +921,6 @@ lvcreate --thin --virtualsize SizeMB --size SizeMB --thinpool LV_new
OO: --type thin, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE,
--stripes Number, --stripesize SizeKB
OP: PV ...
IO: --mirrors 0
ID: lvcreate_thin_vol_and_thinpool
DESC: Create a thin LV, first creating a thin pool for it,
DESC: where the new thin pool is named by the --thinpool arg
@@ -937,7 +932,6 @@ lvcreate --type thin --virtualsize SizeMB --size SizeMB LV_new|VG
OO: --thin, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE,
--stripes Number, --stripesize SizeKB
OP: PV ...
IO: --mirrors 0
ID: lvcreate_thin_vol_and_thinpool
DESC: Create a thin LV, first creating a thin pool for it,
DESC: where the new thin pool is named in the first arg,
@@ -950,7 +944,6 @@ lvcreate --thin --virtualsize SizeMB --size SizeMB LV_new|VG
OO: --type thin, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE,
--stripes Number, --stripesize SizeKB
OP: PV ...
IO: --mirrors 0
ID: lvcreate_thin_vol_and_thinpool
DESC: Create a thin LV, first creating a thin pool for it,
DESC: where the new thin pool is named in the first arg,
@@ -964,7 +957,6 @@ lvcreate --size SizeMB --virtualsize SizeMB VG
OO: --type thin, --type snapshot, --thin, --snapshot, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE,
--stripes Number, --stripesize SizeKB
OP: PV ...
IO: --mirrors 0
ID: lvcreate_thin_vol_with_thinpool_or_sparse_snapshot
DESC: Create a thin LV, first creating a thin pool for it
DESC: (infers --type thin).
@@ -1335,7 +1327,7 @@ OO_VGCHANGE: --autobackup Bool, --ignoremonitoring, --ignoreskippedcluster,
# because it can function as a required opt.
OO_VGCHANGE_META: --addtag Tag, --deltag Tag,
--logicalvolume Number, --maxphysicalvolumes Uint32, --alloc Alloc, --uuid,
--logicalvolume Number, --maxphysicalvolumes Number, --alloc Alloc, --uuid,
--clustered Bool, --pvmetadatacopies MetadataCopiesPV, --vgmetadatacopies MetadataCopiesVG,
--physicalextentsize SizeMB, --resizeable Bool, --systemid String, --locktype LockType,
--profile String, --detachprofile, --metadataprofile String
@@ -1402,7 +1394,7 @@ ID: vgconvert_general
vgcreate VG_new PV ...
OO: --addtag Tag, --alloc Alloc, --autobackup Bool, --clustered Bool, --maxlogicalvolumes Number,
--maxphysicalvolumes Uint32, --metadataprofile String, --metadatatype MetadataType,
--maxphysicalvolumes Number, --metadataprofile String, --metadatatype MetadataType,
--physicalextentsize SizeMB, --force, --zero Bool, --labelsector Number,
--metadatasize SizeMB, --pvmetadatacopies MetadataCopiesPV, --vgmetadatacopies MetadataCopiesVG,
--reportformat ReportFmt, --dataalignment SizeKB, --dataalignmentoffset SizeKB,
@@ -1535,7 +1527,7 @@ OO_VGSPLIT: --autobackup Bool
# used only when the destination VG is new
OO_VGSPLIT_NEW: --alloc Alloc, --clustered Bool,
--maxlogicalvolumes Number, --maxphysicalvolumes Uint32,
--maxlogicalvolumes Number, --maxphysicalvolumes Number,
--metadatatype MetadataType, --vgmetadatacopies MetadataCopiesVG
vgsplit VG VG PV ...

View File

@@ -51,9 +51,8 @@ struct command_name {
*/
/* arg_def flags */
#define ARG_DEF_FLAG_NEW_VG 1 << 0
#define ARG_DEF_FLAG_NEW_LV 1 << 1
#define ARG_DEF_FLAG_MAY_REPEAT 1 << 2
#define ARG_DEF_FLAG_NEW 1 << 0
#define ARG_DEF_FLAG_MAY_REPEAT 1 << 1
static inline int val_bit_is_set(uint64_t val_bits, int val_enum)
{
@@ -145,7 +144,6 @@ struct cmd_rule {
#define CMD_OO_ARGS 150 /* optional opt args */
#define CMD_RP_ARGS 8 /* required positional args */
#define CMD_OP_ARGS 8 /* optional positional args */
#define CMD_IO_ARGS 8 /* ignore opt args */
#define CMD_MAX_RULES 32 /* max number of rules per command def */
/*
@@ -187,16 +185,12 @@ struct command {
/* optional positional args */
struct pos_arg optional_pos_args[CMD_OP_ARGS];
/* unused opt args, are ignored instead of causing an error */
struct opt_arg ignore_opt_args[CMD_IO_ARGS];
struct cmd_rule rules[CMD_MAX_RULES];
int ro_count;
int oo_count;
int rp_count;
int op_count;
int io_count;
/* used for processing current position */
int pos_count;

View File

@@ -34,7 +34,6 @@ int size_kb_arg(struct cmd_context *cmd, struct arg_values *av) { return 0; }
int size_mb_arg(struct cmd_context *cmd, struct arg_values *av) { return 0; }
int size_mb_arg_with_percent(struct cmd_context *cmd, struct arg_values *av) { return 0; }
int int_arg(struct cmd_context *cmd, struct arg_values *av) { return 0; }
int uint32_arg(struct cmd_context *cmd, struct arg_values *av) { return 0; }
int int_arg_with_sign(struct cmd_context *cmd, struct arg_values *av) { return 0; }
int int_arg_with_sign_and_percent(struct cmd_context *cmd, struct arg_values *av) { return 0; }
int major_arg(struct cmd_context *cmd, struct arg_values *av) { return 0; }
@@ -68,7 +67,6 @@ struct opt_name {
int val_enum; /* xyz_VAL when --foo takes a val like "--foo xyz" */
uint32_t unused1;
uint32_t unused2;
const char *desc;
};
/* also see val_props in tools.h and vals.h */
@@ -105,7 +103,7 @@ enum {
/* create foo_ARG enums for --option's */
enum {
#define arg(a, b, c, d, e, f, g) a ,
#define arg(a, b, c, d, e, f) a ,
#include "args.h"
#undef arg
};
@@ -137,7 +135,7 @@ static struct val_name val_names[VAL_COUNT + 1] = {
/* create table of option names, e.g. --foo, and corresponding enum from args.h */
static struct opt_name opt_names[ARG_COUNT + 1] = {
#define arg(a, b, c, d, e, f, g) { # a, a, b, "", "--" c, d, e, f, g },
#define arg(a, b, c, d, e, f) { # a, a, b, "", "--" c, d, e, f },
#include "args.h"
#undef arg
};
@@ -181,18 +179,11 @@ static struct cmd_name cmd_names[MAX_CMD_NAMES] = {
#undef xx
};
/* array of pointers into opt_names[] that is sorted alphabetically (by long opt name) */
static struct opt_name *opt_names_alpha[ARG_COUNT + 1];
#define MAX_LINE 1024
#define MAX_LINE_ARGC 256
#define DESC_LINE 256
#define REQUIRED 1 /* required option */
#define OPTIONAL 0 /* optional option */
#define IGNORE -1 /* ignore option */
#define REQUIRED 1
#define OPTIONAL 0
struct oo_line {
char *name;
@@ -552,13 +543,6 @@ static int is_oo_line(char *str)
return 0;
}
static int is_io_line(char *str)
{
if (!strncmp(str, "IO:", 3))
return 1;
return 0;
}
static int is_op_line(char *str)
{
if (!strncmp(str, "OP:", 3))
@@ -624,12 +608,8 @@ static void set_pos_def(struct command *cmd, char *str, struct arg_def *def)
if ((val_enum == lv_VAL) && strstr(name, "_"))
def->lvt_bits = lv_to_bits(name);
if (strstr(name, "_new")) {
if (val_enum == lv_VAL)
def->flags |= ARG_DEF_FLAG_NEW_LV;
else if (val_enum == vg_VAL)
def->flags |= ARG_DEF_FLAG_NEW_VG;
}
if (strstr(name, "_new"))
def->flags |= ARG_DEF_FLAG_NEW;
}
}
@@ -681,12 +661,9 @@ static void set_opt_def(struct command *cmd, char *str, struct arg_def *def)
def->lvt_bits = lv_to_bits(name);
}
if (strstr(name, "_new")) {
if (val_enum == lv_VAL)
def->flags |= ARG_DEF_FLAG_NEW_LV;
else if (val_enum == vg_VAL)
def->flags |= ARG_DEF_FLAG_NEW_VG;
if ((val_enum == vg_VAL) || (val_enum == lv_VAL) || (val_enum == pv_VAL)) {
if (strstr(name, "_new"))
def->flags |= ARG_DEF_FLAG_NEW;
}
}
}
@@ -811,14 +788,10 @@ static void add_opt_arg(struct command *cmd, char *str, int *takes_arg, int requ
opt = opt_str_to_num(str);
skip:
if (required > 0)
if (required)
cmd->required_opt_args[cmd->ro_count++].opt = opt;
else if (!required)
cmd->optional_opt_args[cmd->oo_count++].opt = opt;
else if (required < 0)
cmd->ignore_opt_args[cmd->io_count++].opt = opt;
else
exit(1);
cmd->optional_opt_args[cmd->oo_count++].opt = opt;
*takes_arg = opt_names[opt].val_enum ? 1 : 0;
}
@@ -841,14 +814,10 @@ static void update_prev_opt_arg(struct command *cmd, char *str, int required)
set_opt_def(cmd, str, &def);
if (required > 0)
if (required)
cmd->required_opt_args[cmd->ro_count-1].def = def;
else if (!required)
cmd->optional_opt_args[cmd->oo_count-1].def = def;
else if (required < 0)
cmd->ignore_opt_args[cmd->io_count-1].def = def;
else
exit(1);
cmd->optional_opt_args[cmd->oo_count-1].def = def;
}
static void add_pos_arg(struct command *cmd, char *str, int required)
@@ -913,24 +882,6 @@ static void add_optional_opt_line(struct command *cmd, int argc, char *argv[])
}
}
static void add_ignore_opt_line(struct command *cmd, int argc, char *argv[])
{
int takes_arg;
int i;
for (i = 0; i < argc; i++) {
if (!i && !strncmp(argv[i], "IO:", 3))
continue;
if (is_opt_name(argv[i]))
add_opt_arg(cmd, argv[i], &takes_arg, IGNORE);
else if (takes_arg)
update_prev_opt_arg(cmd, argv[i], IGNORE);
else
printf("Can't parse argc %d argv %s prev %s\n",
i, argv[i], argv[i-1]);
}
}
/* process what follows OP:, which are optional pos args */
static void add_optional_pos_line(struct command *cmd, int argc, char *argv[])
@@ -1056,10 +1007,10 @@ static void print_def(struct arg_def *def, int usage)
}
}
if ((val_enum == vg_VAL) && (def->flags & ARG_DEF_FLAG_NEW_VG))
printf("_new");
if ((val_enum == lv_VAL) && (def->flags & ARG_DEF_FLAG_NEW_LV))
printf("_new");
if ((val_enum == pv_VAL) || (val_enum == vg_VAL) || (val_enum == lv_VAL)) {
if (def->flags & ARG_DEF_FLAG_NEW)
printf("_new");
}
}
}
@@ -1196,15 +1147,10 @@ static char *flags_to_str(int flags)
strcat(buf_flags, " | ");
strcat(buf_flags, "ARG_DEF_FLAG_MAY_REPEAT");
}
if (flags & ARG_DEF_FLAG_NEW_VG) {
if (flags & ARG_DEF_FLAG_NEW) {
if (buf_flags[0])
strcat(buf_flags, " | ");
strcat(buf_flags, "ARG_DEF_FLAG_NEW_VG");
}
if (flags & ARG_DEF_FLAG_NEW_LV) {
if (buf_flags[0])
strcat(buf_flags, " | ");
strcat(buf_flags, "ARG_DEF_FLAG_NEW_LV");
strcat(buf_flags, "ARG_DEF_FLAG_NEW");
}
return buf_flags;
@@ -1726,15 +1672,12 @@ static void print_def_man(struct arg_def *def, int usage)
printf("\\fP");
}
if ((val_enum == vg_VAL) && (def->flags & ARG_DEF_FLAG_NEW_VG)) {
printf("\\fI");
printf("_new");
printf("\\fP");
}
if ((val_enum == lv_VAL) && (def->flags & ARG_DEF_FLAG_NEW_LV)) {
printf("\\fI");
printf("_new");
printf("\\fP");
if ((val_enum == pv_VAL) || (val_enum == vg_VAL) || (val_enum == lv_VAL)) {
if (def->flags & ARG_DEF_FLAG_NEW) {
printf("\\fI");
printf("_new");
printf("\\fP");
}
}
}
}
@@ -2057,23 +2000,6 @@ void print_man_usage(struct command *cmd)
printf("\n");
}
/*
* common options listed in the usage section.
*
* For commands with only one variant, this is only
* the options which are common to all lvm commands
* (in lvm_all, see is_lvm_all_opt).
*
* For commands with more than one variant, this
* is the set of options common to all variants
* (in cname->common_options), (which obviously
* includes the options common to all lvm commands.)
*
* List ordering:
* options with short+long names, alphabetically,
* then options with only long names, alphabetically
*/
void print_man_usage_common(struct command *cmd)
{
struct cmd_name *cname;
@@ -2087,17 +2013,23 @@ void print_man_usage_common(struct command *cmd)
printf(".RS 4\n");
printf("[");
/* print those with short opts */
for (i = 0; i < ARG_COUNT; i++) {
opt_enum = opt_names_alpha[i]->opt_enum;
/*
* when there's more than one variant, options that
* are common to all commands with a common name.
*/
if (cname->variants < 2)
goto all;
/* print those with short opts */
for (opt_enum = 0; opt_enum < ARG_COUNT; opt_enum++) {
if (!cname->common_options[opt_enum])
continue;
if (!opt_names[opt_enum].short_opt)
continue;
if ((cname->variants < 2) && !is_lvm_all_opt(opt_enum))
if (is_lvm_all_opt(opt_enum))
continue;
if (sep) {
@@ -2125,16 +2057,14 @@ void print_man_usage_common(struct command *cmd)
}
/* print those without short opts */
for (i = 0; i < ARG_COUNT; i++) {
opt_enum = opt_names_alpha[i]->opt_enum;
for (opt_enum = 0; opt_enum < ARG_COUNT; opt_enum++) {
if (!cname->common_options[opt_enum])
continue;
if (opt_names[opt_enum].short_opt)
continue;
if ((cname->variants < 2) && !is_lvm_all_opt(opt_enum))
if (is_lvm_all_opt(opt_enum))
continue;
if (sep) {
@@ -2160,99 +2090,67 @@ void print_man_usage_common(struct command *cmd)
break;
}
}
all:
/* options that are common to all lvm commands */
/* those with short opts */
for (oo = 0; oo < lvm_all.oo_count; oo++) {
opt_enum = lvm_all.optional_opt_args[oo].opt;
if (!opt_names[opt_enum].short_opt)
continue;
if (sep) {
printf(",");
printf("\n.br\n");
printf(" ");
}
printf(" \\fB-%c\\fP|\\fB%s\\fP",
opt_names[opt_enum].short_opt,
man_long_opt_name(cmd->name, opt_enum));
if (lvm_all.optional_opt_args[oo].def.val_bits) {
printf(" ");
print_def(&lvm_all.optional_opt_args[oo].def, 1);
}
sep = 1;
}
/* those without short opts */
for (oo = 0; oo < lvm_all.oo_count; oo++) {
opt_enum = lvm_all.optional_opt_args[oo].opt;
if (opt_names[opt_enum].short_opt)
continue;
if (sep) {
printf(",");
printf("\n.br\n");
printf(" ");
}
/* space alignment without short opt */
printf(" ");
printf(" \\fB%s\\fP", man_long_opt_name(cmd->name, opt_enum));
if (lvm_all.optional_opt_args[oo].def.val_bits) {
printf(" ");
print_def(&lvm_all.optional_opt_args[oo].def, 1);
}
sep = 1;
}
printf(" ]\n");
return;
}
/*
* Format of description, when different command names have
* different descriptions:
*
* "#cmdname1"
* "text foo goes here"
* "a second line of text."
* "#cmdname2"
* "text bar goes here"
* "another line of text."
*
* When called for cmdname2, this function should just print:
*
* "text bar goes here"
* "another line of text."
*/
static void print_man_option_desc(struct cmd_name *cname, int opt_enum)
{
const char *desc = opt_names[opt_enum].desc;
char buf[DESC_LINE];
int started_cname = 0;
int di, bi;
if (!strstr(desc, "#")) {
printf("%s", desc);
return;
}
for (di = 0; di < strlen(desc); di++) {
buf[bi++] = desc[di];
if (bi == DESC_LINE) {
printf("print_man_option_desc line too long\n");
return;
}
if (buf[bi-1] != '\n')
continue;
if (buf[0] != '#') {
if (started_cname)
printf("%s", buf);
memset(buf, 0, sizeof(buf));
bi = 0;
continue;
}
/* Line starting with #cmdname */
/* Must be starting a new command name. */
if (started_cname)
return;
if (!strncmp(buf + 1, cname->name, strlen(cname->name))) {
/* The start of our command name. */
started_cname = 1;
memset(buf, 0, sizeof(buf));
bi = 0;
} else {
/* The start of another command name. */
memset(buf, 0, sizeof(buf));
bi = 0;
}
}
if (bi && started_cname)
printf("%s", buf);
}
/*
* Print a list of all options names for a given
* command name, listed by:
* options with short+long names, alphabetically,
* then options with only long names, alphabetically
*/
void print_man_all_options_list(struct cmd_name *cname)
void print_man_all_options(struct cmd_name *cname)
{
int opt_enum, val_enum;
int sep = 0;
int i;
/* print those with both short and long opts */
for (i = 0; i < ARG_COUNT; i++) {
opt_enum = opt_names_alpha[i]->opt_enum;
/* print those with short opts */
for (opt_enum = 0; opt_enum < ARG_COUNT; opt_enum++) {
if (!cname->all_options[opt_enum])
continue;
@@ -2284,9 +2182,7 @@ void print_man_all_options_list(struct cmd_name *cname)
}
/* print those without short opts */
for (i = 0; i < ARG_COUNT; i++) {
opt_enum = opt_names_alpha[i]->opt_enum;
for (opt_enum = 0; opt_enum < ARG_COUNT; opt_enum++) {
if (!cname->all_options[opt_enum])
continue;
@@ -2319,79 +2215,7 @@ void print_man_all_options_list(struct cmd_name *cname)
}
}
/*
* All options used for a given command name, along with descriptions.
* listed in order of:
* 1. options that are not common to all lvm commands, alphabetically
* 2. options common to all lvm commands, alphabetically
*/
void print_man_all_options_desc(struct cmd_name *cname)
{
int opt_enum, val_enum;
int print_common = 0;
int sep = 0;
int i;
again:
/*
* Loop 1: print options that are not common to all lvm commands.
* Loop 2: print options common to all lvm commands (lvm_all)
*/
for (i = 0; i < ARG_COUNT; i++) {
opt_enum = opt_names_alpha[i]->opt_enum;
if (!cname->all_options[opt_enum])
continue;
if (!print_common && is_lvm_all_opt(opt_enum))
continue;
if (print_common && !is_lvm_all_opt(opt_enum))
continue;
if (sep)
printf("\n.br\n");
printf("\n.TP\n");
if (opt_names[opt_enum].short_opt) {
printf("\\fB-%c\\fP|\\fB%s\\fP",
opt_names[opt_enum].short_opt,
man_long_opt_name(cname->name, opt_enum));
} else {
printf("\\fB%s\\fP", man_long_opt_name(cname->name, opt_enum));
}
val_enum = opt_names[opt_enum].val_enum;
if (!val_names[val_enum].fn) {
/* takes no arg */
} else if (!val_names[val_enum].usage) {
printf(" ");
printf("\\fI");
printf("%s", val_names[val_enum].name);
printf("\\fP");
} else {
printf(" ");
print_val_man(val_names[val_enum].usage);
}
if (opt_names[opt_enum].desc) {
printf("\n");
printf(".br\n");
print_man_option_desc(cname, opt_enum);
}
sep = 1;
}
if (!print_common) {
print_common = 1;
goto again;
}
}
#define DESC_LINE 256
void print_desc_man(const char *desc)
{
@@ -2464,12 +2288,6 @@ void print_man_command(void)
printf("Common options:\n");
printf(".\n");
print_man_usage_common(prev_cmd);
printf("\n");
printf(".SH OPTIONS\n");
printf(".br\n");
print_man_all_options_desc(cname);
prev_cmd = NULL;
}
@@ -2528,7 +2346,7 @@ void print_man_command(void)
/* listing them all when there's only 1 or 2 is just repetative */
if (cname->variants > 2) {
printf(".P\n");
print_man_all_options_list(cname);
print_man_all_options(cname);
printf("\n");
printf(".P\n");
printf("\n");
@@ -2551,12 +2369,6 @@ void print_man_command(void)
printf("Common options:\n");
printf(".\n");
print_man_usage_common(cmd);
printf("\n");
printf(".SH OPTIONS\n");
printf(".br\n");
print_man_all_options_desc(cname);
}
printf("\n");
@@ -2567,7 +2379,7 @@ void print_man_command(void)
void print_command_struct(int only_usage)
{
struct command *cmd;
int i, j, ro, rp, oo, op, ru, ruo, io;
int i, j, ro, rp, oo, op, ru, ruo;
include_optional_opt_args(&lvm_all, "OO_USAGE_COMMON");
@@ -2593,7 +2405,6 @@ void print_command_struct(int only_usage)
printf("commands[%d].rp_count = %d;\n", i, cmd->rp_count);
printf("commands[%d].oo_count = %d;\n", i, cmd->oo_count);
printf("commands[%d].op_count = %d;\n", i, cmd->op_count);
printf("commands[%d].io_count = %d;\n", i, cmd->io_count);
printf("commands[%d].rule_count = %d;\n", i, cmd->rule_count);
if (cmd->cmd_flags)
@@ -2699,35 +2510,6 @@ void print_command_struct(int only_usage)
}
}
if (cmd->io_count) {
for (io = 0; io < cmd->io_count; io++) {
printf("commands[%d].ignore_opt_args[%d].opt = %s;\n",
i, io, opt_to_enum_str(cmd->ignore_opt_args[io].opt));
if (!cmd->ignore_opt_args[io].def.val_bits)
continue;
printf("commands[%d].ignore_opt_args[%d].def.val_bits = %s;\n",
i, io, val_bits_to_str(cmd->ignore_opt_args[io].def.val_bits));
if (cmd->ignore_opt_args[io].def.lvt_bits)
printf("commands[%d].ignore_opt_args[%d].def.lvt_bits = %s;\n",
i, io, lvt_bits_to_str(cmd->ignore_opt_args[io].def.lvt_bits));
if (cmd->ignore_opt_args[io].def.flags)
printf("commands[%d].ignore_opt_args[%d].def.flags = %s;\n",
i, io, flags_to_str(cmd->ignore_opt_args[io].def.flags));
if (val_bit_is_set(cmd->ignore_opt_args[io].def.val_bits, constnum_VAL))
printf("commands[%d].ignore_opt_args[%d].def.num = %d;\n",
i, io, cmd->ignore_opt_args[io].def.num);
if (val_bit_is_set(cmd->ignore_opt_args[io].def.val_bits, conststr_VAL))
printf("commands[%d].ignore_opt_args[%d].def.str = \"%s\";\n",
i, io, cmd->ignore_opt_args[io].def.str ?: "NULL");
}
}
if (cmd->op_count) {
for (op = 0; op < cmd->op_count; op++) {
printf("commands[%d].optional_pos_args[%d].pos = %d;\n",
@@ -2868,23 +2650,6 @@ next:
}
}
static int long_name_compare(const void *on1, const void *on2)
{
struct opt_name **optname1 = on1;
struct opt_name **optname2 = on2;
return strcmp((*optname1)->long_opt + 2, (*optname2)->long_opt + 2);
}
static void create_opt_names_alpha(void)
{
int i;
for (i = 0; i < ARG_COUNT; i++)
opt_names_alpha[i] = &opt_names[i];
qsort(opt_names_alpha, ARG_COUNT, sizeof(long), long_name_compare);
}
void print_command_list(void)
{
int i;
@@ -2909,31 +2674,15 @@ void print_option_list(void)
opt_names[i].short_opt ? opt_names[i].short_opt : 0);
}
void print_option_alpha_list(void)
{
int i;
for (i = 0; i < ARG_COUNT; i++)
printf("%d %s %s %c (%d)\n",
opt_names_alpha[i]->opt_enum, opt_names_alpha[i]->name,
opt_names_alpha[i]->long_opt, opt_names_alpha[i]->short_opt ?: ' ',
opt_names_alpha[i]->short_opt ? opt_names_alpha[i]->short_opt : 0);
}
static void print_help(int argc, char *argv[])
{
printf("%s [options] --output <format> <filename>\n", argv[0]);
printf("%s --output struct|count|usage|expanded <filename>\n", argv[0]);
printf("\n");
printf("output formats:\n");
printf("struct: print C structures for command-lines.h\n");
printf("count: print defines and enums for command-lines-count.h\n");
printf("ambiguous: print commands differing only by LV types\n");
printf("usage: print usage format.\n");
printf("expanded: print expanded input format.\n");
printf("man: print man page format.\n");
printf("\n");
printf("options:\n");
printf("-c|--man-command <commandname> man output for one command name\n");
}
int main(int argc, char *argv[])
@@ -2957,12 +2706,9 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
create_opt_names_alpha();
if (!strcmp(argv[1], "debug")) {
print_command_list();
print_option_list();
print_option_alpha_list();
return 0;
}
@@ -3106,14 +2852,6 @@ int main(int argc, char *argv[])
continue;
}
/* IO: ... */
if (is_io_line(line_argv[0])) {
add_ignore_opt_line(cmd, line_argc, line_argv);
prev_was_oo = 0;
prev_was_op = 0;
continue;
}
/* handle OO_FOO:, OO:, OP: continuing on multiple lines */
if (prev_was_oo_def) {

View File

@@ -370,7 +370,7 @@ static int _lvchange_resync(struct cmd_context *cmd, struct logical_volume *lv)
/* Separate mirror log or metadata devices so we can clear them */
if (!detach_metadata_devices(seg, &device_list)) {
log_error("Failed to clear %s %s for %s.",
lvseg_name(seg), seg_is_raid(seg) ?
seg->segtype->name, seg_is_raid(seg) ?
"metadata area" : "mirror log", display_lvname(lv));
return 0;
}
@@ -1022,12 +1022,6 @@ static int _lvchange_properties_check(struct cmd_context *cmd,
return 0;
}
if (vg_is_clustered(lv->vg) && lv_is_cache_origin(lv) && lv_is_raid(lv)) {
log_error("Unable to change internal LV %s directly in a cluster.",
display_lvname(lv));
return 0;
}
return 1;
}

View File

@@ -2125,17 +2125,10 @@ static int _lvconvert_merge_old_snapshot(struct cmd_context *cmd,
if (!lv_update_and_reload(origin))
return_0;
if (!lv_has_target_type(origin->vg->vgmem, origin, NULL,
TARGET_NAME_SNAPSHOT_MERGE)) {
/* Race during table reload prevented merging */
merge_on_activate = 1;
} else if (!lv_info(cmd, origin, 0, &info, 0, 0) || !info.exists) {
if (!lv_info(cmd, origin, 0, &info, 0, 0) || !info.exists)
log_print_unless_silent("Conversion starts after activation.");
merge_on_activate = 1;
} else {
else
*lv_to_poll = origin;
}
}
if (merge_on_activate)

View File

@@ -64,7 +64,7 @@ static struct val_props _val_props[VAL_COUNT + 1] = {
* Table of valid --option's
*/
static struct arg_props _arg_props[ARG_COUNT + 1] = {
#define arg(a, b, c, d, e, f, g) {a, b, "", "--" c, d, e, f, g},
#define arg(a, b, c, d, e, f) {a, b, "", "--" c, d, e, f},
#include "args.h"
#undef arg
};
@@ -655,14 +655,6 @@ int int_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *
return 1;
}
int uint32_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!int_arg(cmd, av) || (av->ui64_value > UINT32_MAX))
return 0;
return 1;
}
int int_arg_with_sign(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
{
char *ptr;
@@ -1162,25 +1154,6 @@ static int _opt_synonym_is_set(struct cmd_context *cmd, int opt_std)
return opt_syn && arg_is_set(cmd, opt_syn);
}
static int _command_ignore_opt_matches(struct cmd_context *cmd, int ci, int io)
{
int opt_enum = commands[ci].ignore_opt_args[io].opt;
if (val_bit_is_set(commands[ci].ignore_opt_args[io].def.val_bits, conststr_VAL)) {
if (!strcmp(commands[ci].ignore_opt_args[io].def.str, arg_str_value(cmd, opt_enum, "")))
return 1;
return 0;
}
if (val_bit_is_set(commands[ci].ignore_opt_args[io].def.val_bits, constnum_VAL)) {
if (commands[ci].ignore_opt_args[io].def.num == arg_int_value(cmd, opt_enum, 0))
return 1;
return 0;
}
return 1;
}
static int _command_required_opt_matches(struct cmd_context *cmd, int ci, int ro)
{
int opt_enum = commands[ci].required_opt_args[ro].opt;
@@ -1642,14 +1615,6 @@ static struct command *_find_command(struct cmd_context *cmd, const char *path,
}
}
for (j = 0; j < commands[i].io_count; j++) {
if ((commands[i].ignore_opt_args[j].opt == opt_enum) &&
_command_ignore_opt_matches(cmd, i, j)) {
accepted = 1;
break;
}
}
if (!accepted) {
match_unused++;
if (temp_unused_count < MAX_UNUSED_COUNT)
@@ -1857,12 +1822,9 @@ static int _usage(const char *name, int help_count)
log_print(". The _new suffix indicates the VG or LV must not yet exist.");
log_print(". LV followed by _<type> indicates that an LV of the given type");
log_print(" is required. (raid represents any raid<N> type.)");
log_print(". Input units are always treated as base two values, regardless of");
log_print(" unit capitalization, e.g. 'k' and 'K' both refer to 1024.");
log_print(". The default input unit is specified by letter, followed by |unit");
log_print(" which represents other possible input units: bBsSkKmMgGtTpPeE.");
log_print(". Output units can be specified with the --units option, for which");
log_print(" lower/upper case letters refer to base 2/10 values.");
log_print(". The default output unit is specified by letter, followed by |unit");
log_print(" which represents other possible units: hHbBsSkKmMgGtTpPeE.");
log_print(". Output units are 1024 SI base, regardless of unit capitalization.");
log_print(". Use --help --help --help to print secondary command syntax");
log_print(" formats that are recognized, e.g. for compatibility.");
log_print(". See man pages for short option equivalents of long option names,");

View File

@@ -113,40 +113,6 @@ static int _do_info_and_status(struct cmd_context *cmd,
return 1;
}
/* Check if this is really merging origin.
* In such case, origin is gone, and user should see
* only data from merged snapshot. Important for thin. */
static int _check_merging_origin(const struct logical_volume *lv,
struct lv_with_info_and_seg_status *status,
int *merged)
{
uint32_t device_id;
*merged = 0;
switch (status->seg_status.type) {
case SEG_STATUS_THIN:
/* Get 'device_id' from active dm-table */
if (!lv_thin_device_id(lv, &device_id))
return_0;
if (lv->snapshot->device_id != device_id)
return 1;
break;
case SEG_STATUS_SNAPSHOT:
break;
default:
return 1;
}
/* Origin is gone */
log_debug_activation("Merge is progress, reporting merged LV %s.",
display_lvname(lv->snapshot->lv));
*merged = 1;
return 1;
}
static int _do_lvs_with_info_and_status_single(struct cmd_context *cmd,
const struct logical_volume *lv,
int do_info, int do_status,
@@ -157,22 +123,10 @@ static int _do_lvs_with_info_and_status_single(struct cmd_context *cmd,
.seg_status.type = SEG_STATUS_NONE
};
int r = ECMD_FAILED;
int merged;
if (lv_is_merging_origin(lv))
/* Status is need to know which LV should be shown */
do_status = 1;
if (!_do_info_and_status(cmd, first_seg(lv), &status, do_info, do_status))
goto_out;
if (lv_is_merging_origin(lv)) {
if (!_check_merging_origin(lv, &status, &merged))
goto_out;
if (merged)
lv = lv->snapshot->lv;
}
if (!report_object(sh ? : handle->custom_handle, sh != NULL,
lv->vg, lv, NULL, NULL, NULL, &status, NULL))
goto out;
@@ -219,22 +173,10 @@ static int _do_segs_with_info_and_status_single(struct cmd_context *cmd,
.seg_status.type = SEG_STATUS_NONE
};
int r = ECMD_FAILED;
int merged;
if (lv_is_merging_origin(seg->lv))
/* Status is need to know which LV should be shown */
do_status = 1;
if (!_do_info_and_status(cmd, seg, &status, do_info, do_status))
goto_out;
if (lv_is_merging_origin(seg->lv)) {
if (!_check_merging_origin(seg->lv, &status, &merged))
goto_out;
if (merged)
seg = seg->lv->snapshot;
}
if (!report_object(sh ? : handle->custom_handle, sh != NULL,
seg->lv->vg, seg->lv, NULL, seg, NULL, &status, NULL))
goto_out;

View File

@@ -59,7 +59,7 @@ enum {
/* define the enums for the command line --options, foo_ARG */
enum {
#define arg(a, b, c, d, e, f, g) a ,
#define arg(a, b, c, d, e, f) a ,
#include "args.h"
#undef arg
};
@@ -109,7 +109,6 @@ struct arg_props {
int val_enum; /* foo_VAL from vals.h */
uint32_t flags;
uint32_t prio;
const char *desc;
};
struct arg_value_group_list {
@@ -178,7 +177,6 @@ int size_kb_arg(struct cmd_context *cmd, struct arg_values *av);
int size_mb_arg(struct cmd_context *cmd, struct arg_values *av);
int size_mb_arg_with_percent(struct cmd_context *cmd, struct arg_values *av);
int int_arg(struct cmd_context *cmd, struct arg_values *av);
int uint32_arg(struct cmd_context *cmd, struct arg_values *av);
int int_arg_with_sign(struct cmd_context *cmd, struct arg_values *av);
int int_arg_with_sign_and_percent(struct cmd_context *cmd, struct arg_values *av);
int major_arg(struct cmd_context *cmd, struct arg_values *av);

View File

@@ -99,7 +99,6 @@ val(conststr_VAL, NULL, "ConstString", "ERR") /* used only for command defs */
val(constnum_VAL, NULL, "ConstNumber", "ERR") /* used only for command defs */
val(bool_VAL, yes_no_arg, "Bool", "y|n")
val(number_VAL, int_arg, "Number", NULL)
val(uint32_VAL, uint32_arg, "Uint32", "Number")
val(string_VAL, string_arg, "String", NULL)
val(vg_VAL, string_arg, "VG", NULL)
val(lv_VAL, string_arg, "LV", NULL)