diff options
Diffstat (limited to 'tools/vgchange.c')
-rw-r--r-- | tools/vgchange.c | 33 |
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); } |