1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-26 22:50:36 +03:00

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.
This commit is contained in:
David Teigland 2015-07-30 12:04:31 -05:00
parent 78135c24b4
commit b40ccdd57c
4 changed files with 29 additions and 14 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);