summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2014-11-07 13:38:27 -0600
committerDavid Teigland <teigland@redhat.com>2014-11-12 16:06:10 -0600
commit8258798537c85955592ec01ff73d18841bc715c6 (patch)
tree4897155fb13221c39ee8512cc549abac4942bf4e
parent74d47116718341b5eef55b8cd93a7e70b910ae17 (diff)
downloadlvm2-dev-dct-lvmlockd3-locktype.tar.gz
VG lock_type and lvmlockd setupdev-dct-lvmlockd3-locktype
The locking required to access a VG is a property of the VG, and is specified in the VG metadata as the "lock_type". When lvm sees a VG, it looks at the VG's lock_type to determine if locks are needed and from where: - If the VG has no lock_type, or lock_type "none", then no locks are needed. This a "local VG". If the VG is visible to multiple hosts, the VG system_id provides basic protection. A VG with an unmatching system_id is inaccessible. - If the VG has lock_type "sanlock" or "dlm", then locks are needed from lvmlockd, which acquires locks from either sanlock or dlm respectively. This is a "dlock VG". If lvmlockd or the supporting lock manager are not running, then the dlock VG is inaccessible. - If the VG has the CLUSTERED status flag (or lock_type "clvm"), then locks are needed from clvmd. This is a "clvm VG". If clvmd or the supporting clustering or locking are not running, then the clvm VG is inaccessible. Settings in lvm.conf tell lvm commands which locking daemon to use: - global/use_lvmlockd=1: tells lvm to use lvmlockd when accessing VGs with lock_type sanlock|dlm. - global/locking_type=3: tells lvm to use clvmd when accessing VGs with CLUSTERED flag (or lock_type clvm). LVM commands cannot use both lvmlockd and clvmd at the same time: - use_lvmlockd=1 should be combined with locking_type=1 - locking_type=3 (clvmd) should be combined with use_lvmlockd=0 So, different configurations allow access to different VG's: - When configured to use lvmlockd, lvm commands can access VG's with lock_type sanlock|dlm, and VG's with CLUSTERED are ignored. - When configured to use clvmd (locking_type 3), lvm commands can access VG's with the CLUSTERED flag, and VG's with lock_type sanlock|dlm are ignored. - When configured to use neither lvmlockd nor clvmd, lvm commands can access only local VG's. lvm will ignore VG's with lock_type sanlock|dlm, and will ignore VG's with CLUSTERED (or lock_type clvm). A VG is created with a specific lock_type: - vgcreate --lock_type <arg> is a new syntax that can specify the lock_type directly. <arg> may be: none, clvm, sanlock, dlm. sanlock|dlm require lvmlockd to be configured (in lvm.conf) and running. clvm requires clvmd to be configured (in lvm.conf) and running. - vgcreate --clustered y (or -cy) is the old syntax that still works, but it is not preferred because the lock_type is not explicit. When clvmd is configured, -cy creates a VG with lock_type clvm. When lvmlockd is configured, -cy creates a VG with lock_type sanlock, but this can be changed to dlm with lvm.conf vgcreate_cy_lock_type. Notes: The LOCK_TYPE status flag is not strictly necessary, but is an attempt to prevent old versions of lvm (pre-lvmlockd) from using a VG with a lock_type. In the VG metadata, the lock_type string is accompanied by a lock_args string. The lock_args string is lock-manager-specific data associated with the VG. For sanlock, the location on disk of the locks, or for dlm, the cluster name. In a VG with lock_type sanlock|dlm, each LV also has a lock_type and lock_args in the metadata. The LV lock_type currently always matches the lock_type of the VG. For sanlock, the LV lock_args specify the disk location of the LV lock.
-rw-r--r--configure.in26
-rw-r--r--daemons/lvmlockd/lvmlockd-client.h36
-rw-r--r--include/.symlinks.in2
-rw-r--r--lib/Makefile.in5
-rw-r--r--lib/commands/toolcontext.c31
-rw-r--r--lib/config/config_settings.h4
-rw-r--r--lib/config/defaults.h3
-rw-r--r--lib/format1/disk-rep.h1
-rw-r--r--lib/format1/import-export.c6
-rw-r--r--lib/format_text/export.c12
-rw-r--r--lib/format_text/flags.c1
-rw-r--r--lib/format_text/import_vsn1.c20
-rw-r--r--lib/locking/lvmlockd.c107
-rw-r--r--lib/locking/lvmlockd.h87
-rw-r--r--lib/metadata/lv.h2
-rw-r--r--lib/metadata/lv_manip.c10
-rw-r--r--lib/metadata/metadata-exported.h7
-rw-r--r--lib/metadata/metadata.c20
-rw-r--r--lib/metadata/vg.c17
-rw-r--r--lib/metadata/vg.h3
-rw-r--r--tools/Makefile.in1
-rw-r--r--tools/args.h1
-rw-r--r--tools/commands.h2
-rw-r--r--tools/dlock.c17
-rw-r--r--tools/dlock.h14
-rw-r--r--tools/lvmcmdline.c4
-rw-r--r--tools/toollib.c185
-rw-r--r--tools/tools.h2
-rw-r--r--tools/vgcreate.c1
29 files changed, 617 insertions, 10 deletions
diff --git a/configure.in b/configure.in
index 9e10dc365..064f6980d 100644
--- a/configure.in
+++ b/configure.in
@@ -39,6 +39,7 @@ case "$host_os" in
LIB_SUFFIX=so
DEVMAPPER=yes
LVMETAD=no
+ LVMLOCKD=no
ODIRECT=yes
DM_IOCTLS=yes
SELINUX=yes
@@ -1067,6 +1068,29 @@ if test "$BUILD_LVMETAD" = yes; then
fi
################################################################################
+dnl -- Build lvmlockd
+AC_MSG_CHECKING(whether to build lvmlockd)
+AC_ARG_ENABLE(lvmlockd,
+ AC_HELP_STRING([--enable-lvmlockd],
+ [enable the LVM Lock Daemon]),
+ LVMLOCKD=$enableval)
+AC_MSG_RESULT($LVMLOCKD)
+
+BUILD_LVMLOCKD=$LVMLOCKD
+
+if test x$BUILD_LVMLOCKD = xyes; then
+ AC_DEFINE([LVMLOCKD_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd.])
+
+ AC_ARG_WITH(lvmlockd-pidfile,
+ AC_HELP_STRING([--with-lvmlockd-pidfile=PATH],
+ [lvmlockd pidfile [[PID_DIR/lvmlockd.pid]]]),
+ LVMLOCKD_PIDFILE=$withval,
+ LVMLOCKD_PIDFILE="$DEFAULT_PID_DIR/lvmlockd.pid")
+ AC_DEFINE_UNQUOTED(LVMLOCKD_PIDFILE, ["$LVMLOCKD_PIDFILE"],
+ [Path to lvmlockd pidfile.])
+fi
+
+################################################################################
dnl -- Enable blkid wiping functionality
AC_MSG_CHECKING(whether to enable libblkid detection of signatures when wiping)
AC_ARG_ENABLE(blkid_wiping,
@@ -1649,6 +1673,7 @@ AC_SUBST(BLKID_WIPING)
AC_SUBST(BUILD_CMIRRORD)
AC_SUBST(BUILD_DMEVENTD)
AC_SUBST(BUILD_LVMETAD)
+AC_SUBST(BUILD_LVMLOCKD)
AC_SUBST(CACHE)
AC_SUBST(CFLAGS)
AC_SUBST(CFLOW_CMD)
@@ -1765,6 +1790,7 @@ AC_SUBST(UDEV_HAS_BUILTIN_BLKID)
AC_SUBST(WRITE_INSTALL)
AC_SUBST(DMEVENTD_PIDFILE)
AC_SUBST(LVMETAD_PIDFILE)
+AC_SUBST(LVMLOCKD_PIDFILE)
AC_SUBST(CLVMD_PIDFILE)
AC_SUBST(CMIRRORD_PIDFILE)
AC_SUBST(interface)
diff --git a/daemons/lvmlockd/lvmlockd-client.h b/daemons/lvmlockd/lvmlockd-client.h
new file mode 100644
index 000000000..97402cee5
--- /dev/null
+++ b/daemons/lvmlockd/lvmlockd-client.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ */
+
+#ifndef _LVM_LVMLOCKD_CLIENT_H
+#define _LVM_LVMLOCKD_CLIENT_H
+
+#include "daemon-client.h"
+
+/* Wrappers to open/close connection */
+
+static inline daemon_handle lvmlockd_open(const char *socket)
+{
+ daemon_info lvmlockd_info = {
+ .path = "lvmlockd",
+ .socket = socket ?: DEFAULT_RUN_DIR "/lvmlockd.socket",
+ .protocol = "lvmlockd",
+ .protocol_version = 1,
+ .autostart = 0
+ };
+
+ return daemon_open(lvmlockd_info);
+}
+
+static inline void lvmlockd_close(daemon_handle h)
+{
+ return daemon_close(h);
+}
+
+#endif
diff --git a/include/.symlinks.in b/include/.symlinks.in
index 48c4d9d9c..4e11877a9 100644
--- a/include/.symlinks.in
+++ b/include/.symlinks.in
@@ -1,11 +1,13 @@
@top_srcdir@/daemons/clvmd/clvm.h
@top_srcdir@/daemons/dmeventd/libdevmapper-event.h
@top_srcdir@/daemons/lvmetad/lvmetad-client.h
+@top_srcdir@/daemons/lvmlockd/lvmlockd-client.h
@top_srcdir@/liblvm/lvm2app.h
@top_srcdir@/lib/activate/activate.h
@top_srcdir@/lib/activate/targets.h
@top_srcdir@/lib/cache/lvmcache.h
@top_srcdir@/lib/cache/lvmetad.h
+@top_srcdir@/lib/locking/lvmlockd.h
@top_srcdir@/lib/commands/toolcontext.h
@top_srcdir@/lib/config/config.h
@top_srcdir@/lib/config/config_settings.h
diff --git a/lib/Makefile.in b/lib/Makefile.in
index bad5d8cd3..bd7a1e403 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -193,6 +193,11 @@ ifeq ("@BUILD_LVMETAD@", "yes")
SOURCES +=\
cache/lvmetad.c
endif
+
+ifeq ("@BUILD_LVMLOCKD@", "yes")
+ SOURCES +=\
+ locking/lvmlockd.c
+endif
ifeq ("@DMEVENTD@", "yes")
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 2a372c2c7..b6b212597 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -29,6 +29,7 @@
#include "segtype.h"
#include "lvmcache.h"
#include "lvmetad.h"
+#include "lvmlockd.h"
#include "archiver.h"
#ifdef HAVE_LIBDL
@@ -396,7 +397,10 @@ static int _process_config(struct cmd_context *cmd)
const struct dm_config_value *cv;
int64_t pv_min_kb;
const char *lvmetad_socket;
+ const char *lvmlockd_socket;
int udev_disabled = 0;
+ int locking_type;
+ int use_lvmlockd;
char sysfs_dir[PATH_MAX];
if (!_check_config(cmd))
@@ -552,6 +556,32 @@ static int _process_config(struct cmd_context *cmd)
lvmetad_init(cmd);
+ /*
+ * clvmd and lvmlockd cannot be used concurrently, it is
+ * one or the other.
+ * global/locking_type=3 is the clvmd configuration.
+ * global/use_lvmlockd=1 is the lvmlockd configuration.
+ *
+ * use_lvmlockd should be combined with locking_type 1 (local).
+ */
+
+ locking_type = find_config_tree_int(cmd, global_locking_type_CFG, NULL);
+ use_lvmlockd = find_config_tree_bool(cmd, global_use_lvmlockd_CFG, NULL);
+
+ if (locking_type == 3 && use_lvmlockd) {
+ log_error("ERROR: configuration setting use_lvmlockd cannot be used with locking_type 3.");
+ return 0;
+ }
+
+ lvmlockd_disconnect();
+ lvmlockd_socket = getenv("LVM_LVMLOCKD_SOCKET");
+ if (!lvmlockd_socket)
+ lvmlockd_socket = DEFAULT_RUN_DIR "/lvmlockd.socket";
+
+ lvmlockd_set_socket(lvmlockd_socket);
+ lvmlockd_set_active(!!use_lvmlockd);
+ lvmlockd_init(cmd);
+
return 1;
}
@@ -1990,6 +2020,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
#endif
dm_free(cmd);
+ lvmlockd_disconnect();
lvmetad_release_token();
lvmetad_disconnect();
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index 58f0323ea..39e4b0e5a 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -180,6 +180,7 @@ cfg(global_raid10_segtype_default_CFG, "raid10_segtype_default", global_CFG_SECT
cfg(global_sparse_segtype_default_CFG, "sparse_segtype_default", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_SPARSE_SEGTYPE, vsn(2, 2, 112), NULL)
cfg(global_lvdisplay_shows_full_device_path_CFG, "lvdisplay_shows_full_device_path", global_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_LVDISPLAY_SHOWS_FULL_DEVICE_PATH, vsn(2, 2, 89), NULL)
cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 93), NULL)
+cfg(global_use_lvmlockd_CFG, "use_lvmlockd", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 113), NULL)
cfg(global_thin_check_executable_CFG, "thin_check_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, THIN_CHECK_CMD, vsn(2, 2, 94), NULL)
cfg_array(global_thin_check_options_CFG, "thin_check_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_THIN_CHECK_OPTIONS, vsn(2, 2, 96), NULL)
cfg_array(global_thin_disabled_features_CFG, "thin_disabled_features", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, NULL, vsn(2, 2, 99), NULL)
@@ -225,6 +226,9 @@ cfg(activation_polling_interval_CFG, "polling_interval", activation_CFG_SECTION,
cfg(activation_auto_set_activation_skip_CFG, "auto_set_activation_skip", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_AUTO_SET_ACTIVATION_SKIP, vsn(2,2,99), NULL)
cfg(activation_mode_CFG, "activation_mode", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_ACTIVATION_MODE, vsn(2,2,108), NULL)
+cfg(metadata_vgcreate_cy_lock_type_CFG, "vgcreate_cy_lock_type", metadata_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_CY_LOCK_TYPE, vsn(2, 2, 113), NULL)
+cfg(metadata_vgcreate_default_lock_type_CFG, "vgcreate_default_lock_type", metadata_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_LOCK_TYPE, vsn(2, 2, 113), NULL)
+
cfg(metadata_pvmetadatacopies_CFG, "pvmetadatacopies", metadata_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_INT, DEFAULT_PVMETADATACOPIES, vsn(1, 0, 0), NULL)
cfg(metadata_vgmetadatacopies_CFG, "vgmetadatacopies", metadata_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_INT, DEFAULT_VGMETADATACOPIES, vsn(2, 2, 69), NULL)
cfg(metadata_pvmetadatasize_CFG, "pvmetadatasize", metadata_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_INT, DEFAULT_PVMETADATASIZE, vsn(1, 0, 0), NULL)
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index ba5c6b8cd..db5db07ee 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -213,4 +213,7 @@
#define DEFAULT_THIN_POOL_AUTOEXTEND_THRESHOLD 100
#define DEFAULT_THIN_POOL_AUTOEXTEND_PERCENT 20
+#define DEFAULT_CY_LOCK_TYPE "sanlock"
+#define DEFAULT_LOCK_TYPE "none"
+
#endif /* _LVM_DEFAULTS_H */
diff --git a/lib/format1/disk-rep.h b/lib/format1/disk-rep.h
index 729601ee8..94d27894f 100644
--- a/lib/format1/disk-rep.h
+++ b/lib/format1/disk-rep.h
@@ -41,6 +41,7 @@
#define VG_WRITE 0x02 /* " */
#define VG_CLUSTERED 0x04 /* " */
#define VG_SHARED 0x08 /* " */
+#define VG_LOCK_TYPE 0x10 /* " */
/* logical volume */
#define LV_ACTIVE 0x01 /* lv_status */
diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c
index 9318945e2..34ed2b11d 100644
--- a/lib/format1/import-export.c
+++ b/lib/format1/import-export.c
@@ -253,6 +253,9 @@ int import_vg(struct dm_pool *mem,
if (vgd->vg_access & VG_CLUSTERED)
vg->status |= CLUSTERED;
+ if (vgd->vg_access & VG_LOCK_TYPE)
+ vg->status |= LOCK_TYPE;
+
if (vgd->vg_access & VG_SHARED)
vg->status |= SHARED;
@@ -280,6 +283,9 @@ int export_vg(struct vg_disk *vgd, struct volume_group *vg)
if (vg_is_clustered(vg))
vgd->vg_access |= VG_CLUSTERED;
+ if (vg->status & LOCK_TYPE)
+ vgd->vg_access |= VG_LOCK_TYPE;
+
if (vg->status & SHARED)
vgd->vg_access |= VG_SHARED;
diff --git a/lib/format_text/export.c b/lib/format_text/export.c
index c2453f2ba..2c8f5791c 100644
--- a/lib/format_text/export.c
+++ b/lib/format_text/export.c
@@ -410,6 +410,12 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
if (vg->system_id && *vg->system_id)
outf(f, "system_id = \"%s\"", vg->system_id);
+ if (vg->lock_type) {
+ outf(f, "lock_type = \"%s\"", vg->lock_type);
+ if (vg->lock_args)
+ outf(f, "lock_args = \"%s\"", vg->lock_args);
+ }
+
outsize(f, (uint64_t) vg->extent_size, "extent_size = %u",
vg->extent_size);
outf(f, "max_lv = %u", vg->max_lv);
@@ -624,6 +630,12 @@ static int _print_lv(struct formatter *f, struct logical_volume *lv)
lv->timestamp);
}
+ if (lv->lock_type) {
+ outf(f, "lock_type = \"%s\"", lv->lock_type);
+ if (lv->lock_args)
+ outf(f, "lock_args = \"%s\"", lv->lock_args);
+ }
+
if (lv->alloc != ALLOC_INHERIT)
outf(f, "allocation_policy = \"%s\"",
get_alloc_string(lv->alloc));
diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c
index 55681d4f7..f0562b202 100644
--- a/lib/format_text/flags.c
+++ b/lib/format_text/flags.c
@@ -35,6 +35,7 @@ static const struct flag _vg_flags[] = {
{LVM_READ, "READ", STATUS_FLAG},
{LVM_WRITE, "WRITE", STATUS_FLAG},
{CLUSTERED, "CLUSTERED", STATUS_FLAG},
+ {LOCK_TYPE, "LOCK_TYPE", STATUS_FLAG},
{SHARED, "SHARED", STATUS_FLAG},
{PARTIAL_VG, NULL, 0},
{PRECOMMITTED, NULL, 0},
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index c6a0cf91f..838a16d31 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -567,6 +567,16 @@ static int _read_lvnames(struct format_instance *fid __attribute__((unused)),
return 0;
}
+ if (dm_config_get_str(lvn, "lock_type", &str)) {
+ if (!(lv->lock_type = dm_pool_strdup(mem, str)))
+ return_0;
+ }
+
+ if (dm_config_get_str(lvn, "lock_args", &str)) {
+ if (!(lv->lock_args = dm_pool_strdup(mem, str)))
+ return_0;
+ }
+
lv->alloc = ALLOC_INHERIT;
if (dm_config_get_str(lvn, "allocation_policy", &str)) {
lv->alloc = get_alloc_from_string(str);
@@ -777,6 +787,16 @@ static struct volume_group *_read_vg(struct format_instance *fid,
strncpy(vg->system_id, str, NAME_LEN);
}
+ if (dm_config_get_str(vgn, "lock_type", &str)) {
+ if (!(vg->lock_type = dm_pool_strdup(vg->vgmem, str)))
+ goto bad;
+ }
+
+ if (dm_config_get_str(vgn, "lock_args", &str)) {
+ if (!(vg->lock_args = dm_pool_strdup(vg->vgmem, str)))
+ goto bad;
+ }
+
if (!_read_id(&vg->id, vgn, "id")) {
log_error("Couldn't read uuid for volume group %s.", vg->name);
goto bad;
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
new file mode 100644
index 000000000..ab33b6e72
--- /dev/null
+++ b/lib/locking/lvmlockd.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ */
+
+#include "lib.h"
+#include "toolcontext.h"
+#include "metadata.h"
+#include "segtype.h"
+#include "lvmetad.h"
+#include "lvmlockd.h"
+#include "lvmcache.h"
+#include "lvmlockd-client.h"
+
+static daemon_handle _lvmlockd;
+static int _lvmlockd_active;
+static int _lvmlockd_connected;
+
+static const char *_lvmlockd_socket = NULL;
+static struct cmd_context *_lvmlockd_cmd = NULL;
+
+void lvmlockd_disconnect(void)
+{
+ if (_lvmlockd_connected)
+ daemon_close(_lvmlockd);
+ _lvmlockd_connected = 0;
+ _lvmlockd_cmd = NULL;
+}
+
+void lvmlockd_init(struct cmd_context *cmd)
+{
+ if (!_lvmlockd_active && !access(LVMLOCKD_PIDFILE, F_OK))
+ log_warn("lvmlockd is not running.");
+ if (!_lvmlockd_active)
+ return;
+ _lvmlockd_cmd = cmd;
+}
+
+static void _lvmlockd_connect(void)
+{
+ if (!_lvmlockd_active || !_lvmlockd_socket || _lvmlockd_connected)
+ return;
+
+ _lvmlockd = lvmlockd_open(_lvmlockd_socket);
+
+ if (_lvmlockd.socket_fd >= 0 && !_lvmlockd.error) {
+ log_debug("Successfully connected to lvmlockd on fd %d.",
+ _lvmlockd.socket_fd);
+ _lvmlockd_connected = 1;
+ }
+}
+
+void lvmlockd_connect_or_warn(void)
+{
+ if (!_lvmlockd_active || _lvmlockd_connected)
+ return;
+
+ _lvmlockd_connect();
+
+ if (!_lvmlockd_connected) {
+ log_warn("Failed to connect to lvmlockd: %s.",
+ strerror(_lvmlockd.error));
+ }
+}
+
+/*
+ * in command setup:
+ *
+ * 1. if use_lvmlockd is set in config,
+ * lvmlockd_set_active() sets _lvmlockd_active = 1
+ *
+ * 2. lvmlockd_init() sees _lvmlockd_active, and sets _lvmlockd_cmd
+ *
+ * 3. lvmlockd_connect_or_warn()/_lvmlockd_connect() see _lvmlockd_active,
+ * create connection and if successful set _lvmlockd_connected = 1
+ *
+ * in command processing:
+ *
+ * 1. dlock function calls lvmlockd_connected() which returns
+ * _lvmlockd_connected
+ *
+ * 2. if lvmlockd_connected() returns 0, dlock function fails
+ */
+
+int lvmlockd_connected(void)
+{
+ if (_lvmlockd_connected)
+ return 1;
+
+ return 0;
+}
+
+void lvmlockd_set_active(int active)
+{
+ _lvmlockd_active = active;
+}
+
+void lvmlockd_set_socket(const char *sock)
+{
+ _lvmlockd_socket = sock;
+}
+
diff --git a/lib/locking/lvmlockd.h b/lib/locking/lvmlockd.h
new file mode 100644
index 000000000..95b85256f
--- /dev/null
+++ b/lib/locking/lvmlockd.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ */
+
+#ifndef _LVMLOCKD_H
+#define _LVMLOCKD_H
+
+#include "config-util.h"
+#include "daemon-client.h"
+
+#define LOCK_TYPE_NONE 0
+#define LOCK_TYPE_CLVM 1
+#define LOCK_TYPE_DLM 2
+#define LOCK_TYPE_SANLOCK 3
+
+/*
+ * lock_type lock_type_num
+ * "none" -> LOCK_TYPE_NONE
+ * "clvm" -> LOCK_TYPE_CLVM
+ * "dlm -> LOCK_TYPE_DLM
+ * "sanlock" -> LOCK_TYPE_SANLOCK
+ */
+
+static inline int lock_type_to_num(const char *lock_type)
+{
+ if (!lock_type)
+ return LOCK_TYPE_NONE;
+ if (!strcmp(lock_type, "none"))
+ return LOCK_TYPE_NONE;
+ if (!strcmp(lock_type, "clvm"))
+ return LOCK_TYPE_CLVM;
+ if (!strcmp(lock_type, "dlm"))
+ return LOCK_TYPE_DLM;
+ if (!strcmp(lock_type, "sanlock"))
+ return LOCK_TYPE_SANLOCK;
+ return -1;
+}
+
+/*
+ * Check if a lock_type uses lvmlockd.
+ * If not (none, clvm), return 0.
+ * If so (dlm, sanlock), return > 0 (LOCK_TYPE_)
+ */
+
+static inline int is_dlock_type(const char *lock_type)
+{
+ if (!lock_type)
+ return 0;
+
+ if (!strcmp(lock_type, "dlm"))
+ return LOCK_TYPE_DLM;
+ if (!strcmp(lock_type, "sanlock"))
+ return LOCK_TYPE_SANLOCK;
+
+ return 0;
+}
+
+#ifdef LVMLOCKD_SUPPORT
+
+/* daemon management */
+
+void lvmlockd_init(struct cmd_context *);
+void lvmlockd_set_active(int);
+void lvmlockd_set_socket(const char *);
+void lvmlockd_disconnect(void);
+void lvmlockd_connect_or_warn(void);
+int lvmlockd_connected(void);
+
+#else /* LVMLOCKD_SUPPORT */
+
+#define lvmlockd_init(cmd) do { } while (0)
+#define lvmlockd_set_active(int) do { } while (0)
+#define lvmlockd_set_socket(str) do { } while (0)
+#define lvmlockd_disconnect() do { } while (0)
+#define lvmlockd_connect_or_warn() do { } while (0)
+#define lvmlockd_connected (0)
+
+#endif /* LVMLOCKD_SUPPORT */
+
+#endif
+
diff --git a/lib/metadata/lv.h b/lib/metadata/lv.h
index 8064ba22f..b15c31f4a 100644
--- a/lib/metadata/lv.h
+++ b/lib/metadata/lv.h
@@ -52,6 +52,8 @@ struct logical_volume {
uint64_t timestamp;
const char *hostname;
+ const char *lock_type;
+ const char *lock_args;
};
uint64_t lv_size(const struct logical_volume *lv);
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 629262651..438da944f 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6882,6 +6882,16 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
lv->major, lv->minor);
}
+ if (lp->lock_type && !(lv->lock_type = dm_pool_strdup(cmd->mem, lp->lock_type))) {
+ log_error("Failed to allocate lock_type");
+ return NULL;
+ }
+
+ if (lp->lock_args && !(lv->lock_args = dm_pool_strdup(cmd->mem, lp->lock_args))) {
+ log_error("Failed to allocate lock_args");
+ return NULL;
+ }
+
dm_list_splice(&lv->tags, &lp->tags);
if (!lv_extend(lv, create_segtype,
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index ee464eace..baf51d77f 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -61,6 +61,7 @@
#define CLUSTERED UINT64_C(0x0000000000000400) /* VG */
//#define SHARED UINT64_C(0x0000000000000800) /* VG */
+#define LOCK_TYPE UINT64_C(0x0000000000001000) /* VG */
/* FIXME Remove when metadata restructuring is completed */
#define SNAPSHOT UINT64_C(0x0000000000001000) /* LV - internal use only */
@@ -161,6 +162,7 @@
#define FAILED_ALLOCATION 0x00000080U
#define FAILED_EXIST 0x00000100U
#define FAILED_SYSTEMID 0x00000200U
+#define FAILED_LOCK_TYPE 0x00000400U
#define SUCCESS 0x00000000U
#define VGMETADATACOPIES_ALL UINT32_MAX
@@ -834,6 +836,9 @@ struct lvcreate_params {
const char *origin_name; /* snap */
const char *pool_name; /* thin */
+ const char *lock_type;
+ const char *lock_args;
+
/* Keep args given by the user on command line */
/* FIXME: create some more universal solution here */
#define PASS_ARG_CHUNK_SIZE 0x01
@@ -1167,6 +1172,8 @@ struct vgcreate_params {
int clustered; /* FIXME: put this into a 'status' variable instead? */
uint32_t vgmetadatacopies;
const char *system_id;
+ const char *lock_type;
+ const char *lock_args;
};
int validate_major_minor(const struct cmd_context *cmd,
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index ce41a47ba..9e1bb9e5f 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -31,6 +31,7 @@
#include "locking.h"
#include "archiver.h"
#include "defaults.h"
+#include "lvmlockd.h"
#include <math.h>
#include <sys/param.h>
@@ -4326,6 +4327,20 @@ static int _access_vg_clustered(struct cmd_context *cmd, struct volume_group *vg
return 1;
}
+static int _access_vg_lock_type(struct cmd_context *cmd, struct volume_group *vg)
+{
+ if (!is_real_vg(vg->name))
+ return 1;
+
+ if (is_dlock_type(vg->lock_type) && !find_config_tree_bool(cmd, global_use_lvmlockd_CFG, NULL)) {
+ log_warn("Cannot access VG %s which requires lvmlockd (lock_type %s).",
+ vg->name, vg->lock_type);
+ return 0;
+ }
+
+ return 1;
+}
+
static int _access_vg_systemid(struct cmd_context *cmd, struct volume_group *vg)
{
/*
@@ -4384,6 +4399,11 @@ static int _access_vg(struct cmd_context *cmd, struct volume_group *vg, uint32_t
return 0;
}
+ if (!_access_vg_lock_type(cmd, vg)) {
+ *failure |= FAILED_LOCK_TYPE;
+ return 0;
+ }
+
if (!_access_vg_systemid(cmd, vg)) {
*failure |= FAILED_SYSTEMID;
return 0;
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 57c9acfd9..99e51709c 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -20,6 +20,7 @@
#include "toolcontext.h"
#include "lvmcache.h"
#include "archiver.h"
+#include "lvmlockd.h"
struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
const char *vg_name)
@@ -619,6 +620,22 @@ int vg_set_system_id(struct volume_group *vg, const char *system_id)
return 1;
}
+int vg_set_lock_type(struct volume_group *vg, const char *lock_type)
+{
+ if (!lock_type)
+ lock_type = "none";
+
+ if (!(vg->lock_type = dm_pool_strdup(vg->vgmem, lock_type))) {
+ log_error("vg_set_lock_type %s no mem", lock_type);
+ return 0;
+ }
+
+ if (is_dlock_type(lock_type))
+ vg->status |= LOCK_TYPE;
+
+ return 1;
+}
+
char *vg_attr_dup(struct dm_pool *mem, const struct volume_group *vg)
{
char *repstr;
diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h
index 23d60acdd..3a8e1ed60 100644
--- a/lib/metadata/vg.h
+++ b/lib/metadata/vg.h
@@ -68,6 +68,8 @@ struct volume_group {
const char *name;
const char *old_name; /* Set during vgrename and vgcfgrestore */
char *system_id;
+ const char *lock_type;
+ const char *lock_args;
uint32_t extent_size;
uint32_t extent_count;
@@ -145,6 +147,7 @@ uint64_t vg_status(const struct volume_group *vg);
int vg_set_alloc_policy(struct volume_group *vg, alloc_policy_t alloc);
int vg_set_clustered(struct volume_group *vg, int clustered);
int vg_set_system_id(struct volume_group *vg, const char *system_id);
+int vg_set_lock_type(struct volume_group *vg, const char *lock_type);
uint64_t vg_size(const struct volume_group *vg);
uint64_t vg_free(const struct volume_group *vg);
uint64_t vg_extent_size(const struct volume_group *vg);
diff --git a/tools/Makefile.in b/tools/Makefile.in
index 1a8db36e5..30f5fba43 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -17,6 +17,7 @@ top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
SOURCES =\
+ dlock.c \
dumpconfig.c \
formats.c \
lvchange.c \
diff --git a/tools/args.h b/tools/args.h
index 4a8a56a4b..5a2230ad8 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -47,6 +47,7 @@ arg(ignoremonitoring_ARG, '\0', "ignoremonitoring", NULL, 0)
arg(ignoreskippedcluster_ARG, '\0', "ignoreskippedcluster", NULL, 0)
arg(ignoreunsupported_ARG, '\0', "ignoreunsupported", NULL, 0)
arg(labelsector_ARG, '\0', "labelsector", int_arg, 0)
+arg(locktype_ARG, '\0', "lock-type", string_arg, 0)
arg(maxrecoveryrate_ARG, '\0', "maxrecoveryrate", size_kb_arg, 0)
arg(merge_ARG, '\0', "merge", NULL, 0)
arg(mergedconfig_ARG, '\0', "mergedconfig", NULL, 0)
diff --git a/tools/commands.h b/tools/commands.h
index eefd1fec4..563200428 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -1022,7 +1022,7 @@ xx(vgcreate,
physicalextentsize_ARG, test_ARG, force_ARG, zero_ARG, labelsector_ARG,
metadatasize_ARG, pvmetadatacopies_ARG, metadatacopies_ARG,
vgmetadatacopies_ARG, dataalignment_ARG, dataalignmentoffset_ARG,
- systemid_ARG, systemidsource_ARG)
+ systemid_ARG, systemidsource_ARG, locktype_ARG)
xx(vgdisplay,
"Display volume group information",
diff --git a/tools/dlock.c b/tools/dlock.c
new file mode 100644
index 000000000..a962b4c6a
--- /dev/null
+++ b/tools/dlock.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ */
+
+#include "tools.h"
+#include "metadata.h"
+#include "lvmetad.h"
+#include "lvmlockd.h"
+#include "lvmcache.h"
+#include "lvmlockd-client.h"
+
diff --git a/tools/dlock.h b/tools/dlock.h
new file mode 100644
index 000000000..3c852a844
--- /dev/null
+++ b/tools/dlock.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ */
+
+#ifndef _DLOCK_H
+#define _DLOCK_H
+
+#endif
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 1d3e993ad..9f9891fea 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -1063,8 +1063,10 @@ static int _get_settings(struct cmd_context *cmd)
cmd->ignore_clustered_vgs = arg_count(cmd, ignoreskippedcluster_ARG) ? 1 : 0;
- if (!arg_count(cmd, sysinit_ARG))
+ if (!arg_count(cmd, sysinit_ARG)) {
lvmetad_connect_or_warn();
+ lvmlockd_connect_or_warn();
+ }
if (arg_count(cmd, nosuffix_ARG))
cmd->current_settings.suffix = 0;
diff --git a/tools/toollib.c b/tools/toollib.c
index 9291eb42a..8a7c6cc3e 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -191,6 +191,8 @@ static int ignore_vg(struct cmd_context *cmd, struct volume_group *vg, const cha
*ret = ECMD_FAILED;
else if (read_error == FAILED_CLUSTERED && vg->cmd->ignore_clustered_vgs)
log_verbose("Skipping volume group %s", vg_name);
+ else if (read_error == FAILED_LOCK_TYPE)
+ log_verbose("Skipping volume group %s", vg_name);
else {
log_error("Skipping volume group %s", vg_name);
*ret = ECMD_FAILED;
@@ -653,6 +655,12 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
{
const char *arg_str;
const char *system_id_source;
+ const char *lock_type;
+ int locking_type;
+ int use_lvmlockd;
+ int use_clvmd;
+ int clustery;
+ int lock_type_num; /* LOCK_TYPE_ */
vp_new->vg_name = skip_dev_dir(cmd, vp_def->vg_name, NULL);
vp_new->max_lv = arg_uint_value(cmd, maxlogicalvolumes_ARG,
@@ -665,12 +673,6 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
vp_new->extent_size =
arg_uint_value(cmd, physicalextentsize_ARG, vp_def->extent_size);
- if (arg_count(cmd, clustered_ARG))
- vp_new->clustered = arg_int_value(cmd, clustered_ARG, vp_def->clustered);
- else
- /* Default depends on current locking type */
- vp_new->clustered = locking_is_clustered();
-
if (arg_sign_value(cmd, physicalextentsize_ARG, SIGN_NONE) == SIGN_MINUS) {
log_error(_pe_size_may_not_be_negative_msg);
return 0;
@@ -721,10 +723,177 @@ int vgcreate_params_set_from_args(struct cmd_context *cmd,
}
}
- /* A clustered vg has no system_id. */
- if (vp_new->clustered)
+ /*
+ * Locking: what kind of locking should be used for the
+ * new VG, and is it compatible with current lvm.conf settings.
+ *
+ * The end result is to set vp_new->lock_type to:
+ * none | clvm | dlm | sanlock.
+ *
+ * If --lock-type <arg> is set, the answer is given directly by
+ * <arg> which is one of none|clvm|dlm|sanlock.
+ *
+ * If --clustered y is set, then lock_type will depend on
+ * settings found in lvm.conf (see selection logic below.)
+ *
+ * Relevant lvm.conf configurations include:
+ *
+ * global/use_lvmlockd = 0, global/locking_type = 1
+ * ------------------------------------------------
+ * - no locking is enabled
+ * - clvmd is not used
+ * - lvmlockd is not used
+ * - VGs with CLUSTERED set are ignored (requires clvmd)
+ * - VGs with lock_type set are ignored (requires lvmlockd)
+ * - vgcreate can create new VGs with lock_type = none
+ *
+ * global/use_lvmlockd = 0, global/locking_type = 3
+ * ------------------------------------------------
+ * - locking through clvmd is enabled (traditional clvm config)
+ * - clvmd is used
+ * - lvmlockd is not used
+ * - VGs with CLUSTERED set can be used
+ * - VGs with lock_type set are ignored (requires lvmlockd)
+ * - vgcreate can create new VGs with CLUSTERED status flag
+ *
+ * global/use_lvmlockd = 1, global/locking_type = 1
+ * ------------------------------------------------
+ * - locking through lvmlockd is enabled (new lvmlockd config)
+ * - clvmd is not used
+ * - lvmlockd is used
+ * - VGs with CLUSTERED set are ignored (requires clvmd)
+ * - VGs with lock_type set can be used
+ * - vgcreate can create new VGs with lock_type = none|sanlock|dlm
+ *
+ * VG metadata
+ * -----------
+ *
+ * A VG with lock_type sanlock|dlm has the new metadata field:
+ * lock_type = "sanlock" or lock_type = "dlm",
+ * and the new status flag "LOCK_TYPE".
+ *
+ * A VG with lock_type clvm has the old metadata status flag CLUSTERED.
+ *
+ * A VG with lock_type none has no lock_type metadata field.
+ *
+ * A VG with lock_type sanlock|dlm also has a new metadata field
+ * lock_args = "..." where the specific string is set by the
+ * lock manager to lock-manager-specific data.
+ */
+
+ /*
+ * The --clustered option can have varying results depending
+ * on the lvm.conf settings. This is why --lock-type is the
+ * preferred option. When --clustered is used, it is translated
+ * to a lock_type as follows:
+ *
+ * When using lvmlockd:
+ *
+ * 1. --clustered n -> lock_type none
+ *
+ * 2. --clustered y -> lock_type sanlock
+ *
+ * The default is sanlock but can be set to sanlock|dlm with
+ * lvm.conf metadata/vgcreate_cy_lock_type (DEFAULT_CY_LOCK_TYPE)
+ *
+ * 3. Neither --clustered nor --lock-type specified -> lock_type none
+ *
+ * The default is none but can be set to none|sanlock|dlm with
+ * lvm.conf metadata/vgcreate_default_lock_type (DEFAULT_LOCK_TYPE)
+ *
+ * When using clvmd:
+ *
+ * 1. --clustered n -> lock_type none
+ *
+ * 2. --clustered y -> lock_type clvm
+ *
+ * 3. Neither --clustered nor --lock-type specified -> lock_type clvm
+ *
+ * The historical default is clvm.
+ */
+
+ locking_type = find_config_tree_int(cmd, global_locking_type_CFG, NULL);
+ use_lvmlockd = find_config_tree_bool(cmd, global_use_lvmlockd_CFG, NULL);
+ use_clvmd = (locking_type == 3);
+
+ if (arg_is_set(cmd, locktype_ARG)) {
+ lock_type = arg_str_value(cmd, locktype_ARG, "");
+
+ } else if (arg_is_set(cmd, clustered_ARG)) {
+ arg_str = arg_str_value(cmd, clustered_ARG, "");
+
+ if (!strcmp(arg_str, "y")) {
+ clustery = 1;
+ } else if (!strcmp(arg_str, "n")) {
+ clustery = 0;
+ } else {
+ log_error("Unknown clustered value");
+ return 0;
+ }
+
+ if (use_lvmlockd) {
+ if (clustery)
+ lock_type = find_config_tree_str(cmd, metadata_vgcreate_cy_lock_type_CFG, NULL);
+ else
+ lock_type = "none";
+ } else if (use_clvmd) {
+ if (clustery)
+ lock_type = "clvm";
+ else
+ lock_type = "none";
+ } else {
+ log_error("clustered vg requires use_lvmlockd or locking_type 3 (clvmd)");
+ return 0;
+ }
+
+ } else {
+ if (use_clvmd)
+ lock_type = locking_is_clustered() ? "clvm" : "none";
+ else if (use_lvmlockd)
+ lock_type = find_config_tree_str(cmd, metadata_vgcreate_default_lock_type_CFG, NULL);
+
+ /*
+ * lock_type NULL is when there is no --lock-type,
+ * no --clustered, locking_type is not 3, and
+ * vgcreate_default_lock_type is not set.
+ */
+ if (!lock_type)
+ lock_type = "none";
+ }
+
+ /*
+ * Check that the lock_type is recognized, and is being
+ * used with the correct lvm.conf settings.
+ */
+ lock_type_num = lock_type_to_num(lock_type);
+
+ if (lock_type_num < 0) {
+ log_error("lock_type %s is invalid", lock_type);
+ return 0;
+ } else if ((lock_type_num == LOCK_TYPE_DLM || lock_type_num == LOCK_TYPE_SANLOCK) && !use_lvmlockd) {
+ log_error("lock_type %s requires use_lvmlockd configuration setting", lock_type);
+ return 0;
+ } else if ((lock_type_num == LOCK_TYPE_CLVM) && !use_clvmd) {
+ log_error("lock_type clvm requires locking_type 3 configuration setting");
+ return 0;
+ }
+
+ /*
+ * The vg is not owned by one host/system_id.
+ * Locking coordinates access from multiple hosts.
+ */
+ if (lock_type_num == LOCK_TYPE_DLM || lock_type_num == LOCK_TYPE_SANLOCK || lock_type_num == LOCK_TYPE_CLVM)
vp_new->system_id = NULL;
+ vp_new->lock_type = lock_type;
+
+ if (lock_type_num == LOCK_TYPE_CLVM)
+ vp_new->clustered = 1;
+ else
+ vp_new->clustered = 0;
+
+ log_debug("Setting lock_type to %s", vp_new->lock_type);
+
return 1;
}
diff --git a/tools/tools.h b/tools/tools.h
index 5bcc95815..11a88afe0 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -28,12 +28,14 @@
#include "archiver.h"
#include "lvmcache.h"
#include "lvmetad.h"
+#include "lvmlockd.h"
#include "lvm-version.h"
#include "config.h"
#include "defaults.h"
#include "dev-cache.h"
#include "device.h"
#include "display.h"
+#include "dlock.h"
#include "errors.h"
#include "metadata-exported.h"
#include "locking.h"
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
index 5e038457b..7304064fa 100644
--- a/tools/vgcreate.c
+++ b/tools/vgcreate.c
@@ -71,6 +71,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
!vg_set_max_pv(vg, vp_new.max_pv) ||
!vg_set_alloc_policy(vg, vp_new.alloc) ||
!vg_set_clustered(vg, vp_new.clustered) ||
+ !vg_set_lock_type(vg, vp_new.lock_type) ||
!vg_set_system_id(vg, vp_new.system_id) ||
!vg_set_mda_copies(vg, vp_new.vgmetadatacopies))
goto bad_orphan;