1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

lib: locking: Add new type "idm"

We can consider the drive firmware a server to handle the locking
request from nodes, this essentially is a client-server model.
DLM uses the kernel as a central place to manage locks, so it also
complies with client-server model for locking operations.  This is
why IDM and DLM are similar with each other for their wrappers.

This patch largely works by generalizing the DLM code paths and then
providing degeneralized functions as wrappers for both IDM and DLM.

Signed-off-by: Leo Yan <leo.yan@linaro.org>
This commit is contained in:
Leo Yan 2021-05-07 10:25:14 +08:00 committed by David Teigland
parent d02f5392a0
commit ef1c57e68f
4 changed files with 78 additions and 11 deletions

View File

@ -95,6 +95,8 @@ const char *get_lock_type_string(lock_type_t lock_type)
return "dlm";
case LOCK_TYPE_SANLOCK:
return "sanlock";
case LOCK_TYPE_IDM:
return "idm";
}
return "invalid";
}
@ -111,6 +113,8 @@ lock_type_t get_lock_type_from_string(const char *str)
return LOCK_TYPE_DLM;
if (!strcmp(str, "sanlock"))
return LOCK_TYPE_SANLOCK;
if (!strcmp(str, "idm"))
return LOCK_TYPE_IDM;
return LOCK_TYPE_INVALID;
}

View File

@ -553,7 +553,8 @@ static int _deactivate_sanlock_lv(struct cmd_context *cmd, struct volume_group *
return 1;
}
static int _init_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
static int _init_vg(struct cmd_context *cmd, struct volume_group *vg,
const char *lock_type)
{
daemon_reply reply;
const char *reply_str;
@ -569,7 +570,7 @@ static int _init_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
reply = _lockd_send("init_vg",
"pid = " FMTd64, (int64_t) getpid(),
"vg_name = %s", vg->name,
"vg_lock_type = %s", "dlm",
"vg_lock_type = %s", lock_type,
NULL);
if (!_lockd_result(reply, &result, NULL)) {
@ -589,10 +590,12 @@ static int _init_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
log_error("VG %s init failed: invalid parameters for dlm", vg->name);
break;
case -EMANAGER:
log_error("VG %s init failed: lock manager dlm is not running", vg->name);
log_error("VG %s init failed: lock manager %s is not running",
vg->name, lock_type);
break;
case -EPROTONOSUPPORT:
log_error("VG %s init failed: lock manager dlm is not supported by lvmlockd", vg->name);
log_error("VG %s init failed: lock manager %s is not supported by lvmlockd",
vg->name, lock_type);
break;
case -EEXIST:
log_error("VG %s init failed: a lockspace with the same name exists", vg->name);
@ -616,7 +619,7 @@ static int _init_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
goto out;
}
vg->lock_type = "dlm";
vg->lock_type = lock_type;
vg->lock_args = vg_lock_args;
if (!vg_write(vg) || !vg_commit(vg)) {
@ -631,6 +634,16 @@ out:
return ret;
}
static int _init_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
{
return _init_vg(cmd, vg, "dlm");
}
static int _init_vg_idm(struct cmd_context *cmd, struct volume_group *vg)
{
return _init_vg(cmd, vg, "idm");
}
static int _init_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg, int lv_lock_count)
{
daemon_reply reply;
@ -794,7 +807,7 @@ out:
/* called after vg_remove on disk */
static int _free_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
static int _free_vg(struct cmd_context *cmd, struct volume_group *vg)
{
daemon_reply reply;
uint32_t lockd_flags = 0;
@ -820,16 +833,27 @@ static int _free_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
}
if (!ret)
log_error("_free_vg_dlm lvmlockd result %d", result);
log_error("%s: lock type %s lvmlockd result %d",
__func__, vg->lock_type, result);
daemon_reply_destroy(reply);
return 1;
}
static int _free_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
{
return _free_vg(cmd, vg);
}
static int _free_vg_idm(struct cmd_context *cmd, struct volume_group *vg)
{
return _free_vg(cmd, vg);
}
/* called before vg_remove on disk */
static int _busy_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
static int _busy_vg(struct cmd_context *cmd, struct volume_group *vg)
{
daemon_reply reply;
uint32_t lockd_flags = 0;
@ -864,13 +888,24 @@ static int _busy_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
}
if (!ret)
log_error("_busy_vg_dlm lvmlockd result %d", result);
log_error("%s: lock type %s lvmlockd result %d", __func__,
vg->lock_type, result);
out:
daemon_reply_destroy(reply);
return ret;
}
static int _busy_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
{
return _busy_vg(cmd, vg);
}
static int _busy_vg_idm(struct cmd_context *cmd, struct volume_group *vg)
{
return _busy_vg(cmd, vg);
}
/* called before vg_remove on disk */
static int _free_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg)
@ -976,6 +1011,8 @@ int lockd_init_vg(struct cmd_context *cmd, struct volume_group *vg,
return _init_vg_dlm(cmd, vg);
case LOCK_TYPE_SANLOCK:
return _init_vg_sanlock(cmd, vg, lv_lock_count);
case LOCK_TYPE_IDM:
return _init_vg_idm(cmd, vg);
default:
log_error("Unknown lock_type.");
return 0;
@ -1017,7 +1054,8 @@ int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg,
* When removing (not changing), each LV is locked
* when it is removed, they do not need checking here.
*/
if (lock_type_num == LOCK_TYPE_DLM || lock_type_num == LOCK_TYPE_SANLOCK) {
if (lock_type_num == LOCK_TYPE_DLM || lock_type_num == LOCK_TYPE_SANLOCK ||
lock_type_num == LOCK_TYPE_IDM) {
if (changing && !_lockd_all_lvs(cmd, vg)) {
log_error("Cannot change VG %s with active LVs", vg->name);
return 0;
@ -1041,6 +1079,9 @@ int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg,
case LOCK_TYPE_SANLOCK:
/* returning an error will prevent vg_remove() */
return _free_vg_sanlock(cmd, vg);
case LOCK_TYPE_IDM:
/* returning an error will prevent vg_remove() */
return _busy_vg_idm(cmd, vg);
default:
log_error("Unknown lock_type.");
return 0;
@ -1059,6 +1100,9 @@ void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg)
case LOCK_TYPE_DLM:
_free_vg_dlm(cmd, vg);
break;
case LOCK_TYPE_IDM:
_free_vg_idm(cmd, vg);
break;
default:
log_error("Unknown lock_type.");
}
@ -2679,6 +2723,7 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logic
return 1;
case LOCK_TYPE_SANLOCK:
case LOCK_TYPE_DLM:
case LOCK_TYPE_IDM:
break;
default:
log_error("lockd_init_lv: unknown lock_type.");
@ -2821,6 +2866,8 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logic
lv->lock_args = "pending";
else if (!strcmp(vg->lock_type, "dlm"))
lv->lock_args = "dlm";
else if (!strcmp(vg->lock_type, "idm"))
lv->lock_args = "idm";
return 1;
}
@ -2836,6 +2883,7 @@ int lockd_free_lv(struct cmd_context *cmd, struct volume_group *vg,
return 1;
case LOCK_TYPE_DLM:
case LOCK_TYPE_SANLOCK:
case LOCK_TYPE_IDM:
if (!lock_args)
return 1;
return _free_lv(cmd, vg, lv_name, lv_id, lock_args);
@ -3007,6 +3055,10 @@ const char *lockd_running_lock_type(struct cmd_context *cmd, int *found_multiple
log_debug("lvmlockd found dlm");
lock_type = "dlm";
break;
case LOCK_TYPE_IDM:
log_debug("lvmlockd found idm");
lock_type = "idm";
break;
default:
log_error("Failed to find a running lock manager.");
break;

View File

@ -356,6 +356,7 @@ typedef enum {
LOCK_TYPE_CLVM = 1,
LOCK_TYPE_DLM = 2,
LOCK_TYPE_SANLOCK = 3,
LOCK_TYPE_IDM = 4,
} lock_type_t;
struct cmd_context;

View File

@ -2235,6 +2235,13 @@ static int _validate_lv_lock_args(struct logical_volume *lv)
lv->vg->name, display_lvname(lv), lv->lock_args);
r = 0;
}
} else if (!strcmp(lv->vg->lock_type, "idm")) {
if (strcmp(lv->lock_args, "idm")) {
log_error(INTERNAL_ERROR "LV %s/%s has invalid lock_args \"%s\"",
lv->vg->name, display_lvname(lv), lv->lock_args);
r = 0;
}
}
return r;
@ -2569,7 +2576,8 @@ int vg_validate(struct volume_group *vg)
r = 0;
}
if (strcmp(vg->lock_type, "sanlock") && strcmp(vg->lock_type, "dlm")) {
if (strcmp(vg->lock_type, "sanlock") && strcmp(vg->lock_type, "dlm") &&
strcmp(vg->lock_type, "idm")) {
log_error(INTERNAL_ERROR "VG %s has unknown lock_type %s",
vg->name, vg->lock_type);
r = 0;
@ -4355,6 +4363,8 @@ int is_lockd_type(const char *lock_type)
return 1;
if (!strcmp(lock_type, "sanlock"))
return 1;
if (!strcmp(lock_type, "idm"))
return 1;
return 0;
}