mirror of
git://sourceware.org/git/lvm2.git
synced 2025-09-27 05:44:18 +03:00
Compare commits
38 Commits
dev-dct-lv
...
dev-dct-cm
Author | SHA1 | Date | |
---|---|---|---|
|
c7e065fa6f | ||
|
5c55c4ac18 | ||
|
900e899739 | ||
|
8859d4508a | ||
|
e57fd9d963 | ||
|
9c56902365 | ||
|
595af62ebd | ||
|
4fab833920 | ||
|
2830f72288 | ||
|
fe437a6e7d | ||
|
8f30069160 | ||
|
6f576483a8 | ||
|
c8b6c13015 | ||
|
f4ae43934a | ||
|
706d3ddf90 | ||
|
1186cf2ad4 | ||
|
20e74313cd | ||
|
be06fa695e | ||
|
3e45285b40 | ||
|
0c51f369a4 | ||
|
cb4e26dcb3 | ||
|
9f0195ec1e | ||
|
2e941beb44 | ||
|
088b3d036a | ||
|
a8bb8dfb08 | ||
|
d54ffcfcd1 | ||
|
a3f24aaf5c | ||
|
bf5d0a2651 | ||
|
c900cf7ed4 | ||
|
9e33781d95 | ||
|
43662fa081 | ||
|
77ffd39dfb | ||
|
9fe4f2337b | ||
|
cea441f4d1 | ||
|
00f883a4aa | ||
|
d70f112762 | ||
|
ee04f1fcfd | ||
|
e95a252974 |
@@ -1,5 +1,6 @@
|
||||
Version 2.02.167 -
|
||||
======================================
|
||||
Fix a few unconverted return code values for some lvconvert error path.
|
||||
Disable lvconvert of thin pool to raid while active.
|
||||
Disable systemd service start rate limiting for lvm2-pvscan@.service.
|
||||
|
||||
|
@@ -1,5 +1,8 @@
|
||||
Version 1.02.136 -
|
||||
======================================
|
||||
Check and report pthread_sigmask() failure in dmeventd.
|
||||
Check mem alloc fail in _canonicalize_field_ids().
|
||||
Use unsigned math when checking more then 31 legs of raid.
|
||||
Fix 'dmstats delete' with dmsetup older than v1.02.129
|
||||
Fix stats walk segfault with dmsetup older than v1.02.129
|
||||
|
||||
|
@@ -829,17 +829,6 @@ static void _print_sigset(const char *prefix, const sigset_t *sigset)
|
||||
}
|
||||
#endif
|
||||
|
||||
static sigset_t _unblock_sigalrm(void)
|
||||
{
|
||||
sigset_t set, old;
|
||||
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, SIGALRM);
|
||||
pthread_sigmask(SIG_UNBLOCK, &set, &old);
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
enum {
|
||||
DM_WAIT_RETRY,
|
||||
DM_WAIT_INTR,
|
||||
@@ -849,7 +838,7 @@ enum {
|
||||
/* Wait on a device until an event occurs. */
|
||||
static int _event_wait(struct thread_status *thread)
|
||||
{
|
||||
sigset_t set;
|
||||
sigset_t set, old;
|
||||
int ret = DM_WAIT_RETRY;
|
||||
struct dm_info info;
|
||||
|
||||
@@ -859,7 +848,12 @@ static int _event_wait(struct thread_status *thread)
|
||||
* This is so that you can break out of waiting on an event,
|
||||
* either for a timeout event, or to cancel the thread.
|
||||
*/
|
||||
set = _unblock_sigalrm();
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, SIGALRM);
|
||||
if (pthread_sigmask(SIG_UNBLOCK, &set, &old) != 0) {
|
||||
log_sys_error("pthread_sigmask", "unblock alarm");
|
||||
return ret; /* What better */
|
||||
}
|
||||
|
||||
if (dm_task_run(thread->wait_task)) {
|
||||
thread->current_events |= DM_EVENT_DEVICE_ERROR;
|
||||
@@ -883,10 +877,11 @@ static int _event_wait(struct thread_status *thread)
|
||||
}
|
||||
}
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &set, NULL);
|
||||
if (pthread_sigmask(SIG_SETMASK, &old, NULL) != 0)
|
||||
log_sys_error("pthread_sigmask", "block alarm");
|
||||
|
||||
#ifdef DEBUG_SIGNALS
|
||||
_print_sigset("dmeventd blocking ", &set);
|
||||
_print_sigset("dmeventd blocking ", &old);
|
||||
#endif
|
||||
DEBUGLOG("Completed waitevent task for %s.", thread->device.name);
|
||||
|
||||
|
@@ -48,11 +48,11 @@ static int _process_raid_event(struct dso_state *state, char *params, const char
|
||||
while ((d = strchr(d, 'D'))) {
|
||||
uint32_t dev = (uint32_t)(d - status->dev_health);
|
||||
|
||||
if (!(state->raid_devs[dev / 64] & (1 << (dev % 64))))
|
||||
if (!(state->raid_devs[dev / 64] & (UINT64_C(1) << (dev % 64))))
|
||||
log_error("Device #%u of %s array, %s, has failed.",
|
||||
dev, status->raid_type, device);
|
||||
|
||||
state->raid_devs[dev / 64] |= (1 << (dev % 64));
|
||||
state->raid_devs[dev / 64] |= (UINT64_C(1) << (dev % 64));
|
||||
d++;
|
||||
dead = 1;
|
||||
}
|
||||
|
@@ -108,12 +108,6 @@ def call_lvm(command, debug=False):
|
||||
if debug or process.returncode != 0:
|
||||
_debug_c(command, process.returncode, (stdout_text, stderr_text))
|
||||
|
||||
if process.returncode == 0:
|
||||
if cfg.args and cfg.args.debug and out[1] and len(out[1]) and \
|
||||
'help' not in command:
|
||||
log_error('WARNING: lvm is out-putting text to STDERR on success!')
|
||||
_debug_c(command, process.returncode, (stdout_text, stderr_text))
|
||||
|
||||
return process.returncode, stdout_text, stderr_text
|
||||
|
||||
# The actual method which gets called to invoke the lvm command, can vary
|
||||
@@ -485,7 +479,9 @@ def lvm_full_report_json():
|
||||
'vg_name', 'pool_lv_uuid', 'pool_lv', 'origin_uuid',
|
||||
'origin', 'data_percent',
|
||||
'lv_attr', 'lv_tags', 'vg_uuid', 'lv_active', 'data_lv',
|
||||
'metadata_lv', 'lv_parent', 'lv_role', 'lv_layout']
|
||||
'metadata_lv', 'lv_parent', 'lv_role', 'lv_layout',
|
||||
'snap_percent', 'metadata_percent', 'copy_percent',
|
||||
'sync_percent', 'lv_metadata_size', 'move_pv', 'move_pv_uuid']
|
||||
|
||||
lv_seg_columns = ['seg_pe_ranges', 'segtype', 'lv_uuid']
|
||||
|
||||
@@ -735,7 +731,9 @@ def lv_retrieve_with_segments():
|
||||
'origin', 'data_percent',
|
||||
'lv_attr', 'lv_tags', 'vg_uuid', 'lv_active', 'data_lv',
|
||||
'metadata_lv', 'seg_pe_ranges', 'segtype', 'lv_parent',
|
||||
'lv_role', 'lv_layout']
|
||||
'lv_role', 'lv_layout',
|
||||
'snap_percent', 'metadata_percent', 'copy_percent',
|
||||
'sync_percent', 'lv_metadata_size', 'move_pv', 'move_pv_uuid']
|
||||
|
||||
cmd = _dc('lvs', ['-a', '-o', ','.join(columns)])
|
||||
rc, out, err = call(cmd)
|
||||
|
@@ -81,7 +81,14 @@ def lvs_state_retrieve(selection, cache_refresh=True):
|
||||
n32(l['data_percent']), l['lv_attr'],
|
||||
l['lv_tags'], l['lv_active'], l['data_lv'],
|
||||
l['metadata_lv'], l['segtype'], l['lv_role'],
|
||||
l['lv_layout']))
|
||||
l['lv_layout'],
|
||||
n32(l['snap_percent']),
|
||||
n32(l['metadata_percent']),
|
||||
n32(l['copy_percent']),
|
||||
n32(l['sync_percent']),
|
||||
n(l['lv_metadata_size']),
|
||||
l['move_pv'],
|
||||
l['move_pv_uuid']))
|
||||
return rc
|
||||
|
||||
|
||||
@@ -138,7 +145,9 @@ class LvState(State):
|
||||
def __init__(self, Uuid, Name, Path, SizeBytes,
|
||||
vg_name, vg_uuid, pool_lv_uuid, PoolLv,
|
||||
origin_uuid, OriginLv, DataPercent, Attr, Tags, active,
|
||||
data_lv, metadata_lv, segtypes, role, layout):
|
||||
data_lv, metadata_lv, segtypes, role, layout, SnapPercent,
|
||||
MetaDataPercent, CopyPercent, SyncPercent, MetaDataSizeBytes,
|
||||
move_pv, move_pv_uuid):
|
||||
utils.init_class_from_arguments(self)
|
||||
|
||||
# The segtypes is possibly an array with potentially dupes or a single
|
||||
@@ -214,13 +223,20 @@ class LvState(State):
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'Name', 's')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'Path', 's')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'SizeBytes', 't')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'DataPercent', 'u')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'SegType', 'as')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'Vg', 'o')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'OriginLv', 'o')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'PoolLv', 'o')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'Devices', "a(oa(tts))")
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'HiddenLvs', "ao")
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'Attr', 's')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'DataPercent', 'u')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'SnapPercent', 'u')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'DataPercent', 'u')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'MetaDataPercent', 'u')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'CopyPercent', 'u')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'SyncPercent', 'u')
|
||||
@utils.dbus_property(LV_COMMON_INTERFACE, 'MetaDataSizeBytes', 't')
|
||||
class LvCommon(AutomatedProperties):
|
||||
_Tags_meta = ("as", LV_COMMON_INTERFACE)
|
||||
_Roles_meta = ("as", LV_COMMON_INTERFACE)
|
||||
@@ -236,12 +252,25 @@ class LvCommon(AutomatedProperties):
|
||||
_FixedMinor_meta = ('b', LV_COMMON_INTERFACE)
|
||||
_ZeroBlocks_meta = ('b', LV_COMMON_INTERFACE)
|
||||
_SkipActivation_meta = ('b', LV_COMMON_INTERFACE)
|
||||
_MovePv_meta = ('o', LV_COMMON_INTERFACE)
|
||||
|
||||
def _get_move_pv(self):
|
||||
path = None
|
||||
|
||||
# It's likely that the move_pv is empty
|
||||
if self.state.move_pv_uuid and self.state.move_pv:
|
||||
path = cfg.om.get_object_path_by_uuid_lvm_id(
|
||||
self.state.move_pv_uuid, self.state.move_pv)
|
||||
if not path:
|
||||
path = '/'
|
||||
return path
|
||||
|
||||
# noinspection PyUnusedLocal,PyPep8Naming
|
||||
def __init__(self, object_path, object_state):
|
||||
super(LvCommon, self).__init__(object_path, lvs_state_retrieve)
|
||||
self.set_interface(LV_COMMON_INTERFACE)
|
||||
self.state = object_state
|
||||
self._move_pv = self._get_move_pv()
|
||||
|
||||
@property
|
||||
def VolumeType(self):
|
||||
@@ -351,6 +380,10 @@ class LvCommon(AutomatedProperties):
|
||||
def Active(self):
|
||||
return dbus.Boolean(self.state.active == "active")
|
||||
|
||||
@property
|
||||
def MovePv(self):
|
||||
return dbus.ObjectPath(self._move_pv)
|
||||
|
||||
|
||||
# noinspection PyPep8Naming
|
||||
class Lv(LvCommon):
|
||||
|
@@ -75,6 +75,8 @@ class LVMShellProxy(object):
|
||||
report += tmp.decode("utf-8")
|
||||
if len(tmp) != 16384:
|
||||
break
|
||||
else:
|
||||
break
|
||||
|
||||
elif r == self.lvm_shell.stderr.fileno():
|
||||
while True:
|
||||
@@ -84,6 +86,10 @@ class LVMShellProxy(object):
|
||||
else:
|
||||
break
|
||||
|
||||
# Check to see if the lvm process died on us
|
||||
if self.lvm_shell.poll():
|
||||
raise Exception(self.lvm_shell.returncode, "%s" % stderr)
|
||||
|
||||
except IOError as ioe:
|
||||
log_debug(str(ioe))
|
||||
pass
|
||||
@@ -115,6 +121,10 @@ class LVMShellProxy(object):
|
||||
local_env["LVM_REPORT_FD"] = "32"
|
||||
local_env["LVM_COMMAND_PROFILE"] = "lvmdbusd"
|
||||
|
||||
# Disable the abort logic if lvm logs too much, which easily happens
|
||||
# when utilizing the lvm shell.
|
||||
local_env["LVM_LOG_FILE_MAX_LINES"] = "0"
|
||||
|
||||
flags = fcntl(self.report_r, F_GETFL)
|
||||
fcntl(self.report_r, F_SETFL, flags | os.O_NONBLOCK)
|
||||
|
||||
@@ -123,20 +133,24 @@ class LVMShellProxy(object):
|
||||
[LVM_CMD + " 32>%s" % tmp_file],
|
||||
stdin=subprocess.PIPE, stdout=subprocess.PIPE, env=local_env,
|
||||
stderr=subprocess.PIPE, close_fds=True, shell=True)
|
||||
flags = fcntl(self.lvm_shell.stdout, F_GETFL)
|
||||
fcntl(self.lvm_shell.stdout, F_SETFL, flags | os.O_NONBLOCK)
|
||||
flags = fcntl(self.lvm_shell.stderr, F_GETFL)
|
||||
fcntl(self.lvm_shell.stderr, F_SETFL, flags | os.O_NONBLOCK)
|
||||
|
||||
# wait for the first prompt
|
||||
errors = self._read_until_prompt()[2]
|
||||
if errors and len(errors):
|
||||
raise RuntimeError(errors)
|
||||
try:
|
||||
flags = fcntl(self.lvm_shell.stdout, F_GETFL)
|
||||
fcntl(self.lvm_shell.stdout, F_SETFL, flags | os.O_NONBLOCK)
|
||||
flags = fcntl(self.lvm_shell.stderr, F_GETFL)
|
||||
fcntl(self.lvm_shell.stderr, F_SETFL, flags | os.O_NONBLOCK)
|
||||
|
||||
# These will get deleted when the FD count goes to zero so we can be
|
||||
# sure to clean up correctly no matter how we finish
|
||||
os.unlink(tmp_file)
|
||||
os.rmdir(tmp_dir)
|
||||
# wait for the first prompt
|
||||
errors = self._read_until_prompt()[2]
|
||||
if errors and len(errors):
|
||||
raise RuntimeError(errors)
|
||||
except:
|
||||
raise
|
||||
finally:
|
||||
# These will get deleted when the FD count goes to zero so we can be
|
||||
# sure to clean up correctly no matter how we finish
|
||||
os.unlink(tmp_file)
|
||||
os.rmdir(tmp_dir)
|
||||
|
||||
def get_error_msg(self):
|
||||
# We got an error, lets go fetch the error message
|
||||
@@ -171,6 +185,11 @@ class LVMShellProxy(object):
|
||||
error_msg = ""
|
||||
json_result = ""
|
||||
|
||||
if self.lvm_shell.poll():
|
||||
raise Exception(
|
||||
self.lvm_shell.returncode,
|
||||
"Underlying lvm shell process is not present!")
|
||||
|
||||
# create the command string
|
||||
cmd = " ".join(_quote_arg(arg) for arg in argv)
|
||||
cmd += "\n"
|
||||
@@ -222,7 +241,7 @@ if __name__ == "__main__":
|
||||
end = time.time()
|
||||
|
||||
print(("RC: %d" % ret))
|
||||
# print(("OUT:\n%s" % out))
|
||||
print(("OUT:\n%s" % out))
|
||||
print(("ERR:\n%s" % err))
|
||||
|
||||
print("Command = %f seconds" % (end - start))
|
||||
|
@@ -1249,8 +1249,8 @@ static int _update_metadata(lvmetad_state *s, const char *arg_name, const char *
|
||||
const char *old_vgid = NULL;
|
||||
const char *new_vgid = NULL;
|
||||
const char *new_metadata_vgid;
|
||||
int new_seq;
|
||||
int old_seq = -1;
|
||||
int new_seq = -1;
|
||||
int needs_repair = 0;
|
||||
int abort_daemon = 0;
|
||||
int retval = 0;
|
||||
|
2
lib/cache/lvmcache.c
vendored
2
lib/cache/lvmcache.c
vendored
@@ -858,7 +858,7 @@ static void _choose_preferred_devs(struct cmd_context *cmd,
|
||||
struct dm_list *add_cache_devs)
|
||||
{
|
||||
char uuid[64] __attribute__((aligned(8)));
|
||||
const char *reason = "none";
|
||||
const char *reason;
|
||||
struct dm_list altdevs;
|
||||
struct dm_list new_unused;
|
||||
struct dev_types *dt = cmd->dev_types;
|
||||
|
@@ -88,9 +88,10 @@ struct cmd_context {
|
||||
* Command line and arguments.
|
||||
*/
|
||||
const char *cmd_line;
|
||||
const char *name; /* needed before cmd->command is set */
|
||||
struct command *command;
|
||||
char **argv;
|
||||
struct arg_values *arg_values;
|
||||
struct arg_values *opt_arg_values;
|
||||
struct dm_list arg_value_groups;
|
||||
|
||||
/*
|
||||
|
@@ -61,7 +61,6 @@ struct logical_volume {
|
||||
|
||||
uint64_t timestamp;
|
||||
unsigned new_lock_args:1;
|
||||
unsigned process_specific:1; /* lv is identified specifically for processing */
|
||||
const char *hostname;
|
||||
const char *lock_args;
|
||||
};
|
||||
|
@@ -956,7 +956,7 @@ static int _raid_add_images(struct logical_volume *lv,
|
||||
int commit, int use_existing_area_len)
|
||||
{
|
||||
int rebuild_flag_cleared = 0;
|
||||
struct lv_segment *seg = first_seg(lv);
|
||||
struct lv_segment *seg;
|
||||
uint32_t s;
|
||||
|
||||
if (!_raid_add_images_without_commit(lv, new_count, pvs, use_existing_area_len))
|
||||
|
@@ -472,7 +472,7 @@ static int _check_pool_create(const struct logical_volume *lv)
|
||||
|
||||
int update_pool_lv(struct logical_volume *lv, int activate)
|
||||
{
|
||||
int monitored = DMEVENTD_MONITOR_IGNORE;
|
||||
int monitored;
|
||||
int ret = 1;
|
||||
|
||||
if (!lv_is_thin_pool(lv)) {
|
||||
|
@@ -19,7 +19,6 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
@@ -1228,7 +1228,10 @@ static int _canonicalize_field_ids(struct dm_report *rh)
|
||||
return_0;
|
||||
|
||||
if (differs) {
|
||||
canonical_field_dup = dm_pool_strdup(rh->mem, canonical_field);
|
||||
if (!(canonical_field_dup = dm_pool_strdup(rh->mem, canonical_field))) {
|
||||
log_error("_canonicalize_field_dup: dm_pool_alloc failed.");
|
||||
return 0;
|
||||
}
|
||||
rh->canonical_field_ids[i] = canonical_field_dup;
|
||||
} else
|
||||
rh->canonical_field_ids[i] = rh->fields[i].id;
|
||||
|
@@ -4195,9 +4195,9 @@ static int _stats_add_extent(struct dm_pool *mem, struct fiemap_extent *fm_ext,
|
||||
static struct _extent *_stats_get_extents_for_file(struct dm_pool *mem, int fd,
|
||||
uint64_t *count)
|
||||
{
|
||||
uint64_t buf[STATS_FIE_BUF_LEN];
|
||||
struct fiemap *fiemap = (struct fiemap *)buf;
|
||||
struct fiemap_extent *fm_ext = &fiemap->fm_extents[0];
|
||||
uint64_t *buf;
|
||||
struct fiemap *fiemap = NULL;
|
||||
struct fiemap_extent *fm_ext = NULL;
|
||||
struct fiemap_extent fm_last = {0};
|
||||
struct _extent *extents;
|
||||
unsigned long long expected = 0;
|
||||
@@ -4208,10 +4208,18 @@ static struct _extent *_stats_get_extents_for_file(struct dm_pool *mem, int fd,
|
||||
int last = 0;
|
||||
int rc;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
buf = dm_zalloc(STATS_FIE_BUF_LEN);
|
||||
if (!buf) {
|
||||
log_error("Could not allocate memory for FIEMAP buffer.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* initialise pointers into the ioctl buffer. */
|
||||
fiemap = (struct fiemap *) buf;
|
||||
fm_ext = &fiemap->fm_extents[0];
|
||||
|
||||
/* space available per ioctl */
|
||||
*count = (sizeof(buf) - sizeof(*fiemap))
|
||||
*count = (STATS_FIE_BUF_LEN - sizeof(*fiemap))
|
||||
/ sizeof(struct fiemap_extent);
|
||||
|
||||
/* grow temporary extent table in the pool */
|
||||
@@ -4277,9 +4285,16 @@ static struct _extent *_stats_get_extents_for_file(struct dm_pool *mem, int fd,
|
||||
|
||||
/* return total number of extents */
|
||||
*count = tot_extents;
|
||||
return dm_pool_end_object(mem);
|
||||
extents = dm_pool_end_object(mem);
|
||||
|
||||
/* free FIEMAP buffer. */
|
||||
dm_free(buf);
|
||||
|
||||
return extents;
|
||||
|
||||
bad:
|
||||
dm_pool_abandon_object(mem);
|
||||
dm_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@@ -609,9 +609,6 @@ of device-mapper devices.
|
||||
%if %{enable_systemd}
|
||||
systemctl preset dm-event.socket > /dev/null 2>&1 || :
|
||||
%endif
|
||||
if [ -e %{_default_pid_dir}/dmeventd.pid ]; then
|
||||
%{_sbindir}/dmeventd -R || echo "Failed to restart dmeventd daemon. Please, try manual restart."
|
||||
fi
|
||||
|
||||
%preun -n device-mapper-event
|
||||
%if %{enable_systemd}
|
||||
@@ -626,6 +623,11 @@ if [ $1 = 0 ]; then
|
||||
%daemon_reload
|
||||
fi
|
||||
|
||||
%posttrans -n device-mapper-event
|
||||
if [ -e %{_default_pid_dir}/dmeventd.pid ]; then
|
||||
%{_sbindir}/dmeventd -R || echo "Failed to restart dmeventd daemon. Please, try manual restart."
|
||||
fi
|
||||
|
||||
%files -n device-mapper-event
|
||||
%defattr(-,root,root,-)
|
||||
%{_sbindir}/dmeventd
|
||||
|
@@ -18,5 +18,15 @@ SKIP_WITH_CLVMD=1
|
||||
|
||||
aux prepare_pvs 6
|
||||
|
||||
# We need the lvmdbusd.profile for the daemon to utilize JSON
|
||||
# output
|
||||
mkdir -p $TESTDIR/etc/profile/
|
||||
cp -v $TESTOLDPWD/../conf/lvmdbusd.profile $TESTDIR/etc/profile/.
|
||||
|
||||
# Need to set this up so that the lvmdbusd service knows which
|
||||
# binary to be running, which should be the one we just built
|
||||
export LVM_BINARY=$TESTOLDPWD/../tools/lvm
|
||||
|
||||
aux prepare_lvmdbusd
|
||||
|
||||
$test_data_dir/dbus/lvmdbustest.py -v
|
||||
|
@@ -9,6 +9,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# noinspection PyUnresolvedReferences
|
||||
import dbus
|
||||
# noinspection PyUnresolvedReferences
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
@@ -21,6 +22,8 @@ from testlib import *
|
||||
|
||||
g_tmo = 0
|
||||
|
||||
g_prefix = os.getenv('PREFIX', '')
|
||||
|
||||
use_session = os.getenv('LVMDBUSD_USE_SESSION', False)
|
||||
|
||||
if use_session:
|
||||
@@ -29,10 +32,28 @@ else:
|
||||
bus = dbus.SystemBus(mainloop=DBusGMainLoop())
|
||||
|
||||
|
||||
def std_err_print(*args):
|
||||
sys.stderr.write(' '.join(map(str, args)) + '\n')
|
||||
sys.stderr.flush()
|
||||
|
||||
|
||||
def vg_n():
|
||||
return g_prefix + rs(8, '_vg')
|
||||
|
||||
|
||||
def lv_n(suffix=None):
|
||||
if not suffix:
|
||||
s = '_lv'
|
||||
else:
|
||||
s = suffix
|
||||
return g_prefix + rs(8, s)
|
||||
|
||||
|
||||
def get_objects():
|
||||
rc = {MANAGER_INT: [], PV_INT: [], VG_INT: [], LV_INT: [],
|
||||
THINPOOL_INT: [], JOB_INT: [], SNAPSHOT_INT: [], LV_COMMON_INT: [],
|
||||
CACHE_POOL_INT: [], CACHE_LV_INT: []}
|
||||
rc = {
|
||||
MANAGER_INT: [], PV_INT: [], VG_INT: [], LV_INT: [],
|
||||
THINPOOL_INT: [], JOB_INT: [], SNAPSHOT_INT: [], LV_COMMON_INT: [],
|
||||
CACHE_POOL_INT: [], CACHE_LV_INT: []}
|
||||
|
||||
manager = dbus.Interface(bus.get_object(
|
||||
BUSNAME, "/com/redhat/lvmdbus1"),
|
||||
@@ -63,14 +84,14 @@ class TestDbusService(unittest.TestCase):
|
||||
# we are not mucking with someones data on their system
|
||||
self.objs, self.bus = get_objects()
|
||||
if len(self.objs[PV_INT]) == 0:
|
||||
print('No PVs present exiting!')
|
||||
std_err_print('No PVs present exiting!')
|
||||
sys.exit(1)
|
||||
if len(self.objs[MANAGER_INT]) != 1:
|
||||
print('Expecting a manager object!')
|
||||
std_err_print('Expecting a manager object!')
|
||||
sys.exit(1)
|
||||
|
||||
if len(self.objs[VG_INT]) != 0:
|
||||
print('Expecting no VGs to exist!')
|
||||
std_err_print('Expecting no VGs to exist!')
|
||||
sys.exit(1)
|
||||
|
||||
self.pvs = []
|
||||
@@ -141,7 +162,7 @@ class TestDbusService(unittest.TestCase):
|
||||
if not pv_paths:
|
||||
pv_paths = [self.objs[PV_INT][0].object_path]
|
||||
|
||||
vg_name = rs(8, '_vg')
|
||||
vg_name = vg_n()
|
||||
|
||||
vg_path = self.handle_return(
|
||||
self.objs[MANAGER_INT][0].Manager.VgCreate(
|
||||
@@ -270,7 +291,7 @@ class TestDbusService(unittest.TestCase):
|
||||
if len(self.objs[PV_INT]) >= 2:
|
||||
vg = self._vg_create(
|
||||
[self.objs[PV_INT][0].object_path,
|
||||
self.objs[PV_INT][1].object_path]).Vg
|
||||
self.objs[PV_INT][1].object_path]).Vg
|
||||
|
||||
path = self.handle_return(
|
||||
vg.Reduce(False, [vg.Pvs[0]], g_tmo, {})
|
||||
@@ -319,12 +340,14 @@ class TestDbusService(unittest.TestCase):
|
||||
|
||||
for l in lv_paths:
|
||||
lv_proxy = ClientProxy(self.bus, l).LvCommon
|
||||
self.assertTrue(lv_proxy.Vg == vg.object_path, "%s != %s" %
|
||||
(lv_proxy.Vg, vg.object_path))
|
||||
self.assertTrue(
|
||||
lv_proxy.Vg == vg.object_path, "%s != %s" %
|
||||
(lv_proxy.Vg, vg.object_path))
|
||||
full_name = "%s/%s" % (new_name, lv_proxy.Name)
|
||||
lv_path = mgr.LookUpByLvmId(full_name)
|
||||
self.assertTrue(lv_path == lv_proxy.object_path, "%s != %s" %
|
||||
(lv_path, lv_proxy.object_path))
|
||||
self.assertTrue(
|
||||
lv_path == lv_proxy.object_path, "%s != %s" %
|
||||
(lv_path, lv_proxy.object_path))
|
||||
|
||||
def _verify_hidden_lookups(self, lv_common_object, vgname):
|
||||
mgr = self.objs[MANAGER_INT][0].Manager
|
||||
@@ -362,7 +385,7 @@ class TestDbusService(unittest.TestCase):
|
||||
self._verify_hidden_lookups(thin_pool.LvCommon, vg_name_start)
|
||||
|
||||
for i in range(0, 5):
|
||||
lv_name = rs(8, '_lv')
|
||||
lv_name = lv_n()
|
||||
|
||||
thin_lv_path = self.handle_return(
|
||||
thin_pool.ThinPool.LvCreate(
|
||||
@@ -373,8 +396,9 @@ class TestDbusService(unittest.TestCase):
|
||||
full_name = "%s/%s" % (vg_name_start, lv_name)
|
||||
|
||||
lookup_lv_path = mgr.LookUpByLvmId(full_name)
|
||||
self.assertTrue(thin_lv_path == lookup_lv_path,
|
||||
"%s != %s" % (thin_lv_path, lookup_lv_path))
|
||||
self.assertTrue(
|
||||
thin_lv_path == lookup_lv_path,
|
||||
"%s != %s" % (thin_lv_path, lookup_lv_path))
|
||||
|
||||
# Rename the VG
|
||||
new_name = 'renamed_' + vg.Name
|
||||
@@ -392,13 +416,15 @@ class TestDbusService(unittest.TestCase):
|
||||
|
||||
for l in lv_paths:
|
||||
lv_proxy = ClientProxy(self.bus, l).LvCommon
|
||||
self.assertTrue(lv_proxy.Vg == vg.object_path, "%s != %s" %
|
||||
(lv_proxy.Vg, vg.object_path))
|
||||
self.assertTrue(
|
||||
lv_proxy.Vg == vg.object_path, "%s != %s" %
|
||||
(lv_proxy.Vg, vg.object_path))
|
||||
full_name = "%s/%s" % (new_name, lv_proxy.Name)
|
||||
# print('Full Name %s' % (full_name))
|
||||
lv_path = mgr.LookUpByLvmId(full_name)
|
||||
self.assertTrue(lv_path == lv_proxy.object_path, "%s != %s" %
|
||||
(lv_path, lv_proxy.object_path))
|
||||
self.assertTrue(
|
||||
lv_path == lv_proxy.object_path, "%s != %s" %
|
||||
(lv_path, lv_proxy.object_path))
|
||||
|
||||
# noinspection PyTypeChecker
|
||||
self._verify_hidden_lookups(thin_pool.LvCommon, new_name)
|
||||
@@ -424,14 +450,14 @@ class TestDbusService(unittest.TestCase):
|
||||
vg = self._vg_create().Vg
|
||||
self._test_lv_create(
|
||||
vg.LvCreate,
|
||||
(rs(8, '_lv'), mib(4),
|
||||
dbus.Array([], '(ott)'), g_tmo, {}), vg)
|
||||
(lv_n(), mib(4),
|
||||
dbus.Array([], '(ott)'), g_tmo, {}), vg)
|
||||
|
||||
def test_lv_create_job(self):
|
||||
|
||||
vg = self._vg_create().Vg
|
||||
(object_path, job_path) = vg.LvCreate(rs(8, '_lv'), mib(4),
|
||||
dbus.Array([], '(ott)'), 0, {})
|
||||
(object_path, job_path) = vg.LvCreate(
|
||||
lv_n(), mib(4), dbus.Array([], '(ott)'), 0, {})
|
||||
|
||||
self.assertTrue(object_path == '/')
|
||||
self.assertTrue(job_path != '/')
|
||||
@@ -443,7 +469,7 @@ class TestDbusService(unittest.TestCase):
|
||||
vg = self._vg_create().Vg
|
||||
self._test_lv_create(
|
||||
vg.LvCreateLinear,
|
||||
(rs(8, '_lv'), mib(4), False, g_tmo, {}), vg)
|
||||
(lv_n(), mib(4), False, g_tmo, {}), vg)
|
||||
|
||||
def test_lv_create_striped(self):
|
||||
pv_paths = []
|
||||
@@ -452,9 +478,7 @@ class TestDbusService(unittest.TestCase):
|
||||
|
||||
vg = self._vg_create(pv_paths).Vg
|
||||
self._test_lv_create(
|
||||
vg.LvCreateStriped,
|
||||
(rs(8, '_lv'), mib(4), 2, 8, False,
|
||||
g_tmo, {}), vg)
|
||||
vg.LvCreateStriped, (lv_n(), mib(4), 2, 8, False, g_tmo, {}), vg)
|
||||
|
||||
def test_lv_create_mirror(self):
|
||||
pv_paths = []
|
||||
@@ -462,8 +486,8 @@ class TestDbusService(unittest.TestCase):
|
||||
pv_paths.append(pp.object_path)
|
||||
|
||||
vg = self._vg_create(pv_paths).Vg
|
||||
self._test_lv_create(vg.LvCreateMirror,
|
||||
(rs(8, '_lv'), mib(4), 2, g_tmo, {}), vg)
|
||||
self._test_lv_create(
|
||||
vg.LvCreateMirror, (lv_n(), mib(4), 2, g_tmo, {}), vg)
|
||||
|
||||
def test_lv_create_raid(self):
|
||||
pv_paths = []
|
||||
@@ -471,9 +495,8 @@ class TestDbusService(unittest.TestCase):
|
||||
pv_paths.append(pp.object_path)
|
||||
|
||||
vg = self._vg_create(pv_paths).Vg
|
||||
self._test_lv_create(vg.LvCreateRaid,
|
||||
(rs(8, '_lv'), 'raid4',
|
||||
mib(16), 2, 8, g_tmo, {}), vg)
|
||||
self._test_lv_create(
|
||||
vg.LvCreateRaid, (lv_n(), 'raid4', mib(16), 2, 8, g_tmo, {}), vg)
|
||||
|
||||
def _create_lv(self, thinpool=False, size=None, vg=None):
|
||||
|
||||
@@ -489,7 +512,7 @@ class TestDbusService(unittest.TestCase):
|
||||
|
||||
return self._test_lv_create(
|
||||
vg.LvCreateLinear,
|
||||
(rs(8, '_lv'), size, thinpool, g_tmo, {}), vg)
|
||||
(lv_n(), size, thinpool, g_tmo, {}), vg)
|
||||
|
||||
def test_lv_create_rounding(self):
|
||||
self._create_lv(size=(mib(2) + 13))
|
||||
@@ -516,8 +539,9 @@ class TestDbusService(unittest.TestCase):
|
||||
def test_lv_thinpool_rename(self):
|
||||
# Rename a thin pool
|
||||
tp = self._create_lv(True)
|
||||
self.assertTrue(THINPOOL_LV_PATH in tp.object_path,
|
||||
"%s" % (tp.object_path))
|
||||
self.assertTrue(
|
||||
THINPOOL_LV_PATH in tp.object_path,
|
||||
"%s" % (tp.object_path))
|
||||
|
||||
new_name = 'renamed_' + tp.LvCommon.Name
|
||||
self.handle_return(tp.Lv.Rename(new_name, g_tmo, {}))
|
||||
@@ -535,7 +559,7 @@ class TestDbusService(unittest.TestCase):
|
||||
|
||||
thin_path = self.handle_return(
|
||||
tp.ThinPool.LvCreate(
|
||||
rs(10, '_thin_lv'), mib(8), g_tmo, {})
|
||||
lv_n('_thin_lv'), mib(8), g_tmo, {})
|
||||
)
|
||||
|
||||
lv = ClientProxy(self.bus, thin_path)
|
||||
@@ -593,11 +617,13 @@ class TestDbusService(unittest.TestCase):
|
||||
|
||||
pv = vg.Pvs
|
||||
|
||||
pv_proxy = ClientProxy(self.bus, pv[0])
|
||||
pvp = ClientProxy(self.bus, pv[0])
|
||||
|
||||
self._test_lv_create(vg.LvCreate, (rs(8, '_lv'), mib(4),
|
||||
dbus.Array([[pv_proxy.object_path, 0, (pv_proxy.Pv.PeCount - 1)]],
|
||||
'(ott)'), g_tmo, {}), vg)
|
||||
self._test_lv_create(
|
||||
vg.LvCreate,
|
||||
(lv_n(), mib(4),
|
||||
dbus.Array([[pvp.object_path, 0, (pvp.Pv.PeCount - 1)]],
|
||||
'(ott)'), g_tmo, {}), vg)
|
||||
|
||||
def test_lv_resize(self):
|
||||
|
||||
@@ -627,8 +653,8 @@ class TestDbusService(unittest.TestCase):
|
||||
rc = self.handle_return(
|
||||
lv.Lv.Resize(
|
||||
size,
|
||||
dbus.Array([[p.object_path, 0, p.Pv.PeCount - 1]],
|
||||
'(oii)'),
|
||||
dbus.Array(
|
||||
[[p.object_path, 0, p.Pv.PeCount - 1]], '(oii)'),
|
||||
g_tmo, {}))
|
||||
else:
|
||||
rc = self.handle_return(
|
||||
@@ -655,8 +681,8 @@ class TestDbusService(unittest.TestCase):
|
||||
lv = self._create_lv(vg=vg)
|
||||
|
||||
with self.assertRaises(dbus.exceptions.DBusException):
|
||||
lv.Lv.Resize(lv.LvCommon.SizeBytes, dbus.Array([], '(oii)'),
|
||||
-1, {})
|
||||
lv.Lv.Resize(
|
||||
lv.LvCommon.SizeBytes, dbus.Array([], '(oii)'), -1, {})
|
||||
|
||||
def test_lv_move(self):
|
||||
lv = self._create_lv()
|
||||
@@ -674,8 +700,8 @@ class TestDbusService(unittest.TestCase):
|
||||
|
||||
lv.update()
|
||||
new_pv = str(lv.LvCommon.Devices[0][0])
|
||||
self.assertTrue(pv_path_move != new_pv, "%s == %s" %
|
||||
(pv_path_move, new_pv))
|
||||
self.assertTrue(
|
||||
pv_path_move != new_pv, "%s == %s" % (pv_path_move, new_pv))
|
||||
|
||||
def test_lv_activate_deactivate(self):
|
||||
lv_p = self._create_lv()
|
||||
@@ -740,7 +766,7 @@ class TestDbusService(unittest.TestCase):
|
||||
for pp in self.objs[PV_INT]:
|
||||
pv_paths.append(pp.object_path)
|
||||
|
||||
vg_name = rs(8, '_vg')
|
||||
vg_name = vg_n()
|
||||
|
||||
# Test getting a job right away
|
||||
vg_path, vg_job = self.objs[MANAGER_INT][0].Manager.VgCreate(
|
||||
@@ -770,7 +796,7 @@ class TestDbusService(unittest.TestCase):
|
||||
if vg_proxy.Vg.FreeCount > 0:
|
||||
job = self.handle_return(
|
||||
vg_proxy.Vg.LvCreateLinear(
|
||||
rs(8, "_lv"), mib(4), False, g_tmo, {}))
|
||||
lv_n(), mib(4), False, g_tmo, {}))
|
||||
self.assertTrue(job != '/')
|
||||
else:
|
||||
# We ran out of space, test will probably fail
|
||||
@@ -803,12 +829,17 @@ class TestDbusService(unittest.TestCase):
|
||||
|
||||
yes = False
|
||||
|
||||
for pp in self.objs[PV_INT]:
|
||||
if '/dev/sd' not in pp.Pv.Name:
|
||||
std_err_print("Skipping test_job_handling_timer on loopback")
|
||||
return
|
||||
|
||||
# This may not pass
|
||||
for i in [48, 64, 128]:
|
||||
yes = self._test_expired_timer(i)
|
||||
if yes:
|
||||
break
|
||||
print('Attempt (%d) failed, trying again...' % (i))
|
||||
std_err_print('Attempt (%d) failed, trying again...' % (i))
|
||||
|
||||
self.assertTrue(yes)
|
||||
|
||||
@@ -861,7 +892,7 @@ class TestDbusService(unittest.TestCase):
|
||||
vg = self._vg_create().Vg
|
||||
lv = self._test_lv_create(
|
||||
vg.LvCreateLinear,
|
||||
(rs(8, '_lv'), mib(4), False, g_tmo, {}),
|
||||
(lv_n(), mib(4), False, g_tmo, {}),
|
||||
vg)
|
||||
|
||||
t = ['Testing', 'tags']
|
||||
@@ -899,8 +930,9 @@ class TestDbusService(unittest.TestCase):
|
||||
vg.MaxPvSet(p, g_tmo, {}))
|
||||
self.assertEqual(rc, '/')
|
||||
vg.update()
|
||||
self.assertTrue(vg.MaxPv == p, "Expected %s != Actual %s" %
|
||||
(str(p), str(vg.MaxPv)))
|
||||
self.assertTrue(
|
||||
vg.MaxPv == p,
|
||||
"Expected %s != Actual %s" % (str(p), str(vg.MaxPv)))
|
||||
|
||||
def test_vg_max_lv(self):
|
||||
vg = self._vg_create().Vg
|
||||
@@ -911,14 +943,15 @@ class TestDbusService(unittest.TestCase):
|
||||
rc = self.handle_return(vg.MaxLvSet(p, g_tmo, {}))
|
||||
self.assertEqual(rc, '/')
|
||||
vg.update()
|
||||
self.assertTrue(vg.MaxLv == p, "Expected %s != Actual %s" %
|
||||
(str(p), str(vg.MaxLv)))
|
||||
self.assertTrue(
|
||||
vg.MaxLv == p,
|
||||
"Expected %s != Actual %s" % (str(p), str(vg.MaxLv)))
|
||||
|
||||
def test_vg_uuid_gen(self):
|
||||
# TODO renable test case when
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1264169 gets fixed
|
||||
# This was tested with lvmetad disabled and we passed
|
||||
print("\nSkipping Vg.UuidGenerate until BZ: 1264169 resolved\n")
|
||||
std_err_print("\nSkipping Vg.UuidGenerate until BZ: 1264169 resolved\n")
|
||||
|
||||
if False:
|
||||
vg = self._vg_create().Vg
|
||||
@@ -926,14 +959,15 @@ class TestDbusService(unittest.TestCase):
|
||||
rc = self.handle_return(vg.UuidGenerate(g_tmo, {}))
|
||||
self.assertEqual(rc, '/')
|
||||
vg.update()
|
||||
self.assertTrue(vg.Uuid != prev_uuid, "Expected %s != Actual %s" %
|
||||
(vg.Uuid, prev_uuid))
|
||||
self.assertTrue(
|
||||
vg.Uuid != prev_uuid,
|
||||
"Expected %s != Actual %s" % (vg.Uuid, prev_uuid))
|
||||
|
||||
def test_vg_activate_deactivate(self):
|
||||
vg = self._vg_create().Vg
|
||||
self._test_lv_create(
|
||||
vg.LvCreateLinear,
|
||||
(rs(8, '_lv'), mib(4), False, g_tmo, {}),
|
||||
(lv_n(), mib(4), False, g_tmo, {}),
|
||||
vg)
|
||||
|
||||
vg.update()
|
||||
@@ -1008,8 +1042,9 @@ class TestDbusService(unittest.TestCase):
|
||||
|
||||
self.assertEqual(
|
||||
self.handle_return(
|
||||
mgr.PvScan(False, True, dbus.Array([], 's'),
|
||||
dbus.Array([], '(ii)'), g_tmo, {})), '/')
|
||||
mgr.PvScan(
|
||||
False, True, dbus.Array([], 's'),
|
||||
dbus.Array([], '(ii)'), g_tmo, {})), '/')
|
||||
|
||||
self.assertEqual(self._refresh(), 0)
|
||||
self.assertEqual(
|
||||
@@ -1039,13 +1074,8 @@ class TestDbusService(unittest.TestCase):
|
||||
mm.append((int(d.properties['MAJOR']), int(d.properties['MINOR'])))
|
||||
|
||||
self.assertEqual(
|
||||
|
||||
self.handle_return(
|
||||
mgr.PvScan
|
||||
(False, True,
|
||||
block_path,
|
||||
mm, g_tmo, {})
|
||||
), '/')
|
||||
mgr.PvScan(False, True, block_path, mm, g_tmo, {})), '/')
|
||||
|
||||
self.assertEqual(self._refresh(), 0)
|
||||
|
||||
@@ -1092,7 +1122,7 @@ class TestDbusService(unittest.TestCase):
|
||||
|
||||
thin_path = self.handle_return(
|
||||
tp.ThinPool.LvCreate(
|
||||
rs(10, '_thin_lv'), mib(10), g_tmo, {}))
|
||||
lv_n('_thin_lv'), mib(10), g_tmo, {}))
|
||||
|
||||
lv_p = ClientProxy(self.bus, thin_path)
|
||||
|
||||
@@ -1126,8 +1156,8 @@ class TestDbusService(unittest.TestCase):
|
||||
|
||||
vg, cache_pool = self._create_cache_pool()
|
||||
|
||||
self.assertTrue('/com/redhat/lvmdbus1/CachePool' in
|
||||
cache_pool.object_path)
|
||||
self.assertTrue(
|
||||
'/com/redhat/lvmdbus1/CachePool' in cache_pool.object_path)
|
||||
|
||||
def test_cache_lv_create(self):
|
||||
|
||||
@@ -1143,11 +1173,10 @@ class TestDbusService(unittest.TestCase):
|
||||
cached_lv = ClientProxy(self.bus, c_lv_path)
|
||||
|
||||
uncached_lv_path = self.handle_return(
|
||||
cached_lv.CachedLv.DetachCachePool(
|
||||
destroy_cache, g_tmo, {}))
|
||||
cached_lv.CachedLv.DetachCachePool(destroy_cache, g_tmo, {}))
|
||||
|
||||
self.assertTrue('/com/redhat/lvmdbus1/Lv' in
|
||||
uncached_lv_path)
|
||||
self.assertTrue(
|
||||
'/com/redhat/lvmdbus1/Lv' in uncached_lv_path)
|
||||
|
||||
rc = self.handle_return(vg.Remove(g_tmo, {}))
|
||||
self.assertTrue(rc == '/')
|
||||
@@ -1209,22 +1238,24 @@ class TestDbusService(unittest.TestCase):
|
||||
with self.assertRaises(dbus.exceptions.DBusException):
|
||||
self.handle_return(
|
||||
vg_proxy.Vg.LvCreateLinear(
|
||||
rs(8, '_lv') + c,
|
||||
lv_n() + c,
|
||||
mib(4), False, g_tmo, {}))
|
||||
|
||||
for r in ("_cdata", "_cmeta", "_corig", "_mimage", "_mlog",
|
||||
"_pmspare", "_rimage", "_rmeta", "_tdata", "_tmeta", "_vorigin"):
|
||||
for reserved in (
|
||||
"_cdata", "_cmeta", "_corig", "_mimage", "_mlog",
|
||||
"_pmspare", "_rimage", "_rmeta", "_tdata", "_tmeta",
|
||||
"_vorigin"):
|
||||
with self.assertRaises(dbus.exceptions.DBusException):
|
||||
self.handle_return(
|
||||
vg_proxy.Vg.LvCreateLinear(
|
||||
rs(8, '_lv') + r,
|
||||
lv_n() + reserved,
|
||||
mib(4), False, g_tmo, {}))
|
||||
|
||||
for r in ("snapshot", "pvmove"):
|
||||
for reserved in ("snapshot", "pvmove"):
|
||||
with self.assertRaises(dbus.exceptions.DBusException):
|
||||
self.handle_return(
|
||||
vg_proxy.Vg.LvCreateLinear(
|
||||
r + rs(8, '_lv'),
|
||||
reserved + lv_n(),
|
||||
mib(4), False, g_tmo, {}))
|
||||
|
||||
_ALLOWABLE_TAG_CH = string.ascii_letters + string.digits + "._-+/=!:&#"
|
||||
@@ -1264,16 +1295,18 @@ class TestDbusService(unittest.TestCase):
|
||||
for i in range(1, 64):
|
||||
tag = rs(i, "", self._ALLOWABLE_TAG_CH)
|
||||
|
||||
r = self.handle_return(
|
||||
tmp = self.handle_return(
|
||||
vg_proxy.Vg.TagsAdd([tag], g_tmo, {}))
|
||||
self.assertTrue(r == '/')
|
||||
self.assertTrue(tmp == '/')
|
||||
vg_proxy.update()
|
||||
|
||||
self.assertTrue(tag in vg_proxy.Vg.Tags, "%s not in %s" %
|
||||
(tag, str(vg_proxy.Vg.Tags)))
|
||||
self.assertTrue(
|
||||
tag in vg_proxy.Vg.Tags,
|
||||
"%s not in %s" % (tag, str(vg_proxy.Vg.Tags)))
|
||||
|
||||
self.assertEqual(i, len(vg_proxy.Vg.Tags), "%d != %d" %
|
||||
(i, len(vg_proxy.Vg.Tags)))
|
||||
self.assertEqual(
|
||||
i, len(vg_proxy.Vg.Tags),
|
||||
"%d != %d" % (i, len(vg_proxy.Vg.Tags)))
|
||||
|
||||
def test_tag_regression(self):
|
||||
mgr = self.objs[MANAGER_INT][0].Manager
|
||||
@@ -1285,17 +1318,39 @@ class TestDbusService(unittest.TestCase):
|
||||
|
||||
tag = '--h/K.6g0A4FOEatf3+k_nI/Yp&L_u2oy-=j649x:+dUcYWPEo6.IWT0c'
|
||||
|
||||
r = self.handle_return(
|
||||
tmp = self.handle_return(
|
||||
vg_proxy.Vg.TagsAdd([tag], g_tmo, {})
|
||||
)
|
||||
self.assertTrue(r == '/')
|
||||
self.assertTrue(tmp == '/')
|
||||
vg_proxy.update()
|
||||
|
||||
self.assertTrue(tag in vg_proxy.Vg.Tags, "%s not in %s" %
|
||||
(tag, str(vg_proxy.Vg.Tags)))
|
||||
self.assertTrue(
|
||||
tag in vg_proxy.Vg.Tags,
|
||||
"%s not in %s" % (tag, str(vg_proxy.Vg.Tags)))
|
||||
|
||||
|
||||
class AggregateResults(object):
|
||||
|
||||
def __init__(self):
|
||||
self.no_errors = True
|
||||
|
||||
def register_result(self, result):
|
||||
if not result.result.wasSuccessful():
|
||||
self.no_errors = False
|
||||
|
||||
def register_fail(self):
|
||||
self.no_errors = False
|
||||
|
||||
def exit_run(self):
|
||||
if self.no_errors:
|
||||
sys.exit(0)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
r = AggregateResults()
|
||||
|
||||
# Test forking & exec new each time
|
||||
test_shell = os.getenv('LVM_DBUS_TEST_SHELL', 1)
|
||||
|
||||
@@ -1303,20 +1358,24 @@ if __name__ == '__main__':
|
||||
set_execution(False)
|
||||
|
||||
if int(test_shell) == 0:
|
||||
print('\n Shortened fork & exec test ***\n')
|
||||
unittest.main(exit=True)
|
||||
std_err_print('\n Running only lvm fork & exec test ***\n')
|
||||
r.register_result(unittest.main(exit=False))
|
||||
else:
|
||||
print('\n *** Testing fork & exec *** \n')
|
||||
unittest.main(exit=False)
|
||||
std_err_print('\n *** Testing with lvm fork & exec *** \n')
|
||||
r.register_result(unittest.main(exit=False))
|
||||
g_tmo = 15
|
||||
unittest.main(exit=False)
|
||||
r.register_result(unittest.main(exit=False))
|
||||
# Test lvm shell
|
||||
print('\n *** Testing lvm shell *** \n')
|
||||
std_err_print('\n *** Testing with lvm shell *** \n')
|
||||
if set_execution(True):
|
||||
g_tmo = 0
|
||||
unittest.main(exit=False)
|
||||
r.register_result(unittest.main(exit=False))
|
||||
g_tmo = 15
|
||||
unittest.main()
|
||||
r.register_result(unittest.main(exit=False))
|
||||
else:
|
||||
print("WARNING: Unable to dynamically configure "
|
||||
"service to use lvm shell!")
|
||||
r.register_fail()
|
||||
std_err_print(
|
||||
"ERROR: Unable to dynamically configure service to use "
|
||||
"lvm shell!")
|
||||
|
||||
r.exit_run()
|
||||
|
@@ -32,8 +32,7 @@ THINPOOL_LV_PATH = '/' + THINPOOL_INT.replace('.', '/')
|
||||
|
||||
|
||||
def rs(length, suffix, character_set=string.ascii_lowercase):
|
||||
return ''.join(random.choice(character_set)
|
||||
for _ in range(length)) + suffix
|
||||
return ''.join(random.choice(character_set) for _ in range(length)) + suffix
|
||||
|
||||
|
||||
def mib(s):
|
||||
@@ -50,8 +49,7 @@ class DbusIntrospection(object):
|
||||
for c in root:
|
||||
if c.tag == "interface":
|
||||
in_f = c.attrib['name']
|
||||
interfaces[in_f] = \
|
||||
dict(methods=OrderedDict(), properties={})
|
||||
interfaces[in_f] = dict(methods=OrderedDict(), properties={})
|
||||
for nested in c:
|
||||
if nested.tag == "method":
|
||||
mn = nested.attrib['name']
|
||||
@@ -71,7 +69,8 @@ class DbusIntrospection(object):
|
||||
v = dict(
|
||||
name=mn,
|
||||
a_dir=arg_dir,
|
||||
a_type=arg_type)
|
||||
a_type=arg_type
|
||||
)
|
||||
interfaces[in_f]['methods'][mn][n] = v
|
||||
|
||||
elif nested.tag == 'property':
|
||||
@@ -148,10 +147,9 @@ def verify_type(value, dbus_str_rep):
|
||||
# print("%s ~= %s" % (dbus_str_rep, actual_str_rep))
|
||||
# Unless we have a full filled out type we won't match exactly
|
||||
if not dbus_str_rep.startswith(actual_str_rep):
|
||||
raise RuntimeError("Incorrect type, expected= %s actual "
|
||||
"= %s object= %s" %
|
||||
(dbus_str_rep, actual_str_rep,
|
||||
str(type(value))))
|
||||
raise RuntimeError(
|
||||
"Incorrect type, expected= %s actual = %s object= %s" %
|
||||
(dbus_str_rep, actual_str_rep, str(type(value))))
|
||||
|
||||
|
||||
class RemoteObject(object):
|
||||
@@ -174,12 +172,14 @@ class RemoteObject(object):
|
||||
if props:
|
||||
for kl, vl in list(props.items()):
|
||||
# Verify type is correct!
|
||||
verify_type(vl,
|
||||
verify_type(
|
||||
vl,
|
||||
self.introspect[self.interface]['properties'][kl]['p_type'])
|
||||
setattr(self, kl, vl)
|
||||
|
||||
def __init__(self, specified_bus, object_path, interface, introspect,
|
||||
properties=None):
|
||||
def __init__(
|
||||
self, specified_bus, object_path, interface, introspect,
|
||||
properties=None):
|
||||
self.object_path = object_path
|
||||
self.interface = interface
|
||||
self.bus = specified_bus
|
||||
@@ -238,11 +238,11 @@ class ClientProxy(object):
|
||||
# print('Client proxy has interface: %s %s' % (k, sn))
|
||||
|
||||
if interface and interface == k and props is not None:
|
||||
ro = RemoteObject(specified_bus, object_path, k,
|
||||
self.intro_spect, props)
|
||||
ro = RemoteObject(
|
||||
specified_bus, object_path, k, self.intro_spect, props)
|
||||
else:
|
||||
ro = RemoteObject(specified_bus, object_path, k,
|
||||
self.intro_spect)
|
||||
ro = RemoteObject(
|
||||
specified_bus, object_path, k, self.intro_spect)
|
||||
|
||||
setattr(self, sn, ro)
|
||||
|
||||
|
@@ -325,8 +325,8 @@ prepare_lvmdbusd() {
|
||||
daemon="$(which lvmdbusd || :)"
|
||||
fi
|
||||
[[ -n $daemon && -x $daemon ]] || skip "The daemon is missing"
|
||||
|
||||
which python3 >/dev/null || skip "Missing python3"
|
||||
|
||||
python3 -c "import pyudev, dbus, gi.repository" || skip "Missing python modules"
|
||||
|
||||
# Copy the needed file to run on the system bus if it doesn't
|
||||
@@ -336,6 +336,8 @@ prepare_lvmdbusd() {
|
||||
fi
|
||||
|
||||
echo "preparing lvmdbusd..."
|
||||
lvmconf "global/notify_dbus = 1"
|
||||
|
||||
"$daemon" --debug > debug.log_LVMDBUSD_out 2>&1 &
|
||||
local pid=$!
|
||||
|
||||
@@ -1079,6 +1081,7 @@ devices/global_filter = [ "a|$DM_DEV_DIR/mapper/.*pv[0-9_]*$|", "r|.*|" ]
|
||||
devices/md_component_detection = 0
|
||||
devices/scan = "$DM_DEV_DIR"
|
||||
devices/sysfs_scan = 1
|
||||
devices/write_cache_state = 0
|
||||
global/abort_on_internal_errors = 1
|
||||
global/cache_check_executable = "$LVM_TEST_CACHE_CHECK_CMD"
|
||||
global/cache_dump_executable = "$LVM_TEST_CACHE_DUMP_CMD"
|
||||
@@ -1088,6 +1091,7 @@ global/fallback_to_local_locking = 0
|
||||
global/library_dir = "$TESTDIR/lib"
|
||||
global/locking_dir = "$TESTDIR/var/lock/lvm"
|
||||
global/locking_type=$LVM_TEST_LOCKING
|
||||
global/notify_dbus = 0
|
||||
global/si_unit_consistency = 1
|
||||
global/thin_check_executable = "$LVM_TEST_THIN_CHECK_CMD"
|
||||
global/thin_dump_executable = "$LVM_TEST_THIN_DUMP_CMD"
|
||||
|
@@ -81,7 +81,8 @@ lvcreate -l1 -s -n inval $vg/$lv3
|
||||
lvcreate -l4 -I4 -i2 -n stripe $vg
|
||||
# Invalidate snapshot
|
||||
not dd if=/dev/zero of="$DM_DEV_DIR/$vg/inval" bs=4K
|
||||
invalid lvscan "$dev1"
|
||||
# ignores unused positional arg dev1
|
||||
lvscan "$dev1"
|
||||
lvdisplay --maps
|
||||
lvscan --all
|
||||
|
||||
@@ -108,13 +109,16 @@ vgmknodes --refresh
|
||||
lvscan
|
||||
lvmdiskscan
|
||||
|
||||
invalid pvscan "$dev1"
|
||||
# ignores unused arg
|
||||
pvscan "$dev1"
|
||||
invalid pvscan -aay
|
||||
invalid pvscan --major 254
|
||||
invalid pvscan --minor 0
|
||||
invalid pvscan --novolumegroup -e
|
||||
invalid vgscan $vg
|
||||
invalid lvscan $vg
|
||||
# ignores unsed arg
|
||||
vgscan $vg
|
||||
# ignroes unused arg
|
||||
lvscan $vg
|
||||
|
||||
if aux have_readline; then
|
||||
cat <<EOF | lvm
|
||||
|
@@ -56,7 +56,7 @@ fail lvcreate -l 1 --cachepool pool8 $vg
|
||||
|
||||
# no size specified
|
||||
invalid lvcreate --cachepool pool $vg 2>&1 | tee err
|
||||
grep "specify either size or extents" err
|
||||
# grep "specify either size or extents" err
|
||||
|
||||
# Check nothing has been created yet
|
||||
check vg_field $vg lv_count 0
|
||||
|
@@ -42,6 +42,7 @@ dmsetup suspend $vg-$lv1
|
||||
|
||||
# now this should pass without blocking
|
||||
dmsetup suspend --noflush --nolockfs $vg1-snap &
|
||||
DMPID=$!
|
||||
#dmsetup suspend $vg1-snap &
|
||||
|
||||
sleep .5
|
||||
@@ -55,20 +56,28 @@ dmsetup resume $vg-$lv1
|
||||
# otherwise --noudevsync would be needed
|
||||
dmsetup resume $vg1-snap
|
||||
|
||||
# Expecting success from 'dmsetup'
|
||||
wait $DMPID
|
||||
|
||||
|
||||
# Try how force removal works
|
||||
dmsetup suspend $vg-$lv1
|
||||
# needs to fail as device is still open
|
||||
not dmsetup remove --force $vg1-snap &
|
||||
DMPID=$!
|
||||
|
||||
# on older snapshot target 'remove' will wait till $lv1 is resumed
|
||||
if aux target_at_least dm-snapshot 1 6 0 ; then
|
||||
sleep .5
|
||||
|
||||
dmsetup table $vg1-snap | tee out
|
||||
should grep -i error out
|
||||
fi
|
||||
|
||||
dmsetup resume $vg-$lv1
|
||||
|
||||
wait
|
||||
# Expecting success from 'not dmsetup'
|
||||
wait $DMPID
|
||||
|
||||
# check it really is now 'error' target
|
||||
dmsetup table $vg1-snap | tee out
|
||||
|
@@ -76,6 +76,7 @@ SOURCES2 =\
|
||||
|
||||
TARGETS =\
|
||||
.commands \
|
||||
command-lines.h \
|
||||
liblvm2cmd.a \
|
||||
lvm
|
||||
|
||||
@@ -99,7 +100,8 @@ LIB_VERSION = $(LIB_VERSION_LVM)
|
||||
CLEAN_TARGETS = liblvm2cmd.$(LIB_SUFFIX) $(TARGETS_DM) \
|
||||
liblvm2cmd.$(LIB_SUFFIX).$(LIB_VERSION) lvm-static.o \
|
||||
liblvm2cmd-static.a dmsetup.static lvm.static \
|
||||
$(LDDEPS) .exported_symbols_generated
|
||||
$(LDDEPS) .exported_symbols_generated \
|
||||
ccmd command-lines.h command-lines-count.h
|
||||
|
||||
ifeq ("@CMDLIB@", "yes")
|
||||
TARGETS += liblvm2cmd.$(LIB_SUFFIX).$(LIB_VERSION)
|
||||
@@ -171,6 +173,13 @@ liblvm2cmd.$(LIB_SUFFIX).$(LIB_VERSION): liblvm2cmd.$(LIB_SUFFIX)
|
||||
$(CC) -E -P $(srcdir)/cmdnames.h 2> /dev/null | \
|
||||
egrep -v '^ *(|#.*|config|devtypes|dumpconfig|formats|fullreport|help|lastlog|lvpoll|pvdata|segtypes|systemid|tags|version) *$$' > .commands
|
||||
|
||||
ccmd: create-commands.c
|
||||
$(CC) create-commands.c -o ccmd
|
||||
|
||||
command-lines.h: ccmd
|
||||
./ccmd --output struct command-lines.in > command-lines.h
|
||||
./ccmd --output count command-lines.in > command-lines-count.h
|
||||
|
||||
ifneq ("$(CFLOW_CMD)", "")
|
||||
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
|
||||
-include $(top_builddir)/libdm/libdevmapper.cflow
|
||||
|
405
tools/args.h
405
tools/args.h
@@ -17,215 +17,214 @@
|
||||
* Put all long args that don't have a corresponding short option first.
|
||||
*/
|
||||
/* *INDENT-OFF* */
|
||||
arg(abort_ARG, '\0', "abort", NULL, 0, 0)
|
||||
arg(activationmode_ARG, '\0', "activationmode", string_arg, 0, 0)
|
||||
arg(addtag_ARG, '\0', "addtag", tag_arg, ARG_GROUPABLE, 0)
|
||||
arg(aligned_ARG, '\0', "aligned", NULL, 0, 0)
|
||||
arg(alloc_ARG, '\0', "alloc", alloc_arg, 0, 0)
|
||||
arg(atomic_ARG, '\0', "atomic", NULL, 0, 0)
|
||||
arg(atversion_ARG, '\0', "atversion", string_arg, 0, 0)
|
||||
arg(binary_ARG, '\0', "binary", NULL, 0, 0)
|
||||
arg(bootloaderareasize_ARG, '\0', "bootloaderareasize", size_mb_arg, 0, 0)
|
||||
arg(cache_long_ARG, '\0', "cache", NULL, 0, 0)
|
||||
arg(cachemode_ARG, '\0', "cachemode", cachemode_arg, 0, 0)
|
||||
arg(cachepool_ARG, '\0', "cachepool", string_arg, 0, 0)
|
||||
arg(commandprofile_ARG, '\0', "commandprofile", string_arg, 0, 0)
|
||||
arg(config_ARG, '\0', "config", string_arg, 0, 0)
|
||||
arg(configreport_ARG, '\0', "configreport", string_arg, ARG_GROUPABLE, 1)
|
||||
arg(configtype_ARG, '\0', "type", string_arg, 0, 0)
|
||||
arg(corelog_ARG, '\0', "corelog", NULL, 0, 0)
|
||||
arg(dataalignment_ARG, '\0', "dataalignment", size_kb_arg, 0, 0)
|
||||
arg(dataalignmentoffset_ARG, '\0', "dataalignmentoffset", size_kb_arg, 0, 0)
|
||||
arg(deltag_ARG, '\0', "deltag", tag_arg, ARG_GROUPABLE, 0)
|
||||
arg(detachprofile_ARG, '\0', "detachprofile", NULL, 0, 0)
|
||||
arg(discards_ARG, '\0', "discards", discards_arg, 0, 0)
|
||||
arg(driverloaded_ARG, '\0', "driverloaded", yes_no_arg, 0, 0)
|
||||
arg(errorwhenfull_ARG, '\0', "errorwhenfull", yes_no_arg, 0, 0)
|
||||
arg(force_long_ARG, '\0', "force", NULL, ARG_COUNTABLE, 0)
|
||||
arg(foreign_ARG, '\0', "foreign", NULL, 0, 0)
|
||||
arg(handlemissingpvs_ARG, '\0', "handlemissingpvs", NULL, 0, 0)
|
||||
arg(ignoreadvanced_ARG, '\0', "ignoreadvanced", NULL, 0, 0)
|
||||
arg(ignorelocal_ARG, '\0', "ignorelocal", NULL, 0, 0)
|
||||
arg(ignorelockingfailure_ARG, '\0', "ignorelockingfailure", NULL, 0, 0)
|
||||
arg(ignoremonitoring_ARG, '\0', "ignoremonitoring", NULL, 0, 0)
|
||||
arg(ignoreskippedcluster_ARG, '\0', "ignoreskippedcluster", NULL, 0, 0)
|
||||
arg(ignoreunsupported_ARG, '\0', "ignoreunsupported", NULL, 0, 0)
|
||||
arg(labelsector_ARG, '\0', "labelsector", int_arg, 0, 0)
|
||||
arg(lockopt_ARG, '\0', "lockopt", string_arg, 0, 0)
|
||||
arg(lockstart_ARG, '\0', "lockstart", NULL, 0, 0)
|
||||
arg(lockstop_ARG, '\0', "lockstop", NULL, 0, 0)
|
||||
arg(locktype_ARG, '\0', "locktype", locktype_arg, 0, 0)
|
||||
arg(logonly_ARG, '\0', "logonly", NULL, 0, 0)
|
||||
arg(maxrecoveryrate_ARG, '\0', "maxrecoveryrate", size_kb_arg, 0, 0)
|
||||
arg(merge_ARG, '\0', "merge", NULL, 0, 0)
|
||||
arg(mergedconfig_ARG, '\0', "mergedconfig", NULL, 0, 0)
|
||||
arg(metadatacopies_ARG, '\0', "metadatacopies", metadatacopies_arg, 0, 0)
|
||||
arg(metadataignore_ARG, '\0', "metadataignore", yes_no_arg, 0, 0)
|
||||
arg(metadataprofile_ARG, '\0', "metadataprofile", string_arg, 0, 0)
|
||||
arg(metadatasize_ARG, '\0', "metadatasize", size_mb_arg, 0, 0)
|
||||
arg(minor_ARG, '\0', "minor", int_arg, ARG_GROUPABLE, 0)
|
||||
arg(minrecoveryrate_ARG, '\0', "minrecoveryrate", size_kb_arg, 0, 0)
|
||||
arg(mirrorlog_ARG, '\0', "mirrorlog", mirrorlog_arg, 0, 0)
|
||||
arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL, 0, 0)
|
||||
arg(mknodes_ARG, '\0', "mknodes", NULL, 0, 0)
|
||||
arg(monitor_ARG, '\0', "monitor", yes_no_arg, 0, 0)
|
||||
arg(nameprefixes_ARG, '\0', "nameprefixes", NULL, 0, 0)
|
||||
arg(noheadings_ARG, '\0', "noheadings", NULL, 0, 0)
|
||||
arg(nohistory_ARG, '\0', "nohistory", NULL, 0, 0)
|
||||
arg(nolocking_ARG, '\0', "nolocking", NULL, 0, 0)
|
||||
arg(norestorefile_ARG, '\0', "norestorefile", NULL, 0, 0)
|
||||
arg(nosuffix_ARG, '\0', "nosuffix", NULL, 0, 0)
|
||||
arg(nosync_ARG, '\0', "nosync", NULL, 0, 0)
|
||||
arg(notifydbus_ARG, '\0', "notifydbus", NULL, 0, 0)
|
||||
arg(noudevsync_ARG, '\0', "noudevsync", NULL, 0, 0)
|
||||
arg(originname_ARG, '\0', "originname", string_arg, 0, 0)
|
||||
arg(physicalvolumesize_ARG, '\0', "setphysicalvolumesize", size_mb_arg, 0, 0)
|
||||
arg(poll_ARG, '\0', "poll", yes_no_arg, 0, 0)
|
||||
arg(polloperation_ARG, '\0', "polloperation", string_arg, 0, 0)
|
||||
arg(pooldatasize_ARG, '\0', "pooldatasize", size_mb_arg, 0, 0)
|
||||
arg(poolmetadata_ARG, '\0', "poolmetadata", string_arg, 0, 0)
|
||||
arg(poolmetadatasize_ARG, '\0', "poolmetadatasize", size_mb_arg, 0, 0)
|
||||
arg(poolmetadataspare_ARG, '\0', "poolmetadataspare", yes_no_arg, 0, 0)
|
||||
arg(profile_ARG, '\0', "profile", string_arg, 0, 0)
|
||||
arg(pvmetadatacopies_ARG, '\0', "pvmetadatacopies", int_arg, 0, 0)
|
||||
arg(raidrebuild_ARG, '\0', "raidrebuild", string_arg, ARG_GROUPABLE, 0)
|
||||
arg(raidmaxrecoveryrate_ARG, '\0', "raidmaxrecoveryrate", size_kb_arg, 0, 0)
|
||||
arg(raidminrecoveryrate_ARG, '\0', "raidminrecoveryrate", size_kb_arg, 0, 0)
|
||||
arg(raidsyncaction_ARG, '\0', "raidsyncaction", string_arg, 0, 0)
|
||||
arg(raidwritebehind_ARG, '\0', "raidwritebehind", int_arg, 0, 0)
|
||||
arg(raidwritemostly_ARG, '\0', "raidwritemostly", string_arg, ARG_GROUPABLE, 0)
|
||||
arg(readonly_ARG, '\0', "readonly", NULL, 0, 0)
|
||||
arg(refresh_ARG, '\0', "refresh", NULL, 0, 0)
|
||||
arg(removemissing_ARG, '\0', "removemissing", NULL, 0, 0)
|
||||
arg(rebuild_ARG, '\0', "rebuild", string_arg, ARG_GROUPABLE, 0)
|
||||
arg(repair_ARG, '\0', "repair", NULL, 0, 0)
|
||||
arg(replace_ARG, '\0', "replace", string_arg, ARG_GROUPABLE, 0)
|
||||
arg(reportformat_ARG, '\0', "reportformat", string_arg, 0, 0)
|
||||
arg(restorefile_ARG, '\0', "restorefile", string_arg, 0, 0)
|
||||
arg(restoremissing_ARG, '\0', "restoremissing", NULL, 0, 0)
|
||||
arg(resync_ARG, '\0', "resync", NULL, 0, 0)
|
||||
arg(rows_ARG, '\0', "rows", NULL, 0, 0)
|
||||
arg(segments_ARG, '\0', "segments", NULL, 0, 0)
|
||||
arg(separator_ARG, '\0', "separator", string_arg, 0, 0)
|
||||
arg(shared_ARG, '\0', "shared", NULL, 0, 0)
|
||||
arg(sinceversion_ARG, '\0', "sinceversion", string_arg, 0, 0)
|
||||
arg(split_ARG, '\0', "split", NULL, 0, 0)
|
||||
arg(splitcache_ARG, '\0', "splitcache", NULL, 0, 0)
|
||||
arg(splitmirrors_ARG, '\0', "splitmirrors", int_arg, 0, 0)
|
||||
arg(splitsnapshot_ARG, '\0', "splitsnapshot", NULL, 0, 0)
|
||||
arg(showdeprecated_ARG, '\0', "showdeprecated", NULL, 0, 0)
|
||||
arg(showunsupported_ARG, '\0', "showunsupported", NULL, 0, 0)
|
||||
arg(stripes_long_ARG, '\0', "stripes", int_arg, 0, 0)
|
||||
arg(syncaction_ARG, '\0', "syncaction", string_arg, 0, 0) /* FIXME Use custom validation fn */
|
||||
arg(sysinit_ARG, '\0', "sysinit", NULL, 0, 0)
|
||||
arg(systemid_ARG, '\0', "systemid", string_arg, 0, 0)
|
||||
arg(thinpool_ARG, '\0', "thinpool", string_arg, 0, 0)
|
||||
arg(trackchanges_ARG, '\0', "trackchanges", NULL, 0, 0)
|
||||
arg(trustcache_ARG, '\0', "trustcache", NULL, 0, 0)
|
||||
arg(type_ARG, '\0', "type", segtype_arg, 0, 0)
|
||||
arg(unbuffered_ARG, '\0', "unbuffered", NULL, 0, 0)
|
||||
arg(uncache_ARG, '\0', "uncache", NULL, 0, 0)
|
||||
arg(cachepolicy_ARG, '\0', "cachepolicy", string_arg, 0, 0)
|
||||
arg(cachesettings_ARG, '\0', "cachesettings", string_arg, ARG_GROUPABLE, 0)
|
||||
arg(unconfigured_ARG, '\0', "unconfigured", NULL, 0, 0)
|
||||
arg(units_ARG, '\0', "units", string_arg, 0, 0)
|
||||
arg(unquoted_ARG, '\0', "unquoted", NULL, 0, 0)
|
||||
arg(usepolicies_ARG, '\0', "usepolicies", NULL, 0, 0)
|
||||
arg(validate_ARG, '\0', "validate", NULL, 0, 0)
|
||||
arg(version_ARG, '\0', "version", NULL, 0, 0)
|
||||
arg(vgmetadatacopies_ARG, '\0', "vgmetadatacopies", metadatacopies_arg, 0, 0)
|
||||
arg(virtualoriginsize_ARG, '\0', "virtualoriginsize", size_mb_arg, 0, 0)
|
||||
arg(withsummary_ARG, '\0', "withsummary", NULL, 0, 0)
|
||||
arg(withcomments_ARG, '\0', "withcomments", NULL, 0, 0)
|
||||
arg(withspaces_ARG, '\0', "withspaces", NULL, 0, 0)
|
||||
arg(withversions_ARG, '\0', "withversions", NULL, 0, 0)
|
||||
arg(writebehind_ARG, '\0', "writebehind", int_arg, 0, 0)
|
||||
arg(writemostly_ARG, '\0', "writemostly", string_arg, ARG_GROUPABLE, 0)
|
||||
arg(abort_ARG, '\0', "abort", 0, 0, 0)
|
||||
arg(activationmode_ARG, '\0', "activationmode", activationmode_VAL, 0, 0)
|
||||
arg(addtag_ARG, '\0', "addtag", tag_VAL, ARG_GROUPABLE, 0)
|
||||
arg(aligned_ARG, '\0', "aligned", 0, 0, 0)
|
||||
arg(alloc_ARG, '\0', "alloc", alloc_VAL, 0, 0)
|
||||
arg(atomic_ARG, '\0', "atomic", 0, 0, 0)
|
||||
arg(atversion_ARG, '\0', "atversion", string_VAL, 0, 0)
|
||||
arg(binary_ARG, '\0', "binary", 0, 0, 0)
|
||||
arg(bootloaderareasize_ARG, '\0', "bootloaderareasize", sizemb_VAL, 0, 0)
|
||||
arg(cache_long_ARG, '\0', "cache", 0, 0, 0)
|
||||
arg(cachemode_ARG, '\0', "cachemode", cachemode_VAL, 0, 0)
|
||||
arg(cachepool_ARG, '\0', "cachepool", lv_VAL, 0, 0)
|
||||
arg(commandprofile_ARG, '\0', "commandprofile", string_VAL, 0, 0)
|
||||
arg(config_ARG, '\0', "config", string_VAL, 0, 0)
|
||||
arg(configreport_ARG, '\0', "configreport", string_VAL, ARG_GROUPABLE, 1)
|
||||
arg(configtype_ARG, '\0', "typeconfig", string_VAL, 0, 0)
|
||||
arg(corelog_ARG, '\0', "corelog", 0, 0, 0)
|
||||
arg(dataalignment_ARG, '\0', "dataalignment", sizekb_VAL, 0, 0)
|
||||
arg(dataalignmentoffset_ARG, '\0', "dataalignmentoffset", sizekb_VAL, 0, 0)
|
||||
arg(deltag_ARG, '\0', "deltag", tag_VAL, ARG_GROUPABLE, 0)
|
||||
arg(detachprofile_ARG, '\0', "detachprofile", 0, 0, 0)
|
||||
arg(discards_ARG, '\0', "discards", discards_VAL, 0, 0)
|
||||
arg(driverloaded_ARG, '\0', "driverloaded", bool_VAL, 0, 0)
|
||||
arg(errorwhenfull_ARG, '\0', "errorwhenfull", bool_VAL, 0, 0)
|
||||
arg(force_long_ARG, '\0', "force", 0, ARG_COUNTABLE, 0)
|
||||
arg(foreign_ARG, '\0', "foreign", 0, 0, 0)
|
||||
arg(handlemissingpvs_ARG, '\0', "handlemissingpvs", 0, 0, 0)
|
||||
arg(ignoreadvanced_ARG, '\0', "ignoreadvanced", 0, 0, 0)
|
||||
arg(ignorelocal_ARG, '\0', "ignorelocal", 0, 0, 0)
|
||||
arg(ignorelockingfailure_ARG, '\0', "ignorelockingfailure", 0, 0, 0)
|
||||
arg(ignoremonitoring_ARG, '\0', "ignoremonitoring", 0, 0, 0)
|
||||
arg(ignoreskippedcluster_ARG, '\0', "ignoreskippedcluster", 0, 0, 0)
|
||||
arg(ignoreunsupported_ARG, '\0', "ignoreunsupported", 0, 0, 0)
|
||||
arg(labelsector_ARG, '\0', "labelsector", number_VAL, 0, 0)
|
||||
arg(lockopt_ARG, '\0', "lockopt", string_VAL, 0, 0)
|
||||
arg(lockstart_ARG, '\0', "lockstart", 0, 0, 0)
|
||||
arg(lockstop_ARG, '\0', "lockstop", 0, 0, 0)
|
||||
arg(locktype_ARG, '\0', "locktype", locktype_VAL, 0, 0)
|
||||
arg(logonly_ARG, '\0', "logonly", 0, 0, 0)
|
||||
arg(maxrecoveryrate_ARG, '\0', "maxrecoveryrate", sizekb_VAL, 0, 0)
|
||||
arg(merge_ARG, '\0', "merge", 0, 0, 0)
|
||||
arg(mergedconfig_ARG, '\0', "mergedconfig", 0, 0, 0)
|
||||
arg(metadatacopies_ARG, '\0', "metadatacopies", metadatacopies_VAL, 0, 0)
|
||||
arg(metadataignore_ARG, '\0', "metadataignore", bool_VAL, 0, 0)
|
||||
arg(metadataprofile_ARG, '\0', "metadataprofile", string_VAL, 0, 0)
|
||||
arg(metadatasize_ARG, '\0', "metadatasize", sizemb_VAL, 0, 0)
|
||||
arg(minor_ARG, '\0', "minor", number_VAL, ARG_GROUPABLE, 0)
|
||||
arg(minrecoveryrate_ARG, '\0', "minrecoveryrate", sizekb_VAL, 0, 0)
|
||||
arg(mirrorlog_ARG, '\0', "mirrorlog", mirrorlog_VAL, 0, 0)
|
||||
arg(mirrorsonly_ARG, '\0', "mirrorsonly", 0, 0, 0)
|
||||
arg(mknodes_ARG, '\0', "mknodes", 0, 0, 0)
|
||||
arg(monitor_ARG, '\0', "monitor", bool_VAL, 0, 0)
|
||||
arg(nameprefixes_ARG, '\0', "nameprefixes", 0, 0, 0)
|
||||
arg(noheadings_ARG, '\0', "noheadings", 0, 0, 0)
|
||||
arg(nohistory_ARG, '\0', "nohistory", 0, 0, 0)
|
||||
arg(nolocking_ARG, '\0', "nolocking", 0, 0, 0)
|
||||
arg(norestorefile_ARG, '\0', "norestorefile", 0, 0, 0)
|
||||
arg(nosuffix_ARG, '\0', "nosuffix", 0, 0, 0)
|
||||
arg(nosync_ARG, '\0', "nosync", 0, 0, 0)
|
||||
arg(notifydbus_ARG, '\0', "notifydbus", 0, 0, 0)
|
||||
arg(noudevsync_ARG, '\0', "noudevsync", 0, 0, 0)
|
||||
arg(originname_ARG, '\0', "originname", lv_VAL, 0, 0)
|
||||
arg(physicalvolumesize_ARG, '\0', "setphysicalvolumesize", sizemb_VAL, 0, 0)
|
||||
arg(poll_ARG, '\0', "poll", bool_VAL, 0, 0)
|
||||
arg(polloperation_ARG, '\0', "polloperation", string_VAL, 0, 0)
|
||||
arg(pooldatasize_ARG, '\0', "pooldatasize", sizemb_VAL, 0, 0)
|
||||
arg(poolmetadata_ARG, '\0', "poolmetadata", lv_VAL, 0, 0)
|
||||
arg(poolmetadatasize_ARG, '\0', "poolmetadatasize", sizemb_VAL, 0, 0)
|
||||
arg(poolmetadataspare_ARG, '\0', "poolmetadataspare", bool_VAL, 0, 0)
|
||||
arg(profile_ARG, '\0', "profile", string_VAL, 0, 0)
|
||||
arg(pvmetadatacopies_ARG, '\0', "pvmetadatacopies", number_VAL, 0, 0)
|
||||
arg(raidrebuild_ARG, '\0', "raidrebuild", string_VAL, ARG_GROUPABLE, 0)
|
||||
arg(raidmaxrecoveryrate_ARG, '\0', "raidmaxrecoveryrate", sizekb_VAL, 0, 0)
|
||||
arg(raidminrecoveryrate_ARG, '\0', "raidminrecoveryrate", sizekb_VAL, 0, 0)
|
||||
arg(raidsyncaction_ARG, '\0', "raidsyncaction", string_VAL, 0, 0)
|
||||
arg(raidwritebehind_ARG, '\0', "raidwritebehind", number_VAL, 0, 0)
|
||||
arg(raidwritemostly_ARG, '\0', "raidwritemostly", string_VAL, ARG_GROUPABLE, 0)
|
||||
arg(readonly_ARG, '\0', "readonly", 0, 0, 0)
|
||||
arg(refresh_ARG, '\0', "refresh", 0, 0, 0)
|
||||
arg(removemissing_ARG, '\0', "removemissing", 0, 0, 0)
|
||||
arg(rebuild_ARG, '\0', "rebuild", pv_VAL, ARG_GROUPABLE, 0)
|
||||
arg(repair_ARG, '\0', "repair", 0, 0, 0)
|
||||
arg(replace_ARG, '\0', "replace", pv_VAL, ARG_GROUPABLE, 0)
|
||||
arg(reportformat_ARG, '\0', "reportformat", string_VAL, 0, 0)
|
||||
arg(restorefile_ARG, '\0', "restorefile", string_VAL, 0, 0)
|
||||
arg(restoremissing_ARG, '\0', "restoremissing", 0, 0, 0)
|
||||
arg(resync_ARG, '\0', "resync", 0, 0, 0)
|
||||
arg(rows_ARG, '\0', "rows", 0, 0, 0)
|
||||
arg(segments_ARG, '\0', "segments", 0, 0, 0)
|
||||
arg(separator_ARG, '\0', "separator", string_VAL, 0, 0)
|
||||
arg(shared_ARG, '\0', "shared", 0, 0, 0)
|
||||
arg(sinceversion_ARG, '\0', "sinceversion", string_VAL, 0, 0)
|
||||
arg(split_ARG, '\0', "split", 0, 0, 0)
|
||||
arg(splitcache_ARG, '\0', "splitcache", 0, 0, 0)
|
||||
arg(splitmirrors_ARG, '\0', "splitmirrors", number_VAL, 0, 0)
|
||||
arg(splitsnapshot_ARG, '\0', "splitsnapshot", 0, 0, 0)
|
||||
arg(showdeprecated_ARG, '\0', "showdeprecated", 0, 0, 0)
|
||||
arg(showunsupported_ARG, '\0', "showunsupported", 0, 0, 0)
|
||||
arg(stripes_long_ARG, '\0', "stripes", number_VAL, 0, 0)
|
||||
arg(syncaction_ARG, '\0', "syncaction", string_VAL, 0, 0) /* FIXME Use custom VAL */
|
||||
arg(sysinit_ARG, '\0', "sysinit", 0, 0, 0)
|
||||
arg(systemid_ARG, '\0', "systemid", string_VAL, 0, 0)
|
||||
arg(thinpool_ARG, '\0', "thinpool", lv_VAL, 0, 0)
|
||||
arg(trackchanges_ARG, '\0', "trackchanges", 0, 0, 0)
|
||||
arg(trustcache_ARG, '\0', "trustcache", 0, 0, 0)
|
||||
arg(type_ARG, '\0', "type", segtype_VAL, 0, 0)
|
||||
arg(unbuffered_ARG, '\0', "unbuffered", 0, 0, 0)
|
||||
arg(uncache_ARG, '\0', "uncache", 0, 0, 0)
|
||||
arg(cachepolicy_ARG, '\0', "cachepolicy", string_VAL, 0, 0)
|
||||
arg(cachesettings_ARG, '\0', "cachesettings", string_VAL, ARG_GROUPABLE, 0)
|
||||
arg(unconfigured_ARG, '\0', "unconfigured", 0, 0, 0)
|
||||
arg(units_ARG, '\0', "units", units_VAL, 0, 0)
|
||||
arg(unquoted_ARG, '\0', "unquoted", 0, 0, 0)
|
||||
arg(usepolicies_ARG, '\0', "usepolicies", 0, 0, 0)
|
||||
arg(validate_ARG, '\0', "validate", 0, 0, 0)
|
||||
arg(version_ARG, '\0', "version", 0, 0, 0)
|
||||
arg(vgmetadatacopies_ARG, '\0', "vgmetadatacopies", metadatacopies_VAL, 0, 0)
|
||||
arg(virtualoriginsize_ARG, '\0', "virtualoriginsize", sizemb_VAL, 0, 0)
|
||||
arg(withsummary_ARG, '\0', "withsummary", 0, 0, 0)
|
||||
arg(withcomments_ARG, '\0', "withcomments", 0, 0, 0)
|
||||
arg(withspaces_ARG, '\0', "withspaces", 0, 0, 0)
|
||||
arg(withversions_ARG, '\0', "withversions", 0, 0, 0)
|
||||
arg(writebehind_ARG, '\0', "writebehind", number_VAL, 0, 0)
|
||||
arg(writemostly_ARG, '\0', "writemostly", string_VAL, ARG_GROUPABLE, 0)
|
||||
|
||||
/* Allow some variations */
|
||||
arg(allocation_ARG, '\0', "allocation", yes_no_arg, 0, 0)
|
||||
arg(available_ARG, '\0', "available", activation_arg, 0, 0)
|
||||
arg(resizable_ARG, '\0', "resizable", yes_no_arg, 0, 0)
|
||||
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_arg, 0, 0)
|
||||
arg(all_ARG, 'a', "all", NULL, 0, 0)
|
||||
arg(autobackup_ARG, 'A', "autobackup", yes_no_arg, 0, 0)
|
||||
arg(activevolumegroups_ARG, 'A', "activevolumegroups", NULL, 0, 0)
|
||||
arg(background_ARG, 'b', "background", NULL, 0, 0)
|
||||
arg(backgroundfork_ARG, 'b', "background", NULL, 0, 0)
|
||||
arg(basevgname_ARG, 'n', "basevgname", string_arg, 0, 0)
|
||||
arg(blockdevice_ARG, 'b', "blockdevice", NULL, 0, 0)
|
||||
arg(chunksize_ARG, 'c', "chunksize", size_kb_arg, 0, 0)
|
||||
arg(clustered_ARG, 'c', "clustered", yes_no_arg, 0, 0)
|
||||
arg(colon_ARG, 'c', "colon", NULL, 0, 0)
|
||||
arg(columns_ARG, 'C', "columns", NULL, 0, 0)
|
||||
arg(contiguous_ARG, 'C', "contiguous", yes_no_arg, 0, 0)
|
||||
arg(debug_ARG, 'd', "debug", NULL, ARG_COUNTABLE, 0)
|
||||
arg(exported_ARG, 'e', "exported", NULL, 0, 0)
|
||||
arg(physicalextent_ARG, 'E', "physicalextent", NULL, 0, 0)
|
||||
arg(file_ARG, 'f', "file", string_arg, 0, 0)
|
||||
arg(force_ARG, 'f', "force", NULL, ARG_COUNTABLE, 0)
|
||||
arg(full_ARG, 'f', "full", NULL, 0, 0)
|
||||
arg(help_ARG, 'h', "help", NULL, 0, 0)
|
||||
arg(cache_ARG, 'H', "cache", NULL, 0, 0)
|
||||
arg(history_ARG, 'H', "history", NULL, 0, 0)
|
||||
arg(help2_ARG, '?', "", NULL, 0, 0)
|
||||
arg(import_ARG, 'i', "import", NULL, 0, 0)
|
||||
arg(interval_ARG, 'i', "interval", int_arg, 0, 0)
|
||||
arg(iop_version_ARG, 'i', "iop_version", NULL, 0, 0)
|
||||
arg(stripes_ARG, 'i', "stripes", int_arg, 0, 0)
|
||||
arg(stripesize_ARG, 'I', "stripesize", size_kb_arg, 0, 0)
|
||||
arg(logicalvolume_ARG, 'l', "logicalvolume", int_arg, 0, 0)
|
||||
arg(maxlogicalvolumes_ARG, 'l', "maxlogicalvolumes", int_arg, 0, 0)
|
||||
arg(extents_ARG, 'l', "extents", int_arg_with_sign_and_percent, 0, 0)
|
||||
arg(list_ARG, 'l', "list", NULL, 0, 0)
|
||||
arg(lvmpartition_ARG, 'l', "lvmpartition", NULL, 0, 0)
|
||||
arg(logicalextent_ARG, 'L', "logicalextent", int_arg_with_sign, 0, 0)
|
||||
arg(size_ARG, 'L', "size", size_mb_arg, 0, 0)
|
||||
arg(persistent_ARG, 'M', "persistent", yes_no_arg, 0, 0)
|
||||
arg(major_ARG, 'j', "major", int_arg, ARG_GROUPABLE, 0)
|
||||
arg(setactivationskip_ARG, 'k', "setactivationskip", yes_no_arg, 0, 0)
|
||||
arg(ignoreactivationskip_ARG, 'K', "ignoreactivationskip", NULL, 0, 0)
|
||||
arg(maps_ARG, 'm', "maps", NULL, 0, 0)
|
||||
arg(mirrors_ARG, 'm', "mirrors", int_arg_with_sign, 0, 0)
|
||||
arg(metadatatype_ARG, 'M', "metadatatype", metadatatype_arg, 0, 0)
|
||||
arg(name_ARG, 'n', "name", string_arg, 0, 0)
|
||||
arg(nofsck_ARG, 'n', "nofsck", NULL, 0, 0)
|
||||
arg(novolumegroup_ARG, 'n', "novolumegroup", NULL, 0, 0)
|
||||
arg(oldpath_ARG, 'n', "oldpath", NULL, 0, 0)
|
||||
arg(options_ARG, 'o', "options", string_arg, ARG_GROUPABLE, 0)
|
||||
arg(sort_ARG, 'O', "sort", string_arg, ARG_GROUPABLE, 0)
|
||||
arg(maxphysicalvolumes_ARG, 'p', "maxphysicalvolumes", int_arg, 0, 0)
|
||||
arg(permission_ARG, 'p', "permission", permission_arg, 0, 0)
|
||||
arg(partial_ARG, 'P', "partial", NULL, 0, 0)
|
||||
arg(physicalvolume_ARG, 'P', "physicalvolume", NULL, 0, 0)
|
||||
arg(quiet_ARG, 'q', "quiet", NULL, ARG_COUNTABLE, 0)
|
||||
arg(readahead_ARG, 'r', "readahead", readahead_arg, 0, 0)
|
||||
arg(resizefs_ARG, 'r', "resizefs", NULL, 0, 0)
|
||||
arg(reset_ARG, 'R', "reset", NULL, 0, 0)
|
||||
arg(regionsize_ARG, 'R', "regionsize", size_mb_arg, 0, 0)
|
||||
arg(physicalextentsize_ARG, 's', "physicalextentsize", size_mb_arg, 0, 0)
|
||||
arg(snapshot_ARG, 's', "snapshot", NULL, 0, 0)
|
||||
arg(short_ARG, 's', "short", NULL, 0, 0)
|
||||
arg(stdin_ARG, 's', "stdin", NULL, 0, 0)
|
||||
arg(select_ARG, 'S', "select", string_arg, ARG_GROUPABLE, 0)
|
||||
arg(test_ARG, 't', "test", NULL, 0, 0)
|
||||
arg(thin_ARG, 'T', "thin", NULL, 0, 0)
|
||||
arg(uuid_ARG, 'u', "uuid", NULL, 0, 0)
|
||||
arg(uuidstr_ARG, 'u', "uuid", string_arg, 0, 0)
|
||||
arg(uuidlist_ARG, 'U', "uuidlist", NULL, 0, 0)
|
||||
arg(verbose_ARG, 'v', "verbose", NULL, ARG_COUNTABLE, 0)
|
||||
arg(volumegroup_ARG, 'V', "volumegroup", NULL, 0, 0)
|
||||
arg(virtualsize_ARG, 'V', "virtualsize", size_mb_arg, 0, 0)
|
||||
arg(wipesignatures_ARG, 'W', "wipesignatures", yes_no_arg, 0, 0)
|
||||
arg(allocatable_ARG, 'x', "allocatable", yes_no_arg, 0, 0)
|
||||
arg(resizeable_ARG, 'x', "resizeable", yes_no_arg, 0, 0)
|
||||
arg(yes_ARG, 'y', "yes", NULL, 0, 0)
|
||||
arg(zero_ARG, 'Z', "zero", yes_no_arg, 0, 0)
|
||||
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, '-', "", NULL, 0, 0)
|
||||
arg(ARG_COUNT, '-', "", 0, 0, 0)
|
||||
/* *INDENT-ON* */
|
||||
|
1536
tools/command-lines.in
Normal file
1536
tools/command-lines.in
Normal file
File diff suppressed because it is too large
Load Diff
169
tools/command.h
Normal file
169
tools/command.h
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU Lesser General Public License v.2.1.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_COMMAND_H
|
||||
#define _LVM_COMMAND_H
|
||||
|
||||
struct cmd_context;
|
||||
|
||||
/* old per-command-name function */
|
||||
typedef int (*command_fn) (struct cmd_context *cmd, int argc, char **argv);
|
||||
|
||||
/* new per-command-line-id functions */
|
||||
typedef int (*command_line_fn) (struct cmd_context *cmd, int argc, char **argv);
|
||||
|
||||
struct command_function {
|
||||
int command_line_enum;
|
||||
command_line_fn fn;
|
||||
};
|
||||
|
||||
struct command_name {
|
||||
const char *name;
|
||||
const char *desc; /* general command description from commands.h */
|
||||
unsigned int flags;
|
||||
|
||||
/* union of {required,optional}_opt_args for all commands with this name */
|
||||
int valid_args[ARG_COUNT];
|
||||
int num_args;
|
||||
};
|
||||
|
||||
/*
|
||||
* Command defintion
|
||||
*
|
||||
* A command is defined in terms of a command name,
|
||||
* required options (+args), optional options (+args),
|
||||
* required positional args, optional positional args.
|
||||
*
|
||||
* A positional arg always has non-zero pos_arg.def.types.
|
||||
* The first positional arg has pos_arg.pos of 1.
|
||||
*/
|
||||
|
||||
/* arg_def flags */
|
||||
#define ARG_DEF_FLAG_NEW 1 << 0
|
||||
#define ARG_DEF_FLAG_MAY_REPEAT 1 << 1
|
||||
|
||||
/* arg_def lv_types */
|
||||
enum {
|
||||
ARG_DEF_LV_ANY = 0,
|
||||
ARG_DEF_LV_LINEAR = 1 << 0,
|
||||
ARG_DEF_LV_STRIPED = 1 << 1,
|
||||
ARG_DEF_LV_SNAPSHOT = 1 << 2,
|
||||
ARG_DEF_LV_MIRROR = 1 << 3,
|
||||
ARG_DEF_LV_RAID = 1 << 4,
|
||||
ARG_DEF_LV_RAID0 = 1 << 5,
|
||||
ARG_DEF_LV_RAID1 = 1 << 6,
|
||||
ARG_DEF_LV_RAID4 = 1 << 7,
|
||||
ARG_DEF_LV_RAID5 = 1 << 8,
|
||||
ARG_DEF_LV_RAID6 = 1 << 9,
|
||||
ARG_DEF_LV_RAID10 = 1 << 10,
|
||||
ARG_DEF_LV_THIN = 1 << 11,
|
||||
ARG_DEF_LV_THINPOOL = 1 << 12,
|
||||
ARG_DEF_LV_CACHE = 1 << 13,
|
||||
ARG_DEF_LV_CACHEPOOL = 1 << 14,
|
||||
ARG_DEF_LV_LAST = 1 << 15,
|
||||
};
|
||||
|
||||
static inline int val_bit_is_set(uint64_t val_bits, int val_enum)
|
||||
{
|
||||
return (val_bits & (1 << val_enum)) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline uint64_t val_enum_to_bit(int val_enum)
|
||||
{
|
||||
return 1 << val_enum;
|
||||
}
|
||||
|
||||
/* Description a value that follows an option or exists in a position. */
|
||||
|
||||
struct arg_def {
|
||||
uint64_t val_bits; /* bits of x_VAL, can be multiple for pos_arg */
|
||||
uint64_t num; /* a literal number for conststr_VAL */
|
||||
const char *str; /* a literal string for constnum_VAL */
|
||||
uint32_t lv_types; /* ARG_DEF_LV_, for lv_VAL, can be multiple */
|
||||
uint32_t flags; /* ARG_DEF_FLAG_ */
|
||||
};
|
||||
|
||||
/* Description of an option and the value that follows it. */
|
||||
|
||||
struct opt_arg {
|
||||
int opt; /* option, e.g. foo_ARG */
|
||||
struct arg_def def; /* defines accepted values */
|
||||
};
|
||||
|
||||
/* Description of a position and the value that exists there. */
|
||||
|
||||
struct pos_arg {
|
||||
int pos; /* position, e.g. first is 1 */
|
||||
struct arg_def def; /* defines accepted values */
|
||||
};
|
||||
|
||||
/*
|
||||
* CMD_RO_ARGS needs to accomodate a list of options,
|
||||
* of which one is required after which the rest are
|
||||
* optional.
|
||||
*/
|
||||
#define CMD_RO_ARGS 64 /* required opt args */
|
||||
#define CMD_OO_ARGS 150 /* optional opt args */
|
||||
#define CMD_RP_ARGS 8 /* required positional args */
|
||||
#define CMD_OP_ARGS 8 /* optional positional args */
|
||||
|
||||
/*
|
||||
* one or more from required_opt_args is required,
|
||||
* then the rest are optional.
|
||||
*/
|
||||
#define CMD_FLAG_ONE_REQUIRED_OPT 1
|
||||
|
||||
/* a register of the lvm commands */
|
||||
struct command {
|
||||
const char *name;
|
||||
const char *desc; /* specific command description from command-lines.h */
|
||||
const char *usage; /* excludes common options like --help, --debug */
|
||||
const char *usage_common; /* includes commmon options like --help, --debug */
|
||||
const char *command_line_id;
|
||||
int command_line_enum; /* <command_line_id>_CMD */
|
||||
|
||||
struct command_name *cname;
|
||||
|
||||
command_fn fn; /* old style */
|
||||
struct command_function *functions; /* new style */
|
||||
|
||||
unsigned int flags; /* copied from command_name.flags from commands.h */
|
||||
|
||||
unsigned int cmd_flags; /* CMD_FLAG_ */
|
||||
|
||||
/* definitions of opt/pos args */
|
||||
|
||||
/* required args following an --opt */
|
||||
struct opt_arg required_opt_args[CMD_RO_ARGS];
|
||||
|
||||
/* optional args following an --opt */
|
||||
struct opt_arg optional_opt_args[CMD_OO_ARGS];
|
||||
|
||||
/* required positional args */
|
||||
struct pos_arg required_pos_args[CMD_RP_ARGS];
|
||||
|
||||
/* optional positional args */
|
||||
struct pos_arg optional_pos_args[CMD_OP_ARGS];
|
||||
|
||||
int ro_count;
|
||||
int oo_count;
|
||||
int rp_count;
|
||||
int op_count;
|
||||
|
||||
/* used for processing current position */
|
||||
int pos_count;
|
||||
};
|
||||
|
||||
#endif
|
1428
tools/commands.h
1428
tools/commands.h
File diff suppressed because it is too large
Load Diff
2487
tools/create-commands.c
Normal file
2487
tools/create-commands.c
Normal file
File diff suppressed because it is too large
Load Diff
283
tools/lvchange.c
283
tools/lvchange.c
@@ -1436,3 +1436,286 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
|
||||
update ? READ_FOR_UPDATE : 0, NULL,
|
||||
&_lvchange_single);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Check if the status of the LV allows running lvchange.
|
||||
*
|
||||
* FIXME: check for invalid VG/LV properties in a way that is not prone
|
||||
* to missing some. Currently, there are some checks here, some in the
|
||||
* functions above, some in process_each, and some may be missing.
|
||||
*/
|
||||
static int _lvchange_status_is_valid(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
{
|
||||
if (!(lv->vg->status & LVM_WRITE)) {
|
||||
log_error("Operation not permitted on LV %s: writable VG required.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lv_is_pvmove(lv)) {
|
||||
log_error("Operation not permitted on LV %s: used for pvmove.",
|
||||
display_lvname(lv));
|
||||
if (arg_is_set(cmd, activate_ARG))
|
||||
log_error("Use 'pvmove --abort' to abandon a pvmove");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lv_is_mirror_log(lv)) {
|
||||
log_error("Operation not permitted on LV %s: is mirror log.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lv_is_mirror_image(lv)) {
|
||||
log_error("Operation not permitted on LV %s: is mirror image.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lv_is_origin(lv) && !lv_is_thin_volume(lv)) {
|
||||
log_error("Operation not permitted on LV %s: is under snapshot.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _lvchange_properties_single(struct cmd_context *cmd,
|
||||
struct logical_volume *lv,
|
||||
struct processing_handle *handle)
|
||||
{
|
||||
int doit = 0, docmds = 0;
|
||||
|
||||
/* FIXME: sort out hidden/internal LVs, e.g. _lvchange_hidden_is_valid() */
|
||||
|
||||
if (!_lvchange_status_is_valid(cmd, lv))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
if (arg_is_set(cmd, persistent_ARG) && lv_is_pool(lv)) {
|
||||
log_error("Operation not permitted on LV %s: persistent device numbers are not supported with pools.",
|
||||
display_lvname(lv));
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a persistent lv lock already exists from activation
|
||||
* (with the needed mode or higher), this will be a no-op.
|
||||
* Otherwise, the lv lock will be taken as non-persistent
|
||||
* and released when this command exits.
|
||||
*/
|
||||
if (!lockd_lv(cmd, lv, "ex", 0)) {
|
||||
stack;
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
for (i = 0; i < cmd->command->ro_count; i++) {
|
||||
opt_enum = cmd->command->required_opt_args[i].opt;
|
||||
|
||||
if (!arg_is_set(cmd, opt_enum))
|
||||
continue;
|
||||
|
||||
if (!archive(lv->vg))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
docmds++;
|
||||
|
||||
switch (opt_enum) {
|
||||
case permission_ARG:
|
||||
doit += _lvchange_permission(cmd, lv);
|
||||
break;
|
||||
|
||||
case alloc_ARG:
|
||||
case contiguous_ARG:
|
||||
doit += _lvchange_alloc(cmd, lv);
|
||||
break;
|
||||
|
||||
case errorwhenfull_ARG:
|
||||
doit += _lvchange_errorwhenfull(cmd, lv);
|
||||
break;
|
||||
|
||||
case readahead_ARG:
|
||||
doit += _lvchange_readahead(cmd, lv);
|
||||
break;
|
||||
|
||||
case persistent_ARG:
|
||||
doit += _lvchange_persistent(cmd, lv);
|
||||
break;
|
||||
|
||||
case discards_ARG:
|
||||
case zero_ARG:
|
||||
doit += _lvchange_pool_update(cmd, lv);
|
||||
break;
|
||||
|
||||
case addtag_ARG:
|
||||
case deltag_ARG:
|
||||
doit += _lvchange_tag(cmd, lv, opt_enum);
|
||||
break;
|
||||
|
||||
case writemostly_ARG:
|
||||
case writebehind_ARG:
|
||||
doit += _lvchange_writemostly(lv);
|
||||
break;
|
||||
|
||||
case minrecoveryrate_ARG:
|
||||
case maxrecoveryrate_ARG:
|
||||
doit += _lvchange_recovery_rate(lv);
|
||||
break;
|
||||
|
||||
case profile_ARG:
|
||||
case metadataprofile_ARG:
|
||||
case detachprofile_ARG:
|
||||
doit += _lvchange_profile(lv);
|
||||
break;
|
||||
|
||||
case setactivationskip_ARG:
|
||||
doit += _lvchange_activation_skip(lv);
|
||||
break;
|
||||
|
||||
case cachemode_ARG:
|
||||
case cachepolicy_ARG:
|
||||
case cachesettings_ARG:
|
||||
doit += _lvchange_cache(cmd, lv);
|
||||
break;
|
||||
|
||||
default:
|
||||
log_error(INTERNAL_ERROR "Failed to check for option %s",
|
||||
arg_long_option_name(i));
|
||||
}
|
||||
|
||||
if (doit)
|
||||
log_print_unless_silent("Logical volume %s changed.", display_lvname(lv));
|
||||
|
||||
if (doit != docmds)
|
||||
return_ECMD_FAILED;
|
||||
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
int lvchange_properties_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||
{
|
||||
struct processing_handle *handle = init_processing_handle(cmd, NULL);
|
||||
int ret;
|
||||
|
||||
ret = process_each_lv(cmd, argc, argv, NULL, NULL, READ_FOR_UPDATE, handle, _lvchange_properties_single);
|
||||
|
||||
destroy_processing_handle(cmd, handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _lvchange_activate_single(struct cmd_context *cmd,
|
||||
struct logical_volume *lv,
|
||||
struct processing_handle *handle)
|
||||
{
|
||||
struct logical_volume *origin;
|
||||
char snaps_msg[128];
|
||||
|
||||
/* FIXME: sort out hidden/internal LVs, e.g. _lvchange_hidden_is_valid() */
|
||||
|
||||
if (!_lvchange_status_is_valid(cmd, lv))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
/* FIXME: untangle the proper logic for cow / sparse / virtual origin */
|
||||
|
||||
/* If LV is sparse, activate origin instead */
|
||||
if (lv_is_cow(lv) && lv_is_virtual_origin(origin = origin_from_cow(lv)))
|
||||
lv = origin;
|
||||
|
||||
if (lv_is_cow(lv)) {
|
||||
origin = origin_from_cow(lv);
|
||||
if (origin->origin_count < 2)
|
||||
snaps_msg[0] = '\0';
|
||||
else if (dm_snprintf(snaps_msg, sizeof(snaps_msg),
|
||||
" and %u other snapshot(s)",
|
||||
origin->origin_count - 1) < 0) {
|
||||
log_error("Failed to prepare message.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (!arg_is_set(cmd, yes_ARG) &&
|
||||
(yes_no_prompt("Change of snapshot %s will also change its "
|
||||
"origin %s%s. Proceed? [y/n]: ",
|
||||
display_lvname(lv), display_lvname(origin),
|
||||
snaps_msg) == 'n')) {
|
||||
log_error("Logical volume %s not changed.", display_lvname(lv));
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If --sysinit -aay is used and at the same time lvmetad is used,
|
||||
* we want to rely on autoactivation to take place. Also, we
|
||||
* need to take special care here as lvmetad service does
|
||||
* not neet to be running at this moment yet - it could be
|
||||
* just too early during system initialization time.
|
||||
*/
|
||||
if (arg_is_set(cmd, sysinit_ARG) && (arg_uint_value(cmd, activate_ARG, 0) == CHANGE_AAY)) {
|
||||
if (lvmetad_used()) {
|
||||
log_warn("WARNING: lvmetad is active, skipping direct activation during sysinit.");
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_lvchange_activate(cmd, lv))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
int lvchange_activate_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||
{
|
||||
struct processing_handle *handle = init_processing_handle(cmd, NULL);
|
||||
|
||||
cmd->handles_missing_pvs = 1;
|
||||
cmd->lockd_vg_default_sh = 1;
|
||||
|
||||
/*
|
||||
* Include foreign VGs that contain active LVs.
|
||||
* That shouldn't happen in general, but if it does by some
|
||||
* mistake, then we want to allow those LVs to be deactivated.
|
||||
*/
|
||||
cmd->include_active_foreign_vgs = 1;
|
||||
|
||||
/* Allow deactivating if locks fail. */
|
||||
if (is_change_activating((activation_change_t)arg_uint_value(cmd, activate_ARG, CHANGE_AY)))
|
||||
cmd->lockd_vg_enforce_sh = 1;
|
||||
|
||||
ret = process_each_lv(cmd, argc, argv, NULL, NULL, 0, handle, _lvchange_activate_single);
|
||||
|
||||
destroy_processing_handle(cmd, handle);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _lvchange_refresh_single(struct cmd_context *cmd,
|
||||
struct logical_volume *lv,
|
||||
struct processing_handle *handle)
|
||||
{
|
||||
/* FIXME: sort out hidden/internal LVs, e.g. _lvchange_hidden_is_valid() */
|
||||
|
||||
if (!_lvchange_status_is_valid(cmd, lv))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
log_verbose("Refreshing logical volume %s (if active).", display_lvname(lv));
|
||||
|
||||
if (!_lv_refresh(cmd, lv))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
int lvchange_refresh_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||
{
|
||||
struct processing_handle *handle = init_processing_handle(cmd, NULL);
|
||||
int ret;
|
||||
|
||||
cmd->handles_missing_pvs = 1;
|
||||
cmd->lockd_vg_default_sh = 1;
|
||||
|
||||
ret = process_each_lv(cmd, argc, argv, NULL, NULL, 0, handle, _lvchange_refresh_single);
|
||||
|
||||
destroy_processing_handle(cmd, handle);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@@ -50,8 +50,6 @@ struct lvconvert_params {
|
||||
int splitsnapshot;
|
||||
int thin;
|
||||
int uncache;
|
||||
int other_conversion; /* Everything else */
|
||||
|
||||
int corelog; /* Equivalent to --mirrorlog core */
|
||||
int mirrorlog; /* Only one of corelog and mirrorlog may be set */
|
||||
|
||||
@@ -236,6 +234,12 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: avoid this distinct validation out of scope of _convert_*()
|
||||
*
|
||||
* We should not rely on namespace here any more!
|
||||
* It is the duty of lvcreate/lvrename to avoid reserved names.
|
||||
*/
|
||||
if (!lp->merge_mirror &&
|
||||
!lp->repair &&
|
||||
!lp->keep_mimages &&
|
||||
@@ -243,6 +247,7 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
|
||||
!strstr(lp->lv_name, "_tmeta") &&
|
||||
!strstr(lp->lv_name, "_cdata") &&
|
||||
!strstr(lp->lv_name, "_cmeta") &&
|
||||
!strstr(lp->lv_name, "_corig") &&
|
||||
!apply_lvname_restrictions(lp->lv_name))
|
||||
return_0;
|
||||
|
||||
@@ -307,9 +312,14 @@ static int _striped_type_requested(const char *type_str)
|
||||
return (!strcmp(type_str, SEG_TYPE_NAME_STRIPED) || _linear_type_requested(type_str));
|
||||
}
|
||||
|
||||
static int _check_conversion_type(struct cmd_context *cmd, const char *type_str)
|
||||
static int _read_conversion_type(struct cmd_context *cmd,
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
if (!type_str || !*type_str)
|
||||
|
||||
const char *type_str = arg_str_value(cmd, type_ARG, "");
|
||||
|
||||
lp->type_str = type_str;
|
||||
if (!lp->type_str[0])
|
||||
return 1;
|
||||
|
||||
/* FIXME: Check thin-pool and thin more thoroughly! */
|
||||
@@ -320,6 +330,7 @@ static int _check_conversion_type(struct cmd_context *cmd, const char *type_str)
|
||||
return 1;
|
||||
|
||||
log_error("Conversion using --type %s is not supported.", type_str);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -436,11 +447,33 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
int region_size;
|
||||
int pagesize = lvm_getpagesize();
|
||||
|
||||
lp->type_str = arg_str_value(cmd, type_ARG, "");
|
||||
|
||||
if (*lp->type_str && !_check_conversion_type(cmd, lp->type_str))
|
||||
if (!_read_conversion_type(cmd, lp))
|
||||
return_0;
|
||||
|
||||
if (!arg_is_set(cmd, background_ARG))
|
||||
lp->wait_completion = 1;
|
||||
|
||||
if (arg_is_set(cmd, corelog_ARG))
|
||||
lp->corelog = 1;
|
||||
|
||||
if (arg_is_set(cmd, mirrorlog_ARG)) {
|
||||
if (lp->corelog) {
|
||||
log_error("--mirrorlog and --corelog are incompatible.");
|
||||
return 0;
|
||||
}
|
||||
lp->mirrorlog = 1;
|
||||
}
|
||||
|
||||
if (arg_is_set(cmd, merge_ARG)) {
|
||||
if (arg_outside_list_is_set(cmd, "cannot be used with --merge",
|
||||
merge_ARG,
|
||||
background_ARG, interval_ARG,
|
||||
force_ARG, noudevsync_ARG, test_ARG,
|
||||
-1))
|
||||
return_0;
|
||||
lp->merge = 1;
|
||||
}
|
||||
|
||||
/* If --repair, check for incompatible args. */
|
||||
if (arg_is_set(cmd, repair_ARG)) {
|
||||
if (arg_outside_list_is_set(cmd, "cannot be used with --repair",
|
||||
@@ -452,15 +485,8 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
lp->repair = 1;
|
||||
}
|
||||
|
||||
if (arg_is_set(cmd, mirrorlog_ARG))
|
||||
lp->mirrorlog = 1;
|
||||
if (arg_is_set(cmd, corelog_ARG))
|
||||
lp->corelog = 1;
|
||||
|
||||
if (lp->mirrorlog && lp->corelog) {
|
||||
log_error("--mirrorlog and --corelog are incompatible.");
|
||||
return 0;
|
||||
}
|
||||
if (arg_is_set(cmd, replace_ARG))
|
||||
lp->replace = 1;
|
||||
|
||||
if (arg_is_set(cmd, split_ARG)) {
|
||||
if (arg_outside_list_is_set(cmd, "cannot be used with --split",
|
||||
@@ -490,6 +516,9 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
lp->splitsnapshot = 1;
|
||||
}
|
||||
|
||||
if (arg_is_set(cmd, trackchanges_ARG))
|
||||
lp->track_changes = 1;
|
||||
|
||||
if (arg_is_set(cmd, uncache_ARG)) {
|
||||
if (arg_outside_list_is_set(cmd, "cannot be used with --uncache",
|
||||
uncache_ARG,
|
||||
@@ -528,21 +557,14 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
if (!_read_pool_params(cmd, &argc, &argv, lp))
|
||||
return_0;
|
||||
|
||||
if (!arg_is_set(cmd, background_ARG))
|
||||
lp->wait_completion = 1;
|
||||
|
||||
if (_snapshot_type_requested(cmd, lp->type_str)) {
|
||||
if (arg_is_set(cmd, merge_ARG)) {
|
||||
if (lp->merge) {
|
||||
log_error("--snapshot and --merge are mutually exclusive.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
lp->snapshot = 1;
|
||||
}
|
||||
|
||||
if (arg_is_set(cmd, trackchanges_ARG))
|
||||
lp->track_changes = 1;
|
||||
|
||||
if (lp->split) {
|
||||
lp->lv_split_name = arg_str_value(cmd, name_ARG, NULL);
|
||||
|
||||
@@ -579,12 +601,6 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
}
|
||||
}
|
||||
|
||||
if (arg_is_set(cmd, merge_ARG))
|
||||
lp->merge = 1;
|
||||
|
||||
if (arg_is_set(cmd, replace_ARG))
|
||||
lp->replace = 1;
|
||||
|
||||
/* If no other case was identified, then use of --stripes means --type striped */
|
||||
if (!arg_is_set(cmd, type_ARG) && !*lp->type_str && !lp->merge && !lp->splitsnapshot &&
|
||||
!lp->splitcache && !lp->split && !lp->snapshot && !lp->uncache && !lp->cache && !lp->thin &&
|
||||
@@ -611,9 +627,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
}
|
||||
|
||||
if (arg_is_set(cmd, mirrors_ARG)) {
|
||||
/*
|
||||
* --splitmirrors is the mechanism for detaching and keeping a mimage
|
||||
*/
|
||||
/* --splitmirrors is the mechanism for detaching and keeping a mimage */
|
||||
lp->mirrors_supplied = 1;
|
||||
lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0);
|
||||
lp->mirrors_sign = arg_sign_value(cmd, mirrors_ARG, SIGN_NONE);
|
||||
@@ -626,8 +640,7 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
lp->cache + lp->thin + lp->keep_mimages + lp->snapshot + lp->replace + lp->repair > 1) {
|
||||
log_error(INTERNAL_ERROR "Unexpected combination of incompatible options selected.");
|
||||
return 0;
|
||||
} else
|
||||
lp->other_conversion = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Final checking of each case:
|
||||
@@ -645,14 +658,9 @@ static int _read_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
* --type mirror|raid lp->mirrorlog lp->corelog
|
||||
* --type raid0|striped
|
||||
*/
|
||||
if (lp->merge) { /* Snapshot or mirror merge */
|
||||
if (arg_outside_list_is_set(cmd, "cannot be used with --merge",
|
||||
merge_ARG,
|
||||
background_ARG, interval_ARG,
|
||||
force_ARG, noudevsync_ARG, test_ARG,
|
||||
-1))
|
||||
return_0;
|
||||
} else if (lp->splitsnapshot) /* Destroy snapshot retaining cow as separate LV */
|
||||
if (lp->merge) /* Snapshot or mirror merge */
|
||||
;
|
||||
else if (lp->splitsnapshot) /* Destroy snapshot retaining cow as separate LV */
|
||||
;
|
||||
else if (lp->splitcache)
|
||||
;
|
||||
@@ -4097,11 +4105,11 @@ static int _convert_striped_raid(struct cmd_context *cmd, struct logical_volume
|
||||
static int _convert_cow_snapshot(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
if (arg_is_set(cmd, splitsnapshot_ARG))
|
||||
if (lp->splitsnapshot)
|
||||
return _convert_cow_snapshot_splitsnapshot(cmd, lv, lp);
|
||||
|
||||
/* FIXME: add --merge-snapshot to make this distinct from --merge-mirror. */
|
||||
if (arg_is_set(cmd, merge_ARG))
|
||||
if (lp->merge)
|
||||
return _convert_cow_snapshot_merge(cmd, lv, lp);
|
||||
|
||||
log_error("Operation not permitted on COW snapshot LV %s.", display_lvname(lv));
|
||||
@@ -4115,7 +4123,7 @@ static int _convert_thin_volume(struct cmd_context *cmd, struct logical_volume *
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
/* FIXME: add --merge-snapshot to make this distinct from --merge-mirror. */
|
||||
if (arg_is_set(cmd, merge_ARG))
|
||||
if (lp->merge)
|
||||
return _convert_thin_volume_merge(cmd, lv, lp);
|
||||
|
||||
log_error("Operation not permitted on thin LV %s.", display_lvname(lv));
|
||||
@@ -4127,19 +4135,19 @@ static int _convert_thin_volume(struct cmd_context *cmd, struct logical_volume *
|
||||
static int _convert_thin_pool(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
if (arg_is_set(cmd, splitcache_ARG))
|
||||
if (lp->splitcache)
|
||||
return _convert_thin_pool_splitcache(cmd, lv, lp);
|
||||
|
||||
if (arg_is_set(cmd, split_ARG))
|
||||
if (lp->split)
|
||||
return _convert_thin_pool_splitcache(cmd, lv, lp);
|
||||
|
||||
if (arg_is_set(cmd, uncache_ARG))
|
||||
if (lp->uncache)
|
||||
return _convert_thin_pool_uncache(cmd, lv, lp);
|
||||
|
||||
if (lp->cache)
|
||||
return _convert_thin_pool_cache(cmd, lv, lp);
|
||||
|
||||
if (arg_is_set(cmd, repair_ARG))
|
||||
if (lp->repair)
|
||||
return _convert_thin_pool_repair(cmd, lv, lp);
|
||||
|
||||
/* FIXME: swapping the thin pool metadata LV needs a specific option like --swapmetadata */
|
||||
@@ -4160,21 +4168,20 @@ static int _convert_thin_pool(struct cmd_context *cmd, struct logical_volume *lv
|
||||
static int _convert_cache_volume(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
if (arg_is_set(cmd, splitcache_ARG))
|
||||
if (lp->splitcache)
|
||||
return _convert_cache_volume_splitcache(cmd, lv, lp);
|
||||
|
||||
if (arg_is_set(cmd, split_ARG))
|
||||
if (lp->split)
|
||||
return _convert_cache_volume_splitcache(cmd, lv, lp);
|
||||
|
||||
if (arg_is_set(cmd, uncache_ARG))
|
||||
if (lp->uncache)
|
||||
return _convert_cache_volume_uncache(cmd, lv, lp);
|
||||
|
||||
if (arg_is_set(cmd, splitmirrors_ARG))
|
||||
return _convert_cache_volume_splitmirrors(cmd, lv, lp);
|
||||
|
||||
/* Using --thinpool is ambiguous and not preferred. */
|
||||
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_THIN_POOL) || arg_is_set(cmd, thinpool_ARG))
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_THIN_POOL) ||
|
||||
arg_is_set(cmd, thinpool_ARG))
|
||||
return _convert_cache_volume_thin_pool(cmd, lv, lp);
|
||||
|
||||
/* The --thinpool alternative for --type thin-pool is not preferred, so not shown. */
|
||||
@@ -4191,10 +4198,10 @@ static int _convert_cache_volume(struct cmd_context *cmd, struct logical_volume
|
||||
static int _convert_cache_pool(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
if (arg_is_set(cmd, splitcache_ARG))
|
||||
if (lp->splitcache)
|
||||
return _convert_cache_pool_splitcache(cmd, lv, lp);
|
||||
|
||||
if (arg_is_set(cmd, split_ARG))
|
||||
if (lp->split)
|
||||
return _convert_cache_pool_splitcache(cmd, lv, lp);
|
||||
|
||||
/* FIXME: swapping the cache pool metadata LV needs a specific option like --swapmetadata */
|
||||
@@ -4221,7 +4228,7 @@ static int _convert_mirror(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
if (arg_is_set(cmd, mirrorlog_ARG) || arg_is_set(cmd, corelog_ARG))
|
||||
return _convert_mirror_log(cmd, lv, lp);
|
||||
|
||||
if (arg_is_set(cmd, repair_ARG))
|
||||
if (lp->repair)
|
||||
return _convert_mirror_repair(cmd, lv, lp);
|
||||
|
||||
if (_linear_type_requested(lp->type_str))
|
||||
@@ -4262,42 +4269,53 @@ static int _convert_mirror(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
static int _convert_raid(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
struct lvconvert_params *lp)
|
||||
{
|
||||
/* Permitted convert options on visible or hidden RaidLVs */
|
||||
/* The --thinpool alternative for --type thin-pool is not preferred, so not shown. */
|
||||
const char *permitted_options = lv_is_visible(lv) ?
|
||||
" --mirrors\n"
|
||||
" --splitmirrors\n"
|
||||
" --merge\n"
|
||||
" --repair\n"
|
||||
" --replace\n"
|
||||
" --type snapshot\n"
|
||||
" --type thin\n"
|
||||
" --type cache\n"
|
||||
" --type thin-pool\n"
|
||||
" --type cache-pool\n"
|
||||
" --type raid*\n"
|
||||
" --type mirror\n"
|
||||
" --type striped\n"
|
||||
" --type linear\n"
|
||||
:
|
||||
" --mirrors\n"
|
||||
" --splitmirrors\n"
|
||||
" --repair\n"
|
||||
" --replace\n"
|
||||
" --type raid*\n"
|
||||
" --type mirror\n"
|
||||
" --type striped\n"
|
||||
" --type linear\n";
|
||||
|
||||
/* Applicable to any hidden _or_ visible LVs. */
|
||||
if (arg_is_set(cmd, mirrors_ARG))
|
||||
return _convert_raid_number(cmd, lv, lp);
|
||||
|
||||
if (arg_is_set(cmd, splitmirrors_ARG))
|
||||
return _convert_raid_splitmirrors(cmd, lv, lp);
|
||||
|
||||
if (arg_is_set(cmd, merge_ARG))
|
||||
return _convert_raid_merge(cmd, lv, lp);
|
||||
|
||||
if (arg_is_set(cmd, repair_ARG))
|
||||
if (lp->repair)
|
||||
return _convert_raid_repair(cmd, lv, lp);
|
||||
|
||||
if (arg_is_set(cmd, replace_ARG))
|
||||
return _convert_raid_replace(cmd, lv, lp);
|
||||
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_SNAPSHOT) || arg_is_set(cmd, snapshot_ARG))
|
||||
return _convert_raid_snapshot(cmd, lv, lp);
|
||||
if (arg_is_set(cmd, splitmirrors_ARG))
|
||||
return _convert_raid_splitmirrors(cmd, lv, lp);
|
||||
|
||||
if (lp->thin)
|
||||
return _convert_raid_thin(cmd, lv, lp);
|
||||
if (segtype_is_raid(lp->segtype)) {
|
||||
/* Only --type allowed on hidden RaidLV. */
|
||||
if (!lv_is_visible(lv) && !arg_is_set(cmd, type_ARG))
|
||||
goto out;
|
||||
|
||||
if (lp->cache)
|
||||
return _convert_raid_cache(cmd, lv, lp);
|
||||
|
||||
/* Using --thinpool is ambiguous and not preferred. */
|
||||
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_THIN_POOL) || arg_is_set(cmd, thinpool_ARG))
|
||||
return _convert_raid_thin_pool(cmd, lv, lp);
|
||||
|
||||
/* Using --cachepool is ambiguous and not preferred. */
|
||||
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_CACHE_POOL) || arg_is_set(cmd, cachepool_ARG))
|
||||
return _convert_raid_cache_pool(cmd, lv, lp);
|
||||
|
||||
if (segtype_is_raid(lp->segtype))
|
||||
return _convert_raid_raid(cmd, lv, lp);
|
||||
}
|
||||
|
||||
if (segtype_is_mirror(lp->segtype))
|
||||
return _convert_raid_mirror(cmd, lv, lp);
|
||||
@@ -4308,24 +4326,33 @@ static int _convert_raid(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
if (_linear_type_requested(lp->type_str))
|
||||
return _convert_raid_linear(cmd, lv, lp);
|
||||
|
||||
/* The --thinpool alternative for --type thin-pool is not preferred, so not shown. */
|
||||
/* Applicable to visible LVs only. */
|
||||
if (lv_is_visible(lv)) {
|
||||
if (lp->merge)
|
||||
return _convert_raid_merge(cmd, lv, lp);
|
||||
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_SNAPSHOT) || arg_is_set(cmd, snapshot_ARG))
|
||||
return _convert_raid_snapshot(cmd, lv, lp);
|
||||
|
||||
if (lp->thin)
|
||||
return _convert_raid_thin(cmd, lv, lp);
|
||||
|
||||
if (lp->cache)
|
||||
return _convert_raid_cache(cmd, lv, lp);
|
||||
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_THIN_POOL) ||
|
||||
arg_is_set(cmd, thinpool_ARG))
|
||||
return _convert_raid_thin_pool(cmd, lv, lp);
|
||||
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_CACHE_POOL) ||
|
||||
arg_is_set(cmd, cachepool_ARG))
|
||||
return _convert_raid_cache_pool(cmd, lv, lp);
|
||||
}
|
||||
|
||||
out:
|
||||
log_error("Operation not permitted on raid LV %s.", display_lvname(lv));
|
||||
log_error("Operations permitted on a raid LV are:\n"
|
||||
" --mirrors\n"
|
||||
" --splitmirrors\n"
|
||||
" --merge\n"
|
||||
" --repair\n"
|
||||
" --replace\n"
|
||||
" --type snapshot\n"
|
||||
" --type thin\n"
|
||||
" --type cache\n"
|
||||
" --type thin-pool\n"
|
||||
" --type cache-pool\n"
|
||||
" --type raid*\n"
|
||||
" --type mirror\n"
|
||||
" --type striped\n"
|
||||
" --type linear\n");
|
||||
log_error("Operations permitted on a raid LV are:\n%s", permitted_options);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4335,10 +4362,10 @@ static int _convert_striped(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
const char *mirrors_type = find_config_tree_str(cmd, global_mirror_segtype_default_CFG, NULL);
|
||||
|
||||
/* FIXME: add --merge-mirror to make this distinct from --merge-snapshot. */
|
||||
if (arg_is_set(cmd, merge_ARG))
|
||||
if (lp->merge)
|
||||
return _convert_striped_merge(cmd, lv, lp);
|
||||
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_SNAPSHOT) || arg_is_set(cmd, snapshot_ARG))
|
||||
if (lp->snapshot || !strcmp(lp->type_str, SEG_TYPE_NAME_SNAPSHOT))
|
||||
return _convert_striped_snapshot(cmd, lv, lp);
|
||||
|
||||
if (lp->thin)
|
||||
@@ -4347,14 +4374,12 @@ static int _convert_striped(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
if (lp->cache)
|
||||
return _convert_striped_cache(cmd, lv, lp);
|
||||
|
||||
/* Using --thinpool is ambiguous and not preferred. */
|
||||
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_THIN_POOL) || arg_is_set(cmd, thinpool_ARG))
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_THIN_POOL) ||
|
||||
arg_is_set(cmd, thinpool_ARG))
|
||||
return _convert_striped_thin_pool(cmd, lv, lp);
|
||||
|
||||
/* Using --cachepool is ambiguous and not preferred. */
|
||||
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_CACHE_POOL) || arg_is_set(cmd, cachepool_ARG))
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_CACHE_POOL) ||
|
||||
arg_is_set(cmd, cachepool_ARG))
|
||||
return _convert_striped_cache_pool(cmd, lv, lp);
|
||||
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_MIRROR))
|
||||
@@ -4418,13 +4443,11 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
|
||||
if (lv_is_locked(lv)) {
|
||||
log_error("Cannot convert locked LV %s.", display_lvname(lv));
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (lv_is_pvmove(lv)) {
|
||||
log_error("Cannot convert pvmove LV %s.", display_lvname(lv));
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -4440,9 +4463,9 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
!lv_is_thin_pool_metadata(lv) &&
|
||||
!lv_is_thin_pool_data(lv) &&
|
||||
!lv_is_used_cache_pool(lv) &&
|
||||
!lv_is_raid_image(lv)) {
|
||||
!lv_is_mirrored(lv) &&
|
||||
!lv_is_raid(lv)) {
|
||||
log_error("Cannot convert internal LV %s.", display_lvname(lv));
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
@@ -4451,20 +4474,21 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
if (!*lp->type_str)
|
||||
lp->segtype = seg->segtype;
|
||||
else if (!(lp->segtype = get_segtype_from_string(cmd, lp->type_str)))
|
||||
return_0;
|
||||
goto_out;
|
||||
|
||||
if (!strcmp(lp->type_str, SEG_TYPE_NAME_MIRROR)) {
|
||||
if (!lp->mirrors_supplied && !seg_is_raid1(seg)) {
|
||||
log_error("Conversions to --type mirror require -m/--mirrors");
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (activation() && lp->segtype && lp->segtype->ops->target_present &&
|
||||
/* lv->segtype can't be NULL */
|
||||
if (activation() && lp->segtype->ops->target_present &&
|
||||
!lp->segtype->ops->target_present(cmd, NULL, &lp->target_attr)) {
|
||||
log_error("%s: Required device-mapper target(s) not "
|
||||
"detected in your kernel.", lp->segtype->name);
|
||||
return 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Process striping parameters */
|
||||
@@ -4473,7 +4497,7 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
_striped_type_requested(lp->type_str) || lp->repair || lp->mirrorlog || lp->corelog) {
|
||||
/* FIXME Handle +/- adjustments too? */
|
||||
if (!get_stripe_params(cmd, lp->segtype, &lp->stripes, &lp->stripe_size, &lp->stripes_supplied, &lp->stripe_size_supplied))
|
||||
return_0;
|
||||
goto_out;
|
||||
|
||||
if (_raid0_type_requested(lp->type_str) || _striped_type_requested(lp->type_str))
|
||||
/* FIXME Shouldn't need to override get_stripe_params which defaults to 1 stripe (i.e. linear)! */
|
||||
@@ -4539,7 +4563,6 @@ static int _lvconvert(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
* reach here, but this covers anything that was missed.
|
||||
*/
|
||||
log_error("Cannot convert LV %s.", display_lvname(lv));
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
return ret ? ECMD_PROCESSED : ECMD_FAILED;
|
||||
|
32
tools/lvm.c
32
tools/lvm.c
@@ -45,9 +45,9 @@ static char *_list_cmds(const char *text, int state)
|
||||
len = strlen(text);
|
||||
}
|
||||
|
||||
while (i < _cmdline->num_commands)
|
||||
if (!strncmp(text, _cmdline->commands[i++].name, len))
|
||||
return strdup(_cmdline->commands[i - 1].name);
|
||||
while (i < _cmdline->num_command_names)
|
||||
if (!strncmp(text, _cmdline->command_names[i++].name, len))
|
||||
return strdup(_cmdline->command_names[i - 1].name);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -57,7 +57,7 @@ static char *_list_args(const char *text, int state)
|
||||
{
|
||||
static int match_no = 0;
|
||||
static size_t len = 0;
|
||||
static struct command *com;
|
||||
static struct command_name *cname;
|
||||
|
||||
/* Initialise if this is a new completion attempt */
|
||||
if (!state) {
|
||||
@@ -65,40 +65,40 @@ static char *_list_args(const char *text, int state)
|
||||
int j;
|
||||
|
||||
match_no = 0;
|
||||
com = NULL;
|
||||
cname = NULL;
|
||||
len = strlen(text);
|
||||
|
||||
/* Find start of first word in line buffer */
|
||||
while (isspace(*s))
|
||||
s++;
|
||||
|
||||
/* Look for word in list of commands */
|
||||
for (j = 0; j < _cmdline->num_commands; j++) {
|
||||
/* Look for word in list of command names */
|
||||
for (j = 0; j < _cmdline->num_command_names; j++) {
|
||||
const char *p;
|
||||
char *q = s;
|
||||
|
||||
p = _cmdline->commands[j].name;
|
||||
p = _cmdline->command_names[j].name;
|
||||
while (*p == *q) {
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
if ((!*p) && *q == ' ') {
|
||||
com = _cmdline->commands + j;
|
||||
cname = _cmdline->command_names + j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!com)
|
||||
if (!cname)
|
||||
return NULL;
|
||||
|
||||
/* Short form arguments */
|
||||
if (len < 3) {
|
||||
while (match_no < com->num_args) {
|
||||
while (match_no < cname->num_args) {
|
||||
char s[3];
|
||||
char c;
|
||||
if (!(c = (_cmdline->arg_props +
|
||||
com->valid_args[match_no++])->short_arg))
|
||||
cname->valid_args[match_no++])->short_arg))
|
||||
continue;
|
||||
|
||||
sprintf(s, "-%c", c);
|
||||
@@ -108,13 +108,13 @@ static char *_list_args(const char *text, int state)
|
||||
}
|
||||
|
||||
/* Long form arguments */
|
||||
if (match_no < com->num_args)
|
||||
match_no = com->num_args;
|
||||
if (match_no < cname->num_args)
|
||||
match_no = cname->num_args;
|
||||
|
||||
while (match_no - com->num_args < com->num_args) {
|
||||
while (match_no - cname->num_args < cname->num_args) {
|
||||
const char *l;
|
||||
l = (_cmdline->arg_props +
|
||||
com->valid_args[match_no++ - com->num_args])->long_arg;
|
||||
cname->valid_args[match_no++ - cname->num_args])->long_arg;
|
||||
if (*(l + 2) && !strncmp(text, l, len))
|
||||
return strdup(l);
|
||||
}
|
||||
|
@@ -19,10 +19,11 @@
|
||||
struct cmd_context;
|
||||
|
||||
struct cmdline_context {
|
||||
struct arg_props *arg_props;
|
||||
struct command *commands;
|
||||
int num_commands;
|
||||
int commands_size;
|
||||
struct arg_props *arg_props;
|
||||
struct command *commands;
|
||||
int num_commands;
|
||||
struct command_name *command_names;
|
||||
int num_command_names;
|
||||
};
|
||||
|
||||
int lvm2_main(int argc, char **argv);
|
||||
|
@@ -30,12 +30,12 @@ void *cmdlib_lvm2_init(unsigned static_compile)
|
||||
{
|
||||
struct cmd_context *cmd;
|
||||
|
||||
lvm_register_commands();
|
||||
|
||||
init_is_static(static_compile);
|
||||
if (!(cmd = init_lvm(1, 1)))
|
||||
return NULL;
|
||||
|
||||
lvm_register_commands();
|
||||
|
||||
return (void *) cmd;
|
||||
}
|
||||
|
||||
|
1201
tools/lvmcmdline.c
1201
tools/lvmcmdline.c
File diff suppressed because it is too large
Load Diff
@@ -2350,9 +2350,12 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||
struct dm_str_list *sl;
|
||||
struct dm_list final_lvs;
|
||||
struct lv_list *final_lvl;
|
||||
struct dm_list found_arg_lvnames;
|
||||
struct glv_list *glvl, *tglvl;
|
||||
int do_report_ret_code = 1;
|
||||
int lv_is_specific = 0;
|
||||
uint32_t lv_types;
|
||||
struct logical_volume *lv;
|
||||
struct lv_segment *seg;
|
||||
|
||||
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_LV);
|
||||
|
||||
@@ -2361,6 +2364,7 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||
stack;
|
||||
|
||||
dm_list_init(&final_lvs);
|
||||
dm_list_init(&found_arg_lvnames);
|
||||
|
||||
if (!vg_check_status(vg, EXPORTED_VG)) {
|
||||
ret_max = ECMD_FAILED;
|
||||
@@ -2436,8 +2440,9 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||
if (arg_is_set(cmd, all_ARG) ||
|
||||
(lvargs_supplied && str_list_match_item(arg_lvnames, lvl->lv->name))) {
|
||||
log_very_verbose("Processing lockd_sanlock_lv %s/%s.", vg->name, lvl->lv->name);
|
||||
} else
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2449,19 +2454,16 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||
*/
|
||||
|
||||
process_lv = process_all;
|
||||
lv_is_specific = 0;
|
||||
|
||||
if (lvargs_supplied && str_list_match_item(arg_lvnames, lvl->lv->name)) {
|
||||
/* Remove LV from list of unprocessed LV names */
|
||||
str_list_del(arg_lvnames, lvl->lv->name);
|
||||
str_list_add(cmd->mem, &found_arg_lvnames, lvl->lv->name);
|
||||
process_lv = 1;
|
||||
lv_is_specific = 1;
|
||||
}
|
||||
|
||||
if (!process_lv && tags_supplied && str_list_match_list(tags_in, &lvl->lv->tags, NULL)) {
|
||||
if (!process_lv && tags_supplied && str_list_match_list(tags_in, &lvl->lv->tags, NULL))
|
||||
process_lv = 1;
|
||||
lv_is_specific = 1;
|
||||
}
|
||||
|
||||
process_lv = process_lv && select_match_lv(cmd, handle, vg, lvl->lv) && _select_matches(handle);
|
||||
|
||||
@@ -2481,7 +2483,6 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||
goto_out;
|
||||
}
|
||||
final_lvl->lv = lvl->lv;
|
||||
final_lvl->lv->process_specific = lv_is_specific;
|
||||
dm_list_add(&final_lvs, &final_lvl->list);
|
||||
}
|
||||
log_set_report_object_name_and_id(NULL, NULL);
|
||||
@@ -2505,6 +2506,68 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
|
||||
if (lv_is_removed(lvl->lv))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If the command definition specifies one required positional
|
||||
* LV (possibly repeatable), and specifies accepted LV types,
|
||||
* then verify that the LV being processed matches one of those
|
||||
* types.
|
||||
*
|
||||
* process_each_lv() can only be used for commands that have
|
||||
* one positional LV arg (optionally repeating, where each is
|
||||
* processed independently.) It cannot work for commands that
|
||||
* have different required LVs in designated positions, like
|
||||
* 'lvrename LV1 LV2', where each LV is not processed
|
||||
* independently. That means that this LV type check only
|
||||
* needs to check the lv_type of the first positional arg.
|
||||
*
|
||||
* There is one command that violates this rule by stealing
|
||||
* the first positional LV arg before calling process_each_lv:
|
||||
* lvconvert --type snapshot LV_linear_striped_raid LV_snapshot
|
||||
* This code cannot validate that case. process_each_lv() sees
|
||||
* a single LV name arg, but it's in pos 2. Could we work around
|
||||
* this by looking at the final positional arg rather than always
|
||||
* looking at pos 1?
|
||||
*
|
||||
* This only validates types for required LV positional args
|
||||
* (currently there are no command specifications that include
|
||||
* specific LV types in optional positional args.)
|
||||
*/
|
||||
|
||||
if ((cmd->command->rp_count == 1) &&
|
||||
val_bit_is_set(cmd->command->required_pos_args[0].def.val_bits, lv_VAL) &&
|
||||
cmd->command->required_pos_args[0].def.lv_types) {
|
||||
|
||||
lv_types = cmd->command->required_pos_args[0].def.lv_types;
|
||||
lv = lvl->lv;
|
||||
seg = first_seg(lv);
|
||||
|
||||
if ((lv_is_cow(lv) && !(lv_types & ARG_DEF_LV_SNAPSHOT)) ||
|
||||
(lv_is_thin_volume(lv) && !(lv_types & ARG_DEF_LV_THIN)) ||
|
||||
(lv_is_thin_pool(lv) && !(lv_types & ARG_DEF_LV_THINPOOL)) ||
|
||||
(lv_is_cache(lv) && !(lv_types & ARG_DEF_LV_CACHE)) ||
|
||||
(lv_is_cache_pool(lv) && !(lv_types & ARG_DEF_LV_CACHEPOOL)) ||
|
||||
(lv_is_mirror(lv) && !(lv_types & ARG_DEF_LV_MIRROR)) ||
|
||||
(lv_is_raid(lv) && !(lv_types & (ARG_DEF_LV_RAID | ARG_DEF_LV_RAID0 | ARG_DEF_LV_RAID1 | ARG_DEF_LV_RAID4 | ARG_DEF_LV_RAID5 | ARG_DEF_LV_RAID6 | ARG_DEF_LV_RAID10))) ||
|
||||
(segtype_is_striped(seg->segtype) && !(lv_types & ARG_DEF_LV_STRIPED)) ||
|
||||
(segtype_is_linear(seg->segtype) && !(lv_types & ARG_DEF_LV_LINEAR))) {
|
||||
/*
|
||||
* If a named LV arg cannot be processed it's an error, otherwise
|
||||
* the LV is skipped and doesn't cause the command to fail.
|
||||
*/
|
||||
if (str_list_match_item(&found_arg_lvnames, lv->name)) {
|
||||
log_error("Operation not permitted (%s %d) on LV %s with type %s.",
|
||||
cmd->command->command_line_id, cmd->command->command_line_enum,
|
||||
display_lvname(lv), seg->segtype->name);
|
||||
ret_max = ECMD_FAILED;
|
||||
} else {
|
||||
log_warn("Operation not permitted (%s %d) on LV %s with type %s.",
|
||||
cmd->command->command_line_id, cmd->command->command_line_enum,
|
||||
display_lvname(lv), seg->segtype->name);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
log_very_verbose("Processing LV %s in VG %s.", lvl->lv->name, vg->name);
|
||||
|
||||
ret = process_single_lv(cmd, lvl->lv, handle);
|
||||
@@ -3269,9 +3332,12 @@ static int _process_duplicate_pvs(struct cmd_context *cmd,
|
||||
* Don't pass dev to lvmcache_info_from_pvid because we looking
|
||||
* for the chosen/preferred dev for this pvid.
|
||||
*/
|
||||
info = lvmcache_info_from_pvid(devl->dev->pvid, NULL, 0);
|
||||
if (info)
|
||||
vgname = lvmcache_vgname_from_info(info);
|
||||
if (!(info = lvmcache_info_from_pvid(devl->dev->pvid, NULL, 0))) {
|
||||
log_error(INTERNAL_ERROR "No info for pvid");
|
||||
return_ECMD_FAILED;
|
||||
}
|
||||
|
||||
vgname = lvmcache_vgname_from_info(info);
|
||||
if (vgname)
|
||||
vgid = lvmcache_vgid_from_vgname(cmd, vgname);
|
||||
if (vgid)
|
||||
@@ -3834,14 +3900,6 @@ int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
force_t force = (force_t) arg_count(cmd, force_ARG)
|
||||
? : (arg_is_set(cmd, yes_ARG) ? DONT_PROMPT : PROMPT);
|
||||
|
||||
if ((force == PROMPT) &&
|
||||
!lv->process_specific &&
|
||||
(cmd->command->flags & CONFIRM_UNLESS_SPECIFIC)) {
|
||||
if (yes_no_prompt("Remove LV %s that was not named directly? [y/n]: ",
|
||||
display_lvname(lv)) == 'n')
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
if (!lv_remove_with_dependencies(cmd, lv, force, 0))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
|
@@ -50,20 +50,27 @@
|
||||
#define CMD_LEN 256
|
||||
#define MAX_ARGS 64
|
||||
|
||||
/* command functions */
|
||||
typedef int (*command_fn) (struct cmd_context * cmd, int argc, char **argv);
|
||||
/* define the enums for the values accepted by command line --options */
|
||||
enum {
|
||||
#define val(a, b, c, d) a ,
|
||||
#include "vals.h"
|
||||
#undef val
|
||||
};
|
||||
|
||||
#define xx(a, b...) int a(struct cmd_context *cmd, int argc, char **argv);
|
||||
#include "commands.h"
|
||||
#undef xx
|
||||
|
||||
/* define the enums for the command line switches */
|
||||
/* define the enums for the command line --options */
|
||||
enum {
|
||||
#define arg(a, b, c, d, e, f) a ,
|
||||
#include "args.h"
|
||||
#undef arg
|
||||
};
|
||||
|
||||
/* command functions */
|
||||
#define xx(a, b...) int a(struct cmd_context *cmd, int argc, char **argv);
|
||||
#include "commands.h"
|
||||
#undef xx
|
||||
|
||||
#include "command.h"
|
||||
|
||||
#define ARG_COUNTABLE 0x00000001 /* E.g. -vvvv */
|
||||
#define ARG_GROUPABLE 0x00000002 /* E.g. --addtag */
|
||||
|
||||
@@ -79,13 +86,13 @@ struct arg_values {
|
||||
/* void *ptr; // Currently not used. */
|
||||
};
|
||||
|
||||
/* a global table of possible arguments */
|
||||
/* a global table of possible --option's */
|
||||
struct arg_props {
|
||||
int arg_enum; /* foo_ARG from args.h */
|
||||
const char short_arg;
|
||||
char _padding[7];
|
||||
const char *long_arg;
|
||||
|
||||
int (*fn) (struct cmd_context *cmd, struct arg_values *av);
|
||||
int val_enum; /* foo_VAL from vals.h */
|
||||
uint32_t flags;
|
||||
uint32_t prio;
|
||||
};
|
||||
@@ -96,6 +103,14 @@ struct arg_value_group_list {
|
||||
uint32_t prio;
|
||||
};
|
||||
|
||||
/* a global table of possible --option values */
|
||||
struct val_props {
|
||||
int val_enum; /* foo_VAL from vals.h */
|
||||
int (*fn) (struct cmd_context *cmd, struct arg_values *av);
|
||||
const char *name;
|
||||
const char *usage;
|
||||
};
|
||||
|
||||
#define CACHE_VGMETADATA 0x00000001
|
||||
#define PERMITTED_READ_ONLY 0x00000002
|
||||
/* Process all VGs if none specified on the command line. */
|
||||
@@ -118,20 +133,6 @@ struct arg_value_group_list {
|
||||
#define ENABLE_DUPLICATE_DEVS 0x00000400
|
||||
/* Command does not accept tags as args. */
|
||||
#define DISALLOW_TAG_ARGS 0x00000800
|
||||
#define CONFIRM_UNLESS_SPECIFIC 0x00001000
|
||||
|
||||
/* a register of the lvm commands */
|
||||
struct command {
|
||||
const char *name;
|
||||
const char *desc;
|
||||
const char *usage;
|
||||
command_fn fn;
|
||||
|
||||
unsigned flags;
|
||||
|
||||
int num_args;
|
||||
int *valid_args;
|
||||
};
|
||||
|
||||
void usage(const char *name);
|
||||
|
||||
|
135
tools/vals.h
Normal file
135
tools/vals.h
Normal file
@@ -0,0 +1,135 @@
|
||||
|
||||
/*
|
||||
* Define value types which describe values accepted
|
||||
* by the --option's in args.h, and can also describe
|
||||
* the values accepted as positional args.
|
||||
*
|
||||
* Previously, accepted values were only "described"
|
||||
* by identifying the parsing function to use.
|
||||
*
|
||||
* Some standard val types are used by many options,
|
||||
* e.g. many options (aa_ARG, bb_ARG, cc_ARG) all
|
||||
* accept a number_VAL.
|
||||
*
|
||||
* Other special val types are used by only one option,
|
||||
* e.g. only mirrorlog_ARG accepts a mirrorlog_VAL.
|
||||
* This typically means that there are some specific
|
||||
* words that are recognized after the option.
|
||||
*
|
||||
* Some options currently take a standard val type,
|
||||
* (esp string_VAL), but they could be given their
|
||||
* own custom val type. The advantage of using a
|
||||
* custom val type is the possibility of validating
|
||||
* the value when parsing it with a custom parsing
|
||||
* function, and the possibility of displaying the
|
||||
* actual accepted values in the command usage.
|
||||
* Without a custom val type, the code must do ad hoc
|
||||
* validation of the string values, and the usage
|
||||
* output for the option will only say "String"
|
||||
* rather than giving the accepted string values.
|
||||
* Even without a custom parsing function, there is
|
||||
* reason to define a custom x_VAL enum so that a
|
||||
* more descriptive usage string can be specified
|
||||
* as opposed to just "String".
|
||||
*
|
||||
* Most of the val types defined here are used after
|
||||
* --option's, and are referenced in foo_ARG entries
|
||||
* in args.h. But, some val types are only used to
|
||||
* represent positional values in command definitions,
|
||||
* e.g. vg_VAL.
|
||||
*
|
||||
* val(a, b, c, d)
|
||||
*
|
||||
* a: foo_VAL enums
|
||||
* b: the function to parse and set the value
|
||||
* c: the name used to reference this value in command defs
|
||||
* d: what to display in usage output for this value
|
||||
*
|
||||
* command defintions will use --option NAME, where NAME
|
||||
* is shown in val() field c. NAME will be translated to
|
||||
* foo_VAL enum in field a, which is used in commands[]
|
||||
* structs.
|
||||
*
|
||||
* option definitions (arg.h) will reference foo_VAL enum
|
||||
* in field a.
|
||||
*
|
||||
* FIXME: for specialized val types, the set of recognized
|
||||
* words is not defined or stored in a consistent way,
|
||||
* but is just whatever the parsing function happens to look
|
||||
* for, so adding a new accepted value for the val type is
|
||||
* often just making the parsing function recognize a new
|
||||
* word. This new word should then also be added to the
|
||||
* usage string for the val type here. It would be nice
|
||||
* if the accepted values could be defined in a more
|
||||
* consistent way, perhaps in struct val_props.
|
||||
*
|
||||
* The usage text for an option is not always the full
|
||||
* set of words accepted for an option, but may be a
|
||||
* subset. i.e. an outdated word that no longer does
|
||||
* anything may not be shown, but may still be recognized
|
||||
* and ignored, or an option that shouldn't be used in
|
||||
* general isn't shown to avoid suggesting it.
|
||||
* e.g. for --activate we show the most common "y|n|ay"
|
||||
* without showing the lvmlockd variations "ey|sy" which
|
||||
* are not applicable in general.
|
||||
*
|
||||
* FIXME: are there some specialized or irrelevant
|
||||
* options included in the usage text below that should
|
||||
* be removed? Should "lvm1" be removed?
|
||||
*
|
||||
* For Number args that take optional units, a full usage
|
||||
* could be "Number[bBsSkKmMgGtTpPeE]" (with implied |),
|
||||
* but repeating this full specification produces cluttered
|
||||
* output, and doesn't indicate which unit is the default.
|
||||
* "Number[units]" would be cleaner, as would a subset of
|
||||
* common units, e.g. "Number[kmg...]", but neither helps
|
||||
* with default. "Number[k|unit]" and "Number[m|unit]" show
|
||||
* the default, and "unit" indicates that other units
|
||||
* are possible without listing them all. This also
|
||||
* suggests using the preferred lower case letters, because
|
||||
* --size and other option args treat upper/lower letters
|
||||
* the same, all as 1024 SI base. For this reason, we
|
||||
* should avoid suggesting the upper case letters.
|
||||
*/
|
||||
|
||||
val(none_VAL, NULL, "None", "") /* unused, for enum value 0 */
|
||||
val(conststr_VAL, NULL, "ConstString", "") /* used only for command defs */
|
||||
val(constnum_VAL, NULL, "ConstNumber", "") /* used only for command defs */
|
||||
val(bool_VAL, yes_no_arg, "Bool", "y|n")
|
||||
val(number_VAL, int_arg, "Number", NULL)
|
||||
val(string_VAL, string_arg, "String", NULL)
|
||||
val(vg_VAL, string_arg, "VG", NULL)
|
||||
val(lv_VAL, string_arg, "LV", NULL)
|
||||
val(pv_VAL, string_arg, "PV", NULL)
|
||||
val(tag_VAL, tag_arg, "Tag", NULL)
|
||||
val(select_VAL, NULL, "Select", NULL) /* used only for command defs */
|
||||
val(activationmode_VAL, string_arg, "ActivationMode", "partial|degraded|complete")
|
||||
val(activation_VAL, activation_arg, "Active", "y|n|ay")
|
||||
val(cachemode_VAL, cachemode_arg, "CacheMode", "writethrough|writeback")
|
||||
val(discards_VAL, discards_arg, "Discards", "passdown|nopassdown|ignore")
|
||||
val(mirrorlog_VAL, mirrorlog_arg, "MirrorLog", "core|disk")
|
||||
val(sizekb_VAL, size_kb_arg, "SizeKB", "Number[k|unit]")
|
||||
val(sizemb_VAL, size_mb_arg, "SizeMB", "Number[m|unit]")
|
||||
val(numsigned_VAL, int_arg_with_sign, "SNumber", "[+|-]Number")
|
||||
val(numsignedper_VAL, int_arg_with_sign_and_percent, "SNumberP", "[+|-]Number[%{VG|PVS|FREE}]")
|
||||
val(permission_VAL, permission_arg, "Permission", "rw|r")
|
||||
val(metadatatype_VAL, metadatatype_arg, "MetadataType", "lvm2|lvm1")
|
||||
val(units_VAL, string_arg, "Units", "hHbBsSkKmMgGtTpPeE")
|
||||
val(segtype_VAL, segtype_arg, "SegType", "linear|striped|snapshot|mirror|raid*|thin|cache|thin-pool|cache-pool")
|
||||
val(alloc_VAL, alloc_arg, "Alloc", "contiguous|cling|cling_by_tags|normal|anywhere|inherit")
|
||||
val(locktype_VAL, locktype_arg, "LockType", "sanlock|dlm|none")
|
||||
val(readahead_VAL, readahead_arg, "Readahead", "auto|none|NumberSectors")
|
||||
val(metadatacopies_VAL, metadatacopies_arg, "MetadataCopies", "all|unmanaged|Number")
|
||||
|
||||
/* this should always be last */
|
||||
val(VAL_COUNT, NULL, NULL, NULL)
|
||||
|
||||
/*
|
||||
* FIXME: I suspect many of the following are good candidates for a custom VAL
|
||||
* enum for the benefit of custom parsing, or custom usage, or both:
|
||||
*
|
||||
* configreport_ARG, configtype_ARG, polloperation_ARG, raidrebuild_ARG,
|
||||
* raidsyncaction_ARG, raidwritemostly_ARG, reportformat_ARG, syncaction_ARG,
|
||||
* cachepolicy_ARG, cachesettings_ARG, writemostly_ARG
|
||||
*/
|
||||
|
Reference in New Issue
Block a user