709 lines
21 KiB
Diff
709 lines
21 KiB
Diff
|
From d02f5392a0ed8a5f6b7aa14642db1f46ac0682d8 Mon Sep 17 00:00:00 2001
|
||
|
From: Leo Yan <leo.yan@linaro.org>
|
||
|
Date: Fri, 7 May 2021 10:25:13 +0800
|
||
|
Subject: [PATCH 02/33] lvmlockd: idm: Hook Seagate IDM wrapper APIs
|
||
|
|
||
|
To allow the IDM locking scheme be used by users, this patch hooks the
|
||
|
IDM wrapper; it also introducs a new locking type "idm" and we can use
|
||
|
it for global lock with option '-g idm'.
|
||
|
|
||
|
To support IDM locking type, the main change in the data structure is to
|
||
|
add pvs path arrary. The pvs list is transferred from the lvm commands,
|
||
|
when lvmlockd core layer receives message, it extracts the message with
|
||
|
the keyword "path[idx]". Finally, the pv list will pass to IDM lock
|
||
|
manager as the target drives for sending IDM SCSI commands.
|
||
|
|
||
|
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
||
|
Signed-off-by: Heming Zhao <heming.zhao@suse.com>
|
||
|
---
|
||
|
daemons/lvmlockd/lvmlockd-core.c | 281 +++++++++++++++++++++++++++++++----
|
||
|
daemons/lvmlockd/lvmlockd-internal.h | 4 +-
|
||
|
2 files changed, 257 insertions(+), 28 deletions(-)
|
||
|
|
||
|
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
|
||
|
index 238ec718b45a..ea76f2214b3e 100644
|
||
|
--- a/daemons/lvmlockd/lvmlockd-core.c
|
||
|
+++ b/daemons/lvmlockd/lvmlockd-core.c
|
||
|
@@ -421,6 +421,63 @@ struct lockspace *alloc_lockspace(void)
|
||
|
return ls;
|
||
|
}
|
||
|
|
||
|
+static char **alloc_pvs_path(struct pvs *pvs, int num)
|
||
|
+{
|
||
|
+ if (!num)
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ pvs->path = malloc(sizeof(char *) * num);
|
||
|
+ if (!pvs->path)
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ memset(pvs->path, 0x0, sizeof(char *) * num);
|
||
|
+ return pvs->path;
|
||
|
+}
|
||
|
+
|
||
|
+static void free_pvs_path(struct pvs *pvs)
|
||
|
+{
|
||
|
+ int i;
|
||
|
+
|
||
|
+ for (i = 0; i < pvs->num; i++) {
|
||
|
+ if (!pvs->path[i])
|
||
|
+ continue;
|
||
|
+
|
||
|
+ free((char *)pvs->path[i]);
|
||
|
+ pvs->path[i] = NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!pvs->path) {
|
||
|
+ free(pvs->path);
|
||
|
+ pvs->path = NULL;
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static char **alloc_and_copy_pvs_path(struct pvs *dst, struct pvs *src)
|
||
|
+{
|
||
|
+ int i;
|
||
|
+
|
||
|
+ if (!alloc_pvs_path(dst, src->num))
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ dst->num = 0;
|
||
|
+ for (i = 0; i < src->num; i++) {
|
||
|
+ if (!src->path[i] || !strcmp(src->path[i], "none"))
|
||
|
+ continue;
|
||
|
+
|
||
|
+ dst->path[dst->num] = strdup(src->path[i]);
|
||
|
+ if (!dst->path[dst->num]) {
|
||
|
+ log_error("out of memory for copying pvs path");
|
||
|
+ goto failed;
|
||
|
+ }
|
||
|
+ dst->num++;
|
||
|
+ }
|
||
|
+ return dst->path;
|
||
|
+
|
||
|
+failed:
|
||
|
+ free_pvs_path(dst);
|
||
|
+ return NULL;
|
||
|
+}
|
||
|
+
|
||
|
static struct action *alloc_action(void)
|
||
|
{
|
||
|
struct action *act;
|
||
|
@@ -510,6 +567,9 @@ static void free_action(struct action *act)
|
||
|
free(act->path);
|
||
|
act->path = NULL;
|
||
|
}
|
||
|
+
|
||
|
+ free_pvs_path(&act->pvs);
|
||
|
+
|
||
|
pthread_mutex_lock(&unused_struct_mutex);
|
||
|
if (unused_action_count >= MAX_UNUSED_ACTION) {
|
||
|
free(act);
|
||
|
@@ -564,9 +624,12 @@ static int setup_structs(void)
|
||
|
struct lock *lk;
|
||
|
int data_san = lm_data_size_sanlock();
|
||
|
int data_dlm = lm_data_size_dlm();
|
||
|
+ int data_idm = lm_data_size_idm();
|
||
|
int i;
|
||
|
|
||
|
resource_lm_data_size = data_san > data_dlm ? data_san : data_dlm;
|
||
|
+ resource_lm_data_size = resource_lm_data_size > data_idm ?
|
||
|
+ resource_lm_data_size : data_idm;
|
||
|
|
||
|
pthread_mutex_init(&unused_struct_mutex, NULL);
|
||
|
INIT_LIST_HEAD(&unused_action);
|
||
|
@@ -683,6 +746,8 @@ static const char *lm_str(int x)
|
||
|
return "dlm";
|
||
|
case LD_LM_SANLOCK:
|
||
|
return "sanlock";
|
||
|
+ case LD_LM_IDM:
|
||
|
+ return "idm";
|
||
|
default:
|
||
|
return "lm_unknown";
|
||
|
}
|
||
|
@@ -968,6 +1033,8 @@ static int lm_prepare_lockspace(struct lockspace *ls, struct action *act)
|
||
|
rv = lm_prepare_lockspace_dlm(ls);
|
||
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||
|
rv = lm_prepare_lockspace_sanlock(ls);
|
||
|
+ else if (ls->lm_type == LD_LM_IDM)
|
||
|
+ rv = lm_prepare_lockspace_idm(ls);
|
||
|
else
|
||
|
return -1;
|
||
|
|
||
|
@@ -984,6 +1051,8 @@ static int lm_add_lockspace(struct lockspace *ls, struct action *act, int adopt)
|
||
|
rv = lm_add_lockspace_dlm(ls, adopt);
|
||
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||
|
rv = lm_add_lockspace_sanlock(ls, adopt);
|
||
|
+ else if (ls->lm_type == LD_LM_IDM)
|
||
|
+ rv = lm_add_lockspace_idm(ls, adopt);
|
||
|
else
|
||
|
return -1;
|
||
|
|
||
|
@@ -1000,6 +1069,8 @@ static int lm_rem_lockspace(struct lockspace *ls, struct action *act, int free_v
|
||
|
rv = lm_rem_lockspace_dlm(ls, free_vg);
|
||
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||
|
rv = lm_rem_lockspace_sanlock(ls, free_vg);
|
||
|
+ else if (ls->lm_type == LD_LM_IDM)
|
||
|
+ rv = lm_rem_lockspace_idm(ls, free_vg);
|
||
|
else
|
||
|
return -1;
|
||
|
|
||
|
@@ -1017,6 +1088,9 @@ static int lm_lock(struct lockspace *ls, struct resource *r, int mode, struct ac
|
||
|
rv = lm_lock_dlm(ls, r, mode, vb_out, adopt);
|
||
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||
|
rv = lm_lock_sanlock(ls, r, mode, vb_out, retry, adopt);
|
||
|
+ else if (ls->lm_type == LD_LM_IDM)
|
||
|
+ rv = lm_lock_idm(ls, r, mode, vb_out, act->lv_uuid,
|
||
|
+ &act->pvs, adopt);
|
||
|
else
|
||
|
return -1;
|
||
|
|
||
|
@@ -1034,6 +1108,8 @@ static int lm_convert(struct lockspace *ls, struct resource *r,
|
||
|
rv = lm_convert_dlm(ls, r, mode, r_version);
|
||
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||
|
rv = lm_convert_sanlock(ls, r, mode, r_version);
|
||
|
+ else if (ls->lm_type == LD_LM_IDM)
|
||
|
+ rv = lm_convert_idm(ls, r, mode, r_version);
|
||
|
else
|
||
|
return -1;
|
||
|
|
||
|
@@ -1051,6 +1127,8 @@ static int lm_unlock(struct lockspace *ls, struct resource *r, struct action *ac
|
||
|
rv = lm_unlock_dlm(ls, r, r_version, lmu_flags);
|
||
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||
|
rv = lm_unlock_sanlock(ls, r, r_version, lmu_flags);
|
||
|
+ else if (ls->lm_type == LD_LM_IDM)
|
||
|
+ rv = lm_unlock_idm(ls, r, r_version, lmu_flags);
|
||
|
else
|
||
|
return -1;
|
||
|
|
||
|
@@ -1065,6 +1143,8 @@ static int lm_hosts(struct lockspace *ls, int notify)
|
||
|
return lm_hosts_dlm(ls, notify);
|
||
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||
|
return lm_hosts_sanlock(ls, notify);
|
||
|
+ else if (ls->lm_type == LD_LM_IDM)
|
||
|
+ return lm_hosts_idm(ls, notify);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
@@ -1074,6 +1154,8 @@ static void lm_rem_resource(struct lockspace *ls, struct resource *r)
|
||
|
lm_rem_resource_dlm(ls, r);
|
||
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||
|
lm_rem_resource_sanlock(ls, r);
|
||
|
+ else if (ls->lm_type == LD_LM_IDM)
|
||
|
+ lm_rem_resource_idm(ls, r);
|
||
|
}
|
||
|
|
||
|
static int lm_find_free_lock(struct lockspace *ls, uint64_t *free_offset, int *sector_size, int *align_size)
|
||
|
@@ -1082,6 +1164,8 @@ static int lm_find_free_lock(struct lockspace *ls, uint64_t *free_offset, int *s
|
||
|
return 0;
|
||
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||
|
return lm_find_free_lock_sanlock(ls, free_offset, sector_size, align_size);
|
||
|
+ else if (ls->lm_type == LD_LM_IDM)
|
||
|
+ return 0;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
@@ -1690,8 +1774,8 @@ static int res_update(struct lockspace *ls, struct resource *r,
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
- * There is nothing to deallocate when freeing a dlm LV, the LV
|
||
|
- * will simply be unlocked by rem_resource.
|
||
|
+ * For DLM and IDM locking scheme, there is nothing to deallocate when freeing a
|
||
|
+ * LV, the LV will simply be unlocked by rem_resource.
|
||
|
*/
|
||
|
|
||
|
static int free_lv(struct lockspace *ls, struct resource *r)
|
||
|
@@ -1700,6 +1784,8 @@ static int free_lv(struct lockspace *ls, struct resource *r)
|
||
|
return lm_free_lv_sanlock(ls, r);
|
||
|
else if (ls->lm_type == LD_LM_DLM)
|
||
|
return 0;
|
||
|
+ else if (ls->lm_type == LD_LM_IDM)
|
||
|
+ return 0;
|
||
|
else
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
@@ -2758,6 +2844,8 @@ out_act:
|
||
|
ls->drop_vg = drop_vg;
|
||
|
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
|
||
|
global_dlm_lockspace_exists = 0;
|
||
|
+ if (ls->lm_type == LD_LM_IDM && !strcmp(ls->name, gl_lsname_idm))
|
||
|
+ global_idm_lockspace_exists = 0;
|
||
|
|
||
|
/*
|
||
|
* Avoid a name collision of the same lockspace is added again before
|
||
|
@@ -2849,6 +2937,8 @@ static void gl_ls_name(char *ls_name)
|
||
|
memcpy(ls_name, gl_lsname_dlm, MAX_NAME);
|
||
|
else if (gl_use_sanlock)
|
||
|
memcpy(ls_name, gl_lsname_sanlock, MAX_NAME);
|
||
|
+ else if (gl_use_idm)
|
||
|
+ memcpy(ls_name, gl_lsname_idm, MAX_NAME);
|
||
|
else
|
||
|
memset(ls_name, 0, MAX_NAME);
|
||
|
}
|
||
|
@@ -2877,9 +2967,20 @@ static int add_lockspace_thread(const char *ls_name,
|
||
|
strncpy(ls->name, ls_name, MAX_NAME);
|
||
|
ls->lm_type = lm_type;
|
||
|
|
||
|
- if (act)
|
||
|
+ if (act) {
|
||
|
ls->start_client_id = act->client_id;
|
||
|
|
||
|
+ /*
|
||
|
+ * Copy PV list to lockspact structure, so this is
|
||
|
+ * used for VG locking for idm scheme.
|
||
|
+ */
|
||
|
+ if (lm_type == LD_LM_IDM &&
|
||
|
+ !alloc_and_copy_pvs_path(&ls->pvs, &act->pvs)) {
|
||
|
+ free(ls);
|
||
|
+ return -ENOMEM;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
if (vg_uuid)
|
||
|
strncpy(ls->vg_uuid, vg_uuid, 64);
|
||
|
|
||
|
@@ -2906,6 +3007,18 @@ static int add_lockspace_thread(const char *ls_name,
|
||
|
pthread_mutex_lock(&lockspaces_mutex);
|
||
|
ls2 = find_lockspace_name(ls->name);
|
||
|
if (ls2) {
|
||
|
+ /*
|
||
|
+ * If find an existed lockspace, we need to update the PV list
|
||
|
+ * based on the latest information, and release for the old
|
||
|
+ * PV list in case it keeps stale information.
|
||
|
+ */
|
||
|
+ free_pvs_path(&ls2->pvs);
|
||
|
+ if (lm_type == LD_LM_IDM &&
|
||
|
+ !alloc_and_copy_pvs_path(&ls2->pvs, &ls->pvs)) {
|
||
|
+ log_debug("add_lockspace_thread %s fails to allocate pvs", ls->name);
|
||
|
+ rv = -ENOMEM;
|
||
|
+ }
|
||
|
+
|
||
|
if (ls2->thread_stop) {
|
||
|
log_debug("add_lockspace_thread %s exists and stopping", ls->name);
|
||
|
rv = -EAGAIN;
|
||
|
@@ -2918,6 +3031,7 @@ static int add_lockspace_thread(const char *ls_name,
|
||
|
}
|
||
|
pthread_mutex_unlock(&lockspaces_mutex);
|
||
|
free_resource(r);
|
||
|
+ free_pvs_path(&ls->pvs);
|
||
|
free(ls);
|
||
|
return rv;
|
||
|
}
|
||
|
@@ -2931,6 +3045,8 @@ static int add_lockspace_thread(const char *ls_name,
|
||
|
|
||
|
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
|
||
|
global_dlm_lockspace_exists = 1;
|
||
|
+ if (ls->lm_type == LD_LM_IDM && !strcmp(ls->name, gl_lsname_idm))
|
||
|
+ global_idm_lockspace_exists = 1;
|
||
|
list_add_tail(&ls->list, &lockspaces);
|
||
|
pthread_mutex_unlock(&lockspaces_mutex);
|
||
|
|
||
|
@@ -2941,6 +3057,7 @@ static int add_lockspace_thread(const char *ls_name,
|
||
|
list_del(&ls->list);
|
||
|
pthread_mutex_unlock(&lockspaces_mutex);
|
||
|
free_resource(r);
|
||
|
+ free_pvs_path(&ls->pvs);
|
||
|
free(ls);
|
||
|
return rv;
|
||
|
}
|
||
|
@@ -2949,16 +3066,15 @@ static int add_lockspace_thread(const char *ls_name,
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
- * There is no add_sanlock_global_lockspace or
|
||
|
- * rem_sanlock_global_lockspace because with sanlock,
|
||
|
- * the global lockspace is one of the vg lockspaces.
|
||
|
+ * There is no variant for sanlock because, with sanlock, the global
|
||
|
+ * lockspace is one of the vg lockspaces.
|
||
|
*/
|
||
|
-
|
||
|
-static int add_dlm_global_lockspace(struct action *act)
|
||
|
+static int add_global_lockspace(char *ls_name, int lm_type,
|
||
|
+ struct action *act)
|
||
|
{
|
||
|
int rv;
|
||
|
|
||
|
- if (global_dlm_lockspace_exists)
|
||
|
+ if (global_dlm_lockspace_exists || global_idm_lockspace_exists)
|
||
|
return 0;
|
||
|
|
||
|
/*
|
||
|
@@ -2966,9 +3082,9 @@ static int add_dlm_global_lockspace(struct action *act)
|
||
|
* lock request, insert an internal gl sh lock request?
|
||
|
*/
|
||
|
|
||
|
- rv = add_lockspace_thread(gl_lsname_dlm, NULL, NULL, LD_LM_DLM, NULL, act);
|
||
|
+ rv = add_lockspace_thread(ls_name, NULL, NULL, lm_type, NULL, act);
|
||
|
if (rv < 0)
|
||
|
- log_debug("add_dlm_global_lockspace add_lockspace_thread %d", rv);
|
||
|
+ log_debug("add_global_lockspace add_lockspace_thread %d", rv);
|
||
|
|
||
|
/*
|
||
|
* EAGAIN may be returned for a short period because
|
||
|
@@ -2981,12 +3097,12 @@ static int add_dlm_global_lockspace(struct action *act)
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
- * If dlm gl lockspace is the only one left, then stop it.
|
||
|
- * This is not used for an explicit rem_lockspace action from
|
||
|
- * the client, only for auto remove.
|
||
|
+ * When DLM or IDM locking scheme is used for global lock, if the global
|
||
|
+ * lockspace is the only one left, then stop it. This is not used for
|
||
|
+ * an explicit rem_lockspace action from the client, only for auto
|
||
|
+ * remove.
|
||
|
*/
|
||
|
-
|
||
|
-static int rem_dlm_global_lockspace(void)
|
||
|
+static int rem_global_lockspace(char *ls_name)
|
||
|
{
|
||
|
struct lockspace *ls, *ls_gl = NULL;
|
||
|
int others = 0;
|
||
|
@@ -2994,7 +3110,7 @@ static int rem_dlm_global_lockspace(void)
|
||
|
|
||
|
pthread_mutex_lock(&lockspaces_mutex);
|
||
|
list_for_each_entry(ls, &lockspaces, list) {
|
||
|
- if (!strcmp(ls->name, gl_lsname_dlm)) {
|
||
|
+ if (!strcmp(ls->name, ls_name)) {
|
||
|
ls_gl = ls;
|
||
|
continue;
|
||
|
}
|
||
|
@@ -3026,6 +3142,26 @@ out:
|
||
|
return rv;
|
||
|
}
|
||
|
|
||
|
+static int add_dlm_global_lockspace(struct action *act)
|
||
|
+{
|
||
|
+ return add_global_lockspace(gl_lsname_dlm, LD_LM_DLM, act);
|
||
|
+}
|
||
|
+
|
||
|
+static int rem_dlm_global_lockspace(void)
|
||
|
+{
|
||
|
+ return rem_global_lockspace(gl_lsname_dlm);
|
||
|
+}
|
||
|
+
|
||
|
+static int add_idm_global_lockspace(struct action *act)
|
||
|
+{
|
||
|
+ return add_global_lockspace(gl_lsname_idm, LD_LM_IDM, act);
|
||
|
+}
|
||
|
+
|
||
|
+static int rem_idm_global_lockspace(void)
|
||
|
+{
|
||
|
+ return rem_global_lockspace(gl_lsname_idm);
|
||
|
+}
|
||
|
+
|
||
|
/*
|
||
|
* When the first dlm lockspace is added for a vg, automatically add a separate
|
||
|
* dlm lockspace for the global lock.
|
||
|
@@ -3051,6 +3187,9 @@ static int add_lockspace(struct action *act)
|
||
|
if (gl_use_dlm) {
|
||
|
rv = add_dlm_global_lockspace(act);
|
||
|
return rv;
|
||
|
+ } else if (gl_use_idm) {
|
||
|
+ rv = add_idm_global_lockspace(act);
|
||
|
+ return rv;
|
||
|
} else {
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
@@ -3059,6 +3198,8 @@ static int add_lockspace(struct action *act)
|
||
|
if (act->rt == LD_RT_VG) {
|
||
|
if (gl_use_dlm)
|
||
|
add_dlm_global_lockspace(NULL);
|
||
|
+ else if (gl_use_idm)
|
||
|
+ add_idm_global_lockspace(NULL);
|
||
|
|
||
|
vg_ls_name(act->vg_name, ls_name);
|
||
|
|
||
|
@@ -3126,14 +3267,15 @@ static int rem_lockspace(struct action *act)
|
||
|
pthread_mutex_unlock(&lockspaces_mutex);
|
||
|
|
||
|
/*
|
||
|
- * The dlm global lockspace was automatically added when
|
||
|
- * the first dlm vg lockspace was added, now reverse that
|
||
|
- * by automatically removing the dlm global lockspace when
|
||
|
- * the last dlm vg lockspace is removed.
|
||
|
+ * For DLM and IDM locking scheme, the global lockspace was
|
||
|
+ * automatically added when the first vg lockspace was added,
|
||
|
+ * now reverse that by automatically removing the dlm global
|
||
|
+ * lockspace when the last vg lockspace is removed.
|
||
|
*/
|
||
|
-
|
||
|
if (rt == LD_RT_VG && gl_use_dlm)
|
||
|
rem_dlm_global_lockspace();
|
||
|
+ else if (rt == LD_RT_VG && gl_use_idm)
|
||
|
+ rem_idm_global_lockspace();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
@@ -3257,6 +3399,7 @@ static int for_each_lockspace(int do_stop, int do_free, int do_force)
|
||
|
if (ls->free_vg) {
|
||
|
/* In future we may need to free ls->actions here */
|
||
|
free_ls_resources(ls);
|
||
|
+ free_pvs_path(&ls->pvs);
|
||
|
free(ls);
|
||
|
free_count++;
|
||
|
}
|
||
|
@@ -3270,6 +3413,7 @@ static int for_each_lockspace(int do_stop, int do_free, int do_force)
|
||
|
if (!gl_type_static) {
|
||
|
gl_use_dlm = 0;
|
||
|
gl_use_sanlock = 0;
|
||
|
+ gl_use_idm = 0;
|
||
|
}
|
||
|
}
|
||
|
pthread_mutex_unlock(&lockspaces_mutex);
|
||
|
@@ -3345,6 +3489,9 @@ static int work_init_vg(struct action *act)
|
||
|
rv = lm_init_vg_sanlock(ls_name, act->vg_name, act->flags, act->vg_args);
|
||
|
else if (act->lm_type == LD_LM_DLM)
|
||
|
rv = lm_init_vg_dlm(ls_name, act->vg_name, act->flags, act->vg_args);
|
||
|
+ else if (act->lm_type == LD_LM_IDM)
|
||
|
+ /* Non't do anything for IDM when initialize VG */
|
||
|
+ rv = 0;
|
||
|
else
|
||
|
rv = -EINVAL;
|
||
|
|
||
|
@@ -3448,6 +3595,8 @@ static int work_init_lv(struct action *act)
|
||
|
|
||
|
} else if (act->lm_type == LD_LM_DLM) {
|
||
|
return 0;
|
||
|
+ } else if (act->lm_type == LD_LM_IDM) {
|
||
|
+ return 0;
|
||
|
} else {
|
||
|
log_error("init_lv ls_name %s bad lm_type %d", ls_name, act->lm_type);
|
||
|
return -EINVAL;
|
||
|
@@ -3511,20 +3660,29 @@ static void *worker_thread_main(void *arg_in)
|
||
|
if (act->op == LD_OP_RUNNING_LM) {
|
||
|
int run_sanlock = lm_is_running_sanlock();
|
||
|
int run_dlm = lm_is_running_dlm();
|
||
|
+ int run_idm = lm_is_running_idm();
|
||
|
|
||
|
if (daemon_test) {
|
||
|
run_sanlock = gl_use_sanlock;
|
||
|
run_dlm = gl_use_dlm;
|
||
|
+ run_idm = gl_use_idm;
|
||
|
}
|
||
|
|
||
|
- if (run_sanlock && run_dlm)
|
||
|
+ /*
|
||
|
+ * It's not possible to enable multiple locking schemes
|
||
|
+ * for global lock, otherwise, it must be conflict and
|
||
|
+ * reports it!
|
||
|
+ */
|
||
|
+ if ((run_sanlock + run_dlm + run_idm) >= 2)
|
||
|
act->result = -EXFULL;
|
||
|
- else if (!run_sanlock && !run_dlm)
|
||
|
+ else if (!run_sanlock && !run_dlm && !run_idm)
|
||
|
act->result = -ENOLCK;
|
||
|
else if (run_sanlock)
|
||
|
act->result = LD_LM_SANLOCK;
|
||
|
else if (run_dlm)
|
||
|
act->result = LD_LM_DLM;
|
||
|
+ else if (run_idm)
|
||
|
+ act->result = LD_LM_IDM;
|
||
|
add_client_result(act);
|
||
|
|
||
|
} else if ((act->op == LD_OP_LOCK) && (act->flags & LD_AF_SEARCH_LS)) {
|
||
|
@@ -3812,6 +3970,9 @@ static int client_send_result(struct client *cl, struct action *act)
|
||
|
} else if (gl_use_dlm) {
|
||
|
if (!gl_lsname_dlm[0])
|
||
|
strcat(result_flags, "NO_GL_LS,");
|
||
|
+ } else if (gl_use_idm) {
|
||
|
+ if (!gl_lsname_idm[0])
|
||
|
+ strcat(result_flags, "NO_GL_LS,");
|
||
|
} else {
|
||
|
int found_lm = 0;
|
||
|
|
||
|
@@ -3819,6 +3980,8 @@ static int client_send_result(struct client *cl, struct action *act)
|
||
|
found_lm++;
|
||
|
if (lm_support_sanlock() && lm_is_running_sanlock())
|
||
|
found_lm++;
|
||
|
+ if (lm_support_idm() && lm_is_running_idm())
|
||
|
+ found_lm++;
|
||
|
|
||
|
if (!found_lm)
|
||
|
strcat(result_flags, "NO_GL_LS,NO_LM");
|
||
|
@@ -3994,11 +4157,13 @@ static int add_lock_action(struct action *act)
|
||
|
if (gl_use_sanlock && (act->op == LD_OP_ENABLE || act->op == LD_OP_DISABLE)) {
|
||
|
vg_ls_name(act->vg_name, ls_name);
|
||
|
} else {
|
||
|
- if (!gl_use_dlm && !gl_use_sanlock) {
|
||
|
+ if (!gl_use_dlm && !gl_use_sanlock && !gl_use_idm) {
|
||
|
if (lm_is_running_dlm())
|
||
|
gl_use_dlm = 1;
|
||
|
else if (lm_is_running_sanlock())
|
||
|
gl_use_sanlock = 1;
|
||
|
+ else if (lm_is_running_idm())
|
||
|
+ gl_use_idm = 1;
|
||
|
}
|
||
|
gl_ls_name(ls_name);
|
||
|
}
|
||
|
@@ -4046,6 +4211,17 @@ static int add_lock_action(struct action *act)
|
||
|
add_dlm_global_lockspace(NULL);
|
||
|
goto retry;
|
||
|
|
||
|
+ } else if (act->op == LD_OP_LOCK && act->rt == LD_RT_GL && act->mode != LD_LK_UN && gl_use_idm) {
|
||
|
+ /*
|
||
|
+ * Automatically start the idm global lockspace when
|
||
|
+ * a command tries to acquire the global lock.
|
||
|
+ */
|
||
|
+ log_debug("lockspace \"%s\" not found for idm gl, adding...", ls_name);
|
||
|
+ act->flags |= LD_AF_SEARCH_LS;
|
||
|
+ act->flags |= LD_AF_WAIT_STARTING;
|
||
|
+ add_idm_global_lockspace(NULL);
|
||
|
+ goto retry;
|
||
|
+
|
||
|
} else if (act->op == LD_OP_LOCK && act->mode == LD_LK_UN) {
|
||
|
log_debug("lockspace \"%s\" not found for unlock ignored", ls_name);
|
||
|
return -ENOLS;
|
||
|
@@ -4266,6 +4442,8 @@ static int str_to_lm(const char *str)
|
||
|
return LD_LM_SANLOCK;
|
||
|
if (!strcmp(str, "dlm"))
|
||
|
return LD_LM_DLM;
|
||
|
+ if (!strcmp(str, "idm"))
|
||
|
+ return LD_LM_IDM;
|
||
|
return -2;
|
||
|
}
|
||
|
|
||
|
@@ -4601,12 +4779,14 @@ static void client_recv_action(struct client *cl)
|
||
|
const char *vg_sysid;
|
||
|
const char *path;
|
||
|
const char *str;
|
||
|
+ struct pvs pvs;
|
||
|
+ char buf[11]; /* p a t h [ x x x x ] \0 */
|
||
|
int64_t val;
|
||
|
uint32_t opts = 0;
|
||
|
int result = 0;
|
||
|
int cl_pid;
|
||
|
int op, rt, lm, mode;
|
||
|
- int rv;
|
||
|
+ int rv, i;
|
||
|
|
||
|
buffer_init(&req.buffer);
|
||
|
|
||
|
@@ -4695,11 +4875,13 @@ static void client_recv_action(struct client *cl)
|
||
|
if (!cl->name[0] && cl_name)
|
||
|
strncpy(cl->name, cl_name, MAX_NAME);
|
||
|
|
||
|
- if (!gl_use_dlm && !gl_use_sanlock && (lm > 0)) {
|
||
|
+ if (!gl_use_dlm && !gl_use_sanlock && !gl_use_idm && (lm > 0)) {
|
||
|
if (lm == LD_LM_DLM && lm_support_dlm())
|
||
|
gl_use_dlm = 1;
|
||
|
else if (lm == LD_LM_SANLOCK && lm_support_sanlock())
|
||
|
gl_use_sanlock = 1;
|
||
|
+ else if (lm == LD_LM_IDM && lm_support_idm())
|
||
|
+ gl_use_idm = 1;
|
||
|
|
||
|
log_debug("set gl_use_%s", lm_str(lm));
|
||
|
}
|
||
|
@@ -4756,6 +4938,40 @@ static void client_recv_action(struct client *cl)
|
||
|
if (val)
|
||
|
act->host_id = val;
|
||
|
|
||
|
+ /* Create PV list for idm */
|
||
|
+ if (lm == LD_LM_IDM) {
|
||
|
+ memset(&pvs, 0x0, sizeof(pvs));
|
||
|
+
|
||
|
+ pvs.num = daemon_request_int(req, "path_num", 0);
|
||
|
+ log_error("pvs_num = %d", pvs.num);
|
||
|
+
|
||
|
+ if (!pvs.num)
|
||
|
+ goto skip_pvs_path;
|
||
|
+
|
||
|
+ /* Receive the pv list which is transferred from LVM command */
|
||
|
+ if (!alloc_pvs_path(&pvs, pvs.num)) {
|
||
|
+ log_error("fail to allocate pvs path");
|
||
|
+ rv = -ENOMEM;
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ for (i = 0; i < pvs.num; i++) {
|
||
|
+ snprintf(buf, sizeof(buf), "path[%d]", i);
|
||
|
+ pvs.path[i] = (char *)daemon_request_str(req, buf, NULL);
|
||
|
+ }
|
||
|
+
|
||
|
+ if (!alloc_and_copy_pvs_path(&act->pvs, &pvs)) {
|
||
|
+ log_error("fail to allocate pvs path");
|
||
|
+ rv = -ENOMEM;
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (pvs.path)
|
||
|
+ free(pvs.path);
|
||
|
+ pvs.path = NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+skip_pvs_path:
|
||
|
act->max_retries = daemon_request_int(req, "max_retries", DEFAULT_MAX_RETRIES);
|
||
|
|
||
|
dm_config_destroy(req.cft);
|
||
|
@@ -4777,6 +4993,12 @@ static void client_recv_action(struct client *cl)
|
||
|
goto out;
|
||
|
}
|
||
|
|
||
|
+ if (lm == LD_LM_IDM && !lm_support_idm()) {
|
||
|
+ log_debug("idm not supported");
|
||
|
+ rv = -EPROTONOSUPPORT;
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
if (act->op == LD_OP_LOCK && act->mode != LD_LK_UN)
|
||
|
cl->lock_ops = 1;
|
||
|
|
||
|
@@ -5375,6 +5597,7 @@ static void adopt_locks(void)
|
||
|
}
|
||
|
|
||
|
list_del(&ls->list);
|
||
|
+ free_pvs_path(&ls->pvs);
|
||
|
free(ls);
|
||
|
}
|
||
|
|
||
|
@@ -5415,6 +5638,7 @@ static void adopt_locks(void)
|
||
|
if (rv < 0) {
|
||
|
log_error("Failed to create lockspace thread for VG %s", ls->vg_name);
|
||
|
list_del(&ls->list);
|
||
|
+ free_pvs_path(&ls->pvs);
|
||
|
free(ls);
|
||
|
free_action(act);
|
||
|
count_start_fail++;
|
||
|
@@ -5857,6 +6081,7 @@ static int main_loop(daemon_state *ds_arg)
|
||
|
}
|
||
|
|
||
|
strcpy(gl_lsname_dlm, S_NAME_GL_DLM);
|
||
|
+ strcpy(gl_lsname_idm, S_NAME_GL_IDM);
|
||
|
|
||
|
INIT_LIST_HEAD(&lockspaces);
|
||
|
pthread_mutex_init(&lockspaces_mutex, NULL);
|
||
|
@@ -6110,6 +6335,8 @@ int main(int argc, char *argv[])
|
||
|
gl_use_dlm = 1;
|
||
|
else if (lm == LD_LM_SANLOCK && lm_support_sanlock())
|
||
|
gl_use_sanlock = 1;
|
||
|
+ else if (lm == LD_LM_IDM && lm_support_idm())
|
||
|
+ gl_use_idm = 1;
|
||
|
else {
|
||
|
fprintf(stderr, "invalid gl-type option\n");
|
||
|
exit(EXIT_FAILURE);
|
||
|
diff --git a/daemons/lvmlockd/lvmlockd-internal.h b/daemons/lvmlockd/lvmlockd-internal.h
|
||
|
index 06bf07eb59cf..ad32eb3a40e2 100644
|
||
|
--- a/daemons/lvmlockd/lvmlockd-internal.h
|
||
|
+++ b/daemons/lvmlockd/lvmlockd-internal.h
|
||
|
@@ -121,7 +121,7 @@ struct client {
|
||
|
#define DEFAULT_MAX_RETRIES 4
|
||
|
|
||
|
struct pvs {
|
||
|
- const char **path;
|
||
|
+ char **path;
|
||
|
int num;
|
||
|
};
|
||
|
|
||
|
@@ -338,7 +338,9 @@ EXTERN int gl_use_idm;
|
||
|
EXTERN int gl_vg_removed;
|
||
|
EXTERN char gl_lsname_dlm[MAX_NAME+1];
|
||
|
EXTERN char gl_lsname_sanlock[MAX_NAME+1];
|
||
|
+EXTERN char gl_lsname_idm[MAX_NAME+1];
|
||
|
EXTERN int global_dlm_lockspace_exists;
|
||
|
+EXTERN int global_idm_lockspace_exists;
|
||
|
|
||
|
EXTERN int daemon_test; /* run as much as possible without a live lock manager */
|
||
|
EXTERN int daemon_debug;
|
||
|
--
|
||
|
1.8.3.1
|
||
|
|