302 lines
9.5 KiB
Diff
302 lines
9.5 KiB
Diff
|
From ef1c57e68fa67dc0bc144b3a745bc456c3232d3e Mon Sep 17 00:00:00 2001
|
||
|
From: Leo Yan <leo.yan@linaro.org>
|
||
|
Date: Fri, 7 May 2021 10:25:14 +0800
|
||
|
Subject: [PATCH 03/33] 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>
|
||
|
Signed-off-by: Heming Zhao <heming.zhao@suse.com>
|
||
|
---
|
||
|
lib/display/display.c | 4 +++
|
||
|
lib/locking/lvmlockd.c | 72 ++++++++++++++++++++++++++++++++++------
|
||
|
lib/metadata/metadata-exported.h | 1 +
|
||
|
lib/metadata/metadata.c | 12 ++++++-
|
||
|
4 files changed, 78 insertions(+), 11 deletions(-)
|
||
|
|
||
|
diff --git a/lib/display/display.c b/lib/display/display.c
|
||
|
index f0f03c0a5411..f9c9ef83667d 100644
|
||
|
--- a/lib/display/display.c
|
||
|
+++ b/lib/display/display.c
|
||
|
@@ -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;
|
||
|
}
|
||
|
|
||
|
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
|
||
|
index 9a1b4f476f01..040c4246d718 100644
|
||
|
--- a/lib/locking/lvmlockd.c
|
||
|
+++ b/lib/locking/lvmlockd.c
|
||
|
@@ -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;
|
||
|
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
|
||
|
index c6116350f643..52062a1002da 100644
|
||
|
--- a/lib/metadata/metadata-exported.h
|
||
|
+++ b/lib/metadata/metadata-exported.h
|
||
|
@@ -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;
|
||
|
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
|
||
|
index 002d80c010cb..110cbaed4e62 100644
|
||
|
--- a/lib/metadata/metadata.c
|
||
|
+++ b/lib/metadata/metadata.c
|
||
|
@@ -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;
|
||
|
}
|
||
|
|
||
|
--
|
||
|
1.8.3.1
|
||
|
|