summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/locking/lvmlockd.c30
-rw-r--r--lib/locking/lvmlockd.h5
-rw-r--r--lib/metadata/metadata.c4
-rw-r--r--tools/args.h1
-rw-r--r--tools/dlock.c245
-rw-r--r--tools/dlock.h11
-rw-r--r--tools/lvconvert.c3
-rw-r--r--tools/lvcreate.c3
-rw-r--r--tools/lvmcmdline.c2
-rw-r--r--tools/lvrename.c5
-rw-r--r--tools/lvresize.c3
-rw-r--r--tools/toollib.c17
-rw-r--r--tools/tools.h2
-rw-r--r--tools/vgchange.c37
-rw-r--r--tools/vgmerge.c7
-rw-r--r--tools/vgreduce.c2
-rw-r--r--tools/vgremove.c7
-rw-r--r--tools/vgrename.c6
-rw-r--r--tools/vgsplit.c7
19 files changed, 391 insertions, 6 deletions
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index ec8f1c40e..b9b684d4d 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -881,3 +881,33 @@ out:
return ret;
}
+int lvmlockd_vg_update(struct volume_group *vg)
+{
+ daemon_reply reply;
+ int result;
+ int ret;
+
+ if (!is_dlock_type(vg->lock_type))
+ return 1;
+
+ if (!_lvmlockd_active)
+ return 1;
+ if (!lvmlockd_connected())
+ return 0;
+
+ reply = _lvmlockd_send("vg_update",
+ "pid = %d", getpid(),
+ "vg_name = %s", vg->name,
+ "version = %d", (int64_t)vg->seqno,
+ NULL);
+
+ if (!_lvmlockd_result(reply, &result, NULL)) {
+ ret = 0;
+ } else {
+ ret = (result < 0) ? 0 : 1;
+ }
+
+ daemon_reply_destroy(reply);
+ return ret;
+}
+
diff --git a/lib/locking/lvmlockd.h b/lib/locking/lvmlockd.h
index 87b49ccfe..9ee8f9acb 100644
--- a/lib/locking/lvmlockd.h
+++ b/lib/locking/lvmlockd.h
@@ -104,6 +104,9 @@ void lvmlockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg);
int lvmlockd_start_vg(struct cmd_context *cmd, struct volume_group *vg);
int lvmlockd_stop_vg(struct cmd_context *cmd, struct volume_group *vg);
+/* notify lvmlockd of a new VG seqno */
+
+int lvmlockd_vg_update(struct volume_group *vg);
#else /* LVMLOCKD_SUPPORT */
@@ -123,6 +126,8 @@ int lvmlockd_stop_vg(struct cmd_context *cmd, struct volume_group *vg);
#define lvmlockd_start_vg(cmd, vg) (1)
#define lvmlockd_stop_vg(cmd, vg) (1)
+#define lvmlockd_vg_update(vg) (1)
+
#endif /* LVMLOCKD_SUPPORT */
#endif
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 9e1bb9e5f..220de162f 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -605,6 +605,8 @@ int vg_remove(struct volume_group *vg)
if (!lvmetad_vg_remove(vg))
stack;
+ lvmlockd_vg_update(vg);
+
if (!backup_remove(vg->cmd, vg->name))
stack;
@@ -2903,6 +2905,8 @@ int vg_commit(struct volume_group *vg)
if ((vg->fid->fmt->features & FMT_PRECOMMIT) && !lvmetad_vg_update(vg))
return_0;
+ lvmlockd_vg_update(vg);
+
cache_updated = _vg_commit_mdas(vg);
if (cache_updated) {
diff --git a/tools/args.h b/tools/args.h
index 72f592dd5..12c9ce934 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -48,6 +48,7 @@ arg(ignoreskippedcluster_ARG, '\0', "ignoreskippedcluster", NULL, 0)
arg(ignoreunsupported_ARG, '\0', "ignoreunsupported", NULL, 0)
arg(labelsector_ARG, '\0', "labelsector", int_arg, 0)
arg(lockgl_ARG, '\0', "lock-gl", string_arg, 0)
+arg(lockvg_ARG, '\0', "lock-vg", string_arg, 0)
arg(lockstart_ARG, '\0', "lock-start", string_arg, 0)
arg(lockstop_ARG, '\0', "lock-stop", string_arg, 0)
arg(locktype_ARG, '\0', "lock-type", string_arg, 0)
diff --git a/tools/dlock.c b/tools/dlock.c
index cefa54d7c..ab2a47291 100644
--- a/tools/dlock.c
+++ b/tools/dlock.c
@@ -135,11 +135,12 @@ int dlock_gl_create(struct cmd_context *cmd, const char *def_mode, uint32_t flag
/*
* result and result_flags were returned from lvmlockd.
* In lvmlockd, result 0 is success, and error is < 0.
+ *
+ * ENOLS: no lockspace was found with a global lock.
+ * It may not exist (perhaps this command is creating the first),
+ * or it may not be visible or started on the system yet.
*/
- /*
- * No lockspace was found with a global lock.
- */
if (result == -ENOLS) {
/*
* It's not a problem if an unlock happens after the
@@ -319,7 +320,14 @@ int dlock_gl(struct cmd_context *cmd, const char *def_mode, uint32_t flags)
/*
* result and result_flags were returned from lvmlockd.
- * in lvmlockd, result 0 is success, and error is < 0.
+ * In lvmlockd, result 0 is success, and error is < 0.
+ *
+ * ENOLS: no lockspace was found with a global lock.
+ * The VG with the global lock may not be visible or started yet,
+ * this should be a temporary condition.
+ *
+ * ESTARTING: the lockspace with the gl is starting.
+ * The VG with the global lock is starting and should finish shortly.
*/
if (result == -ENOLS || result == -ESTARTING) {
@@ -378,3 +386,232 @@ int dlock_gl(struct cmd_context *cmd, const char *def_mode, uint32_t flags)
return 1;
}
+int dlock_vg(struct cmd_context *cmd, const char *vg_name,
+ const char *def_mode, uint32_t flags)
+{
+ const char *mode = NULL;
+ const char *opts = NULL;
+ uint32_t result_flags;
+ int result;
+ int ret;
+
+ /*
+ * Only real vgs have locks; orphans are covered by global lock.
+ */
+ if (!is_real_vg(vg_name))
+ return 1;
+
+ /*
+ * DLOCK_VG_NA is used in special cases to disable the vg lock.
+ */
+ if (cmd->command->flags & DLOCK_VG_NA)
+ return 1;
+
+ /*
+ * DL_VG_MODE_NOARG disables getting the mode from --lock-vg arg.
+ */
+ if (!(flags & DL_VG_MODE_NOARG)) {
+ mode = arg_str_value(cmd, lockvg_ARG, NULL);
+ if (mode && def_mode &&
+ (_mode_compare(mode, def_mode) < 0) &&
+ !find_config_tree_bool(cmd, global_allow_override_lock_modes_CFG, NULL)) {
+ log_error("Disallowed lock-vg mode \"%s\"", mode);
+ return 0;
+ }
+ }
+
+ if (!mode)
+ mode = def_mode;
+
+ if (!mode) {
+ /*
+ * Default mode is needed, but was not provided
+ * in the function args. This happens when dlock_vg
+ * is called from a process_each function that handles
+ * different commands. Commands that only
+ * read/check/report/display the vg have DLOCK_VG_SH
+ * set in commands.h. All other commands modify the vg.
+ */
+ if (cmd->command->flags & DLOCK_VG_SH)
+ mode = "sh";
+ else
+ mode = "ex";
+ }
+
+ if (!strcmp(mode, "ex") && find_config_tree_bool(cmd, global_read_only_lock_modes_CFG, NULL)) {
+ log_error("Disallow lock-vg ex with read_only_lock_modes");
+ return 0;
+ }
+
+ ret = lvmlockd_send(cmd, command_name(cmd), "lock_vg",
+ vg_name, NULL, NULL, NULL, NULL, mode, opts,
+ &result, &result_flags);
+ if (!ret) {
+ /* No result from lvmlockd, it is probably not running. */
+
+ /* See comment in dlock_gl() about this case. */
+
+ if (arg_count(cmd, sysinit_ARG) || arg_count(cmd, ignorelockingfailure_ARG)) {
+ log_debug("Ignore failed locking for VG %s: option %s", vg_name,
+ arg_count(cmd, sysinit_ARG) ? "sysinit" : "ignorelockingfailure");
+ return 1;
+ }
+
+ /* See comment in dlock_gl() about these cases. */
+
+ if (!strcmp(mode, "un"))
+ return 1;
+
+ if (!strcmp(mode, "sh")) {
+ log_warn("Reading VG %s without shared lock.", vg_name);
+ return 1;
+ }
+
+ log_error("Locking failed for VG %s", vg_name);
+ return 0;
+ }
+
+ /*
+ * result and result_flags were returned from lvmlockd.
+ * In lvmlockd, result 0 is success, and error is < 0.
+ *
+ * ELOCALVG: the VG is local and does not need a dlock.
+ *
+ * EOTHERVG: the VG is local and belongs to another system_id.
+ *
+ * ENOLS: no lockspace for the VG was found, the VG may not
+ * be started yet. The VG should be started manually or by system,
+ * e.g. vgchange --lock-start
+ *
+ * ESTARTING: the lockspace for the VG is starting and should
+ * finish shortly.
+ */
+
+ if (result == -ELOCALVG)
+ return 1;
+
+ if (result == -EOTHERVG) {
+ /*
+ * The VG is local and owned by another system_id.
+ * lvmlockd knows this because it caches the identity of
+ * local VGs (for the ELOCALVG case above).
+ *
+ * . By returning 0 (failure) here we can skip this VG
+ * before vg_read() is even called.
+ *
+ * . By returning 1 (success) here we will continue through
+ * vg_read(), after which we will see the foreign
+ * system_id in the metadata, and return FAILED_SYSTEMID.
+ * This VG would then be skipped by ignore_vg() instead
+ * of being skipped here.
+ *
+ * Skipping the foreign VG here is more efficient, but not
+ * consistent with the way foreign VGs are ignored when
+ * lvmlockd is not used, so we return success instead.
+ * If we decide to skip the VG here (return 0), then we
+ * would need to override this when cmd->include_foreign_vgs
+ * is set (the command wants to read/report foreign VGs.)
+ */
+ log_debug("local VG %s owned by other system_id", vg_name);
+ return 0;
+ }
+
+ if (result == -ENOLS || result == -ESTARTING) {
+
+ /* It doesn't matter if an unlock operation fails. */
+ if (!strcmp(mode, "un"))
+ return 1;
+
+ if (strcmp(mode, "sh")) {
+ /*
+ * An ex lock request always fails here. Based on the
+ * result number and result flags we can often print a
+ * reason for the failure.
+ *
+ * (In the future we might want to continue through
+ * vg_read with the lock and fail after the vg_read.
+ * Doing the vg_read may provide more information about
+ * the failure here.)
+ */
+ if ((result == -ENOLS) && (result_flags & LD_RF_INACTIVE_LS)) {
+ if (result_flags & LD_RF_ADD_LS_ERROR)
+ log_error("VG %s lock failed: lock start error", vg_name);
+ else
+ log_error("VG %s lock failed: locking stopped", vg_name);
+
+ } else if (result == -ENOLS) {
+ log_error("VG %s lock failed: lock start required", vg_name);
+
+ } else if (result == -ESTARTING) {
+ log_error("VG %s lock failed: lock start in progress", vg_name);
+
+ } else {
+ log_error("VG %s lock failed: %d", vg_name, result);
+ }
+ return 0;
+ }
+
+ /*
+ * When a sh lock failed we will allow the command to proceed
+ * because there's little harm that it could do. See the
+ * reasoning above for proceeding after a failed gl sh lock.
+ * Do we want to invalidate the cached VG in these cases to
+ * force rereading from disk?
+ */
+
+ if (result == -ESTARTING) {
+ log_warn("Skipping lock for VG %s: lock start in progress", vg_name);
+ return 1;
+ }
+
+ if ((result == -ENOLS) && (result_flags & LD_RF_ADD_LS_ERROR)) {
+ log_warn("Skipping lock for VG %s: lock start error", vg_name);
+ return 1;
+ }
+
+ if ((result == -ENOLS) && (result_flags & LD_RF_INACTIVE_LS)) {
+ log_warn("Skipping lock for VG %s: locking stopped", vg_name);
+ return 1;
+ }
+
+ if (result == -ENOLS) {
+ log_warn("Skipping lock for VG %s: lock start required", vg_name);
+ return 1;
+ }
+
+ log_error("VG %s shared lock error %d", vg_name, result);
+ return 0;
+ }
+
+ /*
+ * A notice from lvmlockd that duplicate gl locks have been found.
+ * It would be good for the user to disable one of them.
+ */
+ if ((result_flags & LD_RF_DUP_GL_LS) && strcmp(mode, "un"))
+ log_warn("Duplicate sanlock global lock in VG %s", vg_name);
+
+ if (result < 0) {
+ log_error("VG %s lock error: %d", vg_name, result);
+ return 0;
+ }
+
+ return 1;
+}
+
+/* A shortcut for back to back dlock_gl() + dlock_vg() */
+
+int dlock_gl_vg(struct cmd_context *cmd, const char *vg_name,
+ const char *def_gl_mode, const char *def_vg_mode,
+ uint32_t flags)
+{
+ if (!dlock_gl(cmd, def_gl_mode, flags))
+ return 0;
+
+ if (!dlock_vg(cmd, vg_name, def_vg_mode, flags)) {
+ dlock_gl(cmd, "un", DL_GL_MODE_NOARG);
+ return 0;
+ }
+
+ return 1;
+}
+
diff --git a/tools/dlock.h b/tools/dlock.h
index 255c90080..2a6ebe183 100644
--- a/tools/dlock.h
+++ b/tools/dlock.h
@@ -15,16 +15,27 @@
#define DL_GL_SKIP_CACHE_VALIDATE 0x00000002
#define DL_GL_UPDATE_NAMES 0x00000004
+#define DL_VG_MODE_NOARG 0x00000001
+
#ifdef LVMLOCKD_SUPPORT
int dlock_gl_create(struct cmd_context *cmd, const char *def_mode, uint32_t flags,
const char *vg_lock_type);
int dlock_gl(struct cmd_context *cmd, const char *def_mode, uint32_t flags);
+int dlock_vg(struct cmd_context *cmd, const char *vg_name,
+ const char *def_mode, uint32_t flags);
+
+int dlock_gl_vg(struct cmd_context *cmd, const char *vg_name,
+ const char *def_gl_mode, const char *def_vg_mode,
+ uint32_t flags);
+
#else /* LVMLOCKD_SUPPORT */
#define dlock_gl_create(cmd, def_mode, flags, vg_lock_type) (1)
#define dlock_gl(cmd, def_mode, flags) (1)
+#define dlock_vg(cmd, vg_name, def_mode, flags) (1)
+#define dlock_gl_vg(cmd, vg_name, def_gl_mode, def_vg_mode, flags) (1)
#endif /* LVMLOCKD_SUPPORT */
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index fcec8e176..b95e20b82 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -3418,6 +3418,9 @@ static int lvconvert_single(struct cmd_context *cmd, struct lvconvert_params *lp
cmd->handles_missing_pvs = 1;
}
+ if (!dlock_vg(cmd, lp->vg_name, "ex", 0))
+ goto_out;
+
if (!(lv = get_vg_lock_and_logical_volume(cmd, lp->vg_name, lp->lv_name)))
goto_out;
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index cf2a07cb8..333b9c113 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -1424,6 +1424,9 @@ int lvcreate(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
+ if (!dlock_vg(cmd, lp.vg_name, "ex", 0))
+ return_ECMD_FAILED;
+
log_verbose("Finding volume group \"%s\"", lp.vg_name);
vg = vg_read_for_update(cmd, lp.vg_name, NULL, 0);
if (vg_read_error(vg)) {
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 07427f941..337dc4416 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -761,7 +761,7 @@ void lvm_register_commands(void)
yes_ARG, \
quiet_ARG, config_ARG, \
commandprofile_ARG, \
- lockgl_ARG, \
+ lockgl_ARG, lockvg_ARG, \
profile_ARG, -1);
#include "commands.h"
#undef xx
diff --git a/tools/lvrename.c b/tools/lvrename.c
index eeff76da2..2f34f1dd2 100644
--- a/tools/lvrename.c
+++ b/tools/lvrename.c
@@ -124,6 +124,11 @@ int lvrename(struct cmd_context *cmd, int argc, char **argv)
goto bad;
}
+ if (is_dlock_type(vg->lock_type)) {
+ log_error("Cannot rename LV with lock_type %s", vg->lock_type);
+ goto bad;
+ }
+
if (!lv_rename(cmd, lvl->lv, lv_name_new))
goto_bad;
diff --git a/tools/lvresize.c b/tools/lvresize.c
index 08248bbec..f747d4ccf 100644
--- a/tools/lvresize.c
+++ b/tools/lvresize.c
@@ -174,6 +174,9 @@ int lvresize(struct cmd_context *cmd, int argc, char **argv)
if (!_lvresize_params(cmd, argc, argv, &lp))
return EINVALID_CMD_LINE;
+ if (!dlock_vg(cmd, lp.vg_name, "ex", 0))
+ return_ECMD_FAILED;
+
log_verbose("Finding volume group %s", lp.vg_name);
vg = vg_read_for_update(cmd, lp.vg_name, NULL, 0);
if (vg_read_error(vg)) {
diff --git a/tools/toollib.c b/tools/toollib.c
index 8a7c6cc3e..6b6c0db9b 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1695,12 +1695,16 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t flags,
vg_uuid = vgnl->vgid;
ret = 0;
+ if (!dlock_vg(cmd, vg_name, NULL, 0))
+ continue;
+
vg = vg_read(cmd, vg_name, vg_uuid, flags);
if (ignore_vg(cmd, vg, vg_name, arg_vgnames, flags & READ_ALLOW_INCONSISTENT, &ret)) {
if (ret > ret_max)
ret_max = ret;
release_vg(vg);
+ dlock_vg(cmd, vg_name, "un", 0);
stack;
continue;
}
@@ -1716,6 +1720,8 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t flags,
else
unlock_and_release_vg(cmd, vg, vg_name);
+ dlock_vg(cmd, vg_name, "un", 0);
+
if (ret > ret_max)
ret_max = ret;
if (sigint_caught())
@@ -2070,11 +2076,15 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t flags,
}
}
+ if (!dlock_vg(cmd, vg_name, NULL, 0))
+ continue;
+
vg = vg_read(cmd, vg_name, vg_uuid, flags);
if (ignore_vg(cmd, vg, vg_name, arg_vgnames, flags & READ_ALLOW_INCONSISTENT, &ret)) {
if (ret > ret_max)
ret_max = ret;
release_vg(vg);
+ dlock_vg(cmd, vg_name, "un", 0);
stack;
continue;
}
@@ -2083,6 +2093,8 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t flags,
handle, process_single_lv);
unlock_and_release_vg(cmd, vg, vg_name);
+ dlock_vg(cmd, vg_name, "un", 0);
+
if (ret > ret_max)
ret_max = ret;
@@ -2386,6 +2398,9 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t flags,
ret = 0;
skip = 0;
+ if (!dlock_vg(cmd, vg_name, NULL, 0))
+ continue;
+
vg = vg_read(cmd, vg_name, vg_uuid, flags | READ_WARN_INCONSISTENT);
if (ignore_vg(cmd, vg, vg_name, NULL, flags & READ_ALLOW_INCONSISTENT, &ret)) {
if (ret > ret_max)
@@ -2404,6 +2419,8 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t flags,
else
unlock_and_release_vg(cmd, vg, vg->name);
+ dlock_vg(cmd, vg_name, "un", 0);
+
if (sigint_caught())
return_ECMD_FAILED;
diff --git a/tools/tools.h b/tools/tools.h
index 0f0495e0c..af554cc0b 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -110,6 +110,8 @@ struct arg_value_group_list {
#define ENABLE_ALL_DEVS 0x00000008
/* Use only the first free arg as the vg name. */
#define ONLY_FIRST_NAME 0x00000010
+#define DLOCK_VG_SH 0x00000020 /* cmd never modifies a vg */
+#define DLOCK_VG_NA 0x00000040 /* vg lock does not apply to cmd */
/* a register of the lvm commands */
struct command {
diff --git a/tools/vgchange.c b/tools/vgchange.c
index 80d91c647..67f9d43d0 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -665,8 +665,45 @@ static int vgchange_single(struct cmd_context *cmd, const char *vg_name,
return ret;
}
+/*
+ * vgchange can do a 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 dlock_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->command->flags |= DLOCK_VG_SH;
+
+ /* Starting a vg lockspace means there are no locks available yet. */
+
+ if (arg_is_set(cmd, lockstart_ARG))
+ cmd->command->flags |= DLOCK_VG_NA;
+
+ /*
+ * In most cases, dlock_vg does not apply when changing lock type.
+ * (We don't generally allow changing *from* dlock type yet.)
+ * dlock_vg could be called within _vgchange_locktype as needed.
+ */
+
+ if (arg_is_set(cmd, locktype_ARG))
+ cmd->command->flags |= DLOCK_VG_NA;
+
+ /*
+ * Changing system_id or lock_type must only be done on explicitly
+ * named vgs.
+ */
+
+ if (arg_is_set(cmd, systemid_ARG) || arg_is_set(cmd, locktype_ARG))
+ cmd->command->flags &= ~ALL_VGS_IS_DEFAULT;
+
if (!argc || arg_tag_count(argc, argv) || arg_is_set(cmd, lockstart_ARG)) {
/*
* The first two standard conditions want the current
diff --git a/tools/vgmerge.c b/tools/vgmerge.c
index 41658af9a..92b49ad30 100644
--- a/tools/vgmerge.c
+++ b/tools/vgmerge.c
@@ -25,6 +25,13 @@ static struct volume_group *_vgmerge_vg_read(struct cmd_context *cmd,
release_vg(vg);
return NULL;
}
+
+ if (is_dlock_type(vg->lock_type)) {
+ log_error("vgmerge not allowed for lock_type %s", vg->lock_type);
+ unlock_and_release_vg(cmd, vg, vg_name);
+ return NULL;
+ }
+
return vg;
}
diff --git a/tools/vgreduce.c b/tools/vgreduce.c
index 95d0cca50..fb11a0c08 100644
--- a/tools/vgreduce.c
+++ b/tools/vgreduce.c
@@ -195,7 +195,7 @@ int vgreduce(struct cmd_context *cmd, int argc, char **argv)
init_ignore_suspended_devices(1);
cmd->handles_missing_pvs = 1;
- if (!dlock_gl(cmd, "ex", 0))
+ if (!dlock_gl_vg(cmd, vg_name, "ex", "ex", 0))
return_ECMD_FAILED;
vg = vg_read_for_update(cmd, vg_name, NULL, READ_ALLOW_EXPORTED);
diff --git a/tools/vgremove.c b/tools/vgremove.c
index 6c31c9a3e..9941d04b1 100644
--- a/tools/vgremove.c
+++ b/tools/vgremove.c
@@ -67,6 +67,13 @@ static int vgremove_single(struct cmd_context *cmd, const char *vg_name,
lvmlockd_free_vg_final(cmd, vg);
+ /*
+ * The vg lock no longer exists, so don't bother unlocking it.
+ * (This would be nice to do in lvmlockd_free_vg_final(), but
+ * cmd->command is not accessible lib.)
+ */
+ cmd->command->flags |= DLOCK_VG_NA;
+
return ECMD_PROCESSED;
}
diff --git a/tools/vgrename.c b/tools/vgrename.c
index 8dc413920..a287a21f9 100644
--- a/tools/vgrename.c
+++ b/tools/vgrename.c
@@ -29,6 +29,12 @@ static struct volume_group *_get_old_vg_for_rename(struct cmd_context *cmd,
return_NULL;
}
+ if (is_dlock_type(vg->lock_type)) {
+ log_error("vgrename not allowed for lock_type %s", vg->lock_type);
+ unlock_and_release_vg(cmd, vg, vg_name_old);
+ return NULL;
+ }
+
return vg;
}
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
index 339bb52aa..40b6e67a6 100644
--- a/tools/vgsplit.c
+++ b/tools/vgsplit.c
@@ -453,6 +453,13 @@ static struct volume_group *_vgsplit_from(struct cmd_context *cmd,
release_vg(vg_from);
return NULL;
}
+
+ if (is_dlock_type(vg_from->lock_type)) {
+ log_error("vgsplit not allowed for lock_type %s", vg_from->lock_type);
+ unlock_and_release_vg(cmd, vg_from, vg_name_from);
+ return NULL;
+ }
+
return vg_from;
}