summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2015-07-30 12:04:31 -0500
committerDavid Teigland <teigland@redhat.com>2015-07-30 12:04:31 -0500
commitb40ccdd57cc0d57a71e584600c1025e649dc6d8a (patch)
tree8b28962d6b8af0bf5f81de33cffecf28b3623280
parent78135c24b419d070a238f1660408c843707c7cbb (diff)
downloadlvm2-b40ccdd57cc0d57a71e584600c1025e649dc6d8a.tar.gz
lvmlockd: create sanlock lv large enough for existing lvs
When changing an existing VG to lock_type sanlock, make the sanlock lv large enough to hold all the locks needed for existing LVs.
-rw-r--r--lib/locking/lvmlockd.c20
-rw-r--r--lib/locking/lvmlockd.h4
-rw-r--r--tools/vgchange.c17
-rw-r--r--tools/vgcreate.c2
4 files changed, 29 insertions, 14 deletions
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
index 66c6615d9..15abd547a 100644
--- a/lib/locking/lvmlockd.c
+++ b/lib/locking/lvmlockd.c
@@ -320,9 +320,6 @@ static int _lockd_request(struct cmd_context *cmd,
/*
* Eventually add an option to specify which pv the lvmlock lv should be placed on.
- * FIXME: when converting a VG from lock_type none to sanlock, we need to count
- * the number of existing LVs to ensure that the new sanlock_lv is large enough
- * for all of them that need locks.
*/
static int _create_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg,
@@ -559,7 +556,7 @@ out:
return ret;
}
-static int _init_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg)
+static int _init_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg, int lv_lock_count)
{
daemon_reply reply;
const char *reply_str;
@@ -588,7 +585,18 @@ static int _init_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg)
* LV, then activates the lvmlock LV. The lvmlock LV must be active
* before we ask lvmlockd to initialize the VG because sanlock needs
* to initialize leases on the lvmlock LV.
+ *
+ * When converting an existing VG to sanlock, the sanlock lv needs to
+ * be large enough to hold leases for all existing lvs needing locks.
+ * One sanlock lease uses 1MB/8MB for 512/4K sector size devices, so
+ * increase the initial size by 1MB/8MB for each existing lv.
+ * FIXME: we don't know what sector size the pv will have, so we
+ * multiply by 8 (MB) unnecessarily when the sector size is 512.
*/
+
+ if (lv_lock_count)
+ extend_mb += (lv_lock_count * 8);
+
if (!_create_sanlock_lv(cmd, vg, LOCKD_SANLOCK_LV_NAME, extend_mb)) {
log_error("Failed to create internal lv.");
return 0;
@@ -816,7 +824,7 @@ static void _forget_vg_name(struct cmd_context *cmd, struct volume_group *vg)
/* vgcreate */
int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg,
- const char *lock_type)
+ const char *lock_type, int lv_lock_count)
{
switch (get_lock_type_from_string(lock_type)) {
case LOCK_TYPE_NONE:
@@ -827,7 +835,7 @@ int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg,
case LOCK_TYPE_DLM:
return _init_vg_dlm(cmd, vg);
case LOCK_TYPE_SANLOCK:
- return _init_vg_sanlock(cmd, vg);
+ return _init_vg_sanlock(cmd, vg, lv_lock_count);
default:
log_error("Unknown lock_type.");
return 0;
diff --git a/lib/locking/lvmlockd.h b/lib/locking/lvmlockd.h
index f14163524..b0edeae90 100644
--- a/lib/locking/lvmlockd.h
+++ b/lib/locking/lvmlockd.h
@@ -54,7 +54,7 @@ void lvmlockd_disconnect(void);
/* vgcreate/vgremove use init/free */
-int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg, const char *lock_type);
+int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg, const char *lock_type, int lv_lock_count);
int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg);
void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg);
@@ -125,7 +125,7 @@ static inline int lvmlockd_use(void)
return 0;
}
-static inline int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg, const char *lock_type)
+static inline int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg, const char *lock_type, int lv_lock_count)
{
return 1;
}
diff --git a/tools/vgchange.c b/tools/vgchange.c
index 824fd912e..a163cf584 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -526,6 +526,7 @@ static int _vgchange_locktype(struct cmd_context *cmd,
const char *lock_type = arg_str_value(cmd, locktype_ARG, NULL);
struct lv_list *lvl;
struct logical_volume *lv;
+ int lv_lock_count = 0;
/*
* This is a special/forced exception to change the lock type to none.
@@ -654,11 +655,17 @@ static int _vgchange_locktype(struct cmd_context *cmd,
* 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.
*/
- if (!strcmp(lock_type, "dlm")) {
- dm_list_iterate_items(lvl, &vg->lvs) {
- lv = lvl->lv;
- if (lockd_lv_uses_lock(lv))
+ 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";
}
}
@@ -673,7 +680,7 @@ static int _vgchange_locktype(struct cmd_context *cmd,
vg->system_id = NULL;
- if (!lockd_init_vg(cmd, vg, lock_type)) {
+ 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;
}
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
index 20ba4aa31..67b593dcc 100644
--- a/tools/vgcreate.c
+++ b/tools/vgcreate.c
@@ -131,7 +131,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
* a local VG. lockd_init_vg() then writes the VG a second time with
* both lock_type and lock_args set.
*/
- if (!lockd_init_vg(cmd, vg, vp_new.lock_type)) {
+ if (!lockd_init_vg(cmd, vg, vp_new.lock_type, 0)) {
log_error("Failed to initialize lock args for lock type %s",
vp_new.lock_type);
vg_remove_pvs(vg);