[lvm-devel] [LVM2 RFCv1 3/5] lib: locking: Add new type "idm"

Leo Yan leo.yan at linaro.org
Sun Apr 25 02:22:39 UTC 2021


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 at linaro.org>
---
 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 f0f03c0a5..f9c9ef836 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 3b9abd6bf..268f9fc2f 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 874088993..80755c2a3 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -353,6 +353,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 ed1c05f75..b815eda87 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;
@@ -2582,7 +2589,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;
@@ -4368,6 +4376,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;
 }
 
-- 
2.25.1




More information about the lvm-devel mailing list