mirror of
git://sourceware.org/git/lvm2.git
synced 2025-11-08 00:23:49 +03:00
Compare commits
81 Commits
dev-dct-cm
...
sourceware
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ab0725077 | ||
|
|
3f4ecaf8c2 | ||
|
|
da634bfc89 | ||
|
|
1eb1869626 | ||
|
|
aa72caca5a | ||
|
|
f44e69f9fc | ||
|
|
9712995edd | ||
|
|
6716f5a2f4 | ||
|
|
263050bc07 | ||
|
|
c1ce371b59 | ||
|
|
b7ae57c6a6 | ||
|
|
21fc35dd1b | ||
|
|
7e411b111f | ||
|
|
f80d373753 | ||
|
|
d2dbe71fb3 | ||
|
|
1c1ce2739e | ||
|
|
2a65e2d49e | ||
|
|
7c14004f69 | ||
|
|
d409fec079 | ||
|
|
921d5972e8 | ||
|
|
86a660be7b | ||
|
|
e13639053b | ||
|
|
d22cccdf63 | ||
|
|
a2d2cd8777 | ||
|
|
2396c50689 | ||
|
|
4d29d9afb2 | ||
|
|
5f2639d01d | ||
|
|
13dd1ca757 | ||
|
|
2260c6d1e6 | ||
|
|
d8514b24e1 | ||
|
|
aff62c74b7 | ||
|
|
f16ad760cb | ||
|
|
cd24e6de89 | ||
|
|
665479b818 | ||
|
|
2a21a19d90 | ||
|
|
87c89ac279 | ||
|
|
13944738d4 | ||
|
|
fab0d63121 | ||
|
|
87fe9328d3 | ||
|
|
6064b0359a | ||
|
|
50e0345f9d | ||
|
|
10cb8e0ec0 | ||
|
|
3cf3943898 | ||
|
|
f88ce5fb99 | ||
|
|
56deed9d54 | ||
|
|
00f299b932 | ||
|
|
238a79aac4 | ||
|
|
995f7aa92f | ||
|
|
46d6c7d3ad | ||
|
|
772834e40a | ||
|
|
582a272b3f | ||
|
|
80b717af0c | ||
|
|
298b11aed1 | ||
|
|
1cb95fa5a0 | ||
|
|
15f51bc421 | ||
|
|
22bee4fbdb | ||
|
|
81c0ed9fc6 | ||
|
|
6a5c9ba349 | ||
|
|
2556498ee1 | ||
|
|
4a30f5f9b0 | ||
|
|
286d39ee3c | ||
|
|
d3af0e7528 | ||
|
|
7417c8acfa | ||
|
|
d2c5bb5c70 | ||
|
|
1236e0ed29 | ||
|
|
1dddb068c9 | ||
|
|
c0f2a59993 | ||
|
|
f46b28bdb6 | ||
|
|
c868562a79 | ||
|
|
22457ed4d9 | ||
|
|
fc0e49297d | ||
|
|
3350eb67cc | ||
|
|
6118b0fb93 | ||
|
|
65b82a8072 | ||
|
|
05dd566a52 | ||
|
|
5a87d8667d | ||
|
|
5ab051df7a | ||
|
|
c816e8b636 | ||
|
|
717363bb94 | ||
|
|
b2fd5b31d3 | ||
|
|
698abdde16 |
@@ -59,6 +59,8 @@ liblvm: lib
|
||||
daemons: lib libdaemon tools
|
||||
tools: lib libdaemon device-mapper
|
||||
po: tools daemons
|
||||
man: tools
|
||||
all_man: tools
|
||||
scripts: liblvm libdm
|
||||
|
||||
lib.device-mapper: include.device-mapper
|
||||
|
||||
14
WHATS_NEW
14
WHATS_NEW
@@ -1,5 +1,19 @@
|
||||
Version 2.02.169 -
|
||||
=====================================
|
||||
Reject writemostly/writebehind in lvchange during resynchronization.
|
||||
Deactivate active origin first before removal for improved workflow.
|
||||
Fix regression of accepting options --type and -m with lvresize (2.02.158).
|
||||
Add lvconvert --swapmetadata, new specific way to swap pool metadata LVs.
|
||||
Add lvconvert --startpoll, new specific way to start polling conversions.
|
||||
Add lvconvert --mergethin, new specific way to merge thin snapshots.
|
||||
Add lvconvert --mergemirrors, new specific way to merge split mirrors.
|
||||
Add lvconvert --mergesnapshot, new specific way to combine cow LVs.
|
||||
Split up lvconvert code based on command definitions.
|
||||
Split up lvchange code based on command definitions.
|
||||
Generate help output and man pages from command definitions.
|
||||
Verify all command line items against command definition.
|
||||
Match every command run to one command definition.
|
||||
Specify every allowed command definition/syntax in command-lines.in.
|
||||
Add extra memory page when limiting pthread stack size in clvmd.
|
||||
Support striped/raid0* <-> raid10_near conversions
|
||||
Support shrinking of RaidLvs
|
||||
|
||||
198
configure
vendored
198
configure
vendored
@@ -821,6 +821,8 @@ HAVE_PIE
|
||||
POW_LIB
|
||||
LIBOBJS
|
||||
ALLOCA
|
||||
SORT
|
||||
WC
|
||||
CHMOD
|
||||
CSCOPE_CMD
|
||||
CFLOW_CMD
|
||||
@@ -5234,6 +5236,202 @@ else
|
||||
CHMOD="$ac_cv_path_CHMOD"
|
||||
fi
|
||||
|
||||
if test -n "$ac_tool_prefix"; then
|
||||
# Extract the first word of "${ac_tool_prefix}wc", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}wc; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_WC+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $WC in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_WC="$WC" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_WC="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
WC=$ac_cv_path_WC
|
||||
if test -n "$WC"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $WC" >&5
|
||||
$as_echo "$WC" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
if test -z "$ac_cv_path_WC"; then
|
||||
ac_pt_WC=$WC
|
||||
# Extract the first word of "wc", so it can be a program name with args.
|
||||
set dummy wc; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_ac_pt_WC+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $ac_pt_WC in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_ac_pt_WC="$ac_pt_WC" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_ac_pt_WC="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
ac_pt_WC=$ac_cv_path_ac_pt_WC
|
||||
if test -n "$ac_pt_WC"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_WC" >&5
|
||||
$as_echo "$ac_pt_WC" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
if test "x$ac_pt_WC" = x; then
|
||||
WC=""
|
||||
else
|
||||
case $cross_compiling:$ac_tool_warned in
|
||||
yes:)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
|
||||
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
|
||||
ac_tool_warned=yes ;;
|
||||
esac
|
||||
WC=$ac_pt_WC
|
||||
fi
|
||||
else
|
||||
WC="$ac_cv_path_WC"
|
||||
fi
|
||||
|
||||
if test -n "$ac_tool_prefix"; then
|
||||
# Extract the first word of "${ac_tool_prefix}sort", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}sort; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_SORT+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $SORT in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_SORT="$SORT" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_SORT="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
SORT=$ac_cv_path_SORT
|
||||
if test -n "$SORT"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SORT" >&5
|
||||
$as_echo "$SORT" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
if test -z "$ac_cv_path_SORT"; then
|
||||
ac_pt_SORT=$SORT
|
||||
# Extract the first word of "sort", so it can be a program name with args.
|
||||
set dummy sort; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if ${ac_cv_path_ac_pt_SORT+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $ac_pt_SORT in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_ac_pt_SORT="$ac_pt_SORT" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
|
||||
ac_cv_path_ac_pt_SORT="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
ac_pt_SORT=$ac_cv_path_ac_pt_SORT
|
||||
if test -n "$ac_pt_SORT"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_SORT" >&5
|
||||
$as_echo "$ac_pt_SORT" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
if test "x$ac_pt_SORT" = x; then
|
||||
SORT=""
|
||||
else
|
||||
case $cross_compiling:$ac_tool_warned in
|
||||
yes:)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
|
||||
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
|
||||
ac_tool_warned=yes ;;
|
||||
esac
|
||||
SORT=$ac_pt_SORT
|
||||
fi
|
||||
else
|
||||
SORT="$ac_cv_path_SORT"
|
||||
fi
|
||||
|
||||
|
||||
################################################################################
|
||||
ac_header_dirent=no
|
||||
|
||||
@@ -86,6 +86,8 @@ AC_PROG_RANLIB
|
||||
AC_PATH_TOOL(CFLOW_CMD, cflow)
|
||||
AC_PATH_TOOL(CSCOPE_CMD, cscope)
|
||||
AC_PATH_TOOL(CHMOD, chmod)
|
||||
AC_PATH_TOOL(WC, wc)
|
||||
AC_PATH_TOOL(SORT, sort)
|
||||
|
||||
################################################################################
|
||||
dnl -- Check for header files.
|
||||
|
||||
@@ -184,16 +184,12 @@ int register_device(const char *device,
|
||||
goto_bad;
|
||||
|
||||
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvscan, sizeof(state->cmd_lvscan),
|
||||
"lvscan --cache", device)) {
|
||||
dmeventd_lvm2_exit_with_pool(state);
|
||||
"lvscan --cache", device))
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
|
||||
"lvconvert --repair --use-policies", device)) {
|
||||
dmeventd_lvm2_exit_with_pool(state);
|
||||
"lvconvert --repair --use-policies", device))
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
*user = state;
|
||||
|
||||
@@ -203,6 +199,9 @@ int register_device(const char *device,
|
||||
bad:
|
||||
log_error("Failed to monitor mirror %s.", device);
|
||||
|
||||
if (state)
|
||||
dmeventd_lvm2_exit_with_pool(state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -140,10 +140,8 @@ int register_device(const char *device,
|
||||
"lvscan --cache", device) ||
|
||||
!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
|
||||
"lvconvert --config devices{ignore_suspended_devices=1} "
|
||||
"--repair --use-policies", device)) {
|
||||
dmeventd_lvm2_exit_with_pool(state);
|
||||
"--repair --use-policies", device))
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
*user = state;
|
||||
|
||||
@@ -153,6 +151,9 @@ int register_device(const char *device,
|
||||
bad:
|
||||
log_error("Failed to monitor RAID %s.", device);
|
||||
|
||||
if (state)
|
||||
dmeventd_lvm2_exit_with_pool(state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -254,10 +254,8 @@ int register_device(const char *device,
|
||||
|
||||
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvextend,
|
||||
sizeof(state->cmd_lvextend),
|
||||
"lvextend --use-policies", device)) {
|
||||
dmeventd_lvm2_exit_with_pool(state);
|
||||
"lvextend --use-policies", device))
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
state->percent_check = CHECK_MINIMUM;
|
||||
*user = state;
|
||||
@@ -268,6 +266,9 @@ int register_device(const char *device,
|
||||
bad:
|
||||
log_error("Failed to monitor snapshot %s.", device);
|
||||
|
||||
if (state)
|
||||
dmeventd_lvm2_exit_with_pool(state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -359,10 +359,8 @@ int register_device(const char *device,
|
||||
goto_bad;
|
||||
|
||||
if (!dmeventd_lvm2_command(state->mem, cmd_str, sizeof(cmd_str),
|
||||
"_dmeventd_thin_command", device)) {
|
||||
dmeventd_lvm2_exit_with_pool(state);
|
||||
"_dmeventd_thin_command", device))
|
||||
goto_bad;
|
||||
}
|
||||
|
||||
if (strncmp(cmd_str, "lvm ", 4) == 0) {
|
||||
if (!(state->cmd_str = dm_pool_strdup(state->mem, cmd_str + 4))) {
|
||||
@@ -401,6 +399,9 @@ inval:
|
||||
bad:
|
||||
log_error("Failed to monitor thin pool %s.", device);
|
||||
|
||||
if (state)
|
||||
dmeventd_lvm2_exit_with_pool(state);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1948,16 +1948,13 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
||||
|
||||
/* Check [un]monitor results */
|
||||
/* Try a couple times if pending, but not forever... */
|
||||
for (i = 0; i < 40; i++) {
|
||||
for (i = 0;; i++) {
|
||||
pending = 0;
|
||||
monitored = seg->segtype->ops->target_monitored(seg, &pending);
|
||||
if (pending ||
|
||||
(!monitored && monitor) ||
|
||||
(monitored && !monitor))
|
||||
if (!pending || i >= 40)
|
||||
break;
|
||||
log_very_verbose("%s %smonitoring still pending: waiting...",
|
||||
display_lvname(lv), monitor ? "" : "un");
|
||||
else
|
||||
break;
|
||||
usleep(10000 * i);
|
||||
}
|
||||
|
||||
|
||||
@@ -6229,12 +6229,21 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
|
||||
/* Remove snapshot LVs first */
|
||||
if ((force == PROMPT) &&
|
||||
/* Active snapshot already needs to confirm each active LV */
|
||||
!lv_is_active(lv) &&
|
||||
yes_no_prompt("Removing origin %s will also remove %u "
|
||||
"snapshots(s). Proceed? [y/n]: ",
|
||||
lv->name, lv->origin_count) == 'n')
|
||||
(yes_no_prompt("Do you really want to remove%s "
|
||||
"%sorigin logical volume %s with %u snapshot(s)? [y/n]: ",
|
||||
lv_is_active(lv) ? " active" : "",
|
||||
vg_is_clustered(lv->vg) ? "clustered " : "",
|
||||
display_lvname(lv),
|
||||
lv->origin_count) == 'n'))
|
||||
goto no_remove;
|
||||
|
||||
if (!deactivate_lv(cmd, lv)) {
|
||||
stack;
|
||||
goto no_remove;
|
||||
}
|
||||
log_verbose("Removing origin logical volume %s with %u snapshots(s).",
|
||||
display_lvname(lv), lv->origin_count);
|
||||
|
||||
dm_list_iterate_safe(snh, snht, &lv->snapshot_segs)
|
||||
if (!lv_remove_with_dependencies(cmd, dm_list_struct_base(snh, struct lv_segment,
|
||||
origin_list)->cow,
|
||||
|
||||
@@ -1232,6 +1232,7 @@ uint32_t raid_rimage_extents(const struct segment_type *segtype,
|
||||
uint32_t raid_ensure_min_region_size(const struct logical_volume *lv, uint64_t raid_size, uint32_t region_size);
|
||||
int lv_raid_change_region_size(struct logical_volume *lv,
|
||||
int yes, int force, uint32_t new_region_size);
|
||||
int lv_raid_in_sync(const struct logical_volume *lv);
|
||||
/* -- metadata/raid_manip.c */
|
||||
|
||||
/* ++ metadata/cache_manip.c */
|
||||
|
||||
@@ -238,7 +238,7 @@ static int _deactivate_and_remove_lvs(struct volume_group *vg, struct dm_list *r
|
||||
* Returns: 1 if in-sync, 0 otherwise.
|
||||
*/
|
||||
#define _RAID_IN_SYNC_RETRIES 6
|
||||
static int _raid_in_sync(struct logical_volume *lv)
|
||||
static int _raid_in_sync(const struct logical_volume *lv)
|
||||
{
|
||||
int retries = _RAID_IN_SYNC_RETRIES;
|
||||
dm_percent_t sync_percent;
|
||||
@@ -269,6 +269,12 @@ static int _raid_in_sync(struct logical_volume *lv)
|
||||
return (sync_percent == DM_PERCENT_100) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* External interface to raid in-sync check */
|
||||
int lv_raid_in_sync(const struct logical_volume *lv)
|
||||
{
|
||||
return _raid_in_sync(lv);
|
||||
}
|
||||
|
||||
/* Check if RaidLV @lv is synced or any raid legs of @lv are not synced */
|
||||
static int _raid_devs_sync_healthy(struct logical_volume *lv)
|
||||
{
|
||||
|
||||
@@ -3868,37 +3868,6 @@ static int _extent_start_compare(const void *p1, const void *p2)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Resize the group bitmap corresponding to group_id so that it can
|
||||
* contain at least num_regions members.
|
||||
*/
|
||||
static int _stats_resize_group(struct dm_stats_group *group, int num_regions)
|
||||
{
|
||||
int last_bit = dm_bit_get_last(group->regions);
|
||||
dm_bitset_t new, old;
|
||||
|
||||
if (last_bit >= num_regions) {
|
||||
log_error("Cannot resize group bitmap to %d with bit %d set.",
|
||||
num_regions, last_bit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_very_verbose("Resizing group bitmap from %d to %d (last_bit: %d).",
|
||||
group->regions[0], num_regions, last_bit);
|
||||
|
||||
new = dm_bitset_create(NULL, num_regions);
|
||||
if (!new) {
|
||||
log_error("Could not allocate memory for new group bitmap.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
old = group->regions;
|
||||
dm_bit_copy(new, old);
|
||||
group->regions = new;
|
||||
dm_bitset_destroy(old);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _stats_create_group(struct dm_stats *dms, dm_bitset_t regions,
|
||||
const char *alias, uint64_t *group_id)
|
||||
{
|
||||
@@ -4202,6 +4171,37 @@ int dm_stats_get_group_descriptor(const struct dm_stats *dms,
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINUX_FIEMAP_H
|
||||
/*
|
||||
* Resize the group bitmap corresponding to group_id so that it can
|
||||
* contain at least num_regions members.
|
||||
*/
|
||||
static int _stats_resize_group(struct dm_stats_group *group, int num_regions)
|
||||
{
|
||||
int last_bit = dm_bit_get_last(group->regions);
|
||||
dm_bitset_t new, old;
|
||||
|
||||
if (last_bit >= num_regions) {
|
||||
log_error("Cannot resize group bitmap to %d with bit %d set.",
|
||||
num_regions, last_bit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_very_verbose("Resizing group bitmap from %d to %d (last_bit: %d).",
|
||||
group->regions[0], num_regions, last_bit);
|
||||
|
||||
new = dm_bitset_create(NULL, num_regions);
|
||||
if (!new) {
|
||||
log_error("Could not allocate memory for new group bitmap.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
old = group->regions;
|
||||
dm_bit_copy(new, old);
|
||||
group->regions = new;
|
||||
dm_bitset_destroy(old);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Group a table of region_ids corresponding to the extents of a file.
|
||||
*/
|
||||
|
||||
@@ -40,6 +40,11 @@ SED = @SED@
|
||||
CFLOW_CMD = @CFLOW_CMD@
|
||||
AWK = @AWK@
|
||||
CHMOD = @CHMOD@
|
||||
EGREP = @EGREP@
|
||||
GREP = @GREP@
|
||||
SORT = @SORT@
|
||||
WC = @WC@
|
||||
|
||||
PYTHON2 = @PYTHON2@
|
||||
PYTHON3 = @PYTHON3@
|
||||
PYCOMPILE = $(top_srcdir)/autoconf/py-compile
|
||||
@@ -512,9 +517,9 @@ ifeq (,$(firstword $(EXPORTED_SYMBOLS)))
|
||||
) > $@
|
||||
else
|
||||
set -e;\
|
||||
R=$$(sort $^ | uniq -u);\
|
||||
R=$$($(SORT) $^ | uniq -u);\
|
||||
test -z "$$R" || { echo "Mismatch between symbols in shared library and lists in .exported_symbols.* files: $$R"; false; } ;\
|
||||
( for i in $$(echo $(EXPORTED_SYMBOLS) | tr ' ' '\n' | sort -rnt_ -k5 ); do\
|
||||
( for i in $$(echo $(EXPORTED_SYMBOLS) | tr ' ' '\n' | $(SORT) -rnt_ -k5 ); do\
|
||||
echo "$${i##*.} {"; echo " global:";\
|
||||
$(SED) "s/^/ /;s/$$/;/" $$i;\
|
||||
echo "};";\
|
||||
|
||||
@@ -23,40 +23,6 @@ dmeventd is the event monitoring daemon for device-mapper devices.
|
||||
Library plugins can register and carry out actions triggered when
|
||||
particular events occur.
|
||||
.
|
||||
.SH LVM PLUGINS
|
||||
.
|
||||
.HP
|
||||
.IR Mirror
|
||||
.br
|
||||
Attempts to handle device failure automatically. See
|
||||
.BR lvm.conf (5).
|
||||
.
|
||||
.HP
|
||||
.IR Raid
|
||||
.br
|
||||
Attempts to handle device failure automatically. See
|
||||
.BR lvm.conf (5).
|
||||
.
|
||||
.HP
|
||||
.IR Snapshot
|
||||
.br
|
||||
Monitors how full a snapshot is becoming and emits a warning to
|
||||
syslog when it exceeds 80% full.
|
||||
The warning is repeated when 85%, 90% and 95% of the snapshot is filled.
|
||||
See
|
||||
.BR lvm.conf (5).
|
||||
Snapshot which runs out of space gets invalid and when it is mounted,
|
||||
it gets umounted if possible.
|
||||
.
|
||||
.HP
|
||||
.IR Thin
|
||||
.br
|
||||
Monitors how full a thin pool data and metadata is becoming and emits
|
||||
a warning to syslog when it exceeds 80% full.
|
||||
The warning is repeated when 85%, 90% and 95% of the thin pool is filled.
|
||||
See
|
||||
.BR lvm.conf (5).
|
||||
If the thin-pool runs out of space, thin volumes are umounted if possible.
|
||||
.
|
||||
.SH OPTIONS
|
||||
.
|
||||
@@ -104,6 +70,80 @@ events to monitor from the currently running daemon.
|
||||
.br
|
||||
Show version of dmeventd.
|
||||
.
|
||||
.SH LVM PLUGINS
|
||||
.
|
||||
.HP
|
||||
.BR Mirror
|
||||
.br
|
||||
Attempts to handle device failure automatically. See
|
||||
.BR lvm.conf (5).
|
||||
.
|
||||
.HP
|
||||
.BR Raid
|
||||
.br
|
||||
Attempts to handle device failure automatically. See
|
||||
.BR lvm.conf (5).
|
||||
.
|
||||
.HP
|
||||
.BR Snapshot
|
||||
.br
|
||||
Monitors how full a snapshot is becoming and emits a warning to
|
||||
syslog when it exceeds 80% full.
|
||||
The warning is repeated when 85%, 90% and 95% of the snapshot is filled.
|
||||
See
|
||||
.BR lvm.conf (5).
|
||||
Snapshot which runs out of space gets invalid and when it is mounted,
|
||||
it gets umounted if possible.
|
||||
.
|
||||
.HP
|
||||
.BR Thin
|
||||
.br
|
||||
Monitors how full a thin pool data and metadata is becoming and emits
|
||||
a warning to syslog when it exceeds 80% full.
|
||||
The warning is repeated when more then 85%, 90% and 95%
|
||||
of the thin pool is filled. See
|
||||
.BR lvm.conf (5).
|
||||
When a thin pool fills over 50% (data or metadata) thin plugin calls
|
||||
configured \fIdmeventd/thin_command\fP with every 5% increase.
|
||||
With default setting it calls internal
|
||||
\fBlvm lvextend --use-policies\fP to resize thin pool
|
||||
when it's been filled above configured threshold
|
||||
\fIactivation/thin_pool_autoextend_threshold\fP.
|
||||
If the command fails, dmeventd thin plugin will keep
|
||||
retrying execution with increasing time delay between
|
||||
retries upto 42 minutes.
|
||||
User may also configure external command to support more advanced
|
||||
maintenance operations of a thin pool.
|
||||
Such external command can e.g. remove some unneeded snapshots,
|
||||
use \fBfstrim\fP(8) to free recover space in a thin pool,
|
||||
but also can use \fBlvextend --use-policies\fP if other actions
|
||||
have not released enough space.
|
||||
Command is executed with environmental variable
|
||||
\fBLVM_RUN_BY_DMEVENTD=1\fP so any lvm2 command executed
|
||||
in this environment will not try to interact with dmeventd.
|
||||
To see the fullness of a thin pool command may check these
|
||||
two environmental variables
|
||||
\fBDMEVENTD_THIN_POOL_DATA\fP and \fBDMEVENTD_THIN_POOL_DATA\fP.
|
||||
Command can also read status with tools like \fBlvs\fP(8).
|
||||
.
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
.
|
||||
.TP
|
||||
.B DMEVENTD_THIN_POOL_DATA
|
||||
Variable is set by thin plugin and is available to executed program. Value present
|
||||
actual usage of thin pool data volume. Variable is not set when error event
|
||||
is processed.
|
||||
.TP
|
||||
.B DMEVENTD_THIN_POOL_DATA
|
||||
Variable is set by thin plugin and is available to executed program. Value present
|
||||
actual usage of thin pool metadata volume. Variable is not set when error event
|
||||
is processed.
|
||||
.TP
|
||||
.B LVM_RUN_BY_DMEVENTD
|
||||
Variable is set by thin plugin to prohibit recursive interation
|
||||
with dmeventd by any executed lvm2 command from
|
||||
a thin_command environment.
|
||||
.
|
||||
.SH SEE ALSO
|
||||
.
|
||||
.BR lvm (8),
|
||||
|
||||
@@ -27,9 +27,9 @@ dmsetup \(em low level logical volume management
|
||||
. IR uuid ]
|
||||
. RB \%[ \-\-addnodeoncreate | \-\-addnodeonresume ]
|
||||
. RB \%[ \-n | \-\-notable | \-\-table
|
||||
. RI \%{ table | table_file }]
|
||||
. IR \%table | table_file ]
|
||||
. RB [ \-\-readahead
|
||||
. RB \%{[ + ] \fIsectors | auto | none }]
|
||||
. RB \%[ + ] \fIsectors | auto | none ]
|
||||
. ad b
|
||||
..
|
||||
.CMD_CREATE
|
||||
@@ -41,7 +41,7 @@ dmsetup \(em low level logical volume management
|
||||
. BR deps
|
||||
. RB [ \-o
|
||||
. IR options ]
|
||||
. RI [ device_name ]
|
||||
. RI [ device_name ...]
|
||||
. ad b
|
||||
..
|
||||
.CMD_DEPS
|
||||
@@ -58,7 +58,7 @@ dmsetup \(em low level logical volume management
|
||||
.B dmsetup
|
||||
.de CMD_INFO
|
||||
. BR info
|
||||
. RI [ device_name ]
|
||||
. RI [ device_name ...]
|
||||
..
|
||||
.CMD_INFO
|
||||
.
|
||||
@@ -92,7 +92,7 @@ dmsetup \(em low level logical volume management
|
||||
. BR load
|
||||
. IR device_name
|
||||
. RB [ \-\-table
|
||||
. RI { table | table_file }]
|
||||
. IR table | table_file ]
|
||||
. ad b
|
||||
..
|
||||
.CMD_LOAD
|
||||
@@ -117,7 +117,7 @@ dmsetup \(em low level logical volume management
|
||||
.B dmsetup
|
||||
.de CMD_MANGLE
|
||||
. BR mangle
|
||||
. RI [ device_name ]
|
||||
. RI [ device_name ...]
|
||||
..
|
||||
.CMD_MANGLE
|
||||
.
|
||||
@@ -135,7 +135,7 @@ dmsetup \(em low level logical volume management
|
||||
.B dmsetup
|
||||
.de CMD_MKNODES
|
||||
. BR mknodes
|
||||
. RI [ device_name ]
|
||||
. RI [ device_name ...]
|
||||
..
|
||||
.CMD_MKNODES
|
||||
.
|
||||
@@ -146,7 +146,7 @@ dmsetup \(em low level logical volume management
|
||||
. BR reload
|
||||
. IR device_name
|
||||
. RB [ \-\-table
|
||||
. RI { table | table_file }]
|
||||
. IR table | table_file ]
|
||||
. ad b
|
||||
..
|
||||
.CMD_RELOAD
|
||||
@@ -159,7 +159,7 @@ dmsetup \(em low level logical volume management
|
||||
. RB [ \-f | \-\-force ]
|
||||
. RB [ \-\-retry ]
|
||||
. RB [ \-\-deferred ]
|
||||
. IR device_name
|
||||
. IR device_name ...
|
||||
. ad b
|
||||
..
|
||||
.CMD_REMOVE
|
||||
@@ -197,12 +197,12 @@ dmsetup \(em low level logical volume management
|
||||
.de CMD_RESUME
|
||||
. ad l
|
||||
. BR resume
|
||||
. IR device_name
|
||||
. IR device_name ...
|
||||
. RB [ \-\-addnodeoncreate | \-\-addnodeonresume ]
|
||||
. RB [ \-\-noflush ]
|
||||
. RB [ \-\-nolockfs ]
|
||||
. RB \%[ \-\-readahead
|
||||
. RB \%{[ + ] \fIsectors | auto | none }]
|
||||
. RB \%[ + ] \fIsectors | auto | none ]
|
||||
. ad b
|
||||
..
|
||||
.CMD_RESUME
|
||||
@@ -247,7 +247,7 @@ dmsetup \(em low level logical volume management
|
||||
. RB [ \-\-target
|
||||
. IR target_type ]
|
||||
. RB [ \-\-noflush ]
|
||||
. RI [ device_name ]
|
||||
. RI [ device_name ...]
|
||||
. ad b
|
||||
..
|
||||
.CMD_STATUS
|
||||
@@ -259,7 +259,7 @@ dmsetup \(em low level logical volume management
|
||||
. BR suspend
|
||||
. RB [ \-\-nolockfs ]
|
||||
. RB [ \-\-noflush ]
|
||||
. IR device_name
|
||||
. IR device_name ...
|
||||
. ad b
|
||||
..
|
||||
.CMD_SUSPEND
|
||||
@@ -272,7 +272,7 @@ dmsetup \(em low level logical volume management
|
||||
. RB [ \-\-target
|
||||
. IR target_type ]
|
||||
. RB [ \-\-showkeys ]
|
||||
. RI [ device_name ]
|
||||
. RI [ device_name ...]
|
||||
. ad b
|
||||
..
|
||||
.CMD_TABLE
|
||||
@@ -354,7 +354,7 @@ dmsetup \(em low level logical volume management
|
||||
.de CMD_WIPE_TABLE
|
||||
. ad l
|
||||
. BR wipe_table
|
||||
. IR device_name
|
||||
. IR device_name ...
|
||||
. RB [ \-f | \-\-force ]
|
||||
. RB [ \-\-noflush ]
|
||||
. RB [ \-\-nolockfs ]
|
||||
@@ -447,7 +447,7 @@ The default interval is one second.
|
||||
.
|
||||
.HP
|
||||
.BR \-\-manglename
|
||||
.RB { auto | hex | none }
|
||||
.BR auto | hex | none
|
||||
.br
|
||||
Mangle any character not on a whitelist using mangling_mode when
|
||||
processing device-mapper device names and UUIDs. The names and UUIDs
|
||||
@@ -529,7 +529,7 @@ Specify which fields to display.
|
||||
.
|
||||
.HP
|
||||
.BR \-\-readahead
|
||||
.RB {[ + ] \fIsectors | auto | none }
|
||||
.RB [ + ] \fIsectors | auto | none
|
||||
.br
|
||||
Specify read ahead size in units of sectors.
|
||||
The default value is \fBauto\fP which allows the kernel to choose
|
||||
|
||||
@@ -44,7 +44,7 @@ dmstats \(em device-mapper statistics management
|
||||
.B dmsetup
|
||||
.B stats
|
||||
.I command
|
||||
.RB [ options ]
|
||||
[OPTIONS]
|
||||
.sp
|
||||
.
|
||||
.PD 0
|
||||
@@ -53,13 +53,13 @@ dmstats \(em device-mapper statistics management
|
||||
.de CMD_COMMAND
|
||||
. ad l
|
||||
. IR command
|
||||
. RI [ device_name |
|
||||
. RB [ \-u | \-\-uuid
|
||||
. IR uuid ]
|
||||
. RB | [ \-\-major
|
||||
. IR device_name " |"
|
||||
. BR \-\-major
|
||||
. IR major
|
||||
. BR \-\-minor
|
||||
. IR minor ]
|
||||
. IR minor " |"
|
||||
. BR \-u | \-\-uuid
|
||||
. IR uuid
|
||||
. RB \%[ \-v | \-\-verbose]
|
||||
. ad b
|
||||
..
|
||||
@@ -82,9 +82,7 @@ dmstats \(em device-mapper statistics management
|
||||
.de CMD_CREATE
|
||||
. ad l
|
||||
. BR create
|
||||
. RB [ device_name...
|
||||
. RB | file_path...
|
||||
. RB | [ \-\-alldevices ]]
|
||||
. IR device_name... | file_path... | \fB\-\-alldevices
|
||||
. RB [ \-\-areas
|
||||
. IR nr_areas | \fB\-\-areasize
|
||||
. IR area_size ]
|
||||
@@ -110,8 +108,7 @@ dmstats \(em device-mapper statistics management
|
||||
.de CMD_DELETE
|
||||
. ad l
|
||||
. BR delete
|
||||
. RI [ device_name ]
|
||||
. RB [ \-\-alldevices ]
|
||||
. IR device_name | \fB\-\-alldevices
|
||||
. OPT_PROGRAMS
|
||||
. OPT_REGIONS
|
||||
. ad b
|
||||
@@ -123,10 +120,9 @@ dmstats \(em device-mapper statistics management
|
||||
.de CMD_GROUP
|
||||
. ad l
|
||||
. BR group
|
||||
. RI [ device_name ]
|
||||
. RI [ device_name | \fB\-\-alldevices ]
|
||||
. RB [ \-\-alias
|
||||
. IR name ]
|
||||
. RB [ \-\-alldevices ]
|
||||
. RB [ \-\-regions
|
||||
. IR regions ]
|
||||
. ad b
|
||||
@@ -205,8 +201,7 @@ dmstats \(em device-mapper statistics management
|
||||
.de CMD_UNGROUP
|
||||
. ad l
|
||||
. BR ungroup
|
||||
. RI [ device_name ]
|
||||
. RB [ \-\-alldevices ]
|
||||
. RI [ device_name | \fB\-\-alldevices ]
|
||||
. RB [ \-\-groupid
|
||||
. IR id ]
|
||||
. ad b
|
||||
@@ -217,7 +212,7 @@ dmstats \(em device-mapper statistics management
|
||||
.de CMD_UPDATE_FILEMAP
|
||||
. ad l
|
||||
. BR update_filemap
|
||||
. RI file_path
|
||||
. IR file_path
|
||||
. RB [ \-\-groupid
|
||||
. IR id ]
|
||||
. ad b
|
||||
|
||||
@@ -20,12 +20,6 @@ type is deprecated and the
|
||||
.B raid1
|
||||
type should be used. They are both implementations of mirroring.
|
||||
|
||||
The
|
||||
.B raid*
|
||||
type refers to one of many raid levels, e.g.
|
||||
.B raid1,
|
||||
.B raid5.
|
||||
|
||||
In some cases, an LV is a single device mapper (dm) layer above physical
|
||||
devices. In other cases, hidden LVs (dm devices) are layered between the
|
||||
visible LV and physical devices. LVs in the middle layers are called sub LVs.
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
.SH NOTES
|
||||
|
||||
This previous command syntax would perform two different operations:
|
||||
.br
|
||||
\fBlvconvert --thinpool\fP \fILV1\fP \fB--poolmetadata\fP \fILV2\fP
|
||||
.br
|
||||
If LV1 was not a thin pool, the command would convert LV1 to
|
||||
a thin pool, optionally using a specified LV for metadata.
|
||||
But, if LV1 was already a thin pool, the command would swap
|
||||
the current metadata LV with LV2 (for repair purposes.)
|
||||
|
||||
In the same way, this previous command syntax would perform two different
|
||||
operations:
|
||||
.br
|
||||
\fBlvconvert --cachepool\fP \fILV1\fP \fB--poolmetadata\fP \fILV2\fP
|
||||
.br
|
||||
If LV1 was not a cache pool, the command would convert LV1 to
|
||||
a cache pool, optionally using a specified LV for metadata.
|
||||
But, if LV1 was already a cache pool, the command would swap
|
||||
the current metadata LV with LV2 (for repair purposes.)
|
||||
|
||||
.SH EXAMPLES
|
||||
|
||||
Convert a linear LV to a two-way mirror LV.
|
||||
|
||||
@@ -26,3 +26,14 @@ virtual size rather than a physical size. A cache LV is the combination of
|
||||
a standard LV with a cache pool, used to cache active portions of the LV
|
||||
to improve performance.
|
||||
|
||||
.SS Usage notes
|
||||
|
||||
In the usage section below, \fB--size\fP \fINumber\fP can be replaced
|
||||
in each case with \fB--extents\fP \fINumberExtents\fP. Also see both
|
||||
descriptions the options section.
|
||||
|
||||
In the usage section below, \fB--name\fP is omitted from the required
|
||||
options, even though it is typically used. When the name is not
|
||||
specified, a new LV name is generated with the "lvol" prefix and a unique
|
||||
numeric suffix. Also see the description in the options section.
|
||||
|
||||
|
||||
5
man/lvm-config.8.des
Normal file
5
man/lvm-config.8.des
Normal file
@@ -0,0 +1,5 @@
|
||||
This command is the same as \fBlvmconfig\fP(8).
|
||||
|
||||
lvm config produces formatted output from the LVM configuration tree. The
|
||||
sources of the configuration data include \fBlvm.conf\fP(5) and command
|
||||
line settings from \-\-config.
|
||||
5
man/lvm-dumpconfig.8.des
Normal file
5
man/lvm-dumpconfig.8.des
Normal file
@@ -0,0 +1,5 @@
|
||||
This command is the same as \fBlvmconfig\fP(8).
|
||||
|
||||
lvm dumpconfig produces formatted output from the LVM configuration tree. The
|
||||
sources of the configuration data include \fBlvm.conf\fP(5) and command
|
||||
line settings from \-\-config.
|
||||
108
man/lvm.8.in
108
man/lvm.8.in
@@ -484,48 +484,70 @@ directly.
|
||||
.SH SEE ALSO
|
||||
.
|
||||
.nh
|
||||
.BR lvm.conf (5),
|
||||
.BR lvmcache (7),
|
||||
.BR lvmreport(7),
|
||||
.BR lvmthin (7),
|
||||
.BR clvmd (8),
|
||||
.BR lvm (8)
|
||||
.BR lvm.conf (5)
|
||||
.BR lvmconfig (8)
|
||||
|
||||
.BR pvchange (8)
|
||||
.BR pvck (8)
|
||||
.BR pvcreate (8)
|
||||
.BR pvdisplay (8)
|
||||
.BR pvmove (8)
|
||||
.BR pvremove (8)
|
||||
.BR pvresize (8)
|
||||
.BR pvs (8)
|
||||
.BR pvscan (8)
|
||||
|
||||
.BR vgcfgbackup (8)
|
||||
.BR vgcfgrestore (8)
|
||||
.BR vgchange (8)
|
||||
.BR vgck (8)
|
||||
.BR vgcreate (8)
|
||||
.BR vgconvert (8)
|
||||
.BR vgdisplay (8)
|
||||
.BR vgexport (8)
|
||||
.BR vgextend (8)
|
||||
.BR vgimport (8)
|
||||
.BR vgimportclone (8)
|
||||
.BR vgmerge (8)
|
||||
.BR vgmknodes (8)
|
||||
.BR vgreduce (8)
|
||||
.BR vgremove (8)
|
||||
.BR vgrename (8)
|
||||
.BR vgs (8)
|
||||
.BR vgscan (8)
|
||||
.BR vgsplit (8)
|
||||
|
||||
.BR lvcreate (8)
|
||||
.BR lvchange (8)
|
||||
.BR lvconvert (8)
|
||||
.BR lvdisplay (8)
|
||||
.BR lvextend (8)
|
||||
.BR lvreduce (8)
|
||||
.BR lvremove (8)
|
||||
.BR lvrename (8)
|
||||
.BR lvresize (8)
|
||||
.BR lvs (8)
|
||||
.BR lvscan (8)
|
||||
|
||||
.BR lvm2-activation-generator (8)
|
||||
.BR blkdeactivate (8)
|
||||
.BR lvmdump (8)
|
||||
|
||||
.BR dmeventd (8)
|
||||
.BR lvmetad (8)
|
||||
.BR lvmpolld (8)
|
||||
.BR lvmlockd (8)
|
||||
.BR lvmlockctl (8)
|
||||
.BR clvmd (8)
|
||||
.BR cmirrord (8)
|
||||
.BR lvmdbusd (8)
|
||||
|
||||
.BR lvmsystemid (7)
|
||||
.BR lvmreport (7)
|
||||
.BR lvmraid (7)
|
||||
.BR lvmthin (7)
|
||||
.BR lvmcache (7)
|
||||
|
||||
.BR dmsetup (8),
|
||||
.BR lvchange (8),
|
||||
.BR lvcreate (8),
|
||||
.BR lvdisplay (8),
|
||||
.BR lvextend (8),
|
||||
.BR lvmchange (8),
|
||||
.BR lvmconfig (8),
|
||||
.BR lvmdiskscan (8),
|
||||
.BR lvreduce (8),
|
||||
.BR lvremove (8),
|
||||
.BR lvrename (8),
|
||||
.BR lvresize (8),
|
||||
.BR lvs (8),
|
||||
.BR lvscan (8),
|
||||
.BR pvchange (8),
|
||||
.BR pvck (8),
|
||||
.BR pvcreate (8),
|
||||
.BR pvdisplay (8),
|
||||
.BR pvmove (8),
|
||||
.BR pvremove (8),
|
||||
.BR pvs (8),
|
||||
.BR pvscan (8),
|
||||
.BR vgcfgbackup (8),
|
||||
.BR vgchange (8),
|
||||
.BR vgck (8),
|
||||
.BR vgconvert (8),
|
||||
.BR vgcreate (8),
|
||||
.BR vgdisplay (8),
|
||||
.BR vgextend (8),
|
||||
.BR vgimport (8),
|
||||
.BR vgimportclone (8),
|
||||
.BR vgmerge (8),
|
||||
.BR vgmknodes (8),
|
||||
.BR vgreduce (8),
|
||||
.BR vgremove (8),
|
||||
.BR vgrename (8),
|
||||
.BR vgs (8),
|
||||
.BR vgscan (8),
|
||||
.BR vgsplit (8),
|
||||
.BR readline (3)
|
||||
|
||||
@@ -278,22 +278,6 @@ or vgchange to activate thin snapshots with the "k" attribute.
|
||||
|
||||
\&
|
||||
|
||||
.SS Alternate syntax for specifying type thin\-pool
|
||||
|
||||
\&
|
||||
|
||||
The fully specified syntax for creating a thin pool LV shown above is:
|
||||
|
||||
.B lvconvert \-\-type thin-pool \-\-poolmetadata VG/ThinMetaLV VG/ThinDataLV
|
||||
|
||||
An alternate syntax may be used for the same operation:
|
||||
|
||||
.B lvconvert \-\-thinpool VG/ThinDataLV \-\-poolmetadata VG/ThinMetaLV
|
||||
|
||||
The thin-pool type is inferred by lvm; the \-\-thinpool option is not an
|
||||
alias for \-\-type thin\-pool.
|
||||
|
||||
|
||||
.SS Automatic pool metadata LV
|
||||
|
||||
\&
|
||||
|
||||
@@ -6,6 +6,11 @@ removal. LVs cannot be deactivated or removed while they are open (e.g.
|
||||
if they contain a mounted filesystem). Removing an origin LV will also
|
||||
remove all dependent snapshots.
|
||||
|
||||
When a single force option is used, LVs are removed without confirmation,
|
||||
and the command will try to deactivate unused LVs.
|
||||
|
||||
To remove damaged LVs, two force options may be required (\fB-ff\fP).
|
||||
|
||||
\fBHistorical LVs\fP
|
||||
|
||||
If the configuration setting \fBmetadata/record_lvs_history\fP is enabled
|
||||
|
||||
@@ -16,3 +16,6 @@ data on that disk. This can be done by zeroing the first sector with:
|
||||
Use \fBvgcreate\fP(8) to create a new VG on the PV, or \fBvgextend\fP(8)
|
||||
to add the PV to existing VG.
|
||||
|
||||
The force option will create a PV without confirmation. Repeating the
|
||||
force option (\fB-ff\fP) will forcibly create a PV, overriding checks that
|
||||
normally prevent it, e.g. if the PV is already in a VG.
|
||||
|
||||
@@ -14,48 +14,3 @@ More than one pvmove can run concurrently if they are moving data from
|
||||
different source PVs, but additional pvmoves will ignore any LVs already
|
||||
in the process of being changed, so some data might not get moved.
|
||||
|
||||
pvmove works as follows:
|
||||
|
||||
1. A temporary 'pvmove' LV is created to store details of all the data
|
||||
movements required.
|
||||
|
||||
2. Every LV in the VG is searched for contiguous data that need moving
|
||||
according to the command line arguments.
|
||||
For each piece of data found, a new segment is added to the end of the
|
||||
pvmove LV.
|
||||
This segment takes the form of a temporary mirror to copy the data
|
||||
from the original location to a newly allocated location.
|
||||
The original LV is updated to use the new temporary mirror segment
|
||||
in the pvmove LV instead of accessing the data directly.
|
||||
|
||||
3. The VG metadata is updated on disk.
|
||||
|
||||
4. The first segment of the pvmove LV is activated and starts to mirror
|
||||
the first part of the data. Only one segment is mirrored at once as this
|
||||
is usually more efficient.
|
||||
|
||||
5. A daemon repeatedly checks progress at the specified time interval.
|
||||
When it detects that the first temporary mirror is in sync, it breaks that
|
||||
mirror so that only the new location for that data gets used and writes a
|
||||
checkpoint into the VG metadata on disk. Then it activates the mirror for
|
||||
the next segment of the pvmove LV.
|
||||
|
||||
6. When there are no more segments left to be mirrored, the temporary LV
|
||||
is removed and the VG metadata is updated so that the LVs reflect the new
|
||||
data locations.
|
||||
|
||||
Note that this new process cannot support the original LVM1
|
||||
type of on-disk metadata. Metadata can be converted using
|
||||
\fBvgconvert\fP(8).
|
||||
|
||||
If the \fB\-\-atomic\fP option is used, a slightly different approach is
|
||||
used for the move. Again, a temporary 'pvmove' LV is created to store the
|
||||
details of all the data movements required. This temporary LV contains
|
||||
all the segments of the various LVs that need to be moved. However, in
|
||||
this case, an identical LV is allocated that contains the same number of
|
||||
segments and a mirror is created to copy the contents from the first
|
||||
temporary LV to the second. After a complete copy is made, the temporary
|
||||
LVs are removed, leaving behind the segments on the destination PV. If an
|
||||
abort is issued during the move, all LVs being moved will remain on the
|
||||
source PV.
|
||||
|
||||
|
||||
@@ -1,3 +1,50 @@
|
||||
.SH NOTES
|
||||
|
||||
pvmove works as follows:
|
||||
|
||||
1. A temporary 'pvmove' LV is created to store details of all the data
|
||||
movements required.
|
||||
|
||||
2. Every LV in the VG is searched for contiguous data that need moving
|
||||
according to the command line arguments.
|
||||
For each piece of data found, a new segment is added to the end of the
|
||||
pvmove LV.
|
||||
This segment takes the form of a temporary mirror to copy the data
|
||||
from the original location to a newly allocated location.
|
||||
The original LV is updated to use the new temporary mirror segment
|
||||
in the pvmove LV instead of accessing the data directly.
|
||||
|
||||
3. The VG metadata is updated on disk.
|
||||
|
||||
4. The first segment of the pvmove LV is activated and starts to mirror
|
||||
the first part of the data. Only one segment is mirrored at once as this
|
||||
is usually more efficient.
|
||||
|
||||
5. A daemon repeatedly checks progress at the specified time interval.
|
||||
When it detects that the first temporary mirror is in sync, it breaks that
|
||||
mirror so that only the new location for that data gets used and writes a
|
||||
checkpoint into the VG metadata on disk. Then it activates the mirror for
|
||||
the next segment of the pvmove LV.
|
||||
|
||||
6. When there are no more segments left to be mirrored, the temporary LV
|
||||
is removed and the VG metadata is updated so that the LVs reflect the new
|
||||
data locations.
|
||||
|
||||
Note that this new process cannot support the original LVM1
|
||||
type of on-disk metadata. Metadata can be converted using
|
||||
\fBvgconvert\fP(8).
|
||||
|
||||
If the \fB\-\-atomic\fP option is used, a slightly different approach is
|
||||
used for the move. Again, a temporary 'pvmove' LV is created to store the
|
||||
details of all the data movements required. This temporary LV contains
|
||||
all the segments of the various LVs that need to be moved. However, in
|
||||
this case, an identical LV is allocated that contains the same number of
|
||||
segments and a mirror is created to copy the contents from the first
|
||||
temporary LV to the second. After a complete copy is made, the temporary
|
||||
LVs are removed, leaving behind the segments on the destination PV. If an
|
||||
abort is issued during the move, all LVs being moved will remain on the
|
||||
source PV.
|
||||
|
||||
.SH EXAMPLES
|
||||
|
||||
Move all physical extents that are used by simple LVs on the specified PV to
|
||||
|
||||
@@ -1,2 +1,7 @@
|
||||
pvremove wipes the label on a device so that LVM will no longer recognise
|
||||
it as a PV.
|
||||
|
||||
A PV cannot be removed from a VG while it is used by an active LV.
|
||||
|
||||
Repeat the force option (\fB-ff\fP) to forcibly remove a PV belonging to
|
||||
an existing VG. Normally, \fBvgreduce\fP(8) should be used instead.
|
||||
|
||||
@@ -6,3 +6,6 @@ A back up file can be specified with \fB\-\-file\fP. If no backup file is
|
||||
specified, the most recent one is used. Use \fB\-\-list\fP for a list of
|
||||
the available back up and archive files of a VG.
|
||||
|
||||
WARNING: When a VG contains thin pools, changes to thin metadata cannot be
|
||||
reverted, and data loss may occur if thin metadata has changed. The force
|
||||
option is required to restore in this case.
|
||||
|
||||
@@ -4,3 +4,6 @@ to confirm LV removal.
|
||||
If one or more PVs in the VG are lost, consider
|
||||
\fBvgreduce \-\-removemissing\fP to make the VG
|
||||
metadata consistent again.
|
||||
|
||||
Repeat the force option (\fB-ff\fP) to forcibly remove LVs in the VG
|
||||
without confirmation.
|
||||
|
||||
@@ -39,7 +39,7 @@ S ?= @ # never match anything by default
|
||||
VERBOSE ?= 0
|
||||
ALL := $(shell find -L $(srcdir) \( -path \*/shell/\*.sh -or -path \*/api/\*.sh \) | sort)
|
||||
comma = ,
|
||||
RUN := $(shell find -L $(srcdir) -regextype posix-egrep \( -path \*/shell/\*.sh -or -path \*/api/\*.sh \) -and -regex "$(srcdir)/.*($(subst $(comma),|,$(T))).*" -and -not -regex "$(srcdir)/.*($(subst $(comma),|,$(S))).*" | sort)
|
||||
RUN := $(shell find -L $(srcdir) -regextype posix-egrep \( -path \*/shell/\*.sh -or -path \*/api/\*.sh \) -and -regex "$(srcdir)/.*($(subst $(comma),|,$(T))).*" -and -not -regex "$(srcdir)/.*($(subst $(comma),|,$(S))).*" | ($SORT))
|
||||
RUN_BASE = $(subst $(srcdir)/,,$(RUN))
|
||||
|
||||
ifeq ("@BUILD_LVMETAD@", "yes")
|
||||
@@ -267,7 +267,7 @@ lib/%: lib/%.o .lib-dir-stamp
|
||||
|
||||
lib/%: $(srcdir)/lib/%.sh .lib-dir-stamp
|
||||
cp $< $@
|
||||
chmod +x $@
|
||||
$(CHMOD) +x $@
|
||||
|
||||
lib/flavour-%: $(srcdir)/lib/flavour-%.sh .lib-dir-stamp
|
||||
cp $< $@
|
||||
|
||||
@@ -405,17 +405,22 @@ teardown_devs_prefixed() {
|
||||
fi
|
||||
|
||||
# Remove devices, start with closed (sorted by open count)
|
||||
local remfail=no
|
||||
# Run 'dmsetup remove' in parallel
|
||||
local need_udev_wait=0
|
||||
rm -f REMOVE_FAILED
|
||||
#local listdevs=( $(dm_info name,open --sort open,name | grep "$prefix.*:0") )
|
||||
#dmsetup remove --deferred ${listdevs[@]%%:0} || touch REMOVE_FAILED
|
||||
|
||||
init_udev_transaction
|
||||
for dm in $(dm_info name --sort open | grep "$prefix"); do
|
||||
dmsetup remove "$dm" &>/dev/null || remfail=yes
|
||||
for dm in $(dm_info name --sort open,name | grep "$prefix"); do
|
||||
dmsetup remove "$dm" &>/dev/null || touch REMOVE_FAILED &
|
||||
need_udev_wait=1
|
||||
done
|
||||
wait
|
||||
finish_udev_transaction
|
||||
test $need_udev_wait -eq 0 || udev_wait
|
||||
|
||||
if test $remfail = yes; then
|
||||
if test -f REMOVE_FAILED; then
|
||||
local num_devs
|
||||
local num_remaining_devs=999
|
||||
while num_devs=$(dm_table | grep "$prefix" | wc -l) && \
|
||||
@@ -794,6 +799,7 @@ prepare_devs() {
|
||||
|
||||
local size=$(($devsize*2048)) # sectors
|
||||
local count=0
|
||||
rm -f CREATE_FAILED
|
||||
init_udev_transaction
|
||||
for i in $(seq 1 $n); do
|
||||
local name="${PREFIX}$pvname$i"
|
||||
@@ -801,16 +807,18 @@ prepare_devs() {
|
||||
DEVICES[$count]=$dev
|
||||
count=$(( $count + 1 ))
|
||||
echo 0 $size linear "$BACKING_DEV" $((($i-1)*$size + $shift)) > "$name.table"
|
||||
if not dmsetup create -u "TEST-$name" "$name" "$name.table" &&
|
||||
test -n "$LVM_TEST_BACKING_DEVICE";
|
||||
then # maybe the backing device is too small for this test
|
||||
dmsetup create -u "TEST-$name" "$name" "$name.table" || touch CREATE_FAILED &
|
||||
test -f CREATE_FAILED && break;
|
||||
done
|
||||
wait
|
||||
finish_udev_transaction
|
||||
|
||||
if test -f CREATE_FAILED -a -n "$LVM_TEST_BACKING_DEVICE"; then
|
||||
LVM_TEST_BACKING_DEVICE=
|
||||
rm -f BACKING_DEV
|
||||
rm -f BACKING_DEV CREATE_FAILED
|
||||
prepare_devs "$@"
|
||||
return $?
|
||||
fi
|
||||
done
|
||||
finish_udev_transaction
|
||||
|
||||
# non-ephemeral devices need to be cleared between tests
|
||||
test -f LOOP || for d in ${DEVICES[@]}; do
|
||||
@@ -833,9 +841,11 @@ prepare_devs() {
|
||||
# ( IFS=$'\n'; echo "${DEVICES[*]}" ) >DEVICES
|
||||
echo "ok"
|
||||
|
||||
if test -e LOCAL_LVMETAD; then
|
||||
for dev in "${DEVICES[@]}"; do
|
||||
notify_lvmetad "$dev"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -856,7 +866,7 @@ common_dev_() {
|
||||
else
|
||||
test -z "${offsets[@]}" && offsets="0:"
|
||||
fi ;;
|
||||
error) offsets=${@:3}
|
||||
error|zero) offsets=${@:3}
|
||||
test -z "${offsets[@]}" && offsets="0:" ;;
|
||||
esac
|
||||
|
||||
@@ -883,8 +893,8 @@ common_dev_() {
|
||||
case "$tgtype" in
|
||||
delay)
|
||||
echo "$from $len delay $pvdev $(($pos + $offset)) $read_ms $pvdev $(($pos + $offset)) $write_ms" ;;
|
||||
error)
|
||||
echo "$from $len error" ;;
|
||||
error|zero)
|
||||
echo "$from $len $tgtype" ;;
|
||||
esac
|
||||
pos=$(($pos + $len))
|
||||
done > "$name.devtable"
|
||||
@@ -1003,12 +1013,23 @@ restore_from_devtable() {
|
||||
#
|
||||
# Convert device to device with errors
|
||||
# Takes the list of pairs of error segment from:len
|
||||
# Original device table is replace with multiple lines
|
||||
# Combination with zero or delay is unsupported
|
||||
# Original device table is replaced with multiple lines
|
||||
# i.e. error_dev "$dev1" 8:32 96:8
|
||||
error_dev() {
|
||||
common_dev_ error "$@"
|
||||
}
|
||||
|
||||
#
|
||||
# Convert existing device to a device with zero segments
|
||||
# Takes the list of pairs of zero segment from:len
|
||||
# Combination with error or delay is unsupported
|
||||
# Original device table is replaced with multiple lines
|
||||
# i.e. zero_dev "$dev1" 8:32 96:8
|
||||
zero_dev() {
|
||||
common_dev_ zero "$@"
|
||||
}
|
||||
|
||||
backup_dev() {
|
||||
local dev
|
||||
|
||||
|
||||
@@ -77,6 +77,11 @@ find "$TESTOLDPWD/lib" ! \( -name '*.sh' -o -name '*.[cdo]' \
|
||||
DM_DEFAULT_NAME_MANGLING_MODE=none
|
||||
DM_DEV_DIR="$TESTDIR/dev"
|
||||
LVM_SYSTEM_DIR="$TESTDIR/etc"
|
||||
# abort on the internal dm errors in the tests (allowing test user override)
|
||||
DM_ABORT_ON_INTERNAL_ERRORS=${DM_ABORT_ON_INTERNAL_ERRORS:-1}
|
||||
|
||||
export DM_DEFAULT_NAME_MANGLING_MODE DM_DEV_DIR LVM_SYSTEM_DIR DM_ABORT_ON_INTERNAL_ERRORS
|
||||
|
||||
mkdir "$LVM_SYSTEM_DIR" "$DM_DEV_DIR"
|
||||
if test -n "$LVM_TEST_DEVDIR" ; then
|
||||
test -d "$LVM_TEST_DEVDIR" || die "Test device directory LVM_TEST_DEVDIR=\"$LVM_TEST_DEVDIR\" is not valid."
|
||||
@@ -85,14 +90,11 @@ else
|
||||
mknod "$DM_DEV_DIR/testnull" c 1 3 || die "mknod failed"
|
||||
echo >"$DM_DEV_DIR/testnull" || \
|
||||
die "Filesystem does support devices in $DM_DEV_DIR (mounted with nodev?)"
|
||||
mkdir "$DM_DEV_DIR/mapper"
|
||||
# dmsetup makes here needed control entry if still missing
|
||||
dmsetup version || \
|
||||
die "Dmsetup in $DM_DEV_DIR can't report version?"
|
||||
fi
|
||||
|
||||
# abort on the internal dm errors in the tests (allowing test user override)
|
||||
DM_ABORT_ON_INTERNAL_ERRORS=${DM_ABORT_ON_INTERNAL_ERRORS:-1}
|
||||
|
||||
export DM_DEFAULT_NAME_MANGLING_MODE DM_DEV_DIR LVM_SYSTEM_DIR DM_ABORT_ON_INTERNAL_ERRORS
|
||||
|
||||
echo "$TESTNAME" >TESTNAME
|
||||
|
||||
echo "Kernel is $(uname -a)"
|
||||
|
||||
41
test/shell/lvchange-raid1-writemostly.sh
Normal file
41
test/shell/lvchange-raid1-writemostly.sh
Normal file
@@ -0,0 +1,41 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2017 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing to use,
|
||||
# modify, copy, or redistribute it subject to the terms and conditions
|
||||
# of the GNU General Public License v.2.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA2110-1301 USA
|
||||
|
||||
SKIP_WITH_LVMLOCKD=1
|
||||
SKIP_WITH_LVMPOLLD=1
|
||||
|
||||
. lib/inittest
|
||||
|
||||
which mkfs.ext4 || skip
|
||||
aux have_raid 1 3 5 || skip
|
||||
|
||||
aux prepare_vg 4
|
||||
|
||||
for d in $dev1 $dev2 $dev3 $dev4
|
||||
do
|
||||
aux delay_dev $d 1
|
||||
done
|
||||
|
||||
#
|
||||
# Test writemostly prohibited on resyncrhonizing raid1
|
||||
#
|
||||
|
||||
# Create 4-way striped LV
|
||||
lvcreate -aey --ty raid1 -m 3 -L 32M -n $lv1 $vg
|
||||
not lvchange -y --writemostly $dev1 $vg/$lv1
|
||||
check lv_field $vg/$lv1 segtype "raid1"
|
||||
check lv_field $vg/$lv1 stripes 4
|
||||
check lv_attr_bit health $vg/${lv1}_rimage_0 "-"
|
||||
aux wait_for_sync $vg $lv1
|
||||
lvchange -y --writemostly $dev1 $vg/$lv1
|
||||
check lv_attr_bit health $vg/${lv1}_rimage_0 "w"
|
||||
|
||||
vgremove -ff $vg
|
||||
@@ -28,7 +28,7 @@ grep "$dev1" out
|
||||
# check for RHBZ 1080189 -- SEGV in lvremove/vgremove
|
||||
pvcreate -ff -y --metadatatype 1 "$dev1" "$dev2"
|
||||
vgcreate --metadatatype 1 $vg1 "$dev1" "$dev2"
|
||||
lvcreate -l1 $vg1
|
||||
lvcreate -l1 $vg1 "$dev1"
|
||||
pvremove -ff -y "$dev2"
|
||||
vgchange -an $vg1
|
||||
not lvremove $vg1
|
||||
|
||||
@@ -34,9 +34,26 @@ lvremove -ff $vg
|
||||
|
||||
lvcreate -L 10M -n lv $vg "$dev1"
|
||||
lvextend -L +10M $vg/lv "$dev2"
|
||||
lvextend --type striped -m0 -L +10M $vg/lv "$dev2"
|
||||
|
||||
# Attempt to reduce with lvextend and vice versa:
|
||||
not lvextend -L 16M $vg/lv
|
||||
not lvreduce -L 32M $vg/lv
|
||||
|
||||
lvremove -ff $vg
|
||||
|
||||
lvcreate --type mirror -aey -L 4 -n $lv1 $vg
|
||||
# Incorrent name for resized LV
|
||||
not lvextend --type mirror -L 10 -n $lv1 $vg
|
||||
# Same size
|
||||
not lvextend --type mirror -L 4 $vg/$lv1
|
||||
# Cannot use any '-' or '+' sign for --mirror arg
|
||||
not lvextend --type mirror -L+2 -m-1 $vg/$lv1
|
||||
not lvextend --type mirror -L+2 -m+1 $vg/$lv1
|
||||
|
||||
lvextend --type mirror -L+4 -m1 $vg/$lv1
|
||||
|
||||
lvs -a $vg
|
||||
check lv_field $vg/$lv1 size "8.00m"
|
||||
|
||||
lvremove -ff $vg
|
||||
|
||||
@@ -33,9 +33,9 @@ test_pvmove_resume() {
|
||||
# next LV on same VG and differetnt PV (we want to test 2 pvmoves per VG)
|
||||
lvcreate -an -Zn -l30 -n $lv2 $vg "$dev3"
|
||||
|
||||
aux delay_dev "$dev4" 0 250
|
||||
aux delay_dev "$dev4" 0 250 $(get first_extent_sector "$dev4"):
|
||||
test -e HAVE_DM_DELAY || { lvremove -f $vg; return 0; }
|
||||
aux delay_dev "$dev5" 0 250
|
||||
aux delay_dev "$dev5" 0 250 $(get first_extent_sector "$dev5"):
|
||||
|
||||
pvmove -i5 "$dev1" "$dev4" &
|
||||
PVMOVE=$!
|
||||
|
||||
@@ -173,14 +173,7 @@ liblvm2cmd.$(LIB_SUFFIX).$(LIB_VERSION): liblvm2cmd.$(LIB_SUFFIX)
|
||||
|
||||
.commands: $(srcdir)/commands.h $(srcdir)/cmdnames.h Makefile
|
||||
$(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
|
||||
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
# move properly to configure
|
||||
WC = /usr/bin/wc
|
||||
GREP = /bin/grep
|
||||
SORT = /bin/sort
|
||||
$(EGREP) -v '^ *(|#.*|config|devtypes|dumpconfig|formats|fullreport|help|lastlog|lvpoll|pvdata|segtypes|systemid|tags|version) *$$' > .commands
|
||||
|
||||
command-count.h: $(srcdir)/command-lines.in Makefile
|
||||
set -o pipefail && \
|
||||
@@ -204,11 +197,12 @@ command-lines-input.h: $(srcdir)/command-lines.in Makefile
|
||||
( cat $(top_srcdir)/doc/license.txt && \
|
||||
echo "/* Do not edit. This file is generated by the Makefile. */" && \
|
||||
echo -en "const char _command_input[] =\n\n\"" && \
|
||||
$(GREP) -Ev '^#|\-\-\-|^$$' $(srcdir)/command-lines.in | $(AWK) 'BEGIN {ORS = "\\n\"\n\""} //' && \
|
||||
$(EGREP) -v '^#|\-\-\-|^$$' $(srcdir)/command-lines.in | $(AWK) 'BEGIN {ORS = "\\n\"\n\""} //' && \
|
||||
echo "\\n\";" \
|
||||
) > $@
|
||||
|
||||
$(SOURCES:%.c=%.d) $(SOURCES2:%.c=%.d): command-lines-input.h command-count.h cmds.h
|
||||
$(SOURCES:%.c=%.o) $(SOURCES2:%.c=%.o): command-lines-input.h command-count.h cmds.h
|
||||
|
||||
ifneq ("$(CFLOW_CMD)", "")
|
||||
CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))
|
||||
|
||||
44
tools/args.h
44
tools/args.h
@@ -244,6 +244,9 @@ arg(locktype_ARG, '\0', "locktype", locktype_VAL, 0, 0,
|
||||
arg(logonly_ARG, '\0', "logonly", 0, 0, 0,
|
||||
"Suppress command report and display only log report.\n")
|
||||
|
||||
arg(longhelp_ARG, '\0', "longhelp", 0, 0, 0,
|
||||
"Display long help text.\n")
|
||||
|
||||
arg(maxrecoveryrate_ARG, '\0', "maxrecoveryrate", sizekb_VAL, 0, 0,
|
||||
"Sets the maximum recovery rate for a RAID LV. The rate value\n"
|
||||
"is an amount of data per second for each device in the array.\n"
|
||||
@@ -543,7 +546,7 @@ arg(shared_ARG, '\0', "shared", 0, 0, 0,
|
||||
arg(sinceversion_ARG, '\0', "sinceversion", string_VAL, 0, 0,
|
||||
"Specify an LVM version in x.y.z format where x is the major version,\n"
|
||||
"the y is the minor version and z is the patchlevel (e.g. 2.2.106).\n"
|
||||
"This option is currently applicable only with --type new\n"
|
||||
"This option is currently applicable only with --typeconfig new\n"
|
||||
"to display all configuration settings introduced since given version.\n")
|
||||
|
||||
arg(splitcache_ARG, '\0', "splitcache", 0, 0, 0,
|
||||
@@ -586,9 +589,12 @@ arg(stripes_long_ARG, '\0', "stripes", number_VAL, 0, 0,
|
||||
"existing allocated space, only newly allocated space can be striped.\n")
|
||||
|
||||
arg(swapmetadata_ARG, '\0', "swapmetadata", 0, 0, 0,
|
||||
"Remove the metadata LV in a pool and replace it with another specified LV.\n"
|
||||
"The removed LV is preserved and given the name of the LV that replaced it.\n"
|
||||
"Used for repair only.\n")
|
||||
"Extracts the metadata LV from a pool and replaces it with another specified LV.\n"
|
||||
"The extracted LV is preserved and given the name of the LV that replaced it.\n"
|
||||
"Use for repair only. When the metadata LV is swapped out of the pool, it can\n"
|
||||
"be activated directly and used with thin provisioning tools:\n"
|
||||
"\\fBcache_dump\\fP(8), \\fBcache_repair\\fP(8), \\fBcache_restore\\fP(8),\n"
|
||||
"\\fBthin_dump\\fP(8), \\fBthin_repair\\fP(8), \\fBthin_restore\\fP(8).\n")
|
||||
|
||||
arg(syncaction_ARG, '\0', "syncaction", syncaction_VAL, 0, 0,
|
||||
"Initiate different types of RAID synchronization.\n"
|
||||
@@ -640,7 +646,16 @@ arg(trustcache_ARG, '\0', "trustcache", 0, 0, 0,
|
||||
"Avoids certain device scanning during command processing. Do not use.\n")
|
||||
|
||||
arg(type_ARG, '\0', "type", segtype_VAL, 0, 0,
|
||||
"Specifies an LV type, or \"segment type\".\n")
|
||||
"Specifies an LV type, or \"segment type\".\n"
|
||||
"See usage definitions for specific ways to use these types.\n"
|
||||
"For more information about redundancy and performance (\\fBraid\\fP<N>, \\fBmirror\\fP, \\fBstriped\\fP, \\fBlinear\\fP) see \\fBlvmraid\\fP(7).\n"
|
||||
"For thin provisioning (\\fBthin\\fP, \\fBthin-pool\\fP) see \\fBlvmthin\\fP(7).\n"
|
||||
"For performance caching (\\fBcache\\fP, \\fBcache-pool\\fP) see \\fBlvmcache\\fP(7).\n"
|
||||
"For copy-on-write snapshots (\\fBsnapshot\\fP) see usage definitions.\n"
|
||||
"Several commands omit an explicit type option because the type\n"
|
||||
"is inferred from other options or shortcuts\n"
|
||||
"(e.g. --stripes, --mirrors, --snapshot, --virtualsize, --thin, --cache).\n"
|
||||
"Use inferred types with care because it can lead to unexpected results.\n")
|
||||
|
||||
arg(unbuffered_ARG, '\0', "unbuffered", 0, 0, 0,
|
||||
"Produce output immediately without sorting or aligning the columns properly.\n")
|
||||
@@ -666,10 +681,12 @@ arg(unconfigured_ARG, '\0', "unconfigured", 0, 0, 0,
|
||||
"Internal option used for generating config file during build.\n")
|
||||
|
||||
arg(units_ARG, '\0', "units", units_VAL, 0, 0,
|
||||
"All sizes are output in these units: (h)uman-readable, (b)ytes, (s)ectors,\n"
|
||||
"(k)ilobytes, (m)egabytes, (g)igabytes, (t)erabytes, (p)etabytes, (e)xabytes.\n"
|
||||
"Capitalise to use multiples of 1000 (S.I.) instead of 1024. Can also specify\n"
|
||||
"custom units e.g. --units 3M.\n")
|
||||
"All sizes are output in these units:\n"
|
||||
"human-(r)eadable with '<' rounding indicator,\n"
|
||||
"(h)uman-readable, (b)ytes, (s)ectors, (k)ilobytes, (m)egabytes,\n"
|
||||
"(g)igabytes, (t)erabytes, (p)etabytes, (e)xabytes.\n"
|
||||
"Capitalise to use multiples of 1000 (S.I.) instead of 1024.\n"
|
||||
"Custom units can be specified, e.g. --units 3M.\n")
|
||||
|
||||
arg(unquoted_ARG, '\0', "unquoted", 0, 0, 0,
|
||||
"When used with --nameprefixes, output values in the field=value\n"
|
||||
@@ -920,8 +937,8 @@ arg(force_ARG, 'f', "force", 0, ARG_COUNTABLE, 0,
|
||||
/* Not used. */
|
||||
arg(full_ARG, 'f', "full", 0, 0, 0, NULL)
|
||||
|
||||
arg(help_ARG, 'h', "help", 0, ARG_COUNTABLE, 0,
|
||||
"Display help text. Repeat this option for more information.\n")
|
||||
arg(help_ARG, 'h', "help", 0, 0, 0,
|
||||
"Display help text.\n")
|
||||
|
||||
arg(cache_ARG, 'H', "cache", 0, 0, 0,
|
||||
"Specifies the command is handling a cache LV or cache pool.\n"
|
||||
@@ -1015,7 +1032,7 @@ arg(list_ARG, 'l', "list", 0, 0, 0,
|
||||
"#dumpconfig\n"
|
||||
"#config\n"
|
||||
"List config settings with summarizing comment. This is the same as using\n"
|
||||
"options --type list --withsummary.\n"
|
||||
"options --typeconfig list --withsummary.\n"
|
||||
"#vgcfgrestore\n"
|
||||
"List metadata backup and archive files pertaining to the VG.\n"
|
||||
"May be used with --file. Does not restore the VG.\n"
|
||||
@@ -1363,7 +1380,8 @@ arg(resizeable_ARG, 'x', "resizeable", bool_VAL, 0, 0,
|
||||
|
||||
arg(yes_ARG, 'y', "yes", 0, 0, 0,
|
||||
"Do not prompt for confirmation interactively but always assume the\n"
|
||||
"answer yes. Use with extreme caution.\n")
|
||||
"answer yes. Use with extreme caution.\n"
|
||||
"(For automatic no, see -qq.)\n")
|
||||
|
||||
arg(zero_ARG, 'Z', "zero", bool_VAL, 0, 0,
|
||||
"#lvchange\n"
|
||||
|
||||
@@ -187,23 +187,9 @@
|
||||
# OO_ALL is included in every command automatically.
|
||||
#
|
||||
OO_ALL: --commandprofile String, --config String, --debug,
|
||||
--driverloaded Bool, --help, --profile String, --quiet,
|
||||
--driverloaded Bool, --help, --longhelp, --profile String, --quiet,
|
||||
--verbose, --version, --yes, --test
|
||||
|
||||
#
|
||||
# This list only applies to printing the usage text.
|
||||
# These common options are displayed once at the end of
|
||||
# a given command's usage. This is done to avoid excessive
|
||||
# repetition of common options, which may obscure the more
|
||||
# interesting and relevant parts of a common prototype.
|
||||
# This definition is *only* used when generating the command
|
||||
# usage strings, and is the basis for the division between
|
||||
# the "usage" and "usage_common" strings. This OO defn does
|
||||
# not relate to which optional opts are accepted by commands,
|
||||
# which is defined by the OO line.
|
||||
#
|
||||
OO_USAGE_COMMON: OO_ALL, --force, --noudevsync
|
||||
|
||||
#
|
||||
# options for pvs, lvs, vgs, fullreport
|
||||
#
|
||||
@@ -250,7 +236,9 @@ OO_LVCHANGE_META: --addtag Tag, --deltag Tag,
|
||||
lvchange OO_LVCHANGE_META VG|LV|Tag|Select ...
|
||||
OO: --activate Active, OO_LVCHANGE
|
||||
ID: lvchange_properties
|
||||
DESC: Change a general LV property.
|
||||
DESC: Change a general LV attribute.
|
||||
DESC: For options listed in parentheses, any one is
|
||||
DESC: required, after which the others are optional.
|
||||
RULE: all not lv_is_pvmove lv_is_mirror_log lv_is_mirror_image
|
||||
RULE: all and lv_is_vg_writable
|
||||
RULE: --contiguous not --alloc
|
||||
@@ -454,17 +442,36 @@ DESC: Convert LV to type thin-pool.
|
||||
RULE: all and lv_is_visible
|
||||
RULE: all not lv_is_locked lv_is_origin lv_is_merging_origin lv_is_external_origin lv_is_virtual
|
||||
|
||||
# alternate form of lvconvert --type thin-pool
|
||||
# deprecated because of non-standard syntax (missing positional arg)
|
||||
# Commands in this form are converted to standard form so that
|
||||
# the validation of LV types and rules specified above will apply.
|
||||
lvconvert --thinpool LV_linear_striped_raid_cache
|
||||
# This command syntax has two different meanings depending on
|
||||
# whether the LV pos arg is already a thin pool or not.
|
||||
#
|
||||
# 1. When the LV arg is not a pool, this command converts
|
||||
# the LV into a pool, optionally using a specified meta LV.
|
||||
# This is an alternate form of the primary command:
|
||||
# lvconvert --type thin-pool LV
|
||||
#
|
||||
# 2. When the LV is is already a pool and a meta LV is specified,
|
||||
# the meta LV is swapped. Swapping a meta LV is a very specialized
|
||||
# operation that users should never use.
|
||||
# This is an alternate form of the primary command:
|
||||
# lvconvert --swapmetadata --poolmetadata LV LV
|
||||
#
|
||||
# The command def cannot include --poolmetadata as a required
|
||||
# option, otherwise 1 would not pass, so the validation of
|
||||
# this option cannot be done by the command defs, but has to
|
||||
# be done ad hoc in the lvconvert implementation.
|
||||
#
|
||||
# This command syntax is deprecated, and the primary forms
|
||||
# of creating a pool or swapping metadata should be used.
|
||||
|
||||
lvconvert --thinpool LV_linear_striped_raid_cache_thinpool
|
||||
OO: --type thin-pool, --stripes_long Number, --stripesize SizeKB,
|
||||
--discards Discards, --zero Bool, OO_LVCONVERT_POOL, OO_LVCONVERT
|
||||
OP: PV ...
|
||||
ID: lvconvert_to_thinpool_noarg
|
||||
ID: lvconvert_to_thinpool_or_swap_metadata
|
||||
DESC: Convert LV to type thin-pool (variant, use --type thin-pool).
|
||||
FLAGS: SECONDARY_SYNTAX
|
||||
DESC: Swap metadata LV in a thin pool (variant, use --swapmetadata).
|
||||
FLAGS: PREVIOUS_SYNTAX
|
||||
|
||||
---
|
||||
|
||||
@@ -475,17 +482,36 @@ OP: PV ...
|
||||
ID: lvconvert_to_cachepool
|
||||
DESC: Convert LV to type cache-pool.
|
||||
|
||||
# alternate form of lvconvert --type cache-pool
|
||||
# deprecated because of non-standard syntax (missing positional arg)
|
||||
# Commands in this form are converted to standard form so that
|
||||
# the validation of LV types and rules specified above will apply.
|
||||
lvconvert --cachepool LV_linear_striped_raid
|
||||
# This command syntax has two different meanings depending on
|
||||
# whether the LV pos arg is already a cache pool or not.
|
||||
#
|
||||
# 1. When the LV arg is not a pool, this command converts
|
||||
# the LV into a pool, optionally using a specified meta LV.
|
||||
# This is an alternate form of the primary command:
|
||||
# lvconvert --type cache-pool LV
|
||||
#
|
||||
# 2. When the LV is is already a pool and a meta LV is specified,
|
||||
# the meta LV is swapped. Swapping a meta LV is a very specialized
|
||||
# operation that users should never use.
|
||||
# This is an alternate form of the primary command:
|
||||
# lvconvert --swapmetadata --poolmetadata LV LV
|
||||
#
|
||||
# The command def cannot include --poolmetadata as a required
|
||||
# option, otherwise 1 would not pass, so the validation of
|
||||
# this option cannot be done by the command defs, but has to
|
||||
# be done ad hoc in the lvconvert implementation.
|
||||
#
|
||||
# This command syntax is deprecated, and the primary forms
|
||||
# of creating a pool or swapping metadata should be used.
|
||||
|
||||
lvconvert --cachepool LV_linear_striped_raid_cachepool
|
||||
OO: --type cache-pool, OO_LVCONVERT_POOL, OO_LVCONVERT,
|
||||
--cachemode CacheMode, --cachepolicy String, --cachesettings String
|
||||
OP: PV ...
|
||||
ID: lvconvert_to_cachepool_noarg
|
||||
ID: lvconvert_to_cachepool_or_swap_metadata
|
||||
DESC: Convert LV to type cache-pool (variant, use --type cache-pool).
|
||||
FLAGS: SECONDARY_SYNTAX
|
||||
DESC: Swap metadata LV in a cache pool (variant, use --swapmetadata).
|
||||
FLAGS: PREVIOUS_SYNTAX
|
||||
|
||||
---
|
||||
|
||||
@@ -1088,12 +1114,17 @@ ID: lvdisplay_general
|
||||
|
||||
---
|
||||
|
||||
# --type is an option in lvextend/lvresize only so that the specified type
|
||||
# value can be checked to match the existing type; using it doesn't
|
||||
# currently enable any different behavior.
|
||||
|
||||
# --extents is not specified; it's an automatic alternative for --size
|
||||
|
||||
lvextend --size SizeMB LV
|
||||
OO: --alloc Alloc, --autobackup Bool, --force, --mirrors SNumber,
|
||||
--nofsck, --nosync, --noudevsync, --reportformat ReportFmt, --resizefs,
|
||||
--stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB
|
||||
--stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB,
|
||||
--type SegType
|
||||
OP: PV ...
|
||||
ID: lvextend_by_size
|
||||
DESC: Extend an LV by a specified size.
|
||||
@@ -1101,7 +1132,8 @@ DESC: Extend an LV by a specified size.
|
||||
lvextend LV PV ...
|
||||
OO: --alloc Alloc, --autobackup Bool, --force, --mirrors SNumber,
|
||||
--nofsck, --nosync, --noudevsync,
|
||||
--reportformat ReportFmt, --resizefs, --stripes Number, --stripesize SizeKB
|
||||
--reportformat ReportFmt, --resizefs, --stripes Number, --stripesize SizeKB,
|
||||
--type SegType
|
||||
ID: lvextend_by_pv
|
||||
DESC: Extend an LV by specified PV extents.
|
||||
FLAGS: SECONDARY_SYNTAX
|
||||
@@ -1109,7 +1141,8 @@ FLAGS: SECONDARY_SYNTAX
|
||||
lvextend --poolmetadatasize SizeMB LV_thinpool
|
||||
OO: --alloc Alloc, --autobackup Bool, --force, --mirrors SNumber,
|
||||
--nofsck, --nosync, --noudevsync,
|
||||
--reportformat ReportFmt, --stripes Number, --stripesize SizeKB
|
||||
--reportformat ReportFmt, --stripes Number, --stripesize SizeKB,
|
||||
--type SegType
|
||||
OP: PV ...
|
||||
ID: lvextend_pool_metadata_by_size
|
||||
DESC: Extend a pool metadata SubLV by a specified size.
|
||||
@@ -1117,7 +1150,8 @@ DESC: Extend a pool metadata SubLV by a specified size.
|
||||
lvextend --usepolicies LV_thinpool_snapshot
|
||||
OO: --alloc Alloc, --autobackup Bool, --force, --mirrors SNumber,
|
||||
--nofsck, --nosync, --noudevsync,
|
||||
--reportformat ReportFmt, --resizefs
|
||||
--reportformat ReportFmt, --resizefs,
|
||||
--type SegType
|
||||
OP: PV ...
|
||||
ID: lvextend_by_policy
|
||||
DESC: Extend an LV according to a predefined policy.
|
||||
@@ -1155,10 +1189,15 @@ ID: lvrename_lv_lv
|
||||
|
||||
---
|
||||
|
||||
# --type is an option in lvextend/lvresize only so that the specified type
|
||||
# value can be checked to match the existing type; using it doesn't
|
||||
# currently enable any different behavior.
|
||||
|
||||
lvresize --size SizeMB LV
|
||||
OO: --alloc Alloc, --autobackup Bool, --force,
|
||||
--nofsck, --nosync, --noudevsync, --reportformat ReportFmt, --resizefs,
|
||||
--stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB
|
||||
--stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB,
|
||||
--type SegType
|
||||
OP: PV ...
|
||||
ID: lvresize_by_size
|
||||
DESC: Resize an LV by a specified size.
|
||||
@@ -1166,7 +1205,8 @@ DESC: Resize an LV by a specified size.
|
||||
lvresize LV PV ...
|
||||
OO: --alloc Alloc, --autobackup Bool, --force,
|
||||
--nofsck, --nosync, --noudevsync,
|
||||
--reportformat ReportFmt, --resizefs, --stripes Number, --stripesize SizeKB
|
||||
--reportformat ReportFmt, --resizefs, --stripes Number, --stripesize SizeKB,
|
||||
--type SegType
|
||||
ID: lvresize_by_pv
|
||||
DESC: Resize an LV by specified PV extents.
|
||||
FLAGS: SECONDARY_SYNTAX
|
||||
@@ -1174,7 +1214,8 @@ FLAGS: SECONDARY_SYNTAX
|
||||
lvresize --poolmetadatasize SizeMB LV_thinpool
|
||||
OO: --alloc Alloc, --autobackup Bool, --force,
|
||||
--nofsck, --nosync, --noudevsync,
|
||||
--reportformat ReportFmt, --stripes Number, --stripesize SizeKB
|
||||
--reportformat ReportFmt, --stripes Number, --stripesize SizeKB,
|
||||
--type SegType
|
||||
OP: PV ...
|
||||
ID: lvresize_pool_metadata_by_size
|
||||
DESC: Resize a pool metadata SubLV by a specified size.
|
||||
@@ -1355,7 +1396,9 @@ vgchange OO_VGCHANGE_META
|
||||
OO: OO_VGCHANGE
|
||||
OP: VG|Tag|Select ...
|
||||
ID: vgchange_properties
|
||||
DESC: Change a general VG property.
|
||||
DESC: Change a general VG attribute.
|
||||
DESC: For options listed in parentheses, any one is
|
||||
DESC: required, after which the others are optional.
|
||||
|
||||
vgchange --monitor Bool
|
||||
OO: --sysinit, --ignorelockingfailure, --poll Bool, OO_VGCHANGE
|
||||
|
||||
895
tools/command.c
895
tools/command.c
File diff suppressed because it is too large
Load Diff
@@ -69,7 +69,7 @@ struct command_name {
|
||||
|
||||
static inline int val_bit_is_set(uint64_t val_bits, int val_enum)
|
||||
{
|
||||
return (val_bits & (1 << val_enum)) ? 1 : 0;
|
||||
return (val_bits & (1ULL << val_enum)) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline uint64_t val_enum_to_bit(int val_enum)
|
||||
@@ -79,7 +79,7 @@ static inline uint64_t val_enum_to_bit(int val_enum)
|
||||
|
||||
static inline int lvp_bit_is_set(uint64_t lvp_bits, int lvp_enum)
|
||||
{
|
||||
return (lvp_bits & (1 << lvp_enum)) ? 1 : 0;
|
||||
return (lvp_bits & (1ULL << lvp_enum)) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline uint64_t lvp_enum_to_bit(int lvp_enum)
|
||||
@@ -89,7 +89,7 @@ static inline uint64_t lvp_enum_to_bit(int lvp_enum)
|
||||
|
||||
static inline int lvt_bit_is_set(uint64_t lvt_bits, int lvt_enum)
|
||||
{
|
||||
return (lvt_bits & (1 << lvt_enum)) ? 1 : 0;
|
||||
return (lvt_bits & (1ULL << lvt_enum)) ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline uint64_t lvt_enum_to_bit(int lvt_enum)
|
||||
@@ -166,6 +166,8 @@ struct cmd_rule {
|
||||
*/
|
||||
#define CMD_FLAG_ONE_REQUIRED_OPT 1 /* lvchange/vgchage require one item from required_opt_args */
|
||||
#define CMD_FLAG_SECONDARY_SYNTAX 2 /* allows syntax variants to be suppressed in certain output */
|
||||
#define CMD_FLAG_PREVIOUS_SYNTAX 4 /* allows syntax variants to not be advertised in output */
|
||||
#define CMD_FLAG_PARSE_ERROR 8 /* error parsing command-lines.in def */
|
||||
|
||||
/* a register of the lvm commands */
|
||||
struct command {
|
||||
@@ -175,7 +177,7 @@ struct command {
|
||||
int command_enum; /* <command_id>_CMD */
|
||||
int command_index; /* position in commands[] */
|
||||
|
||||
struct command_function *functions; /* new style */
|
||||
const struct command_function *functions; /* new style */
|
||||
command_fn fn; /* old style */
|
||||
|
||||
unsigned int cmd_flags; /* CMD_FLAG_ */
|
||||
@@ -209,9 +211,11 @@ struct command {
|
||||
int pos_count; /* temp counter used by create-command */
|
||||
};
|
||||
|
||||
int define_commands(void);
|
||||
int define_commands(char *run_name);
|
||||
int command_id_to_enum(const char *str);
|
||||
void print_usage(struct command *cmd);
|
||||
void print_usage_common(struct command_name *cname, struct command *cmd);
|
||||
void print_usage(struct command *cmd, int longhelp);
|
||||
void print_usage_common_cmd(struct command_name *cname, struct command *cmd);
|
||||
void print_usage_common_lvm(struct command_name *cname, struct command *cmd);
|
||||
void factor_common_options(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5726,32 +5726,32 @@ static int _stats_help(CMD_ARGS);
|
||||
* dmsetup stats <cmd> [options] [device_name]
|
||||
* dmstats <cmd> [options] [device_name]
|
||||
*
|
||||
* clear [--allregions|--regionid id] [--alldevices|<device...>]
|
||||
* clear [--allregions|--regionid id] [--alldevices|<device>...]
|
||||
* create [--start <start> [--length <len>]
|
||||
* [--areas <nr_areas>] [--areasize <size>]
|
||||
* [--programid <id>] [--userdata <data> ]
|
||||
* [--bounds histogram_boundaries] [--precise]
|
||||
* [--alldevices|<device...>]
|
||||
* [--alldevices|<device>...]
|
||||
* create --filemap [--nogroup]
|
||||
* [--programid <id>] [--userdata <data> ]
|
||||
* [--bounds histogram_boundaries] [--precise] [<file_path>]
|
||||
* delete [--allprograms|--programid id]
|
||||
* [--allregions|--regionid id]
|
||||
* [--alldevices|<device...>]
|
||||
* [--alldevices|<device>...]
|
||||
* group [--alias NAME] --regions <regions>
|
||||
* [--allprograms|--programid id] [--alldevices|<device...>]
|
||||
* [--allprograms|--programid id] [--alldevices|<device>...]
|
||||
* list [--allprograms|--programid id] [--allregions|--regionid id]
|
||||
* print [--clear] [--allprograms|--programid id]
|
||||
* [--allregions|--regionid id]
|
||||
* [--alldevices|<device...>]
|
||||
* [--alldevices|<device>...]
|
||||
* report [--interval <seconds>] [--count <cnt>]
|
||||
* [--units <u>] [--programid <id>] [--regionid <id>]
|
||||
* [-o <fields>] [-O|--sort <sort_fields>]
|
||||
* [-S|--select <selection>] [--nameprefixes]
|
||||
* [--noheadings] [--separator <separator>]
|
||||
* [--allprograms|--programid id] [<device...>]
|
||||
* [--allprograms|--programid id] [<device>...]
|
||||
* ungroup --groupid <id> [--allprograms|--programid id]
|
||||
* [--alldevices|<device...>]
|
||||
* [--alldevices|<device>...]
|
||||
*/
|
||||
|
||||
#define INDENT "\n\t "
|
||||
@@ -5766,7 +5766,7 @@ static int _stats_help(CMD_ARGS);
|
||||
#define EXTRA_OPTS HIST_OPTS PRECISE_OPTS
|
||||
#define ALL_PROGS_OPT "[--allprograms|--programid id] "
|
||||
#define ALL_REGIONS_OPT "[--allregions|--regionid id] "
|
||||
#define ALL_DEVICES_OPT "[--alldevices|<device...>] "
|
||||
#define ALL_DEVICES_OPT "[--alldevices|<device>...] "
|
||||
#define ALL_PROGS_REGIONS_DEVICES ALL_PROGS_OPT INDENT ALL_REGIONS_OPT INDENT ALL_DEVICES_OPT
|
||||
#define FIELD_OPTS "[-o <fields>] [-O|--sort <sort_fields>]"
|
||||
#define DM_REPORT_OPTS FIELD_OPTS INDENT "[-S|--select <selection>] [--nameprefixes]" INDENT \
|
||||
@@ -5795,7 +5795,7 @@ static struct command _stats_subcommands[] = {
|
||||
{"group", GROUP_OPTS, 1, -1, 1, 0, _stats_group},
|
||||
{"list", ALL_PROGS_OPT ALL_REGIONS_OPT, 0, -1, 1, 0, _stats_report},
|
||||
{"print", PRINT_OPTS, 0, -1, 1, 0, _stats_print},
|
||||
{"report", REPORT_OPTS "[<device...>]", 0, -1, 1, 0, _stats_report},
|
||||
{"report", REPORT_OPTS "[<device>...]", 0, -1, 1, 0, _stats_report},
|
||||
{"ungroup", "--groupid <id> " UNGROUP_OPTS, 1, -1, 1, 0, _stats_ungroup},
|
||||
{"update_filemap", "--groupid <id> <file_path>", 1, 1, 0, 0, _stats_update_file},
|
||||
{"version", "", 0, -1, 1, 0, _version},
|
||||
@@ -5832,27 +5832,27 @@ static struct command _dmsetup_commands[] = {
|
||||
"\t [-u|uuid <uuid>] [--addnodeonresume|--addnodeoncreate]\n"
|
||||
"\t [--readahead {[+]<sectors>|auto|none}]\n"
|
||||
"\t [-n|--notable|--table {<table>|<table_file>}]", 1, 2, 0, 0, _create},
|
||||
{"remove", "[--deferred] [-f|--force] [--retry] <device>", 0, -1, 1, 0, _remove},
|
||||
{"remove", "[--deferred] [-f|--force] [--retry] <device>...", 0, -1, 1, 0, _remove},
|
||||
{"remove_all", "[-f|--force]", 0, 0, 0, 0, _remove_all},
|
||||
{"suspend", "[--noflush] [--nolockfs] <device>", 0, -1, 1, 0, _suspend},
|
||||
{"resume", "[--noflush] [--nolockfs] <device>\n"
|
||||
{"suspend", "[--noflush] [--nolockfs] <device>...", 0, -1, 1, 0, _suspend},
|
||||
{"resume", "[--noflush] [--nolockfs] <device>...\n"
|
||||
"\t [--addnodeonresume|--addnodeoncreate]\n"
|
||||
"\t [--readahead {[+]<sectors>|auto|none}]", 0, -1, 1, 0, _resume},
|
||||
{"load", "<device> [<table>|<table_file>]", 0, 2, 0, 0, _load},
|
||||
{"clear", "<device>", 0, -1, 1, 0, _clear},
|
||||
{"reload", "<device> [<table>|<table_file>]", 0, 2, 0, 0, _load},
|
||||
{"wipe_table", "[-f|--force] [--noflush] [--nolockfs] <device>", 1, -1, 1, 0, _error_device},
|
||||
{"wipe_table", "[-f|--force] [--noflush] [--nolockfs] <device>...", 1, -1, 1, 0, _error_device},
|
||||
{"rename", "<device> [--setuuid] <new_name_or_uuid>", 1, 2, 0, 0, _rename},
|
||||
{"message", "<device> <sector> <message>", 2, -1, 0, 0, _message},
|
||||
{"ls", "[--target <target_type>] [--exec <command>] [-o <options>] [--tree]", 0, 0, 0, 0, _ls},
|
||||
{"info", "[<device>]", 0, -1, 1, 0, _info},
|
||||
{"deps", "[-o <options>] [<device>]", 0, -1, 1, 0, _deps},
|
||||
{"stats", "<command> [<options>] [<devices>]", 1, -1, 1, 1, _stats},
|
||||
{"status", "[<device>] [--noflush] [--target <target_type>]", 0, -1, 1, 0, _status},
|
||||
{"table", "[<device>] [--target <target_type>] [--showkeys]", 0, -1, 1, 0, _status},
|
||||
{"info", "[<device>...]", 0, -1, 1, 0, _info},
|
||||
{"deps", "[-o <options>] [<device>...]", 0, -1, 1, 0, _deps},
|
||||
{"stats", "<command> [<options>] [<device>...]", 1, -1, 1, 1, _stats},
|
||||
{"status", "[<device>...] [--noflush] [--target <target_type>]", 0, -1, 1, 0, _status},
|
||||
{"table", "[<device>...] [--target <target_type>] [--showkeys]", 0, -1, 1, 0, _status},
|
||||
{"wait", "<device> [<event_nr>] [--noflush]", 0, 2, 0, 0, _wait},
|
||||
{"mknodes", "[<device>]", 0, -1, 1, 0, _mknodes},
|
||||
{"mangle", "[<device>]", 0, -1, 1, 0, _mangle},
|
||||
{"mknodes", "[<device>...]", 0, -1, 1, 0, _mknodes},
|
||||
{"mangle", "[<device>...]", 0, -1, 1, 0, _mangle},
|
||||
{"udevcreatecookie", "", 0, 0, 0, 0, _udevcreatecookie},
|
||||
{"udevreleasecookie", "[<cookie>]", 0, 1, 0, 0, _udevreleasecookie},
|
||||
{"udevflags", "<cookie>", 1, 1, 0, 0, _udevflags},
|
||||
@@ -5894,8 +5894,7 @@ static void _stats_usage(FILE *out)
|
||||
for (i = 0; _stats_subcommands[i].name; i++)
|
||||
fprintf(out, "\t%s %s\n", _stats_subcommands[i].name, _stats_subcommands[i].help);
|
||||
|
||||
fprintf(out, "\n<device> may be device name or -u <uuid> or "
|
||||
"-j <major> -m <minor>\n");
|
||||
fprintf(out, "\n<device> may be device name or (if only one) -u <uuid> or -j <major> -m <minor>\n");
|
||||
fprintf(out, "<fields> are comma-separated. Use 'help -c' for list.\n");
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
@@ -5920,7 +5919,7 @@ static void _dmsetup_usage(FILE *out)
|
||||
for (i = 0; _dmsetup_commands[i].name; i++)
|
||||
fprintf(out, "\t%s %s\n", _dmsetup_commands[i].name, _dmsetup_commands[i].help);
|
||||
|
||||
fprintf(out, "\n<device> may be device name or -u <uuid> or "
|
||||
fprintf(out, "\n<device> may be device name or (if only one) -u <uuid> or "
|
||||
"-j <major> -m <minor>\n");
|
||||
fprintf(out, "<mangling_mode> is one of 'none', 'auto' and 'hex'.\n");
|
||||
fprintf(out, "<fields> are comma-separated. Use 'help -c' for list.\n");
|
||||
|
||||
@@ -739,6 +739,21 @@ static int _lvchange_writemostly(struct logical_volume *lv)
|
||||
struct cmd_context *cmd = lv->vg->cmd;
|
||||
struct lv_segment *raid_seg = first_seg(lv);
|
||||
|
||||
/*
|
||||
* Prohibit writebehind and writebehind during synchronization.
|
||||
*
|
||||
* FIXME: we can do better once we can distingush between
|
||||
* an initial sync after a linear -> raid1 upconversion
|
||||
* and any later additions of legs, requested resyncs
|
||||
* via lvchange or leg repairs/replacements.
|
||||
*/
|
||||
if (!lv_raid_in_sync(lv)) {
|
||||
log_error("Unable to change write%s on %s while it is not in-sync.",
|
||||
arg_is_set(cmd, writemostly_ARG) ? "mostly" : "behind",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (arg_is_set(cmd, writebehind_ARG))
|
||||
raid_seg->writebehind = arg_uint_value(cmd, writebehind_ARG, 0);
|
||||
|
||||
|
||||
@@ -3649,6 +3649,43 @@ static int _lvconvert_combine_split_snapshot_single(struct cmd_context *cmd,
|
||||
|
||||
int lvconvert_combine_split_snapshot_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||
{
|
||||
const char *vgname = NULL;
|
||||
const char *lvname1;
|
||||
const char *lvname2;
|
||||
char *vglv;
|
||||
int vglv_sz;
|
||||
|
||||
/*
|
||||
* Hack to accomodate an old parsing quirk that allowed the
|
||||
* the VG name to be attached to only the LV in arg pos 1,
|
||||
* i.e. lvconvert -s vgname/lvname lvname
|
||||
*
|
||||
* The LV name in arg pos 2 is the one that is processed
|
||||
* by process_each_lv(). If that LV has no VG name, but
|
||||
* the first LV does, then copy the VG name from arg pos 1
|
||||
* and add it to the LV name in arg pos 2 so that the
|
||||
* standard arg parsing in process_each_lv will find it.
|
||||
*
|
||||
* This is the only instance in all commands.
|
||||
*/
|
||||
|
||||
lvname1 = cmd->position_argv[0];
|
||||
lvname2 = cmd->position_argv[1];
|
||||
|
||||
if (strstr("/", lvname1) && !strstr("/", lvname2) && !getenv("LVM_VG_NAME")) {
|
||||
if (!validate_lvname_param(cmd, &vgname, &lvname1))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
vglv_sz = strlen(vgname) + strlen(lvname2) + 2;
|
||||
if (!(vglv = dm_pool_alloc(cmd->mem, vglv_sz)) ||
|
||||
dm_snprintf(vglv, vglv_sz, "%s/%s", vgname, lvname2) < 0) {
|
||||
log_error("vg/lv string alloc failed.");
|
||||
return_ECMD_FAILED;
|
||||
}
|
||||
|
||||
cmd->position_argv[1] = vglv;
|
||||
}
|
||||
|
||||
return process_each_lv(cmd, 1, cmd->position_argv + 1, NULL, NULL, READ_FOR_UPDATE,
|
||||
NULL, NULL, &_lvconvert_combine_split_snapshot_single);
|
||||
}
|
||||
@@ -3753,51 +3790,6 @@ int lvconvert_to_pool_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||
NULL, NULL, &_lvconvert_to_pool_single);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reformats non-standard command form into standard command form.
|
||||
*
|
||||
* In the command variants with no position LV arg, the LV arg is taken from
|
||||
* the --thinpool/--cachepool arg, and the position args are modified to match
|
||||
* the standard command form.
|
||||
*/
|
||||
|
||||
int lvconvert_to_pool_noarg_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||
{
|
||||
struct command *new_command;
|
||||
char *pool_data_name;
|
||||
int i, p;
|
||||
|
||||
switch (cmd->command->command_enum) {
|
||||
case lvconvert_to_thinpool_noarg_CMD:
|
||||
pool_data_name = (char *)arg_str_value(cmd, thinpool_ARG, NULL);
|
||||
new_command = get_command(lvconvert_to_thinpool_CMD);
|
||||
break;
|
||||
case lvconvert_to_cachepool_noarg_CMD:
|
||||
pool_data_name = (char *)arg_str_value(cmd, cachepool_ARG, NULL);
|
||||
new_command = get_command(lvconvert_to_cachepool_CMD);
|
||||
break;
|
||||
default:
|
||||
log_error(INTERNAL_ERROR "Unknown pool conversion.");
|
||||
return 0;
|
||||
};
|
||||
|
||||
log_debug("Changing command %d:%s to standard form %d:%s",
|
||||
cmd->command->command_index, cmd->command->command_id,
|
||||
new_command->command_index, new_command->command_id);
|
||||
|
||||
/* Make the LV the first position arg. */
|
||||
|
||||
p = cmd->position_argc;
|
||||
for (i = 0; i < cmd->position_argc; i++)
|
||||
cmd->position_argv[p] = cmd->position_argv[p-1];
|
||||
|
||||
cmd->position_argv[0] = pool_data_name;
|
||||
cmd->position_argc++;
|
||||
cmd->command = new_command;
|
||||
|
||||
return lvconvert_to_pool_cmd(cmd, argc, argv);
|
||||
}
|
||||
|
||||
static int _lvconvert_to_cache_vol_single(struct cmd_context *cmd,
|
||||
struct logical_volume *lv,
|
||||
struct processing_handle *handle)
|
||||
@@ -4040,39 +4032,96 @@ int lvconvert_swap_pool_metadata_cmd(struct cmd_context *cmd, int argc, char **a
|
||||
NULL, NULL, &_lvconvert_swap_pool_metadata_single);
|
||||
}
|
||||
|
||||
#if 0
|
||||
int lvconvert_swap_pool_metadata_noarg_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||
static int _lvconvert_to_pool_or_swap_metadata_single(struct cmd_context *cmd,
|
||||
struct logical_volume *lv,
|
||||
struct processing_handle *handle)
|
||||
{
|
||||
struct command *new_command;
|
||||
char *pool_name;
|
||||
struct dm_list *use_pvh = NULL;
|
||||
int to_thinpool = 0;
|
||||
int to_cachepool = 0;
|
||||
|
||||
switch (cmd->command->command_enum) {
|
||||
case lvconvert_swap_thinpool_metadata_CMD:
|
||||
pool_name = (char *)arg_str_value(cmd, thinpool_ARG, NULL);
|
||||
case lvconvert_to_thinpool_or_swap_metadata_CMD:
|
||||
to_thinpool = 1;
|
||||
break;
|
||||
case lvconvert_swap_cachepool_metadata_CMD:
|
||||
pool_name = (char *)arg_str_value(cmd, cachepool_ARG, NULL);
|
||||
case lvconvert_to_cachepool_or_swap_metadata_CMD:
|
||||
to_cachepool = 1;
|
||||
break;
|
||||
default:
|
||||
log_error(INTERNAL_ERROR "Invalid lvconvert pool command");
|
||||
return 0;
|
||||
};
|
||||
|
||||
if (cmd->position_argc > 1) {
|
||||
/* First pos arg is required LV, remaining are optional PVs. */
|
||||
if (!(use_pvh = create_pv_list(cmd->mem, lv->vg, cmd->position_argc - 1, cmd->position_argv + 1, 0)))
|
||||
return_ECMD_FAILED;
|
||||
} else
|
||||
use_pvh = &lv->vg->pvs;
|
||||
|
||||
/*
|
||||
* We can finally determine if this command is supposed to create
|
||||
* a pool or swap the metadata in an existing pool.
|
||||
*
|
||||
* This allows the ambiguous command:
|
||||
* 'lvconvert --thinpool LV1 --poolmetadata LV2' to mean either:
|
||||
* 1. convert LV2 to a pool using the specified meta LV2
|
||||
* 2. swap the meta lv in LV1 with LV2
|
||||
*
|
||||
* In case 2, the poolmetadata option is required, but in case 1
|
||||
* it is optional. So, the command def is not able to validate
|
||||
* the required/optional option, and we have to check here
|
||||
* for missing poolmetadata in case 2.
|
||||
*/
|
||||
if (lv_is_pool(lv)) {
|
||||
if (!arg_is_set(cmd, poolmetadata_ARG)) {
|
||||
log_error("The --poolmetadata option is required to swap metadata.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
return _lvconvert_swap_pool_metadata_single(cmd, lv, handle);
|
||||
}
|
||||
|
||||
if (!_lvconvert_to_pool(cmd, lv, to_thinpool, to_cachepool, use_pvh))
|
||||
return_ECMD_FAILED;
|
||||
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
/*
|
||||
* In the command variants with no position LV arg, the LV arg is taken from
|
||||
* the --thinpool/--cachepool arg, and the position args are modified to match
|
||||
* the standard command form.
|
||||
*/
|
||||
|
||||
int lvconvert_to_pool_or_swap_metadata_cmd(struct cmd_context *cmd, int argc, char **argv)
|
||||
{
|
||||
char *pool_data_name;
|
||||
int i, p;
|
||||
|
||||
switch (cmd->command->command_enum) {
|
||||
case lvconvert_to_thinpool_or_swap_metadata_CMD:
|
||||
pool_data_name = (char *)arg_str_value(cmd, thinpool_ARG, NULL);
|
||||
break;
|
||||
case lvconvert_to_cachepool_or_swap_metadata_CMD:
|
||||
pool_data_name = (char *)arg_str_value(cmd, cachepool_ARG, NULL);
|
||||
break;
|
||||
default:
|
||||
log_error(INTERNAL_ERROR "Unknown pool conversion.");
|
||||
return 0;
|
||||
};
|
||||
|
||||
new_command = get_command(lvconvert_swap_pool_metadata_CMD);
|
||||
|
||||
log_debug("Changing command %d:%s to standard form %d:%s",
|
||||
cmd->command->command_index, cmd->command->command_id,
|
||||
new_command->command_index, new_command->command_id);
|
||||
|
||||
/* Make the LV the first position arg. */
|
||||
|
||||
cmd->position_argv[0] = pool_name;
|
||||
cmd->position_argc++;
|
||||
cmd->command = new_command;
|
||||
p = cmd->position_argc;
|
||||
for (i = 0; i < cmd->position_argc; i++)
|
||||
cmd->position_argv[p] = cmd->position_argv[p-1];
|
||||
|
||||
return lvconvert_swap_pool_metadata_cmd(cmd, argc, argv);
|
||||
cmd->position_argv[0] = pool_data_name;
|
||||
cmd->position_argc++;
|
||||
|
||||
return process_each_lv(cmd, 1, cmd->position_argv, NULL, NULL, READ_FOR_UPDATE,
|
||||
NULL, NULL, &_lvconvert_to_pool_or_swap_metadata_single);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _lvconvert_merge_thin_single(struct cmd_context *cmd,
|
||||
struct logical_volume *lv,
|
||||
|
||||
@@ -32,7 +32,7 @@ void *cmdlib_lvm2_init(unsigned static_compile);
|
||||
void lvm_fin(struct cmd_context *cmd);
|
||||
|
||||
struct cmd_context *init_lvm(unsigned set_connections, unsigned set_filters);
|
||||
void lvm_register_commands(void);
|
||||
int lvm_register_commands(char *name);
|
||||
int lvm_split(char *str, int *argc, char **argv, int max);
|
||||
int lvm_run_command(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvm_return_code(int ret);
|
||||
|
||||
@@ -34,7 +34,8 @@ void *cmdlib_lvm2_init(unsigned static_compile)
|
||||
if (!(cmd = init_lvm(1, 1)))
|
||||
return NULL;
|
||||
|
||||
lvm_register_commands();
|
||||
if (!lvm_register_commands(NULL))
|
||||
return NULL;
|
||||
|
||||
return (void *) cmd;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ static struct cmdline_context _cmdline;
|
||||
* to use these functions instead of the old per-command-name function.
|
||||
* For now, any command id not included here uses the old command fn.
|
||||
*/
|
||||
struct command_function command_functions[CMD_COUNT] = {
|
||||
static const struct command_function command_functions[CMD_COUNT] = {
|
||||
{ lvmconfig_general_CMD, lvmconfig },
|
||||
{ lvchange_properties_CMD, lvchange_properties_cmd },
|
||||
{ lvchange_resync_CMD, lvchange_resync_cmd },
|
||||
@@ -135,12 +135,12 @@ struct command_function command_functions[CMD_COUNT] = {
|
||||
|
||||
/* lvconvert utilities for creating/maintaining thin and cache objects. */
|
||||
{ lvconvert_to_thinpool_CMD, lvconvert_to_pool_cmd },
|
||||
{ lvconvert_to_thinpool_noarg_CMD, lvconvert_to_pool_noarg_cmd },
|
||||
{ lvconvert_to_cachepool_CMD, lvconvert_to_pool_cmd },
|
||||
{ lvconvert_to_cachepool_noarg_CMD, lvconvert_to_pool_noarg_cmd },
|
||||
{ lvconvert_to_thin_with_external_CMD, lvconvert_to_thin_with_external_cmd },
|
||||
{ lvconvert_to_cache_vol_CMD, lvconvert_to_cache_vol_cmd },
|
||||
{ lvconvert_swap_pool_metadata_CMD, lvconvert_swap_pool_metadata_cmd },
|
||||
{ lvconvert_to_thinpool_or_swap_metadata_CMD, lvconvert_to_pool_or_swap_metadata_cmd },
|
||||
{ lvconvert_to_cachepool_or_swap_metadata_CMD, lvconvert_to_pool_or_swap_metadata_cmd },
|
||||
{ lvconvert_merge_thin_CMD, lvconvert_merge_thin_cmd },
|
||||
{ lvconvert_split_and_keep_cachepool_CMD, lvconvert_split_cachepool_cmd },
|
||||
{ lvconvert_split_and_remove_cachepool_CMD, lvconvert_split_cachepool_cmd },
|
||||
@@ -1112,7 +1112,7 @@ static struct command_name *find_command_name(const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct command_function *_find_command_id_function(int command_enum)
|
||||
static const struct command_function *_find_command_id_function(int command_enum)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -1126,19 +1126,23 @@ static struct command_function *_find_command_id_function(int command_enum)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void lvm_register_commands(void)
|
||||
int lvm_register_commands(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* already initialized */
|
||||
if (_cmdline.commands)
|
||||
return 1;
|
||||
|
||||
memset(&commands, 0, sizeof(commands));
|
||||
|
||||
/*
|
||||
* populate commands[] array with command definitions
|
||||
* by parsing command-lines.in/command-lines-input.h
|
||||
*/
|
||||
if (!define_commands()) {
|
||||
log_error("Failed to parse command definitions.");
|
||||
return;
|
||||
if (!define_commands(name)) {
|
||||
log_error(INTERNAL_ERROR "Failed to parse command definitions.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
_cmdline.commands = commands;
|
||||
@@ -1147,12 +1151,20 @@ void lvm_register_commands(void)
|
||||
for (i = 0; i < COMMAND_COUNT; i++) {
|
||||
commands[i].command_enum = command_id_to_enum(commands[i].command_id);
|
||||
|
||||
if (!commands[i].command_enum) {
|
||||
log_error(INTERNAL_ERROR "Failed to find command id %s.", commands[i].command_id);
|
||||
_cmdline.commands = NULL;
|
||||
_cmdline.num_commands = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* new style */
|
||||
commands[i].functions = _find_command_id_function(commands[i].command_enum);
|
||||
|
||||
/* old style */
|
||||
if (!commands[i].functions) {
|
||||
struct command_name *cname = find_command_name(commands[i].name);
|
||||
if (cname)
|
||||
commands[i].fn = cname->fn;
|
||||
}
|
||||
}
|
||||
@@ -1167,6 +1179,8 @@ void lvm_register_commands(void)
|
||||
|
||||
for (i = 0; i < _cmdline.num_command_names; i++)
|
||||
_set_valid_args_for_command_name(i);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct lv_props *get_lv_prop(int lvp_enum)
|
||||
@@ -1310,14 +1324,19 @@ static int _command_required_pos_matches(struct cmd_context *cmd, int ci, int rp
|
||||
if (!strcmp(cmd->name, "lvcreate") &&
|
||||
(rp == 0) &&
|
||||
val_bit_is_set(commands[ci].required_pos_args[rp].def.val_bits, vg_VAL) &&
|
||||
(arg_is_set(cmd, name_ARG) || arg_is_set(cmd, thinpool_ARG) || arg_is_set(cmd, cachepool_ARG))) {
|
||||
(arg_is_set(cmd, name_ARG) ||
|
||||
arg_is_set(cmd, thinpool_ARG) ||
|
||||
arg_is_set(cmd, cachepool_ARG) ||
|
||||
getenv("LVM_VG_NAME"))) {
|
||||
|
||||
if (getenv("LVM_VG_NAME"))
|
||||
return 1;
|
||||
|
||||
if ((name = arg_str_value(cmd, name_ARG, NULL))) {
|
||||
if (strstr(name, "/") || getenv("LVM_VG_NAME"))
|
||||
if (strstr(name, "/"))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* FIXME: does LVM_VG_NAME also work with --thinpool/--cachepool ? */
|
||||
|
||||
if ((name = arg_str_value(cmd, thinpool_ARG, NULL))) {
|
||||
if (strstr(name, "/"))
|
||||
return 1;
|
||||
@@ -1363,7 +1382,7 @@ static struct command *_find_command(struct cmd_context *cmd, const char *path,
|
||||
char buf[64];
|
||||
int match_required, match_ro, match_rp, match_type, match_unused, mismatch_required;
|
||||
int best_i = 0, best_required = 0, best_type = 0, best_unused = 0;
|
||||
int close_i = 0, close_ro = 0, close_type;
|
||||
int close_i = 0, close_ro = 0, close_type = 0;
|
||||
int temp_unused_options[MAX_UNUSED_COUNT];
|
||||
int temp_unused_count;
|
||||
int best_unused_options[MAX_UNUSED_COUNT] = { 0 };
|
||||
@@ -1381,7 +1400,7 @@ static struct command *_find_command(struct cmd_context *cmd, const char *path,
|
||||
continue;
|
||||
|
||||
/* For help and version just return the first entry with matching name. */
|
||||
if (arg_is_set(cmd, help_ARG) || arg_is_set(cmd, help2_ARG) || arg_is_set(cmd, version_ARG))
|
||||
if (arg_is_set(cmd, help_ARG) || arg_is_set(cmd, help2_ARG) || arg_is_set(cmd, longhelp_ARG) || arg_is_set(cmd, version_ARG))
|
||||
return &commands[i];
|
||||
|
||||
match_required = 0; /* required parameters that match */
|
||||
@@ -1542,9 +1561,10 @@ static struct command *_find_command(struct cmd_context *cmd, const char *path,
|
||||
if (!best_required) {
|
||||
/* cmd did not have all the required opt/pos args of any command */
|
||||
log_error("Failed to find a matching command definition.");
|
||||
log_error("Run '%s --help' for more information.", name);
|
||||
if (close_ro) {
|
||||
log_warn("Closest command usage is:");
|
||||
print_usage(&_cmdline.commands[close_i]);
|
||||
print_usage(&_cmdline.commands[close_i], 0);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -1657,7 +1677,7 @@ static void _short_usage(const char *name)
|
||||
log_error("Run `%s --help' for more information.", name);
|
||||
}
|
||||
|
||||
static int _usage(const char *name, int help_count)
|
||||
static int _usage(const char *name, int longhelp)
|
||||
{
|
||||
struct command_name *cname = find_command_name(name);
|
||||
struct command *cmd;
|
||||
@@ -1668,58 +1688,54 @@ static int _usage(const char *name, int help_count)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Looks at all variants of each command name and figures out
|
||||
* which options are common to all variants (for compact output)
|
||||
*/
|
||||
factor_common_options();
|
||||
|
||||
log_print("%s - %s\n", name, cname->desc);
|
||||
|
||||
/* Reduce the default output when there are several variants. */
|
||||
|
||||
if (cname->variants < 3)
|
||||
longhelp = 1;
|
||||
|
||||
for (i = 0; i < COMMAND_COUNT; i++) {
|
||||
if (strcmp(_cmdline.commands[i].name, name))
|
||||
continue;
|
||||
|
||||
if ((_cmdline.commands[i].cmd_flags & CMD_FLAG_SECONDARY_SYNTAX) && (help_count < 3))
|
||||
if (_cmdline.commands[i].cmd_flags & CMD_FLAG_PREVIOUS_SYNTAX)
|
||||
continue;
|
||||
|
||||
print_usage(&_cmdline.commands[i]);
|
||||
if ((_cmdline.commands[i].cmd_flags & CMD_FLAG_SECONDARY_SYNTAX) && !longhelp)
|
||||
continue;
|
||||
|
||||
print_usage(&_cmdline.commands[i], longhelp);
|
||||
cmd = &_cmdline.commands[i];
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* Common options are printed once for all variants of a command name. */
|
||||
print_usage_common(cname, cmd);
|
||||
|
||||
if (help_count > 1) {
|
||||
/*
|
||||
* Excluding commonly understood syntax style like the meanings of:
|
||||
* [ ] for optional, ... for repeatable, | for one of the following,
|
||||
* -- for an option name, lower case strings and digits for literals.
|
||||
*/
|
||||
log_print("Usage notes:");
|
||||
log_print(". Variable parameters are: Number, String, PV, VG, LV, Tag.");
|
||||
log_print(". Select indicates that a required positional parameter can");
|
||||
log_print(" be omitted if the --select option is used.");
|
||||
log_print(". --size Number can be replaced with --extents NumberExtents.");
|
||||
log_print(". When --name is omitted from lvcreate, a new LV name is");
|
||||
log_print(" generated with the \"lvol\" prefix and a unique numeric suffix.");
|
||||
log_print(". The required VG parameter in lvcreate may be omitted when");
|
||||
log_print(" the VG name is included in another option, e.g. --name VG/LV.");
|
||||
log_print(". For required options listed in parentheses, e.g. (--A, --B),");
|
||||
log_print(" any one is required, after which the others are optional.");
|
||||
log_print(". The _new suffix indicates the VG or LV must not yet exist.");
|
||||
log_print(". LV followed by _<type> indicates that an LV of the given type");
|
||||
log_print(" is required. (raid represents any raid<N> type.)");
|
||||
log_print(". Input units are always treated as base two values, regardless of");
|
||||
log_print(" unit capitalization, e.g. 'k' and 'K' both refer to 1024.");
|
||||
log_print(". The default input unit is specified by letter, followed by |unit");
|
||||
log_print(" which represents other possible input units: bBsSkKmMgGtTpPeE.");
|
||||
log_print(". Output units can be specified with the --units option, for which");
|
||||
log_print(" lower/upper case letters refer to base 2/10 values.");
|
||||
log_print(". Use --help --help --help to print secondary command syntax");
|
||||
log_print(" formats that are recognized, e.g. for compatibility.");
|
||||
log_print(". See man pages for short option equivalents of long option names,");
|
||||
log_print(" and for more detailed descriptions of variable parameters.");
|
||||
}
|
||||
if (longhelp) {
|
||||
print_usage_common_cmd(cname, cmd);
|
||||
print_usage_common_lvm(cname, cmd);
|
||||
} else
|
||||
log_print("Use --longhelp to show all options.");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void _usage_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_COMMAND_NAMES; i++) {
|
||||
if (!command_names[i].name)
|
||||
break;
|
||||
_usage(command_names[i].name, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets up the arguments to pass to getopt_long().
|
||||
*
|
||||
@@ -2154,11 +2170,10 @@ static int _get_settings(struct cmd_context *cmd)
|
||||
|
||||
static int _process_common_commands(struct cmd_context *cmd)
|
||||
{
|
||||
if (arg_is_set(cmd, help_ARG) || arg_is_set(cmd, help2_ARG)) {
|
||||
_usage(cmd->name, arg_count(cmd, help_ARG));
|
||||
|
||||
if (arg_count(cmd, help_ARG) < 2)
|
||||
log_print("(Use --help --help for usage notes.)");
|
||||
if (arg_is_set(cmd, help_ARG) ||
|
||||
arg_is_set(cmd, longhelp_ARG) ||
|
||||
arg_is_set(cmd, help2_ARG)) {
|
||||
_usage(cmd->name, arg_is_set(cmd, longhelp_ARG));
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
@@ -2191,6 +2206,8 @@ int help(struct cmd_context *cmd __attribute__((unused)), int argc, char **argv)
|
||||
|
||||
if (!argc)
|
||||
_display_help();
|
||||
else if (argc == 1 && !strcmp(argv[0], "all"))
|
||||
_usage_all();
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; i < argc; i++)
|
||||
@@ -2481,7 +2498,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
|
||||
/* each command should start out with sigint flag cleared */
|
||||
sigint_clear();
|
||||
|
||||
cmd->name = strdup(argv[0]);
|
||||
cmd->name = dm_pool_strdup(cmd->mem, argv[0]);
|
||||
|
||||
/* eliminate '-' from all options starting with -- */
|
||||
for (i = 1; i < argc; i++) {
|
||||
@@ -3139,6 +3156,7 @@ int lvm2_main(int argc, char **argv)
|
||||
int ret, alias = 0;
|
||||
struct custom_fds custom_fds;
|
||||
struct cmd_context *cmd;
|
||||
char *name;
|
||||
|
||||
if (!argv)
|
||||
return -1;
|
||||
@@ -3180,7 +3198,17 @@ int lvm2_main(int argc, char **argv)
|
||||
|
||||
cmd->argv = argv;
|
||||
|
||||
lvm_register_commands();
|
||||
if (!alias && argc == 1)
|
||||
name = NULL;
|
||||
else if (alias)
|
||||
name = argv[0];
|
||||
else
|
||||
name = argv[1];
|
||||
|
||||
if (!lvm_register_commands(name)) {
|
||||
ret = ECMD_FAILED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (_lvm1_fallback(cmd)) {
|
||||
/* Attempt to run equivalent LVM1 tool instead */
|
||||
@@ -3236,6 +3264,6 @@ int lvm2_main(int argc, char **argv)
|
||||
|
||||
out:
|
||||
lvm_fin(cmd);
|
||||
|
||||
return lvm_return_code(ret);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
const char *cmd_name = command_name(cmd);
|
||||
const char *type_str = arg_str_value(cmd, type_ARG, NULL);
|
||||
|
||||
if (type_str && (lp->segtype = get_segtype_from_string(cmd, type_str)))
|
||||
if (type_str && !(lp->segtype = get_segtype_from_string(cmd, type_str)))
|
||||
return_0;
|
||||
|
||||
if (!strcmp(cmd_name, "lvreduce"))
|
||||
@@ -122,11 +122,14 @@ static int _lvresize_params(struct cmd_context *cmd, int argc, char **argv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((lp->mirrors = arg_count(cmd, mirrors_ARG)) &&
|
||||
(arg_sign_value(cmd, mirrors_ARG, SIGN_NONE) == SIGN_MINUS)) {
|
||||
if (arg_is_set(cmd, mirrors_ARG)) {
|
||||
if (arg_sign_value(cmd, mirrors_ARG, SIGN_NONE) != SIGN_NONE) {
|
||||
log_error("Mirrors argument may not be signed.");
|
||||
return 0;
|
||||
}
|
||||
if ((lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0)))
|
||||
lp->mirrors++;
|
||||
}
|
||||
|
||||
if ((lp->stripes = arg_uint_value(cmd, stripes_ARG, 0)) &&
|
||||
(arg_sign_value(cmd, stripes_ARG, SIGN_NONE) == SIGN_MINUS)) {
|
||||
|
||||
@@ -3362,10 +3362,10 @@ static int _get_arg_lvnames(struct cmd_context *cmd,
|
||||
* came up with its own inconsistent approach.
|
||||
*
|
||||
* In this case, when the position arg is a single name, it is treated as an LV
|
||||
* name (not a VG name). This leaves the VG unknown. So, other option values
|
||||
* must be searched for a VG name. If one of those option values contains a
|
||||
* vgname/lvname value, then the VG name is extracted and used for the LV
|
||||
* position arg.
|
||||
* name (not a VG name). This leaves the VG unknown. So, other option values,
|
||||
* or env var, must be searched for a VG name. If one of the option values
|
||||
* contains a vgname/lvname value, then the VG name is extracted and used for
|
||||
* the LV position arg. Or, if the env var has the VG name, that is used.
|
||||
*
|
||||
* Other option values that are searched for a VG name are:
|
||||
* --thinpool, --cachepool.
|
||||
@@ -3375,21 +3375,21 @@ static int _get_arg_lvnames(struct cmd_context *cmd,
|
||||
* . add vg/lv1 to arg_lvnames
|
||||
*
|
||||
* command lv1
|
||||
* . error: no vg name
|
||||
* . error: no vg name (unless LVM_VG_NAME)
|
||||
*
|
||||
* command --option vg/lv1 vg/lv2
|
||||
* command --option=vg/lv1 vg/lv2
|
||||
* . verify both vg names match
|
||||
* . add vg to arg_vgnames
|
||||
* . add vg/lv2 to arg_lvnames
|
||||
*
|
||||
* command --option lv1 lv2
|
||||
* . error: no vg name
|
||||
* command --option=lv1 lv2
|
||||
* . error: no vg name (unless LVM_VG_NAME)
|
||||
*
|
||||
* command --option vg/lv1 lv2
|
||||
* command --option=vg/lv1 lv2
|
||||
* . add vg to arg_vgnames
|
||||
* . add vg/lv2 to arg_lvnames
|
||||
*
|
||||
* command --option lv1 vg/lv2
|
||||
* command --option=lv1 vg/lv2
|
||||
* . add vg to arg_vgnames
|
||||
* . add vg/lv2 to arg_lvnames
|
||||
*/
|
||||
@@ -3405,6 +3405,7 @@ static int _get_arg_lvnames_using_options(struct cmd_context *cmd,
|
||||
const char *pos_vgname = NULL;
|
||||
const char *opt_vgname = NULL;
|
||||
const char *pos_lvname = NULL;
|
||||
const char *env_vgname = NULL;
|
||||
const char *use_vgname = NULL;
|
||||
char *tmp_name;
|
||||
char *split;
|
||||
@@ -3434,10 +3435,18 @@ static int _get_arg_lvnames_using_options(struct cmd_context *cmd,
|
||||
return ECMD_PROCESSED;
|
||||
}
|
||||
|
||||
if (*pos_name == '/') {
|
||||
if (!(pos_name = skip_dev_dir(cmd, pos_name, NULL)))
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if ((split = strchr(pos_name, '/'))) {
|
||||
pos_vgname = pos_name;
|
||||
pos_lvname = split + 1;
|
||||
*split = '\0';
|
||||
/*
|
||||
* This splits pos_name 'x/y' into pos_vgname 'x' and pos_lvname 'y'
|
||||
* It skips repeated '/', e.g. x//y
|
||||
* It also checks and fails for extra '/', e.g. x/y/z
|
||||
*/
|
||||
pos_vgname = _extract_vgname(cmd, pos_name, &pos_lvname);
|
||||
} else {
|
||||
pos_lvname = pos_name;
|
||||
pos_vgname = NULL;
|
||||
@@ -3448,7 +3457,9 @@ static int _get_arg_lvnames_using_options(struct cmd_context *cmd,
|
||||
else if (arg_is_set(cmd, cachepool_ARG))
|
||||
arg_name = arg_str_value(cmd, cachepool_ARG, NULL);
|
||||
|
||||
if (!pos_vgname && !arg_name) {
|
||||
env_vgname = _default_vgname(cmd);
|
||||
|
||||
if (!pos_vgname && !arg_name && !env_vgname) {
|
||||
log_error("Cannot find VG name for LV %s.", pos_lvname);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
@@ -3474,7 +3485,7 @@ static int _get_arg_lvnames_using_options(struct cmd_context *cmd,
|
||||
opt_vgname = NULL;
|
||||
}
|
||||
|
||||
if (!pos_vgname && !opt_vgname) {
|
||||
if (!pos_vgname && !opt_vgname && !env_vgname) {
|
||||
log_error("Cannot find VG name for LV %s.", pos_lvname);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
@@ -3485,7 +3496,14 @@ static int _get_arg_lvnames_using_options(struct cmd_context *cmd,
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
use_vgname = pos_vgname ? pos_vgname : opt_vgname;
|
||||
if (pos_vgname)
|
||||
use_vgname = pos_vgname;
|
||||
else if (opt_vgname)
|
||||
use_vgname = opt_vgname;
|
||||
else if (env_vgname)
|
||||
use_vgname = env_vgname;
|
||||
else
|
||||
return_ECMD_FAILED;
|
||||
|
||||
if (!str_list_add(cmd->mem, arg_vgnames, dm_pool_strdup(cmd->mem, use_vgname))) {
|
||||
log_error("strlist allocation failed.");
|
||||
@@ -5737,4 +5755,3 @@ bad:
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -274,10 +274,10 @@ int lvconvert_combine_split_snapshot_cmd(struct cmd_context *cmd, int argc, char
|
||||
int lvconvert_start_poll_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
|
||||
int lvconvert_to_pool_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_to_pool_noarg_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_to_cache_vol_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_to_thin_with_external_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_swap_pool_metadata_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_to_pool_or_swap_metadata_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_merge_thin_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
int lvconvert_split_cachepool_cmd(struct cmd_context *cmd, int argc, char **argv);
|
||||
|
||||
|
||||
16
tools/vals.h
16
tools/vals.h
@@ -83,10 +83,10 @@
|
||||
* 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
|
||||
* "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
|
||||
* 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
|
||||
@@ -115,15 +115,15 @@ 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(regionsize_VAL, regionsize_arg, "RegionSize", "Number[m|unit]")
|
||||
val(sizekb_VAL, size_kb_arg, "SizeKB", "Number[k|Unit]")
|
||||
val(sizemb_VAL, size_mb_arg, "SizeMB", "Number[m|Unit]")
|
||||
val(regionsize_VAL, regionsize_arg, "RegionSize", "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(units_VAL, string_arg, "Units", "r|R|h|H|b|B|s|S|k|K|m|M|g|G|t|T|p|P|e|E")
|
||||
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")
|
||||
|
||||
@@ -23,7 +23,7 @@ ifeq ("@BUILD_LVMETAD@", "yes")
|
||||
LVM_RULES+=69-dm-lvm-metad.rules
|
||||
endif
|
||||
|
||||
DM_DIR=$(shell grep "\#define DM_DIR" $(top_srcdir)/libdm/misc/dm-ioctl.h | awk '{print $$3}')
|
||||
DM_DIR=$(shell $(GREP) "\#define DM_DIR" $(top_srcdir)/libdm/misc/dm-ioctl.h | $(AWK) '{print $$3}')
|
||||
|
||||
ifeq ("@UDEV_RULE_EXEC_DETECTION@", "yes")
|
||||
SBIN=\$$env{DM_SBIN_PATH}
|
||||
|
||||
Reference in New Issue
Block a user