summaryrefslogtreecommitdiff
path: root/tools/vgchange.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/vgchange.c')
-rw-r--r--tools/vgchange.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/tools/vgchange.c b/tools/vgchange.c
index f3e7aaa5a..80d91c647 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -665,6 +665,36 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
return ret;
}
+static int dlock_vgchange(struct cmd_context *cmd, int argc, char **argv)
+{
+ if (!argc || arg_tag_count(argc, argv) || arg_is_set(cmd, lockstart_ARG)) {
+ /*
+ * The first two standard conditions want the current
+ * list of all vg names. The lockstart condition takes
+ * the gl to serialize with any other host that tries to
+ * remove the VG while this tries to start it.
+ */
+ if (!dlock_gl(cmd, "sh", 0))
+ return_ECMD_FAILED;
+
+ } else if (arg_is_set(cmd, systemid_ARG) ||
+ arg_is_set(cmd, uuid_ARG) ||
+ arg_is_set(cmd, locktype_ARG)) {
+ /*
+ * VG names, uuids and system_ids are the three things that
+ * other hosts cache related to local vg's, so we use the
+ * name-change counter in the global lock to indicate that
+ * one of these global VG identifiers has changed so other
+ * hosts will update these cached values in VG's that they
+ * otherwise ignore (because they have foreign system_ids).
+ */
+ if (!dlock_gl(cmd, "ex", DL_GL_UPDATE_NAMES))
+ return_ECMD_FAILED;
+ }
+
+ return 1;
+}
+
int vgchange(struct cmd_context *cmd, int argc, char **argv)
{
int noupdate =
@@ -787,6 +817,9 @@ int vgchange(struct cmd_context *cmd, int argc, char **argv)
if (!update || !update_partial_unsafe)
cmd->handles_missing_pvs = 1;
+ if (!dlock_vgchange(cmd, argc, argv))
+ return_ECMD_FAILED;
+
return process_each_vg(cmd, argc, argv, update ? READ_FOR_UPDATE : 0,
NULL, &vgchange_single);
}