master - toolcontext: Improve invalid units error message.
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=3654f478e1beab950f9...
Commit: 3654f478e1beab950f9ee91bc2fd759d22552e1c
Parent: 54f5bc01b9509f80b3e8fe16f8bb1bc0228265ab
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Thu Jul 27 00:51:50 2017 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Thu Jul 27 00:51:50 2017 +0100
toolcontext: Improve invalid units error message.
---
lib/commands/toolcontext.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 678ee8a..39b300a 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -474,10 +474,12 @@ bad:
int process_profilable_config(struct cmd_context *cmd)
{
+ const char *units;
+
if (!(cmd->default_settings.unit_factor =
- dm_units_to_factor(find_config_tree_str(cmd, global_units_CFG, NULL),
+ dm_units_to_factor(units = find_config_tree_str(cmd, global_units_CFG, NULL),
&cmd->default_settings.unit_type, 1, NULL))) {
- log_error("Invalid units specification");
+ log_error("Unrecognised configuration setting for global/units: %s", units);
return 0;
}
@@ -2009,7 +2011,6 @@ out:
cmd = NULL;
}
-
return cmd;
}
6 years, 4 months
master - tools: Introduce exit code EINIT_FAILED.
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=54f5bc01b9509f80b3e...
Commit: 54f5bc01b9509f80b3e8fe16f8bb1bc0228265ab
Parent: f9f75de3da98e0f6f43d46539e4c17781d209478
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Wed Jul 26 23:18:03 2017 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Wed Jul 26 23:18:03 2017 +0100
tools: Introduce exit code EINIT_FAILED.
Replace -1 (reported as 255) by 4.
---
WHATS_NEW | 1 +
tools/errors.h | 1 +
tools/lvm2cmd.h | 1 +
tools/lvmcmdline.c | 14 +++++++-------
4 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index a9b3a08..20da268 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.174 -
=================================
+ Introduce exit code 4 EINIT_FAILED to replace -1 when initialisation fails.
Add synchronization points with udev during reshape of raid LVs.
Version 2.02.173 - 20th July 2017
diff --git a/tools/errors.h b/tools/errors.h
index bfc0461..3d87a48 100644
--- a/tools/errors.h
+++ b/tools/errors.h
@@ -19,6 +19,7 @@
#define ECMD_PROCESSED 1
#define ENO_SUCH_CMD 2
#define EINVALID_CMD_LINE 3
+#define EINIT_FAILED 4
#define ECMD_FAILED 5
/* FIXME Also returned by cmdlib. */
diff --git a/tools/lvm2cmd.h b/tools/lvm2cmd.h
index 2966ec9..cd2e0ec 100644
--- a/tools/lvm2cmd.h
+++ b/tools/lvm2cmd.h
@@ -40,6 +40,7 @@ typedef void (*lvm2_log_fn_t) (int level, const char *file, int line,
#define LVM2_COMMAND_SUCCEEDED 1 /* ECMD_PROCESSED */
#define LVM2_NO_SUCH_COMMAND 2 /* ENO_SUCH_CMD */
#define LVM2_INVALID_PARAMETERS 3 /* EINVALID_CMD_LINE */
+#define LVM2_INIT_FAILED 4 /* EINIT_FAILED */
#define LVM2_PROCESSING_FAILED 5 /* ECMD_FAILED */
/*
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index ae55e12..81cc5e0 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -3420,7 +3420,7 @@ int lvm2_main(int argc, char **argv)
const char *run_command_name = NULL;
if (!argv)
- return -1;
+ return EINIT_FAILED;
base = last_path_component(argv[0]);
if (strcmp(base, "lvm") && strcmp(base, "lvm.static") &&
@@ -3428,16 +3428,16 @@ int lvm2_main(int argc, char **argv)
alias = 1;
if (!_check_standard_fds())
- return -1;
+ return EINIT_FAILED;
if (!_get_custom_fds(&custom_fds))
- return -1;
+ return EINIT_FAILED;
if (!_close_stray_fds(base, &custom_fds))
- return -1;
+ return EINIT_FAILED;
if (!init_custom_log_streams(&custom_fds))
- return -1;
+ return EINIT_FAILED;
if (is_static() && strcmp(base, "lvm.static") &&
path_exists(LVM_PATH) &&
@@ -3461,12 +3461,12 @@ int lvm2_main(int argc, char **argv)
if (*argv[1] == '-') {
log_error("Specify options after a command: lvm [command] [options].");
- return -1;
+ return EINVALID_CMD_LINE;
}
}
if (!(cmd = init_lvm(0, 0)))
- return -1;
+ return EINIT_FAILED;
/* Store original argv location so we may customise it if we become a daemon */
cmd->argv = argv;
6 years, 4 months
master - dmsetup: Add minor number to concise table output format.
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f9f75de3da98e0f6f43...
Commit: f9f75de3da98e0f6f43d46539e4c17781d209478
Parent: a1dbefe9c8cd7f9bcbf19d0516082a3f354703b4
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Tue Jul 25 12:22:46 2017 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jul 25 12:22:46 2017 +0100
dmsetup: Add minor number to concise table output format.
When using this new format for input, it'll sometimes help to
be able to specify the minor number.
---
man/dmsetup.8_main | 6 +++---
tools/dmsetup.c | 3 +--
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/man/dmsetup.8_main b/man/dmsetup.8_main
index 1d0219f..c218f6c 100644
--- a/man/dmsetup.8_main
+++ b/man/dmsetup.8_main
@@ -826,9 +826,9 @@ target unless the \fB--showkeys\fP parameter is supplied. Kernel key
references prefixed with \fB:\fP are not affected by the parameter and get
displayed always.
With \fB--concise\fP, the output is presented concisely on a single line.
-Commas then separate the name, uuid, flags ('ro' or 'rw') and the table
-(if present). Semi-colons separate devices. Backslashes escape any commas,
-semi-colons or backslashes.
+Commas then separate the name, uuid, minor device number, flags ('ro' or 'rw')
+and the table (if present). Semi-colons separate devices. Backslashes escape
+any commas, semi-colons or backslashes.
.
.HP
.CMD_TARGETS
diff --git a/tools/dmsetup.c b/tools/dmsetup.c
index 3514fc5..e92ba17 100644
--- a/tools/dmsetup.c
+++ b/tools/dmsetup.c
@@ -2224,8 +2224,7 @@ static int _status(CMD_ARGS)
_print_string_quoted(name);
putchar(',');
_print_string_quoted(dm_task_get_uuid(dmt));
- putchar(',');
- printf("%s", info.read_only ? "ro" : "rw");
+ printf(",%u,%s", info.minor, info.read_only ? "ro" : "rw");
}
/* Next print any target-specific information */
if (target_type) {
6 years, 4 months
master - make generate
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=a1dbefe9c8cd7f9bcbf...
Commit: a1dbefe9c8cd7f9bcbf19d0516082a3f354703b4
Parent: 5fd7c0aa3340a58318d0bcfb0ae5aeb9924881f6
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Tue Jul 25 01:26:58 2017 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jul 25 01:26:58 2017 +0100
make generate
---
man/lvconvert.8_pregen | 14 ++--
man/lvcreate.8_pregen | 60 +++++++-------
man/vgchange.8_pregen | 203 ++++++++++++++++++++++++++++++++++++++++--------
3 files changed, 208 insertions(+), 69 deletions(-)
diff --git a/man/lvconvert.8_pregen b/man/lvconvert.8_pregen
index 6855550..93a8b27 100644
--- a/man/lvconvert.8_pregen
+++ b/man/lvconvert.8_pregen
@@ -1424,7 +1424,7 @@ Alternate command forms, advanced command usage, and listing of all valid syntax
.P
Convert LV to type mirror (also see type raid1),
.br
-(also see lvconvert \-\-mirrors).
+(also see lvconvert --mirrors).
.br
.P
\fBlvconvert\fP \fB--type\fP \fBmirror\fP \fILV\fP
@@ -1481,7 +1481,7 @@ Change the type of mirror log used by a mirror LV.
Convert LV to a thin LV, using the original LV as an external origin
.br
-(infers \-\-type thin).
+(infers --type thin).
.br
.P
\fBlvconvert\fP \fB-T\fP|\fB--thin\fP \fB--thinpool\fP \fILV\fP \fILV\fP\fI_linear_striped_cache_raid\fP
@@ -1528,7 +1528,7 @@ Convert LV to a thin LV, using the original LV as an external origin
.br
-
-Convert LV to type cache (infers \-\-type cache).
+Convert LV to type cache (infers --type cache).
.br
.P
\fBlvconvert\fP \fB-H\fP|\fB--cache\fP \fB--cachepool\fP \fILV\fP \fILV\fP\fI_linear_striped_thinpool_raid\fP
@@ -1613,11 +1613,11 @@ Swap metadata LV in a thin pool or cache pool (for repair only).
.br
-
-Merge LV that was split from a mirror (variant, use \-\-mergemirrors).
+Merge LV that was split from a mirror (variant, use --mergemirrors).
.br
-Merge thin LV into its origin LV (variant, use \-\-mergethin).
+Merge thin LV into its origin LV (variant, use --mergethin).
.br
-Merge COW snapshot LV into its origin (variant, use \-\-mergesnapshot).
+Merge COW snapshot LV into its origin (variant, use --mergesnapshot).
.br
.P
\fBlvconvert\fP \fB--merge\fP \fIVG\fP|\fILV\fP\fI_linear_striped_snapshot_thin_raid\fP|\fITag\fP ...
@@ -1693,7 +1693,7 @@ origin LV (first arg) to reverse a splitsnapshot command.
.br
-
-Poll LV to continue conversion (also see \-\-startpoll).
+Poll LV to continue conversion (also see --startpoll).
.br
.P
\fBlvconvert\fP \fILV\fP\fI_mirror_raid\fP
diff --git a/man/lvcreate.8_pregen b/man/lvcreate.8_pregen
index 6b05147..71bd82b 100644
--- a/man/lvcreate.8_pregen
+++ b/man/lvcreate.8_pregen
@@ -300,7 +300,7 @@ Create a linear LV.
.RE
-
-Create a striped LV (infers \-\-type striped).
+Create a striped LV (infers --type striped).
.br
.P
\fBlvcreate\fP \fB-i\fP|\fB--stripes\fP \fINumber\fP \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT] \fIVG\fP
@@ -322,7 +322,7 @@ Create a striped LV (infers \-\-type striped).
.RE
-
-Create a raid1 or mirror LV (infers \-\-type raid1|mirror).
+Create a raid1 or mirror LV (infers --type raid1|mirror).
.br
.P
\fBlvcreate\fP \fB-m\fP|\fB--mirrors\fP \fINumber\fP \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT] \fIVG\fP
@@ -569,7 +569,7 @@ Create a cache pool.
.RE
-
-Create a thin LV in a thin pool (infers \-\-type thin).
+Create a thin LV in a thin pool (infers --type thin).
.br
.P
\fBlvcreate\fP \fB-V\fP|\fB--virtualsize\fP \fISize\fP[m|UNIT] \fB--thinpool\fP \fILV\fP\fI_thinpool\fP \fIVG\fP
@@ -598,7 +598,7 @@ Create a thin LV in a thin pool (infers \-\-type thin).
Create a thin LV that is a snapshot of an existing thin LV
.br
-(infers \-\-type thin).
+(infers --type thin).
.br
.P
\fBlvcreate\fP \fB-s\fP|\fB--snapshot\fP \fILV\fP\fI_thin\fP
@@ -658,7 +658,7 @@ Create a thin LV that is a snapshot of an external origin LV.
Create a thin LV, first creating a thin pool for it,
.br
-where the new thin pool is named by the \-\-thinpool arg.
+where the new thin pool is named by the --thinpool arg.
.br
.P
\fBlvcreate\fP \fB--type\fP \fBthin\fP \fB-V\fP|\fB--virtualsize\fP \fISize\fP[m|UNIT]
@@ -715,7 +715,7 @@ Create a cache LV, first creating a new origin LV,
.br
then combining it with the existing cache pool named
.br
-by the \-\-cachepool arg.
+by the --cachepool arg.
.br
.P
\fBlvcreate\fP \fB--type\fP \fBcache\fP \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT]
@@ -1606,7 +1606,7 @@ Create a linear LV.
.RE
-
-Create a striped LV (also see lvcreate \-\-stripes).
+Create a striped LV (also see lvcreate --stripes).
.br
.P
\fBlvcreate\fP \fB--type\fP \fBstriped\fP \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT] \fIVG\fP
@@ -1632,7 +1632,7 @@ Create a striped LV (also see lvcreate \-\-stripes).
.RE
-
-Create a mirror LV (also see \-\-type raid1).
+Create a mirror LV (also see --type raid1).
.br
.P
\fBlvcreate\fP \fB--type\fP \fBmirror\fP \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT] \fIVG\fP
@@ -1672,7 +1672,7 @@ Create a mirror LV (also see \-\-type raid1).
Create a COW snapshot LV of an origin LV
.br
-(also see \-\-snapshot).
+(also see --snapshot).
.br
.P
\fBlvcreate\fP \fB--type\fP \fBsnapshot\fP \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT] \fILV\fP
@@ -1708,7 +1708,7 @@ Create a COW snapshot LV of an origin LV
Create a sparse COW snapshot LV of a virtual origin LV
.br
-(also see \-\-snapshot).
+(also see --snapshot).
.br
.P
\fBlvcreate\fP \fB--type\fP \fBsnapshot\fP \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT]
@@ -1766,7 +1766,7 @@ Create a sparse COW snapshot LV of a virtual origin LV.
.RE
-
-Create a thin pool (infers \-\-type thin-pool).
+Create a thin pool (infers --type thin-pool).
.br
.P
\fBlvcreate\fP \fB-T\fP|\fB--thin\fP \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT] \fIVG\fP
@@ -1816,9 +1816,9 @@ Create a thin pool (infers \-\-type thin-pool).
.RE
-
-Create a thin pool named by the \-\-thinpool arg
+Create a thin pool named by the --thinpool arg
.br
-(infers \-\-type thin-pool).
+(infers --type thin-pool).
.br
.P
\fBlvcreate\fP \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT] \fB--thinpool\fP \fILV\fP\fI_new\fP \fIVG\fP
@@ -1872,9 +1872,9 @@ Create a thin pool named by the \-\-thinpool arg
.RE
-
-Create a cache pool named by the \-\-cachepool arg
+Create a cache pool named by the --cachepool arg
.br
-(variant, uses \-\-cachepool in place of \-\-name).
+(variant, uses --cachepool in place of --name).
.br
.P
\fBlvcreate\fP \fB--type\fP \fBcache-pool\fP \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT]
@@ -1967,7 +1967,7 @@ Create a thin LV in a thin pool.
Create a thin LV in a thin pool named in the first arg
.br
-(variant, also see \-\-thinpool for naming pool).
+(variant, also see --thinpool for naming pool).
.br
.P
\fBlvcreate\fP \fB--type\fP \fBthin\fP \fB-V\fP|\fB--virtualsize\fP \fISize\fP[m|UNIT] \fILV\fP\fI_thinpool\fP
@@ -1992,7 +1992,7 @@ Create a thin LV in a thin pool named in the first arg
Create a thin LV in the thin pool named in the first arg
.br
-(variant, infers \-\-type thin, also see \-\-thinpool for
+(variant, infers --type thin, also see --thinpool for
.br
naming pool.)
.br
@@ -2046,7 +2046,7 @@ Create a thin LV that is a snapshot of an existing thin LV.
Create a thin LV that is a snapshot of an existing thin LV
.br
-(infers \-\-type thin).
+(infers --type thin).
.br
.P
\fBlvcreate\fP \fB-T\fP|\fB--thin\fP \fILV\fP\fI_thin\fP
@@ -2071,7 +2071,7 @@ Create a thin LV that is a snapshot of an existing thin LV
Create a thin LV that is a snapshot of an external origin LV
.br
-(infers \-\-type thin).
+(infers --type thin).
.br
.P
\fBlvcreate\fP \fB-s\fP|\fB--snapshot\fP \fB--thinpool\fP \fILV\fP\fI_thinpool\fP \fILV\fP
@@ -2096,9 +2096,9 @@ Create a thin LV that is a snapshot of an external origin LV
Create a thin LV, first creating a thin pool for it,
.br
-where the new thin pool is named by the \-\-thinpool arg
+where the new thin pool is named by the --thinpool arg
.br
-(variant, infers \-\-type thin).
+(variant, infers --type thin).
.br
.P
\fBlvcreate\fP \fB-V\fP|\fB--virtualsize\fP \fISize\fP[m|UNIT] \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT]
@@ -2153,9 +2153,9 @@ where the new thin pool is named by the \-\-thinpool arg
Create a thin LV, first creating a thin pool for it,
.br
-where the new thin pool is named by the \-\-thinpool arg
+where the new thin pool is named by the --thinpool arg
.br
-(variant, infers \-\-type thin).
+(variant, infers --type thin).
.br
.P
\fBlvcreate\fP \fB-V\fP|\fB--virtualsize\fP \fISize\fP[m|UNIT] \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT]
@@ -2273,7 +2273,7 @@ where the new thin pool is named in the first arg,
.br
or the new thin pool name is generated when the first
.br
-arg is a VG name (variant, infers \-\-type thin).
+arg is a VG name (variant, infers --type thin).
.br
.P
\fBlvcreate\fP \fB-T\fP|\fB--thin\fP \fB-V\fP|\fB--virtualsize\fP \fISize\fP[m|UNIT]
@@ -2324,13 +2324,13 @@ arg is a VG name (variant, infers \-\-type thin).
Create a thin LV, first creating a thin pool for it
.br
-(infers \-\-type thin).
+(infers --type thin).
.br
Create a sparse snapshot of a virtual origin LV
.br
-(infers \-\-type snapshot).
+(infers --type snapshot).
.br
-Chooses \-\-type thin or \-\-type snapshot according to
+Chooses --type thin or --type snapshot according to
.br
config setting sparse_segtype_default.
.br
@@ -2390,7 +2390,7 @@ Create a cache LV, first creating a new origin LV,
.br
then combining it with the existing cache pool named
.br
-by the \-\-cachepool arg (variant, infers \-\-type cache).
+by the --cachepool arg (variant, infers --type cache).
.br
.P
\fBlvcreate\fP \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT] \fB--cachepool\fP \fILV\fP\fI_cachepool\fP \fIVG\fP
@@ -2448,7 +2448,7 @@ Create a cache LV, first creating a new origin LV,
.br
then combining it with the existing cache pool named
.br
-in the first arg (variant, also use \-\-cachepool).
+in the first arg (variant, also use --cachepool).
.br
.P
\fBlvcreate\fP \fB--type\fP \fBcache\fP \fB-L\fP|\fB--size\fP \fISize\fP[m|UNIT] \fILV\fP\fI_cachepool\fP
@@ -2512,7 +2512,7 @@ first creating a new origin LV, then combining it with
.br
the existing cache pool named in the first arg
.br
-(variant, infers \-\-type cache, also use \-\-cachepool).
+(variant, infers --type cache, also use --cachepool).
.br
When LV is not a cache pool, convert the specified LV
.br
diff --git a/man/vgchange.8_pregen b/man/vgchange.8_pregen
index b08c2f9..c1628a7 100644
--- a/man/vgchange.8_pregen
+++ b/man/vgchange.8_pregen
@@ -3,7 +3,7 @@
vgchange - Change volume group attributes
.
.SH SYNOPSIS
-\fBvgchange\fP \fIoption_args\fP
+\fBvgchange\fP \fIoption_args\fP \fIposition_args\fP
.br
[ \fIoption_args\fP ]
.br
@@ -250,30 +250,50 @@ required, after which the others are optional.
.ad b
.br
.ad l
- \fB--systemid\fP \fIString\fP,
+ \fB--profile\fP \fIString\fP,
.ad b
.br
.ad l
- \fB--locktype\fP \fBsanlock\fP|\fBdlm\fP|\fBnone\fP,
+ \fB--detachprofile\fP,
.ad b
.br
.ad l
- \fB--profile\fP \fIString\fP,
+ \fB--metadataprofile\fP \fIString\fP )
+.RE
+.br
+.RS 4
+.ad l
+[ \fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP ]
.ad b
.br
.ad l
- \fB--detachprofile\fP,
+[ \fB-S\fP|\fB--select\fP \fIString\fP ]
.ad b
.br
.ad l
- \fB--metadataprofile\fP \fIString\fP )
-.RE
+[ \fB-f\fP|\fB--force\fP ]
+.ad b
.br
-.RS 4
.ad l
[ \fB--poll\fP \fBy\fP|\fBn\fP ]
.ad b
.br
+.ad l
+[ \fB--ignoremonitoring\fP ]
+.ad b
+.br
+.ad l
+[ \fB--ignoreskippedcluster\fP ]
+.ad b
+.br
+.ad l
+[ \fB--noudevsync\fP ]
+.ad b
+.br
+.ad l
+[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
+.ad b
+.br
[ COMMON_OPTIONS ]
.RE
.br
@@ -289,6 +309,18 @@ Start or stop monitoring LVs from dmeventd.
.br
.RS 4
.ad l
+[ \fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP ]
+.ad b
+.br
+.ad l
+[ \fB-S\fP|\fB--select\fP \fIString\fP ]
+.ad b
+.br
+.ad l
+[ \fB-f\fP|\fB--force\fP ]
+.ad b
+.br
+.ad l
[ \fB--sysinit\fP ]
.ad b
.br
@@ -300,6 +332,22 @@ Start or stop monitoring LVs from dmeventd.
[ \fB--poll\fP \fBy\fP|\fBn\fP ]
.ad b
.br
+.ad l
+[ \fB--ignoremonitoring\fP ]
+.ad b
+.br
+.ad l
+[ \fB--ignoreskippedcluster\fP ]
+.ad b
+.br
+.ad l
+[ \fB--noudevsync\fP ]
+.ad b
+.br
+.ad l
+[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
+.ad b
+.br
[ COMMON_OPTIONS ]
.RE
.br
@@ -315,9 +363,37 @@ Start or stop processing LV conversions.
.br
.RS 4
.ad l
+[ \fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP ]
+.ad b
+.br
+.ad l
+[ \fB-S\fP|\fB--select\fP \fIString\fP ]
+.ad b
+.br
+.ad l
+[ \fB-f\fP|\fB--force\fP ]
+.ad b
+.br
+.ad l
[ \fB--ignorelockingfailure\fP ]
.ad b
.br
+.ad l
+[ \fB--ignoremonitoring\fP ]
+.ad b
+.br
+.ad l
+[ \fB--ignoreskippedcluster\fP ]
+.ad b
+.br
+.ad l
+[ \fB--noudevsync\fP ]
+.ad b
+.br
+.ad l
+[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
+.ad b
+.br
[ COMMON_OPTIONS ]
.RE
.br
@@ -341,6 +417,18 @@ Activate or deactivate LVs.
.ad b
.br
.ad l
+[ \fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP ]
+.ad b
+.br
+.ad l
+[ \fB-S\fP|\fB--select\fP \fIString\fP ]
+.ad b
+.br
+.ad l
+[ \fB-f\fP|\fB--force\fP ]
+.ad b
+.br
+.ad l
[ \fB--activationmode\fP \fBpartial\fP|\fBdegraded\fP|\fBcomplete\fP ]
.ad b
.br
@@ -360,6 +448,22 @@ Activate or deactivate LVs.
[ \fB--poll\fP \fBy\fP|\fBn\fP ]
.ad b
.br
+.ad l
+[ \fB--ignoremonitoring\fP ]
+.ad b
+.br
+.ad l
+[ \fB--ignoreskippedcluster\fP ]
+.ad b
+.br
+.ad l
+[ \fB--noudevsync\fP ]
+.ad b
+.br
+.ad l
+[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
+.ad b
+.br
[ COMMON_OPTIONS ]
.RE
.br
@@ -375,6 +479,18 @@ Reactivate LVs using the latest metadata.
.br
.RS 4
.ad l
+[ \fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP ]
+.ad b
+.br
+.ad l
+[ \fB-S\fP|\fB--select\fP \fIString\fP ]
+.ad b
+.br
+.ad l
+[ \fB-f\fP|\fB--force\fP ]
+.ad b
+.br
+.ad l
[ \fB--sysinit\fP ]
.ad b
.br
@@ -386,6 +502,22 @@ Reactivate LVs using the latest metadata.
[ \fB--poll\fP \fBy\fP|\fBn\fP ]
.ad b
.br
+.ad l
+[ \fB--ignoremonitoring\fP ]
+.ad b
+.br
+.ad l
+[ \fB--ignoreskippedcluster\fP ]
+.ad b
+.br
+.ad l
+[ \fB--noudevsync\fP ]
+.ad b
+.br
+.ad l
+[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
+.ad b
+.br
[ COMMON_OPTIONS ]
.RE
.br
@@ -394,6 +526,17 @@ Reactivate LVs using the latest metadata.
.RE
-
+Change the system ID of a VG.
+.br
+.P
+\fBvgchange\fP \fB--systemid\fP \fIString\fP \fIVG\fP
+.br
+.RS 4
+[ COMMON_OPTIONS ]
+.RE
+.br
+-
+
Start the lockspace of a shared VG in lvmlockd.
.br
.P
@@ -401,6 +544,10 @@ Start the lockspace of a shared VG in lvmlockd.
.br
.RS 4
.ad l
+[ \fB-S\fP|\fB--select\fP \fIString\fP ]
+.ad b
+.br
+.ad l
[ \fB--lockopt\fP \fIString\fP ]
.ad b
.br
@@ -419,6 +566,10 @@ Stop the lockspace of a shared VG in lvmlockd.
.br
.RS 4
.ad l
+[ \fB-S\fP|\fB--select\fP \fIString\fP ]
+.ad b
+.br
+.ad l
[ \fB--lockopt\fP \fIString\fP ]
.ad b
.br
@@ -430,36 +581,24 @@ Stop the lockspace of a shared VG in lvmlockd.
.RE
-
-Common options for command:
-.
-.RS 4
-.ad l
-[ \fB-A\fP|\fB--autobackup\fP \fBy\fP|\fBn\fP ]
-.ad b
-.br
-.ad l
-[ \fB-f\fP|\fB--force\fP ]
-.ad b
+Change the lock type for a shared VG.
.br
-.ad l
-[ \fB-S\fP|\fB--select\fP \fIString\fP ]
-.ad b
-.br
-.ad l
-[ \fB--ignoremonitoring\fP ]
-.ad b
+.P
+\fBvgchange\fP \fB--locktype\fP \fBsanlock\fP|\fBdlm\fP|\fBnone\fP \fIVG\fP
.br
+.RS 4
.ad l
-[ \fB--ignoreskippedcluster\fP ]
+[ \fB--lockopt\fP \fIString\fP ]
.ad b
.br
-.ad l
-[ \fB--noudevsync\fP ]
-.ad b
+[ COMMON_OPTIONS ]
+.RE
.br
-.ad l
-[ \fB--reportformat\fP \fBbasic\fP|\fBjson\fP ]
-.ad b
+-
+
+Common options for command:
+.
+.RS 4
.RE
Common options for lvm:
6 years, 4 months
master - dmsetup: Add concise table output format.
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=5fd7c0aa3340a58318d...
Commit: 5fd7c0aa3340a58318d0bcfb0ae5aeb9924881f6
Parent: ca71ad0d5025d2d01eb9666368c1da7db3c9c7ce
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Tue Jul 25 01:13:14 2017 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Tue Jul 25 01:13:14 2017 +0100
dmsetup: Add concise table output format.
Create a new table output format that concisely shows multiple devices
on one line.
dmsetup table --concise [device...]
<dev_name>,<uuid>,<flags>[,<table>]*[;<dev_name>,<uuid>,<flags>[,<table>]*]*
Table lines are separated by commas.
Devices are separated by semi-colons.
Flags is currently 'ro' or 'rw' (and might be extended in a
yet-to-be-defined way in future).
Any comma, semi-colon or backslash within a field is quoted by a
preceding backslash.
The format can later be supplied as input to dmsetup or even to the
booting kernel as an alternative way to set up devices.
Based on patches submitted by
Enric Balletbo i Serra <enric.balletbo(a)collabora.com>.
---
WHATS_NEW_DM | 1 +
man/dmsetup.8_main | 5 +++
tools/dmsetup.c | 74 ++++++++++++++++++++++++++++++++++++++++++++-------
3 files changed, 69 insertions(+), 11 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 7007c95..c41bcfd 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.143 -
=================================
+ Introduce single-line concise table output format: dmsetup table --concise
Version 1.02.142 - 20th July 2017
=================================
diff --git a/man/dmsetup.8_main b/man/dmsetup.8_main
index 4421882..1d0219f 100644
--- a/man/dmsetup.8_main
+++ b/man/dmsetup.8_main
@@ -269,6 +269,7 @@ dmsetup \(em low level logical volume management
.de CMD_TABLE
. ad l
. BR table
+. RB [ --concise ]
. RB [ --target
. IR target_type ]
. RB [ --showkeys ]
@@ -824,6 +825,10 @@ Real encryption keys are suppressed in the table output for the crypt
target unless the \fB--showkeys\fP parameter is supplied. Kernel key
references prefixed with \fB:\fP are not affected by the parameter and get
displayed always.
+With \fB--concise\fP, the output is presented concisely on a single line.
+Commas then separate the name, uuid, flags ('ro' or 'rw') and the table
+(if present). Semi-colons separate devices. Backslashes escape any commas,
+semi-colons or backslashes.
.
.HP
.CMD_TARGETS
diff --git a/tools/dmsetup.c b/tools/dmsetup.c
index 803ae56..3514fc5 100644
--- a/tools/dmsetup.c
+++ b/tools/dmsetup.c
@@ -163,6 +163,7 @@ enum {
AREA_ARG,
AREAS_ARG,
AREA_SIZE_ARG,
+ CONCISE_ARG,
BOUNDS_ARG,
CHECKS_ARG,
CLEAR_ARG,
@@ -273,6 +274,7 @@ static uint64_t _disp_factor = 512; /* display sizes in sectors */
static char _disp_units = 's';
const char *_program_id = DM_STATS_PROGRAM_ID; /* program_id used for reports. */
static uint64_t _statstype = 0; /* stats objects to report */
+static int _concise_output_produced = 0; /* Was any concise output already printed? */
/* string names for stats object types */
const char *_stats_types[] = {
@@ -2114,6 +2116,19 @@ static int _exec_command(const char *name)
return 1;
}
+/*
+ * Print string s using a backslash to quote each character that has a special
+ * meaning in the concise format - comma, semi-colon and backslash.
+ */
+static void _print_string_quoted(const char *s)
+{
+ while (*s) {
+ if (strchr(",;\\", *s))
+ putchar('\\');
+ putchar(*s++);
+ }
+}
+
static int _status(CMD_ARGS)
{
int r = 0;
@@ -2126,6 +2141,7 @@ static int _status(CMD_ARGS)
const char *name = NULL;
int matched = 0;
int ls_only = 0;
+ int use_concise = 0;
struct dm_info info;
if (names)
@@ -2136,9 +2152,12 @@ static int _status(CMD_ARGS)
name = argv[0];
}
- if (!strcmp(cmd->name, "table"))
+ if (!strcmp(cmd->name, "table")) {
cmdno = DM_DEVICE_TABLE;
- else
+ /* --concise only applies to 'table' */
+ if (_switches[CONCISE_ARG])
+ use_concise = 1;
+ } else
cmdno = DM_DEVICE_STATUS;
if (!strcmp(cmd->name, "ls"))
@@ -2179,6 +2198,7 @@ static int _status(CMD_ARGS)
if (_switches[TARGET_ARG] &&
(!target_type || strcmp(target_type, _target)))
continue;
+
if (ls_only) {
if (!_switches[EXEC_ARG] || !_command_to_exec ||
_switches[VERBOSE_ARG])
@@ -2186,10 +2206,28 @@ static int _status(CMD_ARGS)
next = NULL;
} else if (!_switches[EXEC_ARG] || !_command_to_exec ||
_switches[VERBOSE_ARG]) {
- if (!matched && _switches[VERBOSE_ARG])
- _display_info(dmt);
- if (multiple_devices && !_switches[VERBOSE_ARG])
- printf("%s: ", name);
+ if (!use_concise) {
+ if (!matched && _switches[VERBOSE_ARG])
+ _display_info(dmt);
+ if (multiple_devices && !_switches[VERBOSE_ARG])
+ printf("%s: ", name);
+ } else if (!matched) {
+ /*
+ * Before first target of device in concise output,
+ * print basic device information in the appropriate format.
+ * Separate devices by a semi-colon.
+ */
+ if (_concise_output_produced)
+ putchar(';');
+ _concise_output_produced = 1;
+
+ _print_string_quoted(name);
+ putchar(',');
+ _print_string_quoted(dm_task_get_uuid(dmt));
+ putchar(',');
+ printf("%s", info.read_only ? "ro" : "rw");
+ }
+ /* Next print any target-specific information */
if (target_type) {
/* Suppress encryption key */
if (!_switches[SHOWKEYS_ARG] &&
@@ -2210,15 +2248,22 @@ static int _status(CMD_ARGS)
while (*c && *c != ' ')
*c++ = '0';
}
- printf(FMTu64 " " FMTu64 " %s %s",
- start, length, target_type, params);
+ if (use_concise)
+ putchar(',');
+ printf(FMTu64 " " FMTu64 " %s ", start, length, target_type);
+ if (use_concise)
+ _print_string_quoted(params);
+ else
+ printf("%s", params);
}
- putchar('\n');
+ /* --concise places all devices on a single output line */
+ if (!use_concise)
+ putchar('\n');
}
matched = 1;
} while (next);
- if (multiple_devices && _switches[VERBOSE_ARG] && matched && !ls_only)
+ if (multiple_devices && _switches[VERBOSE_ARG] && matched && !ls_only && (!use_concise || _switches[VERBOSE_ARG] > 1))
putchar('\n');
if (matched && _switches[EXEC_ARG] && _command_to_exec && !_exec_command(name))
@@ -5904,7 +5949,7 @@ static struct command _dmsetup_commands[] = {
{"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},
+ {"table", "[<device>...] [--concise] [--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},
@@ -6473,6 +6518,7 @@ static int _process_switches(int *argcp, char ***argvp, const char *dev_dir)
{"checks", 0, &ind, CHECKS_ARG},
{"clear", 0, &ind, CLEAR_ARG},
{"columns", 0, &ind, COLS_ARG},
+ {"concise", 0, &ind, CONCISE_ARG},
{"count", 1, &ind, COUNT_ARG},
{"deferred", 0, &ind, DEFERRED_ARG},
{"select", 1, &ind, SELECT_ARG},
@@ -6637,6 +6683,8 @@ static int _process_switches(int *argcp, char ***argvp, const char *dev_dir)
return_0;
if (c == 'h' || ind == HELP_ARG)
_switches[HELP_ARG]++;
+ if (ind == CONCISE_ARG)
+ _switches[CONCISE_ARG]++;
if (ind == BOUNDS_ARG) {
_switches[BOUNDS_ARG]++;
_string_args[BOUNDS_ARG] = optarg;
@@ -7073,6 +7121,10 @@ doit:
do {
r = _perform_command_for_all_repeatable_args(cmd, subcommand, argc, argv, NULL, multiple_devices);
+ if (_concise_output_produced) {
+ putchar('\n');
+ fflush(stdout);
+ }
if (_report) {
/* only output headings for repeating reports */
if (_int_args[COUNT_ARG] != 1 && !dm_report_is_empty(_report))
6 years, 4 months
master - commands: expand comment on configuring option vals
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=ca71ad0d5025d2d01eb...
Commit: ca71ad0d5025d2d01eb9666368c1da7db3c9c7ce
Parent: 2938fa541aa66da66e32b9ea4b796dbedcf5062e
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Jul 20 16:54:40 2017 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jul 24 14:12:08 2017 -0500
commands: expand comment on configuring option vals
---
tools/command.c | 48 ++++++++++++++++++++++++++++++++++++++----------
1 files changed, 38 insertions(+), 10 deletions(-)
diff --git a/tools/command.c b/tools/command.c
index b4e5e76..52a3766 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -1575,17 +1575,45 @@ int define_commands(struct cmd_context *cmdtool, const char *run_name)
}
/*
- * This does not change the option vals in the cmd defs in commands[]
- * which are used when printing help/man output.
+ * The opt_names[] table describes each option. It is indexed by the
+ * option typedef, e.g. size_ARG. The size_ARG entry specifies the
+ * option name, e.g. --size, and the kind of value it accepts,
+ * e.g. sizemb_VAL.
*
- * The specific val types for each command are specified in
- * command-lines.in/commands[], and those are used for printing
- * man/help. But the opt_names[] array for each option is global
- * and has no command name context. So the opt_names[] array always
- * specifies a non-signed val, e.g. sizemb_VAL, extents_VAL. The
- * opt_names[] array is used by run time processing, and for part
- * of the help/man output. This adjusts the opt_names[] val types
- * according to the command being run.
+ * The val_names[] table describes each option value type. It is indexed by
+ * the value typedef, e.g. sizemb_VAL. The sizemb_VAL entry specifies the
+ * function used to parse the value, e.g. size_mb_arg(), the string used to
+ * refer to the value in the command-lines.in specifications, e.g. SizeMB,
+ * and how the value should be displayed in a man page, e.g. Size[m|UNIT].
+ *
+ * A problem is that these tables are independent of a particular command
+ * (they are created at build time), but different commands accept different
+ * types of values for the same option, e.g. one command will accept
+ * signed size values (ssizemb_VAL), while another does not accept a signed
+ * number, (sizemb_VAL). This function deals with this problem by tweaking
+ * the opt_names[] table at run time according to the specific command being run.
+ * i.e. it changes size_ARG to accept sizemb_VAL or ssizemb_VAL depending
+ * on the command.
+ *
+ * By default, size_ARG in opt_names[] is set up to accept a standard
+ * sizemb_VAL. The same is done for other opt_names[] entries that
+ * take different option values.
+ *
+ * This function overrides default opt_names[] entries at run time according
+ * to the command name, adjusting the value types accepted by various options.
+ * So, for lvresize, opt_names[sizemb_VAL] is overriden to accept
+ * the relative (+ or -) value type ssizemb_VAL, instead of the default
+ * sizemb_VAL. This way, when lvresize processes the --size value, it
+ * will use the ssize_mb_arg() function which accepts relative size values.
+ * When lvcreate processes the --size value, it uses size_mb_arg() which
+ * rejects signed values.
+ *
+ * The command defs in commands[] do not need to be overriden because
+ * the command-lines.in defs have the context of a command, and are
+ * described using the proper value type, e.g. this cmd def already
+ * uses the relative size value: "lvresize --size SSizeMB LV",
+ * so the commands[] entry for the cmd def already references the
+ * correct ssizemb_VAL.
*/
void configure_command_option_values(const char *name)
{
6 years, 4 months
master - man: remove hyphen escapes from source
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=2938fa541aa66da66e3...
Commit: 2938fa541aa66da66e32b9ea4b796dbedcf5062e
Parent: 1460cac27391ace1047588bb915d2734e4703fa6
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Jul 20 16:26:13 2017 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jul 24 14:12:08 2017 -0500
man: remove hyphen escapes from source
they are escaped by running sed in makefile
---
tools/command-lines.in | 86 ++++++++++++++++++++++++------------------------
1 files changed, 43 insertions(+), 43 deletions(-)
diff --git a/tools/command-lines.in b/tools/command-lines.in
index f2ad915..6e9192e 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -338,7 +338,7 @@ OO: --mirrors SNumber, --regionsize RegionSize, --interval Number, --mirrorlog M
OP: PV ...
ID: lvconvert_raid_types
DESC: Convert LV to type mirror (also see type raid1),
-DESC: (also see lvconvert \\-\\-mirrors).
+DESC: (also see lvconvert --mirrors).
RULE: all not lv_is_locked lv_is_pvmove
FLAGS: SECONDARY_SYNTAX
@@ -434,7 +434,7 @@ lvconvert --thin --thinpool LV LV_linear_striped_raid_cache
OO: --type thin, --originname LV_new, OO_LVCONVERT_POOL, OO_LVCONVERT
ID: lvconvert_to_thin_with_external
DESC: Convert LV to a thin LV, using the original LV as an external origin
-DESC: (infers \\-\\-type thin).
+DESC: (infers --type thin).
FLAGS: SECONDARY_SYNTAX
RULE: all and lv_is_visible
RULE: all not lv_is_locked
@@ -453,7 +453,7 @@ RULE: --poolmetadata not --readahead --stripesize --stripes_long
lvconvert --cache --cachepool LV LV_linear_striped_raid_thinpool
OO: --type cache, OO_LVCONVERT_CACHE, OO_LVCONVERT_POOL, OO_LVCONVERT
ID: lvconvert_to_cache_vol
-DESC: Convert LV to type cache (infers \\-\\-type cache).
+DESC: Convert LV to type cache (infers --type cache).
RULE: all and lv_is_visible
RULE: --poolmetadata not --readahead --stripesize --stripes_long
FLAGS: SECONDARY_SYNTAX
@@ -497,8 +497,8 @@ OO: --type thin-pool, --stripes_long Number, --stripesize SizeKB,
--discards Discards, OO_LVCONVERT_POOL, OO_LVCONVERT
OP: PV ...
ID: lvconvert_to_thinpool_or_swap_metadata
-DESC: Convert LV to type thin-pool (variant, use \\-\\-type thin-pool).
-DESC: Swap metadata LV in a thin pool (variant, use \\-\\-swapmetadata).
+DESC: Convert LV to type thin-pool (variant, use --type thin-pool).
+DESC: Swap metadata LV in a thin pool (variant, use --swapmetadata).
FLAGS: PREVIOUS_SYNTAX
RULE: all and lv_is_visible
RULE: --poolmetadata not --readahead --stripesize --stripes_long
@@ -538,8 +538,8 @@ lvconvert --cachepool LV_linear_striped_raid_cachepool
OO: --type cache-pool, OO_LVCONVERT_CACHE, OO_LVCONVERT_POOL, OO_LVCONVERT
OP: PV ...
ID: lvconvert_to_cachepool_or_swap_metadata
-DESC: Convert LV to type cache-pool (variant, use \\-\\-type cache-pool).
-DESC: Swap metadata LV in a cache pool (variant, use \\-\\-swapmetadata).
+DESC: Convert LV to type cache-pool (variant, use --type cache-pool).
+DESC: Swap metadata LV in a cache pool (variant, use --swapmetadata).
FLAGS: PREVIOUS_SYNTAX
RULE: all and lv_is_visible
RULE: --poolmetadata not --readahead --stripesize --stripes_long
@@ -579,9 +579,9 @@ FLAGS: SECONDARY_SYNTAX
lvconvert --merge LV_linear_striped_raid_thin_snapshot|VG|Tag ...
OO: --background, --interval Number, OO_LVCONVERT
ID: lvconvert_merge
-DESC: Merge LV that was split from a mirror (variant, use \\-\\-mergemirrors).
-DESC: Merge thin LV into its origin LV (variant, use \\-\\-mergethin).
-DESC: Merge COW snapshot LV into its origin (variant, use \\-\\-mergesnapshot).
+DESC: Merge LV that was split from a mirror (variant, use --mergemirrors).
+DESC: Merge thin LV into its origin LV (variant, use --mergethin).
+DESC: Merge COW snapshot LV into its origin (variant, use --mergesnapshot).
RULE: all not lv_is_locked lv_is_pvmove lv_is_merging_origin lv_is_virtual_origin lv_is_external_origin lv_is_merging_cow
FLAGS: SECONDARY_SYNTAX
@@ -694,7 +694,7 @@ RULE: all and lv_is_converting
lvconvert LV_mirror_raid
OO: OO_LVCONVERT
ID: lvconvert_start_poll
-DESC: Poll LV to continue conversion (also see \\-\\-startpoll).
+DESC: Poll LV to continue conversion (also see --startpoll).
RULE: all and lv_is_converting
FLAGS: SECONDARY_SYNTAX
@@ -782,7 +782,7 @@ lvcreate --type striped --size SizeMB VG
OO: --stripes Number, --stripesize SizeKB, OO_LVCREATE
OP: PV ...
ID: lvcreate_striped
-DESC: Create a striped LV (also see lvcreate \\-\\-stripes).
+DESC: Create a striped LV (also see lvcreate --stripes).
FLAGS: SECONDARY_SYNTAX
# R13 (just --stripes)
@@ -790,7 +790,7 @@ lvcreate --stripes Number --size SizeMB VG
OO: --stripesize SizeKB, OO_LVCREATE
OP: PV ...
ID: lvcreate_striped
-DESC: Create a striped LV (infers \\-\\-type striped).
+DESC: Create a striped LV (infers --type striped).
# R5,R7 (--type mirror with or without --mirrors)
lvcreate --type mirror --size SizeMB VG
@@ -798,7 +798,7 @@ OO: --mirrors PNumber, --mirrorlog MirrorLog, --regionsize RegionSize,
--stripes Number, --stripesize SizeKB, OO_LVCREATE
OP: PV ...
ID: lvcreate_mirror
-DESC: Create a mirror LV (also see \\-\\-type raid1).
+DESC: Create a mirror LV (also see --type raid1).
FLAGS: SECONDARY_SYNTAX
# R14 (just --mirrors)
@@ -807,7 +807,7 @@ lvcreate --mirrors PNumber --size SizeMB VG
OO: --mirrorlog MirrorLog, --regionsize RegionSize, --minrecoveryrate SizeKB, --maxrecoveryrate SizeKB, OO_LVCREATE
OP: PV ...
ID: lvcreate_mirror_or_raid1
-DESC: Create a raid1 or mirror LV (infers \\-\\-type raid1|mirror).
+DESC: Create a raid1 or mirror LV (infers --type raid1|mirror).
# R9,R10,R11,R12 (--type raid with any use of --stripes/--mirrors)
lvcreate --type raid --size SizeMB VG
@@ -838,7 +838,7 @@ OO: --snapshot, --stripes Number, --stripesize SizeKB,
OP: PV ...
ID: lvcreate_cow_snapshot
DESC: Create a COW snapshot LV of an origin LV
-DESC: (also see \\-\\-snapshot).
+DESC: (also see --snapshot).
FLAGS: SECONDARY_SYNTAX
lvcreate --snapshot --size SizeMB LV
@@ -856,7 +856,7 @@ OO: --snapshot, --chunksize SizeKB, OO_LVCREATE
OP: PV ...
ID: lvcreate_cow_snapshot_with_virtual_origin
DESC: Create a sparse COW snapshot LV of a virtual origin LV
-DESC: (also see \\-\\-snapshot).
+DESC: (also see --snapshot).
FLAGS: SECONDARY_SYNTAX
lvcreate --snapshot --size SizeMB --virtualsize SizeMB VG
@@ -883,7 +883,7 @@ OO: --type thin-pool, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE,
OP: PV ...
IO: --mirrors 0
ID: lvcreate_thinpool
-DESC: Create a thin pool (infers \\-\\-type thin-pool).
+DESC: Create a thin pool (infers --type thin-pool).
FLAGS: SECONDARY_SYNTAX
# alternate form of lvcreate --type thin-pool
@@ -893,8 +893,8 @@ OO: --thin, --type thin-pool, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE,
OP: PV ...
IO: --mirrors 0
ID: lvcreate_thinpool
-DESC: Create a thin pool named by the \\-\\-thinpool arg
-DESC: (infers \\-\\-type thin-pool).
+DESC: Create a thin pool named by the --thinpool arg
+DESC: (infers --type thin-pool).
FLAGS: SECONDARY_SYNTAX
---
@@ -915,8 +915,8 @@ lvcreate --type cache-pool --size SizeMB --cachepool LV_new VG
OO: --cache, OO_LVCREATE_POOL, OO_LVCREATE_CACHE, OO_LVCREATE
OP: PV ...
ID: lvcreate_cachepool
-DESC: Create a cache pool named by the \\-\\-cachepool arg
-DESC: (variant, uses \\-\\-cachepool in place of \\-\\-name).
+DESC: Create a cache pool named by the --cachepool arg
+DESC: (variant, uses --cachepool in place of --name).
FLAGS: SECONDARY_SYNTAX
---
@@ -934,7 +934,7 @@ OO: --thin, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_vol
DESC: Create a thin LV in a thin pool named in the first arg
-DESC: (variant, also see \\-\\-thinpool for naming pool).
+DESC: (variant, also see --thinpool for naming pool).
FLAGS: SECONDARY_SYNTAX
# NB. this is the variant which can substitute
@@ -945,7 +945,7 @@ lvcreate --virtualsize SizeMB --thinpool LV_thinpool VG
OO: --type thin, --thin, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_vol
-DESC: Create a thin LV in a thin pool (infers \\-\\-type thin).
+DESC: Create a thin LV in a thin pool (infers --type thin).
# alternate form of lvcreate --type thin
lvcreate --virtualsize SizeMB LV_thinpool
@@ -953,7 +953,7 @@ OO: --type thin, --thin, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_vol
DESC: Create a thin LV in the thin pool named in the first arg
-DESC: (variant, infers \\-\\-type thin, also see \\-\\-thinpool for
+DESC: (variant, infers --type thin, also see --thinpool for
DESC: naming pool.)
FLAGS: SECONDARY_SYNTAX
@@ -972,7 +972,7 @@ OO: --type thin, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_snapshot
DESC: Create a thin LV that is a snapshot of an existing thin LV
-DESC: (infers \\-\\-type thin).
+DESC: (infers --type thin).
FLAGS: SECONDARY_SYNTAX
# alternate form of lvcreate --type thin
@@ -981,7 +981,7 @@ OO: --type thin, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_snapshot
DESC: Create a thin LV that is a snapshot of an existing thin LV
-DESC: (infers \\-\\-type thin).
+DESC: (infers --type thin).
lvcreate --type thin --thinpool LV_thinpool LV
OO: --thin, OO_LVCREATE_POOL, OO_LVCREATE_THIN, OO_LVCREATE
@@ -995,7 +995,7 @@ OO: --type thin, OO_LVCREATE_THIN, OO_LVCREATE
IO: --mirrors 0
ID: lvcreate_thin_snapshot_of_external
DESC: Create a thin LV that is a snapshot of an external origin LV
-DESC: (infers \\-\\-type thin).
+DESC: (infers --type thin).
FLAGS: SECONDARY_SYNTAX
---
@@ -1023,7 +1023,7 @@ OP: PV ...
IO: --mirrors 0
ID: lvcreate_thin_vol_and_thinpool
DESC: Create a thin LV, first creating a thin pool for it,
-DESC: where the new thin pool is named by the \\-\\-thinpool arg.
+DESC: where the new thin pool is named by the --thinpool arg.
# alternate form of lvcreate --type thin
lvcreate --virtualsize SizeMB --size SizeMB --thinpool LV_new
@@ -1033,8 +1033,8 @@ OP: PV ...
IO: --mirrors 0
ID: lvcreate_thin_vol_and_thinpool
DESC: Create a thin LV, first creating a thin pool for it,
-DESC: where the new thin pool is named by the \\-\\-thinpool arg
-DESC: (variant, infers \\-\\-type thin).
+DESC: where the new thin pool is named by the --thinpool arg
+DESC: (variant, infers --type thin).
FLAGS: SECONDARY_SYNTAX
# same as prev but accepts VG pos arg
@@ -1046,8 +1046,8 @@ OP: PV ...
IO: --mirrors 0
ID: lvcreate_thin_vol_and_thinpool
DESC: Create a thin LV, first creating a thin pool for it,
-DESC: where the new thin pool is named by the \\-\\-thinpool arg
-DESC: (variant, infers \\-\\-type thin).
+DESC: where the new thin pool is named by the --thinpool arg
+DESC: (variant, infers --type thin).
FLAGS: SECONDARY_SYNTAX
# alternate form of lvcreate --type thin
@@ -1073,7 +1073,7 @@ ID: lvcreate_thin_vol_and_thinpool
DESC: Create a thin LV, first creating a thin pool for it,
DESC: where the new thin pool is named in the first arg,
DESC: or the new thin pool name is generated when the first
-DESC: arg is a VG name (variant, infers \\-\\-type thin).
+DESC: arg is a VG name (variant, infers --type thin).
FLAGS: SECONDARY_SYNTAX
---
@@ -1085,10 +1085,10 @@ OP: PV ...
IO: --mirrors 0
ID: lvcreate_thin_vol_with_thinpool_or_sparse_snapshot
DESC: Create a thin LV, first creating a thin pool for it
-DESC: (infers \\-\\-type thin).
+DESC: (infers --type thin).
DESC: Create a sparse snapshot of a virtual origin LV
-DESC: (infers \\-\\-type snapshot).
-DESC: Chooses \\-\\-type thin or \\-\\-type snapshot according to
+DESC: (infers --type snapshot).
+DESC: Chooses --type thin or --type snapshot according to
DESC: config setting sparse_segtype_default.
FLAGS: SECONDARY_SYNTAX
@@ -1105,7 +1105,7 @@ OP: PV ...
ID: lvcreate_cache_vol_with_new_origin
DESC: Create a cache LV, first creating a new origin LV,
DESC: then combining it with the existing cache pool named
-DESC: by the \\-\\-cachepool arg.
+DESC: by the --cachepool arg.
# alternate form of lvcreate --type cache
lvcreate --size SizeMB --cachepool LV_cachepool VG
@@ -1115,7 +1115,7 @@ OP: PV ...
ID: lvcreate_cache_vol_with_new_origin
DESC: Create a cache LV, first creating a new origin LV,
DESC: then combining it with the existing cache pool named
-DESC: by the \\-\\-cachepool arg (variant, infers \\-\\-type cache).
+DESC: by the --cachepool arg (variant, infers --type cache).
FLAGS: SECONDARY_SYNTAX
# alternate form of lvcreate --type cache
@@ -1126,7 +1126,7 @@ OP: PV ...
ID: lvcreate_cache_vol_with_new_origin
DESC: Create a cache LV, first creating a new origin LV,
DESC: then combining it with the existing cache pool named
-DESC: in the first arg (variant, also use \\-\\-cachepool).
+DESC: in the first arg (variant, also use --cachepool).
FLAGS: SECONDARY_SYNTAX
# This is a ridiculously crazy command which nobody could
@@ -1144,8 +1144,8 @@ FLAGS: SECONDARY_SYNTAX
# ID: lvcreate_cache_vol_with_new_origin
# DESC: Create a cache LV, first creating a new origin LV,
# DESC: then combining it with the existing cache pool named
-# DESC: in the first arg (variant, infers \\-\\-type cache,
-# DESC: also use \\-\\-cachepool).
+# DESC: in the first arg (variant, infers --type cache,
+# DESC: also use --cachepool).
#
# 2. If LV is not a cachepool, then it's a disguised lvconvert.
#
@@ -1175,7 +1175,7 @@ ID: lvcreate_cache_vol_with_new_origin_or_convert_to_cache_vol_with_cachepool
DESC: When LV is a cache pool, create a cache LV,
DESC: first creating a new origin LV, then combining it with
DESC: the existing cache pool named in the first arg
-DESC: (variant, infers \\-\\-type cache, also use \\-\\-cachepool).
+DESC: (variant, infers --type cache, also use --cachepool).
DESC: When LV is not a cache pool, convert the specified LV
DESC: to type cache after creating a new cache pool LV to use
DESC: (use lvconvert).
6 years, 4 months
master - vgchange: split out code for systemid
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1460cac27391ace1047...
Commit: 1460cac27391ace1047588bb915d2734e4703fa6
Parent: 07cd88dcfa1411f23f5c0c8189377eee8ea2ee50
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Jul 13 13:43:39 2017 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jul 24 14:12:08 2017 -0500
vgchange: split out code for systemid
Use the command definitions to separate the implementation
of vgchange systemid from the rest of vgchange.
---
tools/command-lines.in | 6 ++-
tools/lvmcmdline.c | 1 +
tools/tools.h | 1 +
tools/vgchange.c | 112 ++++++++++++++++++++++++++----------------------
4 files changed, 68 insertions(+), 52 deletions(-)
diff --git a/tools/command-lines.in b/tools/command-lines.in
index 4cfbe74..f2ad915 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -1474,7 +1474,7 @@ OO_VGCHANGE: --autobackup Bool, --ignoremonitoring, --ignoreskippedcluster,
OO_VGCHANGE_META: --addtag Tag, --deltag Tag,
--logicalvolume Uint32, --maxphysicalvolumes Uint32, --alloc Alloc, --uuid,
--clustered Bool, --pvmetadatacopies MetadataCopiesPV, --vgmetadatacopies MetadataCopiesVG,
---physicalextentsize SizeMB, --resizeable Bool, --systemid String,
+--physicalextentsize SizeMB, --resizeable Bool,
--profile String, --detachprofile, --metadataprofile String
vgchange OO_VGCHANGE_META
@@ -1510,6 +1510,10 @@ OP: VG|Tag|Select ...
ID: vgchange_refresh
DESC: Reactivate LVs using the latest metadata.
+vgchange --systemid String VG
+ID: vgchange_systemid
+DESC: Change the system ID of a VG.
+
vgchange --lockstart
OO: --lockopt String, --select String
OP: VG|Tag|Select ...
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index dda75c6..ae55e12 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -106,6 +106,7 @@ static const struct command_function command_functions[CMD_COUNT] = {
{ vgchange_locktype_CMD, vgchange_locktype_cmd },
{ vgchange_lockstart_CMD, vgchange_lock_start_stop_cmd },
{ vgchange_lockstop_CMD, vgchange_lock_start_stop_cmd },
+ { vgchange_systemid_CMD, vgchange_systemid_cmd },
/* lvconvert utilities related to repair. */
{ lvconvert_repair_pvs_or_thinpool_CMD, lvconvert_repair_pvs_or_thinpool_cmd },
diff --git a/tools/tools.h b/tools/tools.h
index b2ddad2..ba4edeb 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -225,6 +225,7 @@ int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg
int vgchange_locktype_cmd(struct cmd_context *cmd, int argc, char **argv);
int vgchange_lock_start_stop_cmd(struct cmd_context *cmd, int argc, char **argv);
+int vgchange_systemid_cmd(struct cmd_context *cmd, int argc, char **argv);
struct lv_prop *get_lv_prop(int lvp_enum);
struct lv_type *get_lv_type(int lvt_enum);
diff --git a/tools/vgchange.c b/tools/vgchange.c
index 43ad962..263b5a6 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -690,7 +690,6 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
struct volume_group *vg,
struct processing_handle *handle)
{
- struct vgchange_params *vp = (struct vgchange_params *)handle->custom_handle;
int ret = ECMD_PROCESSED;
unsigned i;
struct lv_list *lvl;
@@ -712,7 +711,6 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
{ metadataprofile_ARG, &_vgchange_profile },
{ profile_ARG, &_vgchange_profile },
{ detachprofile_ARG, &_vgchange_profile },
- { systemid_ARG, &_vgchange_system_id },
};
if (vg_is_exported(vg)) {
@@ -803,51 +801,6 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
return ret;
}
-/*
- * vgchange can do different things that require different
- * locking, so look at each of those things here.
- *
- * Set up overrides for the default VG locking for various special cases.
- * The VG lock will be acquired in process_each_vg.
- *
- * Acquire the gl lock according to which kind of vgchange command this is.
- */
-
-static int _lockd_vgchange(struct cmd_context *cmd, int argc, char **argv)
-{
- /* The default vg lock mode is ex, but these options only need sh. */
-
- if (arg_is_set(cmd, activate_ARG) || arg_is_set(cmd, refresh_ARG)) {
- cmd->lockd_vg_default_sh = 1;
- /* Allow deactivating if locks fail. */
- if (is_change_activating((activation_change_t)arg_uint_value(cmd, activate_ARG, CHANGE_AY)))
- cmd->lockd_vg_enforce_sh = 1;
- }
-
- /*
- * Changing system_id or lock_type must only be done on explicitly
- * named vgs.
- */
-
- if (arg_is_set(cmd, systemid_ARG))
- cmd->cname->flags &= ~ALL_VGS_IS_DEFAULT;
-
- if (arg_is_set(cmd, systemid_ARG)) {
- /*
- * This is a special case where taking the global lock is
- * not needed to protect global state, because the change is
- * only to an existing VG. But, taking the global lock ex is
- * helpful in this case to trigger a global cache validation
- * on other hosts, to cause them to see the new system_id or
- * lock_type.
- */
- if (!lockd_gl(cmd, "ex", LDGL_UPDATE_NAMES))
- return 0;
- }
-
- return 1;
-}
-
int vgchange(struct cmd_context *cmd, int argc, char **argv)
{
struct processing_handle *handle;
@@ -875,8 +828,7 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
arg_is_set(cmd, physicalextentsize_ARG) ||
arg_is_set(cmd, clustered_ARG) ||
arg_is_set(cmd, alloc_ARG) ||
- arg_is_set(cmd, vgmetadatacopies_ARG) ||
- arg_is_set(cmd, systemid_ARG);
+ arg_is_set(cmd, vgmetadatacopies_ARG);
int update = update_partial_safe || update_partial_unsafe;
@@ -964,8 +916,14 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
if (arg_is_set(cmd, activate_ARG))
cmd->include_active_foreign_vgs = 1;
- if (!_lockd_vgchange(cmd, argc, argv))
- return_ECMD_FAILED;
+ /* The default vg lock mode is ex, but these options only need sh. */
+ if ((cmd->command->command_enum == vgchange_activate_CMD) ||
+ (cmd->command->command_enum == vgchange_refresh_CMD)) {
+ cmd->lockd_vg_default_sh = 1;
+ /* Allow deactivating if locks fail. */
+ if (is_change_activating((activation_change_t)arg_uint_value(cmd, activate_ARG, CHANGE_AY)))
+ cmd->lockd_vg_enforce_sh = 1;
+ }
if (update)
flags |= READ_FOR_UPDATE;
@@ -1360,3 +1318,55 @@ int vgchange_lock_start_stop_cmd(struct cmd_context *cmd, int argc, char **argv)
return ret;
}
+static int _vgchange_systemid_single(struct cmd_context *cmd, const char *vg_name,
+ struct volume_group *vg,
+ struct processing_handle *handle)
+{
+ if (vg_is_exported(vg)) {
+ log_error("Volume group \"%s\" is exported", vg_name);
+ return ECMD_FAILED;
+ }
+
+ if (!archive(vg))
+ return_ECMD_FAILED;
+
+ if (!_vgchange_system_id(cmd, vg))
+ return_ECMD_FAILED;
+
+ if (!vg_write(vg) || !vg_commit(vg))
+ return_ECMD_FAILED;
+
+ backup(vg);
+
+ log_print_unless_silent("Volume group \"%s\" successfully changed", vg->name);
+
+ return ECMD_PROCESSED;
+}
+
+int vgchange_systemid_cmd(struct cmd_context *cmd, int argc, char **argv)
+{
+ struct processing_handle *handle;
+ int ret;
+
+ /*
+ * This is a special case where taking the global lock is
+ * not needed to protect global state, because the change is
+ * only to an existing VG. But, taking the global lock ex is
+ * helpful in this case to trigger a global cache validation
+ * on other hosts, to cause them to see the new system_id or
+ * lock_type.
+ */
+ if (!lockd_gl(cmd, "ex", LDGL_UPDATE_NAMES))
+ return 0;
+
+ if (!(handle = init_processing_handle(cmd, NULL))) {
+ log_error("Failed to initialize processing handle.");
+ return ECMD_FAILED;
+ }
+
+ ret = process_each_vg(cmd, argc, argv, NULL, NULL, READ_FOR_UPDATE, 0, handle, &_vgchange_systemid_single);
+
+ destroy_processing_handle(cmd, handle);
+ return ret;
+}
+
6 years, 4 months
master - vgchange: split out code for lockstart and lockstop
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=07cd88dcfa1411f23f5...
Commit: 07cd88dcfa1411f23f5c0c8189377eee8ea2ee50
Parent: f611b68f3c02b9af2521d7ea61061af3709fe87c
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu Jul 13 13:26:10 2017 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jul 24 14:12:08 2017 -0500
vgchange: split out code for lockstart and lockstop
Use the command definitions to separate the implementation
of lockstop and lockstart from the rest of vgchange.
---
tools/command-lines.in | 4 +-
tools/lvmcmdline.c | 2 +
tools/tools.h | 1 +
tools/vgchange.c | 149 +++++++++++++++++++++++++++---------------------
4 files changed, 89 insertions(+), 67 deletions(-)
diff --git a/tools/command-lines.in b/tools/command-lines.in
index da097af..4cfbe74 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -1511,13 +1511,13 @@ ID: vgchange_refresh
DESC: Reactivate LVs using the latest metadata.
vgchange --lockstart
-OO: --lockopt String, OO_VGCHANGE
+OO: --lockopt String, --select String
OP: VG|Tag|Select ...
ID: vgchange_lockstart
DESC: Start the lockspace of a shared VG in lvmlockd.
vgchange --lockstop
-OO: --lockopt String, OO_VGCHANGE
+OO: --lockopt String, --select String
OP: VG|Tag|Select ...
ID: vgchange_lockstop
DESC: Stop the lockspace of a shared VG in lvmlockd.
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index f23e994..dda75c6 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -104,6 +104,8 @@ static const struct command_function command_functions[CMD_COUNT] = {
{ lvchange_persistent_CMD, lvchange_persistent_cmd },
{ vgchange_locktype_CMD, vgchange_locktype_cmd },
+ { vgchange_lockstart_CMD, vgchange_lock_start_stop_cmd },
+ { vgchange_lockstop_CMD, vgchange_lock_start_stop_cmd },
/* lvconvert utilities related to repair. */
{ lvconvert_repair_pvs_or_thinpool_CMD, lvconvert_repair_pvs_or_thinpool_cmd },
diff --git a/tools/tools.h b/tools/tools.h
index 8255cdc..b2ddad2 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -224,6 +224,7 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg);
int vgchange_locktype_cmd(struct cmd_context *cmd, int argc, char **argv);
+int vgchange_lock_start_stop_cmd(struct cmd_context *cmd, int argc, char **argv);
struct lv_prop *get_lv_prop(int lvp_enum);
struct lv_type *get_lv_type(int lvt_enum);
diff --git a/tools/vgchange.c b/tools/vgchange.c
index dc453f8..43ad962 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -715,8 +715,7 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
{ systemid_ARG, &_vgchange_system_id },
};
- if (vg_is_exported(vg) &&
- !(arg_is_set(cmd, lockstop_ARG) || arg_is_set(cmd, lockstart_ARG))) {
+ if (vg_is_exported(vg)) {
log_error("Volume group \"%s\" is exported", vg_name);
return ECMD_FAILED;
}
@@ -801,15 +800,7 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
!vgchange_background_polling(cmd, vg))
return_ECMD_FAILED;
- if (arg_is_set(cmd, lockstart_ARG)) {
- if (!_vgchange_lock_start(cmd, vg, vp))
- return_ECMD_FAILED;
- } else if (arg_is_set(cmd, lockstop_ARG)) {
- if (!_vgchange_lock_stop(cmd, vg))
- return_ECMD_FAILED;
- }
-
- return ret;
+ return ret;
}
/*
@@ -826,11 +817,6 @@ static int _lockd_vgchange(struct cmd_context *cmd, int argc, char **argv)
{
/* The default vg lock mode is ex, but these options only need sh. */
- if (!lvmlockd_use() && (arg_is_set(cmd, lockstart_ARG) || arg_is_set(cmd, lockstop_ARG))) {
- log_error("Using lock start and lock stop requires lvmlockd.");
- return 0;
- }
-
if (arg_is_set(cmd, activate_ARG) || arg_is_set(cmd, refresh_ARG)) {
cmd->lockd_vg_default_sh = 1;
/* Allow deactivating if locks fail. */
@@ -838,29 +824,6 @@ static int _lockd_vgchange(struct cmd_context *cmd, int argc, char **argv)
cmd->lockd_vg_enforce_sh = 1;
}
- if (arg_is_set(cmd, lockstop_ARG))
- cmd->lockd_vg_default_sh = 1;
-
- /*
- * Starting lockspaces. For VGs not yet started, locks are not
- * available to acquire, and for VGs already started, there's nothing
- * to do, so disable VG locks. Try to acquire the global lock sh to
- * validate the cache (if no gl is available, lockd_gl will force a
- * cache validation). If the global lock is available, it can be
- * benficial to hold sh to serialize lock-start with vgremove of the
- * same VG from another host.
- */
- if (arg_is_set(cmd, lockstart_ARG)) {
- cmd->lockd_vg_disable = 1;
-
- if (!lockd_gl(cmd, "sh", 0))
- log_debug("No global lock for lock start");
-
- /* Disable the lockd_gl in process_each_vg. */
- cmd->lockd_gl_disable = 1;
- return 1;
- }
-
/*
* Changing system_id or lock_type must only be done on explicitly
* named vgs.
@@ -888,14 +851,11 @@ static int _lockd_vgchange(struct cmd_context *cmd, int argc, char **argv)
int vgchange(struct cmd_context *cmd, int argc, char **argv)
{
struct processing_handle *handle;
- struct vgchange_params vp = { 0 };
uint32_t flags = 0;
int ret;
int noupdate =
arg_is_set(cmd, activate_ARG) ||
- arg_is_set(cmd, lockstart_ARG) ||
- arg_is_set(cmd, lockstop_ARG) ||
arg_is_set(cmd, monitor_ARG) ||
arg_is_set(cmd, poll_ARG) ||
arg_is_set(cmd, refresh_ARG);
@@ -1009,37 +969,14 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
if (update)
flags |= READ_FOR_UPDATE;
- if (arg_is_set(cmd, lockstart_ARG) || arg_is_set(cmd, lockstop_ARG))
- flags |= READ_ALLOW_EXPORTED;
if (!(handle = init_processing_handle(cmd, NULL))) {
log_error("Failed to initialize processing handle.");
return ECMD_FAILED;
}
- handle->custom_handle = &vp;
-
ret = process_each_vg(cmd, argc, argv, NULL, NULL, flags, 0, handle, &vgchange_single);
- /* Wait for lock-start ops that were initiated in vgchange_lockstart. */
-
- if (arg_is_set(cmd, lockstart_ARG) && vp.lock_start_count) {
- const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
-
- if (!lockd_gl(cmd, "un", 0))
- stack;
-
- if (!start_opt || !strcmp(start_opt, "auto")) {
- if (vp.lock_start_sanlock)
- log_print_unless_silent("Starting locking. Waiting for sanlock may take 20 sec to 3 min...");
- else
- log_print_unless_silent("Starting locking. Waiting until locks are ready...");
- lockd_start_wait(cmd);
- } else if (!strcmp(start_opt, "nowait") || !strcmp(start_opt, "autonowait")) {
- log_print_unless_silent("Starting locking. VG can only be read until locks are ready.");
- }
- }
-
destroy_processing_handle(cmd, handle);
return ret;
}
@@ -1341,3 +1278,85 @@ process:
return ret;
}
+static int _vgchange_lock_start_stop_single(struct cmd_context *cmd, const char *vg_name,
+ struct volume_group *vg,
+ struct processing_handle *handle)
+{
+ struct vgchange_params *vp = (struct vgchange_params *)handle->custom_handle;
+
+ if (arg_is_set(cmd, lockstart_ARG)) {
+ if (!_vgchange_lock_start(cmd, vg, vp))
+ return_ECMD_FAILED;
+ } else if (arg_is_set(cmd, lockstop_ARG)) {
+ if (!_vgchange_lock_stop(cmd, vg))
+ return_ECMD_FAILED;
+ }
+
+ return ECMD_PROCESSED;
+}
+
+int vgchange_lock_start_stop_cmd(struct cmd_context *cmd, int argc, char **argv)
+{
+ struct processing_handle *handle;
+ struct vgchange_params vp = { 0 };
+ int ret;
+
+ if (!lvmlockd_use()) {
+ log_error("Using lock start and lock stop requires lvmlockd.");
+ return 0;
+ }
+
+ if (!(handle = init_processing_handle(cmd, NULL))) {
+ log_error("Failed to initialize processing handle.");
+ return ECMD_FAILED;
+ }
+
+ if (arg_is_set(cmd, lockstop_ARG))
+ cmd->lockd_vg_default_sh = 1;
+
+ /*
+ * Starting lockspaces. For VGs not yet started, locks are not
+ * available to acquire, and for VGs already started, there's nothing
+ * to do, so disable VG locks. Try to acquire the global lock sh to
+ * validate the cache (if no gl is available, lockd_gl will force a
+ * cache validation). If the global lock is available, it can be
+ * benficial to hold sh to serialize lock-start with vgremove of the
+ * same VG from another host.
+ */
+ if (arg_is_set(cmd, lockstart_ARG)) {
+ cmd->lockd_vg_disable = 1;
+
+ if (!lockd_gl(cmd, "sh", 0))
+ log_debug("No global lock for lock start");
+
+ /* Disable the lockd_gl in process_each_vg. */
+ cmd->lockd_gl_disable = 1;
+ }
+
+ handle->custom_handle = &vp;
+
+ ret = process_each_vg(cmd, argc, argv, NULL, NULL, READ_ALLOW_EXPORTED, 0, handle, &_vgchange_lock_start_stop_single);
+
+ /* Wait for lock-start ops that were initiated in vgchange_lockstart. */
+
+ if (arg_is_set(cmd, lockstart_ARG) && vp.lock_start_count) {
+ const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
+
+ if (!lockd_gl(cmd, "un", 0))
+ stack;
+
+ if (!start_opt || !strcmp(start_opt, "auto")) {
+ if (vp.lock_start_sanlock)
+ log_print_unless_silent("Starting locking. Waiting for sanlock may take 20 sec to 3 min...");
+ else
+ log_print_unless_silent("Starting locking. Waiting until locks are ready...");
+ lockd_start_wait(cmd);
+ } else if (!strcmp(start_opt, "nowait") || !strcmp(start_opt, "autonowait")) {
+ log_print_unless_silent("Starting locking. VG can only be read until locks are ready.");
+ }
+ }
+
+ destroy_processing_handle(cmd, handle);
+ return ret;
+}
+
6 years, 4 months
master - vgchange: separate change locktype and allow recovery
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f611b68f3c02b9af252...
Commit: f611b68f3c02b9af2521d7ea61061af3709fe87c
Parent: 876c4a1b3bdf2d2f9202438a406a803efa01bf9a
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jul 12 16:03:41 2017 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jul 24 14:12:08 2017 -0500
vgchange: separate change locktype and allow recovery
Add an independent command definition for "vgchange --locktype",
and split the implementation out of the set of common metadata
changes. It is unlike normal metadata changes, and can only
be run by itself. (Changing the lock type is similar in
principle to changing the VG name or the VG system ID; it
effects the ability of any host to see or access the VG.)
At some point this command lost the ability to forcibly change
the lock type of a shared VG to "none" (making it a local VG).
This can be necessary to repair shared VGs (e.g. recovery steps
that occur in vg_read are disabled for shared VGs because
they are not locked properly, or recovering sanlock locks
when the PV holding them is lost.)
"vgchange --locktype none --lockopt force VG" is used as the
method of forcing the shared VG to become local so that it
can be repaired.
---
man/lvmlockd.8_main | 24 ++-
tools/command-lines.in | 7 +-
tools/lvmcmdline.c | 2 +
tools/tools.h | 2 +
tools/vgchange.c | 531 +++++++++++++++++++++++++++---------------------
5 files changed, 329 insertions(+), 237 deletions(-)
diff --git a/man/lvmlockd.8_main b/man/lvmlockd.8_main
index 552eb94..1dbdaf9 100644
--- a/man/lvmlockd.8_main
+++ b/man/lvmlockd.8_main
@@ -610,12 +610,26 @@ The command deactivates the LV. After deactivating the LV, the command
uses lvmlockd to release the current lock on the LV.
+.SS manually repairing a shared VG
+
+Some failure conditions may not be repairable while the VG has a shared
+lock type. In these cases, it may be possible to repair the VG by
+forcibly changing the lock type to "none". This is done by adding
+"--lock-opt force" to the normal command for changing the lock type:
+vgchange --lock-type none VG. The VG lockspace should first be stopped on
+all hosts, and be certain that no hosts are using the VG before this is
+done.
+
+
.SS recover from lost PV holding sanlock locks
-The general approach is to change the VG lock type to "none", and then
-change the lock type back to "sanlock". This recreates the internal
-lvmlock LV and the necessary locks on it. Additional steps may be
-required to deal with the missing PV.
+In a sanlock VG, the sanlock locks are held on the hidden "lvmlock" LV.
+If the PV holding this LV is lost, a new lvmlock LV needs to be created.
+To do this, ensure no hosts are using the VG, then forcibly change the
+lock type to "none" (see above). Then change the lock type back to
+"sanlock" with the normal command for changing the lock type: vgchange
+--lock-type sanlock VG. This recreates the internal lvmlock LV with the
+necessary locks.
.SS locking system failures
@@ -733,7 +747,7 @@ cat /sys/kernel/config/dlm/cluster/cluster_name
.IP \[bu] 2
Change the VG lock type to none:
.br
-vgchange --lock-type none --force <vgname>
+vgchange --lock-type none --lock-opt force <vgname>
.IP \[bu] 2
Change the VG lock type back to dlm which sets the new cluster name:
diff --git a/tools/command-lines.in b/tools/command-lines.in
index 7f9c31f..da097af 100644
--- a/tools/command-lines.in
+++ b/tools/command-lines.in
@@ -1474,7 +1474,7 @@ OO_VGCHANGE: --autobackup Bool, --ignoremonitoring, --ignoreskippedcluster,
OO_VGCHANGE_META: --addtag Tag, --deltag Tag,
--logicalvolume Uint32, --maxphysicalvolumes Uint32, --alloc Alloc, --uuid,
--clustered Bool, --pvmetadatacopies MetadataCopiesPV, --vgmetadatacopies MetadataCopiesVG,
---physicalextentsize SizeMB, --resizeable Bool, --systemid String, --locktype LockType,
+--physicalextentsize SizeMB, --resizeable Bool, --systemid String,
--profile String, --detachprofile, --metadataprofile String
vgchange OO_VGCHANGE_META
@@ -1522,6 +1522,11 @@ OP: VG|Tag|Select ...
ID: vgchange_lockstop
DESC: Stop the lockspace of a shared VG in lvmlockd.
+vgchange --locktype LockType VG
+OO: --lockopt String
+ID: vgchange_locktype
+DESC: Change the lock type for a shared VG.
+
---
vgck
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index a952c8c..f23e994 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -103,6 +103,8 @@ static const struct command_function command_functions[CMD_COUNT] = {
{ lvchange_poll_CMD, lvchange_monitor_poll_cmd },
{ lvchange_persistent_CMD, lvchange_persistent_cmd },
+ { vgchange_locktype_CMD, vgchange_locktype_cmd },
+
/* lvconvert utilities related to repair. */
{ lvconvert_repair_pvs_or_thinpool_CMD, lvconvert_repair_pvs_or_thinpool_cmd },
{ lvconvert_replace_pv_CMD, lvconvert_replace_pv_cmd },
diff --git a/tools/tools.h b/tools/tools.h
index 9543147..8255cdc 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -223,6 +223,8 @@ int vgchange_activate(struct cmd_context *cmd, struct volume_group *vg,
int vgchange_background_polling(struct cmd_context *cmd, struct volume_group *vg);
+int vgchange_locktype_cmd(struct cmd_context *cmd, int argc, char **argv);
+
struct lv_prop *get_lv_prop(int lvp_enum);
struct lv_type *get_lv_type(int lvt_enum);
struct command *get_command(int cmd_enum);
diff --git a/tools/vgchange.c b/tools/vgchange.c
index 2a8f868..dc453f8 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -528,228 +528,6 @@ static int _vgchange_profile(struct cmd_context *cmd,
return 1;
}
-static int _vgchange_locktype(struct cmd_context *cmd,
- struct volume_group *vg)
-{
- const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
- struct lv_list *lvl;
- struct logical_volume *lv;
- int lv_lock_count = 0;
-
- if (!lock_type) {
- log_error(INTERNAL_ERROR "No locktype_ARG.");
- return 0;
- }
-
- /*
- * This is a special/forced exception to change the lock type to none.
- * It's needed for recovery cases and skips the normal steps of undoing
- * the current lock type. It's a way to forcibly get access to a VG
- * when the normal locking mechanisms are not working.
- *
- * It ignores: the current lvm locking config, lvmlockd, the state of
- * the vg on other hosts, etc. It is meant to just remove any locking
- * related metadata from the VG (cluster/lock_type flags, lock_type,
- * lock_args).
- *
- * This can be necessary when manually recovering from certain failures.
- * e.g. when a pv is lost containing the lvmlock lv (holding sanlock
- * leases), the vg lock_type needs to be changed to none, and then
- * back to sanlock, which recreates the lvmlock lv and leases.
- */
- if (!strcmp(lock_type, "none") && arg_is_set(cmd, force_ARG)) {
- if (yes_no_prompt("Forcibly change VG %s lock type to none? [y/n]: ", vg->name) == 'n') {
- log_error("VG lock type not changed.");
- return 0;
- }
-
- vg->status &= ~CLUSTERED;
- vg->lock_type = "none";
- vg->lock_args = NULL;
-
- dm_list_iterate_items(lvl, &vg->lvs)
- lvl->lv->lock_args = NULL;
-
- return 1;
- }
-
- if (!vg->lock_type) {
- if (vg_is_clustered(vg))
- vg->lock_type = "clvm";
- else
- vg->lock_type = "none";
- }
-
- if (!strcmp(vg->lock_type, lock_type)) {
- log_warn("New lock type %s matches the current lock type %s.",
- lock_type, vg->lock_type);
- return 1;
- }
-
- if (is_lockd_type(vg->lock_type) && is_lockd_type(lock_type)) {
- log_error("Cannot change lock type directly from \"%s\" to \"%s\".",
- vg->lock_type, lock_type);
- log_error("First change lock type to \"none\", then to \"%s\".",
- lock_type);
- return 0;
- }
-
- /*
- * When lvm is currently using clvm, this function is just an alternative
- * to vgchange -c{y,n}, and can:
- * - change none to clvm
- * - change clvm to none
- * - it CANNOT change to or from a lockd type
- */
- if (locking_is_clustered()) {
- if (is_lockd_type(lock_type)) {
- log_error("Changing to lock type %s requires lvmlockd.", lock_type);
- return 0;
- }
-
- return _vgchange_clustered(cmd, vg);
- }
-
- /*
- * When lvm is currently using lvmlockd, this function can:
- * - change none to lockd type
- * - change none to clvm (with warning about not being able to use it)
- * - change lockd type to none
- * - change lockd type to clvm (with warning about not being able to use it)
- * - change clvm to none
- * - change clvm to lockd type
- */
-
- if (lvs_in_vg_activated(vg)) {
- log_error("Changing VG %s lock type not allowed with active LVs",
- vg->name);
- return 0;
- }
-
- /* none to clvm */
- if (!strcmp(vg->lock_type, "none") && !strcmp(lock_type, "clvm")) {
- log_warn("New clvm lock type will not be usable with lvmlockd.");
- vg->status |= CLUSTERED;
- vg->lock_type = "clvm"; /* this is optional */
- return 1;
- }
-
- /* clvm to none */
- if (!strcmp(vg->lock_type, "clvm") && !strcmp(lock_type, "none")) {
- vg->status &= ~CLUSTERED;
- vg->lock_type = "none";
- return 1;
- }
-
- /* clvm to ..., first undo clvm */
- if (!strcmp(vg->lock_type, "clvm")) {
- vg->status &= ~CLUSTERED;
- }
-
- /*
- * lockd type to ..., first undo lockd type
- */
- if (is_lockd_type(vg->lock_type)) {
- if (!lockd_free_vg_before(cmd, vg, 1))
- return 0;
-
- lockd_free_vg_final(cmd, vg);
-
- vg->status &= ~CLUSTERED;
- vg->lock_type = "none";
- vg->lock_args = NULL;
-
- dm_list_iterate_items(lvl, &vg->lvs)
- lvl->lv->lock_args = NULL;
- }
-
- /* ... to clvm */
- if (!strcmp(lock_type, "clvm")) {
- log_warn("New clvm lock type will not be usable with lvmlockd.");
- vg->status |= CLUSTERED;
- vg->lock_type = "clvm"; /* this is optional */
- vg->system_id = NULL;
- return 1;
- }
-
- /* ... to lockd type */
- if (is_lockd_type(lock_type)) {
- /*
- * For lock_type dlm, lockd_init_vg() will do a single
- * vg_write() that sets lock_type, sets lock_args, clears
- * system_id, and sets all LV lock_args to dlm.
- * For lock_type sanlock, lockd_init_vg() needs to know
- * how many LV locks are needed so that it can make the
- * sanlock lv large enough.
- */
- dm_list_iterate_items(lvl, &vg->lvs) {
- lv = lvl->lv;
-
- if (lockd_lv_uses_lock(lv)) {
- lv_lock_count++;
-
- if (!strcmp(lock_type, "dlm"))
- lv->lock_args = "dlm";
- }
- }
-
- /*
- * See below. We cannot set valid LV lock_args until stage 1
- * of the change is done, so we need to skip the validation of
- * the lock_args during stage 1.
- */
- if (!strcmp(lock_type, "sanlock"))
- vg->skip_validate_lock_args = 1;
-
- vg->system_id = NULL;
-
- if (!lockd_init_vg(cmd, vg, lock_type, lv_lock_count)) {
- log_error("Failed to initialize lock args for lock type %s", lock_type);
- return 0;
- }
-
- /*
- * For lock_type sanlock, there must be multiple steps
- * because the VG needs an active lvmlock LV before
- * LV lock areas can be allocated, which must be done
- * before LV lock_args are written. So, the LV lock_args
- * remain unset during the first stage of the conversion.
- *
- * Stage 1:
- * lockd_init_vg() creates and activates the lvmlock LV,
- * then sets lock_type, sets lock_args, and clears system_id.
- *
- * Stage 2:
- * We get here, and can now set LV lock_args. This uses
- * the standard code path for allocating LV locks in
- * vg_write() by setting LV lock_args to "pending",
- * which tells vg_write() to call lockd_init_lv()
- * and sets the lv->lock_args value before writing the VG.
- */
- if (!strcmp(lock_type, "sanlock")) {
- dm_list_iterate_items(lvl, &vg->lvs) {
- lv = lvl->lv;
- if (lockd_lv_uses_lock(lv))
- lv->lock_args = "pending";
- }
-
- vg->skip_validate_lock_args = 0;
- }
-
- return 1;
- }
-
- /* ... to none */
- if (!strcmp(lock_type, "none")) {
- vg->lock_type = NULL;
- vg->system_id = cmd->system_id ? dm_pool_strdup(vg->vgmem, cmd->system_id) : NULL;
- return 1;
- }
-
- log_error("Cannot change to unknown lock type %s", lock_type);
- return 0;
-}
-
/*
* This function will not be called unless the local host is allowed to use the
* VG. Either the VG has no system_id, or the VG and host have matching
@@ -934,7 +712,6 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
{ metadataprofile_ARG, &_vgchange_profile },
{ profile_ARG, &_vgchange_profile },
{ detachprofile_ARG, &_vgchange_profile },
- { locktype_ARG, &_vgchange_locktype },
{ systemid_ARG, &_vgchange_system_id },
};
@@ -1049,11 +826,6 @@ static int _lockd_vgchange(struct cmd_context *cmd, int argc, char **argv)
{
/* The default vg lock mode is ex, but these options only need sh. */
- if (!lvmlockd_use() && arg_is_set(cmd, locktype_ARG)) {
- log_error("Using lock type requires lvmlockd.");
- return 0;
- }
-
if (!lvmlockd_use() && (arg_is_set(cmd, lockstart_ARG) || arg_is_set(cmd, lockstop_ARG))) {
log_error("Using lock start and lock stop requires lvmlockd.");
return 0;
@@ -1094,10 +866,10 @@ static int _lockd_vgchange(struct cmd_context *cmd, int argc, char **argv)
* named vgs.
*/
- if (arg_is_set(cmd, systemid_ARG) || arg_is_set(cmd, locktype_ARG))
+ if (arg_is_set(cmd, systemid_ARG))
cmd->cname->flags &= ~ALL_VGS_IS_DEFAULT;
- if (arg_is_set(cmd, systemid_ARG) || arg_is_set(cmd, locktype_ARG)) {
+ if (arg_is_set(cmd, systemid_ARG)) {
/*
* This is a special case where taking the global lock is
* not needed to protect global state, because the change is
@@ -1144,7 +916,6 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
arg_is_set(cmd, clustered_ARG) ||
arg_is_set(cmd, alloc_ARG) ||
arg_is_set(cmd, vgmetadatacopies_ARG) ||
- arg_is_set(cmd, locktype_ARG) ||
arg_is_set(cmd, systemid_ARG);
int update = update_partial_safe || update_partial_unsafe;
@@ -1272,3 +1043,301 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
destroy_processing_handle(cmd, handle);
return ret;
}
+
+static int _vgchange_locktype(struct cmd_context *cmd, struct volume_group *vg)
+{
+ const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
+ const char *lockopt = arg_str_value(cmd, lockopt_ARG, NULL);
+ struct lv_list *lvl;
+ struct logical_volume *lv;
+ int lv_lock_count = 0;
+
+ /* Special recovery case. */
+ if (lockopt && !strcmp(lock_type, "none") && !strcmp(lockopt, "force")) {
+ vg->status &= ~CLUSTERED;
+ vg->lock_type = "none";
+ vg->lock_args = NULL;
+
+ dm_list_iterate_items(lvl, &vg->lvs)
+ lvl->lv->lock_args = NULL;
+
+ return 1;
+ }
+
+ if (!vg->lock_type) {
+ if (vg_is_clustered(vg))
+ vg->lock_type = "clvm";
+ else
+ vg->lock_type = "none";
+ }
+
+ if (!strcmp(vg->lock_type, lock_type)) {
+ log_warn("New lock type %s matches the current lock type %s.",
+ lock_type, vg->lock_type);
+ return 1;
+ }
+
+ if (is_lockd_type(vg->lock_type) && is_lockd_type(lock_type)) {
+ log_error("Cannot change lock type directly from \"%s\" to \"%s\".",
+ vg->lock_type, lock_type);
+ log_error("First change lock type to \"none\", then to \"%s\".",
+ lock_type);
+ return 0;
+ }
+
+ /*
+ * When lvm is currently using clvm, this function is just an alternative
+ * to vgchange -c{y,n}, and can:
+ * - change none to clvm
+ * - change clvm to none
+ * - it CANNOT change to or from a lockd type
+ */
+ if (locking_is_clustered()) {
+ if (is_lockd_type(lock_type)) {
+ log_error("Changing to lock type %s requires lvmlockd.", lock_type);
+ return 0;
+ }
+
+ return _vgchange_clustered(cmd, vg);
+ }
+
+ /*
+ * When lvm is currently using lvmlockd, this function can:
+ * - change none to lockd type
+ * - change none to clvm (with warning about not being able to use it)
+ * - change lockd type to none
+ * - change lockd type to clvm (with warning about not being able to use it)
+ * - change clvm to none
+ * - change clvm to lockd type
+ */
+
+ if (lvs_in_vg_activated(vg)) {
+ log_error("Changing VG %s lock type not allowed with active LVs",
+ vg->name);
+ return 0;
+ }
+
+ /* none to clvm */
+ if (!strcmp(vg->lock_type, "none") && !strcmp(lock_type, "clvm")) {
+ log_warn("New clvm lock type will not be usable with lvmlockd.");
+ vg->status |= CLUSTERED;
+ vg->lock_type = "clvm"; /* this is optional */
+ return 1;
+ }
+
+ /* clvm to none */
+ if (!strcmp(vg->lock_type, "clvm") && !strcmp(lock_type, "none")) {
+ vg->status &= ~CLUSTERED;
+ vg->lock_type = "none";
+ return 1;
+ }
+
+ /* clvm to ..., first undo clvm */
+ if (!strcmp(vg->lock_type, "clvm")) {
+ vg->status &= ~CLUSTERED;
+ }
+
+ /*
+ * lockd type to ..., first undo lockd type
+ */
+ if (is_lockd_type(vg->lock_type)) {
+ if (!lockd_free_vg_before(cmd, vg, 1))
+ return 0;
+
+ lockd_free_vg_final(cmd, vg);
+
+ vg->status &= ~CLUSTERED;
+ vg->lock_type = "none";
+ vg->lock_args = NULL;
+
+ dm_list_iterate_items(lvl, &vg->lvs)
+ lvl->lv->lock_args = NULL;
+ }
+
+ /* ... to clvm */
+ if (!strcmp(lock_type, "clvm")) {
+ log_warn("New clvm lock type will not be usable with lvmlockd.");
+ vg->status |= CLUSTERED;
+ vg->lock_type = "clvm"; /* this is optional */
+ vg->system_id = NULL;
+ return 1;
+ }
+
+ /* ... to lockd type */
+ if (is_lockd_type(lock_type)) {
+ /*
+ * For lock_type dlm, lockd_init_vg() will do a single
+ * vg_write() that sets lock_type, sets lock_args, clears
+ * system_id, and sets all LV lock_args to dlm.
+ * For lock_type sanlock, lockd_init_vg() needs to know
+ * how many LV locks are needed so that it can make the
+ * sanlock lv large enough.
+ */
+ dm_list_iterate_items(lvl, &vg->lvs) {
+ lv = lvl->lv;
+
+ if (lockd_lv_uses_lock(lv)) {
+ lv_lock_count++;
+
+ if (!strcmp(lock_type, "dlm"))
+ lv->lock_args = "dlm";
+ }
+ }
+
+ /*
+ * See below. We cannot set valid LV lock_args until stage 1
+ * of the change is done, so we need to skip the validation of
+ * the lock_args during stage 1.
+ */
+ if (!strcmp(lock_type, "sanlock"))
+ vg->skip_validate_lock_args = 1;
+
+ vg->system_id = NULL;
+
+ if (!lockd_init_vg(cmd, vg, lock_type, lv_lock_count)) {
+ log_error("Failed to initialize lock args for lock type %s", lock_type);
+ return 0;
+ }
+
+ /*
+ * For lock_type sanlock, there must be multiple steps
+ * because the VG needs an active lvmlock LV before
+ * LV lock areas can be allocated, which must be done
+ * before LV lock_args are written. So, the LV lock_args
+ * remain unset during the first stage of the conversion.
+ *
+ * Stage 1:
+ * lockd_init_vg() creates and activates the lvmlock LV,
+ * then sets lock_type, sets lock_args, and clears system_id.
+ *
+ * Stage 2:
+ * We get here, and can now set LV lock_args. This uses
+ * the standard code path for allocating LV locks in
+ * vg_write() by setting LV lock_args to "pending",
+ * which tells vg_write() to call lockd_init_lv()
+ * and sets the lv->lock_args value before writing the VG.
+ */
+ if (!strcmp(lock_type, "sanlock")) {
+ dm_list_iterate_items(lvl, &vg->lvs) {
+ lv = lvl->lv;
+ if (lockd_lv_uses_lock(lv))
+ lv->lock_args = "pending";
+ }
+
+ vg->skip_validate_lock_args = 0;
+ }
+
+ return 1;
+ }
+
+ /* ... to none */
+ if (!strcmp(lock_type, "none")) {
+ vg->lock_type = NULL;
+ vg->system_id = cmd->system_id ? dm_pool_strdup(vg->vgmem, cmd->system_id) : NULL;
+ return 1;
+ }
+
+ log_error("Cannot change to unknown lock type %s", lock_type);
+ return 0;
+}
+
+static int _vgchange_locktype_single(struct cmd_context *cmd, const char *vg_name,
+ struct volume_group *vg,
+ struct processing_handle *handle)
+{
+ if (vg_is_exported(vg)) {
+ log_error("Volume group \"%s\" is exported", vg_name);
+ return ECMD_FAILED;
+ }
+
+ if (!archive(vg))
+ return_ECMD_FAILED;
+
+ if (!_vgchange_locktype(cmd, vg))
+ return_ECMD_FAILED;
+
+ if (!vg_write(vg) || !vg_commit(vg))
+ return_ECMD_FAILED;
+
+ backup(vg);
+
+ log_print_unless_silent("Volume group \"%s\" successfully changed", vg->name);
+
+ return ECMD_PROCESSED;
+}
+
+int vgchange_locktype_cmd(struct cmd_context *cmd, int argc, char **argv)
+{
+ struct processing_handle *handle;
+ const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
+ const char *lockopt = arg_str_value(cmd, lockopt_ARG, NULL);
+ int ret;
+
+ /*
+ * vgchange --locktype none --lockopt force VG
+ *
+ * This is a special/forced exception to change the lock type to none.
+ * It's needed for recovery cases and skips the normal steps of undoing
+ * the current lock type. It's a way to forcibly get access to a VG
+ * when the normal locking mechanisms are not working.
+ *
+ * It ignores: the current lvm locking config, lvmlockd, the state of
+ * the vg on other hosts, etc. It is meant to just remove any locking
+ * related metadata from the VG (cluster/lock_type flags, lock_type,
+ * lock_args).
+ *
+ * This can be necessary when manually recovering from certain failures.
+ * e.g. when a pv is lost containing the lvmlock lv (holding sanlock
+ * leases), the vg lock_type needs to be changed to none, and then
+ * back to sanlock, which recreates the lvmlock lv and leases.
+ *
+ * Set lockd_gl_disable, lockd_vg_disable, lockd_lv_disable to
+ * disable locking. lockd_gl(), lockd_vg() and lockd_lv() will
+ * just return success when they see the disable flag set.
+ */
+ if (lockopt && !strcmp(lockopt, "force")) {
+ if (strcmp(lock_type, "none")) {
+ log_error("Lock type can only be forced to \"none\" for recovery.");
+ return 0;
+ }
+
+ if (yes_no_prompt("Forcibly change VG lock type to none? [y/n]: ") == 'n') {
+ log_error("VG lock type not changed.");
+ return 0;
+ }
+
+ cmd->lockd_gl_disable = 1;
+ cmd->lockd_vg_disable = 1;
+ cmd->lockd_lv_disable = 1;
+ cmd->handles_missing_pvs = 1;
+ goto process;
+ }
+
+ if (!lvmlockd_use()) {
+ log_error("Using lock type requires lvmlockd.");
+ return 0;
+ }
+
+ /*
+ * This is a special case where taking the global lock is
+ * not needed to protect global state, because the change is
+ * only to an existing VG. But, taking the global lock ex is
+ * helpful in this case to trigger a global cache validation
+ * on other hosts, to cause them to see the new system_id or
+ * lock_type.
+ */
+ if (!lockd_gl(cmd, "ex", LDGL_UPDATE_NAMES))
+ return 0;
+
+process:
+ if (!(handle = init_processing_handle(cmd, NULL))) {
+ log_error("Failed to initialize processing handle.");
+ return ECMD_FAILED;
+ }
+
+ ret = process_each_vg(cmd, argc, argv, NULL, NULL, READ_FOR_UPDATE, 0, handle, &_vgchange_locktype_single);
+
+ destroy_processing_handle(cmd, handle);
+ return ret;
+}
+
6 years, 4 months