diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c index 6d0d4d98c..b2e98efa3 100644 --- a/daemons/lvmlockd/lvmlockd-core.c +++ b/daemons/lvmlockd/lvmlockd-core.c @@ -5954,7 +5954,18 @@ static void adopt_locks(void) } - /* FIXME: purge any remaining orphan locks in each rejoined ls? */ + /* Try to purge the orphan locks when lock manager is dlm */ + if (lm_support_dlm() && lm_is_running_dlm()) { + list_for_each_entry(ls, &ls_found, list) { + pthread_mutex_lock(&lockspaces_mutex); + ls1 = find_lockspace_name(ls->name); + if (ls1) { + log_debug("ls: %s purge locks", ls->name); + lm_purge_locks_dlm(ls1); + } + pthread_mutex_unlock(&lockspaces_mutex); + } + } if (count_start_fail || count_adopt_fail) goto fail; diff --git a/daemons/lvmlockd/lvmlockd-dlm.c b/daemons/lvmlockd/lvmlockd-dlm.c index 1305c3dc2..01bec6f43 100644 --- a/daemons/lvmlockd/lvmlockd-dlm.c +++ b/daemons/lvmlockd/lvmlockd-dlm.c @@ -220,6 +220,85 @@ int lm_prepare_lockspace_dlm(struct lockspace *ls) return 0; } +#define DLM_COMMS_PATH "/sys/kernel/config/dlm/cluster/comms" +#define LOCK_LINE_MAX 1024 +static int get_local_nodeid() +{ + struct dirent *de; + DIR *ls_dir; + char ls_comms_path[PATH_MAX]; + FILE *file = NULL; + char line[LOCK_LINE_MAX]; + int rv = -1, val; + + memset(ls_comms_path, 0, sizeof(ls_comms_path)); + snprintf(ls_comms_path, PATH_MAX, "%s",DLM_COMMS_PATH); + + if (!(ls_dir = opendir(ls_comms_path))) + return -ECONNREFUSED; + + while ((de = readdir(ls_dir))) { + if (de->d_name[0] == '.') + continue; + memset(ls_comms_path, 0, sizeof(ls_comms_path)); + snprintf(ls_comms_path, PATH_MAX, "%s/%s/local", + DLM_COMMS_PATH, de->d_name); + file = fopen(ls_comms_path, "r"); + if (!file) + continue; + if (fgets(line, LOCK_LINE_MAX, file)) { + fclose(file); + rv = sscanf(line, "%d", &val); + if ((rv == 1) && (val == 1 )) { + memset(ls_comms_path, 0, sizeof(ls_comms_path)); + snprintf(ls_comms_path, PATH_MAX, "%s/%s/nodeid", + DLM_COMMS_PATH, de->d_name); + file = fopen(ls_comms_path, "r"); + if (!file) + continue; + if (fgets(line, LOCK_LINE_MAX, file)) { + rv = sscanf(line, "%d", &val); + if (rv == 1) { + fclose(file); + return val; + } + } + } + } + fclose(file); + } + + if (closedir(ls_dir)) + log_error("get_local_nodeid closedir error"); + return rv; +} + +int lm_purge_locks_dlm(struct lockspace *ls) +{ + struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data; + int nodeid; + int rv = -1; + + if (!lmd || !lmd->dh) { + log_error("purge_locks_dlm %s no dlm_handle_t error", ls->name); + goto fail; + } + + nodeid = get_local_nodeid(); + if (nodeid < 0) { + log_error("failed to get local nodeid"); + goto fail; + } + if (dlm_ls_purge(lmd->dh, nodeid, 0)) { + log_error("purge_locks_dlm %s error", ls->name); + goto fail; + } + + rv = 0; +fail: + return rv; +} + int lm_add_lockspace_dlm(struct lockspace *ls, int adopt) { struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data; diff --git a/daemons/lvmlockd/lvmlockd-internal.h b/daemons/lvmlockd/lvmlockd-internal.h index ad32eb3a4..dd59b6a5d 100644 --- a/daemons/lvmlockd/lvmlockd-internal.h +++ b/daemons/lvmlockd/lvmlockd-internal.h @@ -392,6 +392,7 @@ static inline const char *mode_str(int x) int lm_init_vg_dlm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args); int lm_prepare_lockspace_dlm(struct lockspace *ls); int lm_add_lockspace_dlm(struct lockspace *ls, int adopt); +int lm_purge_locks_dlm(struct lockspace *ls); int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg); int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode, struct val_blk *vb_out, int adopt); @@ -429,6 +430,11 @@ static inline int lm_add_lockspace_dlm(struct lockspace *ls, int adopt) return -1; } +static inline int lm_purge_locks_dlm(struct lockspace *ls) +{ + return -1; +} + static inline int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg) { return -1;