mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
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>
This commit is contained in:
parent
7a8b7b4add
commit
d02f5392a0
@ -421,6 +421,63 @@ struct lockspace *alloc_lockspace(void)
|
|||||||
return ls;
|
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)
|
static struct action *alloc_action(void)
|
||||||
{
|
{
|
||||||
struct action *act;
|
struct action *act;
|
||||||
@ -510,6 +567,9 @@ static void free_action(struct action *act)
|
|||||||
free(act->path);
|
free(act->path);
|
||||||
act->path = NULL;
|
act->path = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_pvs_path(&act->pvs);
|
||||||
|
|
||||||
pthread_mutex_lock(&unused_struct_mutex);
|
pthread_mutex_lock(&unused_struct_mutex);
|
||||||
if (unused_action_count >= MAX_UNUSED_ACTION) {
|
if (unused_action_count >= MAX_UNUSED_ACTION) {
|
||||||
free(act);
|
free(act);
|
||||||
@ -564,9 +624,12 @@ static int setup_structs(void)
|
|||||||
struct lock *lk;
|
struct lock *lk;
|
||||||
int data_san = lm_data_size_sanlock();
|
int data_san = lm_data_size_sanlock();
|
||||||
int data_dlm = lm_data_size_dlm();
|
int data_dlm = lm_data_size_dlm();
|
||||||
|
int data_idm = lm_data_size_idm();
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
resource_lm_data_size = data_san > data_dlm ? data_san : data_dlm;
|
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);
|
pthread_mutex_init(&unused_struct_mutex, NULL);
|
||||||
INIT_LIST_HEAD(&unused_action);
|
INIT_LIST_HEAD(&unused_action);
|
||||||
@ -683,6 +746,8 @@ static const char *lm_str(int x)
|
|||||||
return "dlm";
|
return "dlm";
|
||||||
case LD_LM_SANLOCK:
|
case LD_LM_SANLOCK:
|
||||||
return "sanlock";
|
return "sanlock";
|
||||||
|
case LD_LM_IDM:
|
||||||
|
return "idm";
|
||||||
default:
|
default:
|
||||||
return "lm_unknown";
|
return "lm_unknown";
|
||||||
}
|
}
|
||||||
@ -968,6 +1033,8 @@ static int lm_prepare_lockspace(struct lockspace *ls, struct action *act)
|
|||||||
rv = lm_prepare_lockspace_dlm(ls);
|
rv = lm_prepare_lockspace_dlm(ls);
|
||||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||||
rv = lm_prepare_lockspace_sanlock(ls);
|
rv = lm_prepare_lockspace_sanlock(ls);
|
||||||
|
else if (ls->lm_type == LD_LM_IDM)
|
||||||
|
rv = lm_prepare_lockspace_idm(ls);
|
||||||
else
|
else
|
||||||
return -1;
|
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);
|
rv = lm_add_lockspace_dlm(ls, adopt);
|
||||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||||
rv = lm_add_lockspace_sanlock(ls, adopt);
|
rv = lm_add_lockspace_sanlock(ls, adopt);
|
||||||
|
else if (ls->lm_type == LD_LM_IDM)
|
||||||
|
rv = lm_add_lockspace_idm(ls, adopt);
|
||||||
else
|
else
|
||||||
return -1;
|
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);
|
rv = lm_rem_lockspace_dlm(ls, free_vg);
|
||||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||||
rv = lm_rem_lockspace_sanlock(ls, free_vg);
|
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
|
else
|
||||||
return -1;
|
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);
|
rv = lm_lock_dlm(ls, r, mode, vb_out, adopt);
|
||||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||||
rv = lm_lock_sanlock(ls, r, mode, vb_out, retry, adopt);
|
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
|
else
|
||||||
return -1;
|
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);
|
rv = lm_convert_dlm(ls, r, mode, r_version);
|
||||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||||
rv = lm_convert_sanlock(ls, r, mode, r_version);
|
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
|
else
|
||||||
return -1;
|
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);
|
rv = lm_unlock_dlm(ls, r, r_version, lmu_flags);
|
||||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||||
rv = lm_unlock_sanlock(ls, r, r_version, lmu_flags);
|
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
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1065,6 +1143,8 @@ static int lm_hosts(struct lockspace *ls, int notify)
|
|||||||
return lm_hosts_dlm(ls, notify);
|
return lm_hosts_dlm(ls, notify);
|
||||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||||
return lm_hosts_sanlock(ls, notify);
|
return lm_hosts_sanlock(ls, notify);
|
||||||
|
else if (ls->lm_type == LD_LM_IDM)
|
||||||
|
return lm_hosts_idm(ls, notify);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1074,6 +1154,8 @@ static void lm_rem_resource(struct lockspace *ls, struct resource *r)
|
|||||||
lm_rem_resource_dlm(ls, r);
|
lm_rem_resource_dlm(ls, r);
|
||||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||||
lm_rem_resource_sanlock(ls, r);
|
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)
|
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;
|
return 0;
|
||||||
else if (ls->lm_type == LD_LM_SANLOCK)
|
else if (ls->lm_type == LD_LM_SANLOCK)
|
||||||
return lm_find_free_lock_sanlock(ls, free_offset, sector_size, align_size);
|
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;
|
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
|
* For DLM and IDM locking scheme, there is nothing to deallocate when freeing a
|
||||||
* will simply be unlocked by rem_resource.
|
* LV, the LV will simply be unlocked by rem_resource.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int free_lv(struct lockspace *ls, struct resource *r)
|
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);
|
return lm_free_lv_sanlock(ls, r);
|
||||||
else if (ls->lm_type == LD_LM_DLM)
|
else if (ls->lm_type == LD_LM_DLM)
|
||||||
return 0;
|
return 0;
|
||||||
|
else if (ls->lm_type == LD_LM_IDM)
|
||||||
|
return 0;
|
||||||
else
|
else
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -2758,6 +2844,8 @@ out_act:
|
|||||||
ls->drop_vg = drop_vg;
|
ls->drop_vg = drop_vg;
|
||||||
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
|
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
|
||||||
global_dlm_lockspace_exists = 0;
|
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
|
* 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);
|
memcpy(ls_name, gl_lsname_dlm, MAX_NAME);
|
||||||
else if (gl_use_sanlock)
|
else if (gl_use_sanlock)
|
||||||
memcpy(ls_name, gl_lsname_sanlock, MAX_NAME);
|
memcpy(ls_name, gl_lsname_sanlock, MAX_NAME);
|
||||||
|
else if (gl_use_idm)
|
||||||
|
memcpy(ls_name, gl_lsname_idm, MAX_NAME);
|
||||||
else
|
else
|
||||||
memset(ls_name, 0, MAX_NAME);
|
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);
|
strncpy(ls->name, ls_name, MAX_NAME);
|
||||||
ls->lm_type = lm_type;
|
ls->lm_type = lm_type;
|
||||||
|
|
||||||
if (act)
|
if (act) {
|
||||||
ls->start_client_id = act->client_id;
|
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)
|
if (vg_uuid)
|
||||||
strncpy(ls->vg_uuid, vg_uuid, 64);
|
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);
|
pthread_mutex_lock(&lockspaces_mutex);
|
||||||
ls2 = find_lockspace_name(ls->name);
|
ls2 = find_lockspace_name(ls->name);
|
||||||
if (ls2) {
|
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) {
|
if (ls2->thread_stop) {
|
||||||
log_debug("add_lockspace_thread %s exists and stopping", ls->name);
|
log_debug("add_lockspace_thread %s exists and stopping", ls->name);
|
||||||
rv = -EAGAIN;
|
rv = -EAGAIN;
|
||||||
@ -2918,6 +3031,7 @@ static int add_lockspace_thread(const char *ls_name,
|
|||||||
}
|
}
|
||||||
pthread_mutex_unlock(&lockspaces_mutex);
|
pthread_mutex_unlock(&lockspaces_mutex);
|
||||||
free_resource(r);
|
free_resource(r);
|
||||||
|
free_pvs_path(&ls->pvs);
|
||||||
free(ls);
|
free(ls);
|
||||||
return rv;
|
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))
|
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
|
||||||
global_dlm_lockspace_exists = 1;
|
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);
|
list_add_tail(&ls->list, &lockspaces);
|
||||||
pthread_mutex_unlock(&lockspaces_mutex);
|
pthread_mutex_unlock(&lockspaces_mutex);
|
||||||
|
|
||||||
@ -2941,6 +3057,7 @@ static int add_lockspace_thread(const char *ls_name,
|
|||||||
list_del(&ls->list);
|
list_del(&ls->list);
|
||||||
pthread_mutex_unlock(&lockspaces_mutex);
|
pthread_mutex_unlock(&lockspaces_mutex);
|
||||||
free_resource(r);
|
free_resource(r);
|
||||||
|
free_pvs_path(&ls->pvs);
|
||||||
free(ls);
|
free(ls);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -2949,16 +3066,15 @@ static int add_lockspace_thread(const char *ls_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There is no add_sanlock_global_lockspace or
|
* There is no variant for sanlock because, with sanlock, the global
|
||||||
* rem_sanlock_global_lockspace because with sanlock,
|
* lockspace is one of the vg lockspaces.
|
||||||
* the global lockspace is one of the vg lockspaces.
|
|
||||||
*/
|
*/
|
||||||
|
static int add_global_lockspace(char *ls_name, int lm_type,
|
||||||
static int add_dlm_global_lockspace(struct action *act)
|
struct action *act)
|
||||||
{
|
{
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
if (global_dlm_lockspace_exists)
|
if (global_dlm_lockspace_exists || global_idm_lockspace_exists)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2966,9 +3082,9 @@ static int add_dlm_global_lockspace(struct action *act)
|
|||||||
* lock request, insert an internal gl sh lock request?
|
* 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)
|
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
|
* 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.
|
* When DLM or IDM locking scheme is used for global lock, if the global
|
||||||
* This is not used for an explicit rem_lockspace action from
|
* lockspace is the only one left, then stop it. This is not used for
|
||||||
* the client, only for auto remove.
|
* an explicit rem_lockspace action from the client, only for auto
|
||||||
|
* remove.
|
||||||
*/
|
*/
|
||||||
|
static int rem_global_lockspace(char *ls_name)
|
||||||
static int rem_dlm_global_lockspace(void)
|
|
||||||
{
|
{
|
||||||
struct lockspace *ls, *ls_gl = NULL;
|
struct lockspace *ls, *ls_gl = NULL;
|
||||||
int others = 0;
|
int others = 0;
|
||||||
@ -2994,7 +3110,7 @@ static int rem_dlm_global_lockspace(void)
|
|||||||
|
|
||||||
pthread_mutex_lock(&lockspaces_mutex);
|
pthread_mutex_lock(&lockspaces_mutex);
|
||||||
list_for_each_entry(ls, &lockspaces, list) {
|
list_for_each_entry(ls, &lockspaces, list) {
|
||||||
if (!strcmp(ls->name, gl_lsname_dlm)) {
|
if (!strcmp(ls->name, ls_name)) {
|
||||||
ls_gl = ls;
|
ls_gl = ls;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -3026,6 +3142,26 @@ out:
|
|||||||
return rv;
|
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
|
* When the first dlm lockspace is added for a vg, automatically add a separate
|
||||||
* dlm lockspace for the global lock.
|
* dlm lockspace for the global lock.
|
||||||
@ -3051,6 +3187,9 @@ static int add_lockspace(struct action *act)
|
|||||||
if (gl_use_dlm) {
|
if (gl_use_dlm) {
|
||||||
rv = add_dlm_global_lockspace(act);
|
rv = add_dlm_global_lockspace(act);
|
||||||
return rv;
|
return rv;
|
||||||
|
} else if (gl_use_idm) {
|
||||||
|
rv = add_idm_global_lockspace(act);
|
||||||
|
return rv;
|
||||||
} else {
|
} else {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -3059,6 +3198,8 @@ static int add_lockspace(struct action *act)
|
|||||||
if (act->rt == LD_RT_VG) {
|
if (act->rt == LD_RT_VG) {
|
||||||
if (gl_use_dlm)
|
if (gl_use_dlm)
|
||||||
add_dlm_global_lockspace(NULL);
|
add_dlm_global_lockspace(NULL);
|
||||||
|
else if (gl_use_idm)
|
||||||
|
add_idm_global_lockspace(NULL);
|
||||||
|
|
||||||
vg_ls_name(act->vg_name, ls_name);
|
vg_ls_name(act->vg_name, ls_name);
|
||||||
|
|
||||||
@ -3126,14 +3267,15 @@ static int rem_lockspace(struct action *act)
|
|||||||
pthread_mutex_unlock(&lockspaces_mutex);
|
pthread_mutex_unlock(&lockspaces_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The dlm global lockspace was automatically added when
|
* For DLM and IDM locking scheme, the global lockspace was
|
||||||
* the first dlm vg lockspace was added, now reverse that
|
* automatically added when the first vg lockspace was added,
|
||||||
* by automatically removing the dlm global lockspace when
|
* now reverse that by automatically removing the dlm global
|
||||||
* the last dlm vg lockspace is removed.
|
* lockspace when the last vg lockspace is removed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (rt == LD_RT_VG && gl_use_dlm)
|
if (rt == LD_RT_VG && gl_use_dlm)
|
||||||
rem_dlm_global_lockspace();
|
rem_dlm_global_lockspace();
|
||||||
|
else if (rt == LD_RT_VG && gl_use_idm)
|
||||||
|
rem_idm_global_lockspace();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3257,6 +3399,7 @@ static int for_each_lockspace(int do_stop, int do_free, int do_force)
|
|||||||
if (ls->free_vg) {
|
if (ls->free_vg) {
|
||||||
/* In future we may need to free ls->actions here */
|
/* In future we may need to free ls->actions here */
|
||||||
free_ls_resources(ls);
|
free_ls_resources(ls);
|
||||||
|
free_pvs_path(&ls->pvs);
|
||||||
free(ls);
|
free(ls);
|
||||||
free_count++;
|
free_count++;
|
||||||
}
|
}
|
||||||
@ -3270,6 +3413,7 @@ static int for_each_lockspace(int do_stop, int do_free, int do_force)
|
|||||||
if (!gl_type_static) {
|
if (!gl_type_static) {
|
||||||
gl_use_dlm = 0;
|
gl_use_dlm = 0;
|
||||||
gl_use_sanlock = 0;
|
gl_use_sanlock = 0;
|
||||||
|
gl_use_idm = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&lockspaces_mutex);
|
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);
|
rv = lm_init_vg_sanlock(ls_name, act->vg_name, act->flags, act->vg_args);
|
||||||
else if (act->lm_type == LD_LM_DLM)
|
else if (act->lm_type == LD_LM_DLM)
|
||||||
rv = lm_init_vg_dlm(ls_name, act->vg_name, act->flags, act->vg_args);
|
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
|
else
|
||||||
rv = -EINVAL;
|
rv = -EINVAL;
|
||||||
|
|
||||||
@ -3448,6 +3595,8 @@ static int work_init_lv(struct action *act)
|
|||||||
|
|
||||||
} else if (act->lm_type == LD_LM_DLM) {
|
} else if (act->lm_type == LD_LM_DLM) {
|
||||||
return 0;
|
return 0;
|
||||||
|
} else if (act->lm_type == LD_LM_IDM) {
|
||||||
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
log_error("init_lv ls_name %s bad lm_type %d", ls_name, act->lm_type);
|
log_error("init_lv ls_name %s bad lm_type %d", ls_name, act->lm_type);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -3511,20 +3660,29 @@ static void *worker_thread_main(void *arg_in)
|
|||||||
if (act->op == LD_OP_RUNNING_LM) {
|
if (act->op == LD_OP_RUNNING_LM) {
|
||||||
int run_sanlock = lm_is_running_sanlock();
|
int run_sanlock = lm_is_running_sanlock();
|
||||||
int run_dlm = lm_is_running_dlm();
|
int run_dlm = lm_is_running_dlm();
|
||||||
|
int run_idm = lm_is_running_idm();
|
||||||
|
|
||||||
if (daemon_test) {
|
if (daemon_test) {
|
||||||
run_sanlock = gl_use_sanlock;
|
run_sanlock = gl_use_sanlock;
|
||||||
run_dlm = gl_use_dlm;
|
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;
|
act->result = -EXFULL;
|
||||||
else if (!run_sanlock && !run_dlm)
|
else if (!run_sanlock && !run_dlm && !run_idm)
|
||||||
act->result = -ENOLCK;
|
act->result = -ENOLCK;
|
||||||
else if (run_sanlock)
|
else if (run_sanlock)
|
||||||
act->result = LD_LM_SANLOCK;
|
act->result = LD_LM_SANLOCK;
|
||||||
else if (run_dlm)
|
else if (run_dlm)
|
||||||
act->result = LD_LM_DLM;
|
act->result = LD_LM_DLM;
|
||||||
|
else if (run_idm)
|
||||||
|
act->result = LD_LM_IDM;
|
||||||
add_client_result(act);
|
add_client_result(act);
|
||||||
|
|
||||||
} else if ((act->op == LD_OP_LOCK) && (act->flags & LD_AF_SEARCH_LS)) {
|
} 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) {
|
} else if (gl_use_dlm) {
|
||||||
if (!gl_lsname_dlm[0])
|
if (!gl_lsname_dlm[0])
|
||||||
strcat(result_flags, "NO_GL_LS,");
|
strcat(result_flags, "NO_GL_LS,");
|
||||||
|
} else if (gl_use_idm) {
|
||||||
|
if (!gl_lsname_idm[0])
|
||||||
|
strcat(result_flags, "NO_GL_LS,");
|
||||||
} else {
|
} else {
|
||||||
int found_lm = 0;
|
int found_lm = 0;
|
||||||
|
|
||||||
@ -3819,6 +3980,8 @@ static int client_send_result(struct client *cl, struct action *act)
|
|||||||
found_lm++;
|
found_lm++;
|
||||||
if (lm_support_sanlock() && lm_is_running_sanlock())
|
if (lm_support_sanlock() && lm_is_running_sanlock())
|
||||||
found_lm++;
|
found_lm++;
|
||||||
|
if (lm_support_idm() && lm_is_running_idm())
|
||||||
|
found_lm++;
|
||||||
|
|
||||||
if (!found_lm)
|
if (!found_lm)
|
||||||
strcat(result_flags, "NO_GL_LS,NO_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)) {
|
if (gl_use_sanlock && (act->op == LD_OP_ENABLE || act->op == LD_OP_DISABLE)) {
|
||||||
vg_ls_name(act->vg_name, ls_name);
|
vg_ls_name(act->vg_name, ls_name);
|
||||||
} else {
|
} else {
|
||||||
if (!gl_use_dlm && !gl_use_sanlock) {
|
if (!gl_use_dlm && !gl_use_sanlock && !gl_use_idm) {
|
||||||
if (lm_is_running_dlm())
|
if (lm_is_running_dlm())
|
||||||
gl_use_dlm = 1;
|
gl_use_dlm = 1;
|
||||||
else if (lm_is_running_sanlock())
|
else if (lm_is_running_sanlock())
|
||||||
gl_use_sanlock = 1;
|
gl_use_sanlock = 1;
|
||||||
|
else if (lm_is_running_idm())
|
||||||
|
gl_use_idm = 1;
|
||||||
}
|
}
|
||||||
gl_ls_name(ls_name);
|
gl_ls_name(ls_name);
|
||||||
}
|
}
|
||||||
@ -4046,6 +4211,17 @@ static int add_lock_action(struct action *act)
|
|||||||
add_dlm_global_lockspace(NULL);
|
add_dlm_global_lockspace(NULL);
|
||||||
goto retry;
|
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) {
|
} else if (act->op == LD_OP_LOCK && act->mode == LD_LK_UN) {
|
||||||
log_debug("lockspace \"%s\" not found for unlock ignored", ls_name);
|
log_debug("lockspace \"%s\" not found for unlock ignored", ls_name);
|
||||||
return -ENOLS;
|
return -ENOLS;
|
||||||
@ -4266,6 +4442,8 @@ static int str_to_lm(const char *str)
|
|||||||
return LD_LM_SANLOCK;
|
return LD_LM_SANLOCK;
|
||||||
if (!strcmp(str, "dlm"))
|
if (!strcmp(str, "dlm"))
|
||||||
return LD_LM_DLM;
|
return LD_LM_DLM;
|
||||||
|
if (!strcmp(str, "idm"))
|
||||||
|
return LD_LM_IDM;
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4601,12 +4779,14 @@ static void client_recv_action(struct client *cl)
|
|||||||
const char *vg_sysid;
|
const char *vg_sysid;
|
||||||
const char *path;
|
const char *path;
|
||||||
const char *str;
|
const char *str;
|
||||||
|
struct pvs pvs;
|
||||||
|
char buf[11]; /* p a t h [ x x x x ] \0 */
|
||||||
int64_t val;
|
int64_t val;
|
||||||
uint32_t opts = 0;
|
uint32_t opts = 0;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int cl_pid;
|
int cl_pid;
|
||||||
int op, rt, lm, mode;
|
int op, rt, lm, mode;
|
||||||
int rv;
|
int rv, i;
|
||||||
|
|
||||||
buffer_init(&req.buffer);
|
buffer_init(&req.buffer);
|
||||||
|
|
||||||
@ -4695,11 +4875,13 @@ static void client_recv_action(struct client *cl)
|
|||||||
if (!cl->name[0] && cl_name)
|
if (!cl->name[0] && cl_name)
|
||||||
strncpy(cl->name, cl_name, MAX_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())
|
if (lm == LD_LM_DLM && lm_support_dlm())
|
||||||
gl_use_dlm = 1;
|
gl_use_dlm = 1;
|
||||||
else if (lm == LD_LM_SANLOCK && lm_support_sanlock())
|
else if (lm == LD_LM_SANLOCK && lm_support_sanlock())
|
||||||
gl_use_sanlock = 1;
|
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));
|
log_debug("set gl_use_%s", lm_str(lm));
|
||||||
}
|
}
|
||||||
@ -4756,6 +4938,40 @@ static void client_recv_action(struct client *cl)
|
|||||||
if (val)
|
if (val)
|
||||||
act->host_id = 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);
|
act->max_retries = daemon_request_int(req, "max_retries", DEFAULT_MAX_RETRIES);
|
||||||
|
|
||||||
dm_config_destroy(req.cft);
|
dm_config_destroy(req.cft);
|
||||||
@ -4777,6 +4993,12 @@ static void client_recv_action(struct client *cl)
|
|||||||
goto out;
|
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)
|
if (act->op == LD_OP_LOCK && act->mode != LD_LK_UN)
|
||||||
cl->lock_ops = 1;
|
cl->lock_ops = 1;
|
||||||
|
|
||||||
@ -5375,6 +5597,7 @@ static void adopt_locks(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
list_del(&ls->list);
|
list_del(&ls->list);
|
||||||
|
free_pvs_path(&ls->pvs);
|
||||||
free(ls);
|
free(ls);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5415,6 +5638,7 @@ static void adopt_locks(void)
|
|||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
log_error("Failed to create lockspace thread for VG %s", ls->vg_name);
|
log_error("Failed to create lockspace thread for VG %s", ls->vg_name);
|
||||||
list_del(&ls->list);
|
list_del(&ls->list);
|
||||||
|
free_pvs_path(&ls->pvs);
|
||||||
free(ls);
|
free(ls);
|
||||||
free_action(act);
|
free_action(act);
|
||||||
count_start_fail++;
|
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_dlm, S_NAME_GL_DLM);
|
||||||
|
strcpy(gl_lsname_idm, S_NAME_GL_IDM);
|
||||||
|
|
||||||
INIT_LIST_HEAD(&lockspaces);
|
INIT_LIST_HEAD(&lockspaces);
|
||||||
pthread_mutex_init(&lockspaces_mutex, NULL);
|
pthread_mutex_init(&lockspaces_mutex, NULL);
|
||||||
@ -6110,6 +6335,8 @@ int main(int argc, char *argv[])
|
|||||||
gl_use_dlm = 1;
|
gl_use_dlm = 1;
|
||||||
else if (lm == LD_LM_SANLOCK && lm_support_sanlock())
|
else if (lm == LD_LM_SANLOCK && lm_support_sanlock())
|
||||||
gl_use_sanlock = 1;
|
gl_use_sanlock = 1;
|
||||||
|
else if (lm == LD_LM_IDM && lm_support_idm())
|
||||||
|
gl_use_idm = 1;
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "invalid gl-type option\n");
|
fprintf(stderr, "invalid gl-type option\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
@ -121,7 +121,7 @@ struct client {
|
|||||||
#define DEFAULT_MAX_RETRIES 4
|
#define DEFAULT_MAX_RETRIES 4
|
||||||
|
|
||||||
struct pvs {
|
struct pvs {
|
||||||
const char **path;
|
char **path;
|
||||||
int num;
|
int num;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -338,7 +338,9 @@ EXTERN int gl_use_idm;
|
|||||||
EXTERN int gl_vg_removed;
|
EXTERN int gl_vg_removed;
|
||||||
EXTERN char gl_lsname_dlm[MAX_NAME+1];
|
EXTERN char gl_lsname_dlm[MAX_NAME+1];
|
||||||
EXTERN char gl_lsname_sanlock[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_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_test; /* run as much as possible without a live lock manager */
|
||||||
EXTERN int daemon_debug;
|
EXTERN int daemon_debug;
|
||||||
|
Loading…
Reference in New Issue
Block a user