main - lvmlockd: purge the lock resources left in previous lockspace
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=39e6c4f749e97c0efae...
Commit: 39e6c4f749e97c0efae116e1fa0dbc25451de80e
Parent: a23588d77cb1585e642946fe84c3eaafe7e2d270
Author: Lidong Zhong <lidong.zhong(a)suse.com>
AuthorDate: Fri Sep 30 16:34:51 2022 +0800
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Oct 7 09:45:57 2022 -0500
lvmlockd: purge the lock resources left in previous lockspace
If lvmlockd in cluster is killed accidently or any other reason, the
lock resources will become orphaned in the VG lockspace. When the
cluster manager tries to restart this daemon, the LVs will probably
become inactive because of resource schedule policy and thus the lock
resouce will be omited during the adoption process. This patch will
try to purge the lock resources left in previous lockspace, so the
following actions can work again.
---
daemons/lvmlockd/lvmlockd-core.c | 13 +++++-
daemons/lvmlockd/lvmlockd-dlm.c | 79 ++++++++++++++++++++++++++++++++++++
daemons/lvmlockd/lvmlockd-internal.h | 6 +++
3 files changed, 97 insertions(+), 1 deletion(-)
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;
1 year, 6 months
main - lvresize: move the lockd_lv earlier
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=a23588d77cb1585e642...
Commit: a23588d77cb1585e642946fe84c3eaafe7e2d270
Parent: 599cbd7dd37ba50b44579f64207cc1e47e004899
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Sep 30 12:16:32 2022 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Oct 3 12:42:02 2022 -0500
lvresize: move the lockd_lv earlier
the lock should cover any potential activation,
not just the resizing changes
---
lib/metadata/lv_manip.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 99045c220..d6452e849 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6814,6 +6814,13 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
return 0;
}
+ /*
+ * If the LV is locked due to being active, this lock call is a no-op.
+ * Otherwise, this acquires a transient lock on the lv (not PERSISTENT)
+ */
+ if (!lockd_lv_resize(cmd, lv_top, "ex", 0, lp))
+ return_0;
+
/*
* Active 'hidden' -tpool can be waiting for resize, but the pool LV
* itself might be inactive. Here plain suspend/resume would not work.
@@ -6909,13 +6916,6 @@ int lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
if (is_reduce && !lp->fsopt[0] && !_lv_reduce_confirmation(lv_top, lp))
goto_out;
- /*
- * If the LV is locked due to being active, this lock call is a no-op.
- * Otherwise, this acquires a transient lock on the lv (not PERSISTENT)
- */
- if (!lockd_lv_resize(cmd, lv_top, "ex", 0, lp))
- goto_out;
-
/* Part of old approach to fs handling using fsadm. */
if (!strcmp(lp->fsopt, "resize_fsadm") && !lp->nofsck &&
!_fsadm_cmd(FSADM_CMD_CHECK, lv_top, 0, lp->yes, lp->force, &status)) {
1 year, 6 months