Compare commits

...

No commits in common. "c8" and "c8-beta" have entirely different histories.
c8 ... c8-beta

5 changed files with 1 additions and 582 deletions

View File

@ -1,232 +0,0 @@
From 7b6c22b254181a2b1921a4c31228fc8920b5547e Mon Sep 17 00:00:00 2001
From: Alexander Aring <aahringo@redhat.com>
Date: Fri, 13 Jan 2023 17:33:31 -0500
Subject: [PATCH 1/3] dlm_controld: better uevent filtering
When I did test with dlm_locktorture module I got several log messages
about:
uevent message has 3 args: add@/module/dlm_locktorture
uevent message has 3 args: remove@/module/dlm_locktorture
which are not expected and not able to parse by dlm_controld
process_uevent() function, because mismatch of argument counts.
Debugging it more, I figured out that those uevents are for
loading/unloading the dlm_locktorture module and there are uevents for
loading and unloading modules which have nothing todo with dlm lockspace
uevent handling.
The current filter works as:
if (!strstr(buf, "dlm"))
for matching the dlm joining/leaving uevent string which looks like:
offline@/kernel/dlm/locktorture
to avoid matching with other uevent which has somehow the string "dlm"
in it, we switch to the match the uevent env variables for action,
devpath (just to check if it's set) and subsystem. Additional the dlm
subsystem sets the LOCKSPACE variable which can be used to get the
lockspace name instead of extracting it previously from the devpath.
The code to decode the uevent envs were taken from the gfs2_controld
utility [0].
[0] https://github.com/andyprice/gfs2-utils/blob/91c3e9a69ed70d3d522f5b47015da5e5868722ec/group/gfs_controld/main.c
---
dlm_controld/main.c | 126 +++++++++++++++++++++++++-------------------
1 file changed, 71 insertions(+), 55 deletions(-)
diff --git a/dlm_controld/main.c b/dlm_controld/main.c
index c35756d4..74a5e61b 100644
--- a/dlm_controld/main.c
+++ b/dlm_controld/main.c
@@ -46,6 +46,50 @@ struct client {
struct lockspace *ls;
};
+enum {
+ Env_ACTION = 0,
+ Env_DEVPATH,
+ Env_SUBSYSTEM,
+ Env_LOCKSPACE,
+ Env_Last, /* Flag for end of vars */
+};
+
+static const char *uevent_vars[] = {
+ [Env_ACTION] = "ACTION=",
+ [Env_DEVPATH] = "DEVPATH=",
+ [Env_SUBSYSTEM] = "SUBSYSTEM=",
+ [Env_LOCKSPACE] = "LOCKSPACE=",
+};
+
+static void decode_uevent(const char *buf, unsigned len, const char *vars[],
+ unsigned nvars, const char *vals[])
+{
+ const char *ptr;
+ unsigned int i;
+ int slen, vlen;
+
+ memset(vals, 0, sizeof(const char *) * nvars);
+
+ while (len > 0) {
+ ptr = buf;
+ slen = strlen(ptr);
+ buf += slen;
+ len -= slen;
+ buf++;
+ len--;
+
+ for (i = 0; i < nvars; i++) {
+ vlen = strlen(vars[i]);
+ if (vlen > slen)
+ continue;
+ if (memcmp(vars[i], ptr, vlen) != 0)
+ continue;
+ vals[i] = ptr + vlen;
+ break;
+ }
+ }
+}
+
int do_read(int fd, void *buf, size_t count)
{
int rv, off = 0;
@@ -627,38 +671,6 @@ static void fs_register_del(char *name)
}
}
-#define MAXARGS 8
-
-static char *get_args(char *buf, int *argc, char **argv, char sep, int want)
-{
- char *p = buf, *rp = NULL;
- int i;
-
- argv[0] = p;
-
- for (i = 1; i < MAXARGS; i++) {
- p = strchr(buf, sep);
- if (!p)
- break;
- *p = '\0';
-
- if (want == i) {
- rp = p + 1;
- break;
- }
-
- argv[i] = p + 1;
- buf = p + 1;
- }
- *argc = i;
-
- /* we ended by hitting \0, return the point following that */
- if (!rp)
- rp = strchr(buf, '\0') + 1;
-
- return rp;
-}
-
const char *dlm_mode_str(int mode)
{
switch (mode) {
@@ -686,13 +698,12 @@ const char *dlm_mode_str(int mode)
static void process_uevent(int ci)
{
+ const char *uevent_vals[Env_Last];
struct lockspace *ls;
char buf[MAX_LINE_UEVENT];
- char *argv[MAXARGS], *act, *sys;
- int rv, argc = 0;
+ int rv;
memset(buf, 0, sizeof(buf));
- memset(argv, 0, sizeof(char *) * MAXARGS);
retry_recv:
rv = recv(client[ci].fd, &buf, sizeof(buf), 0);
@@ -704,35 +715,38 @@ static void process_uevent(int ci)
return;
}
- if (!strstr(buf, "dlm"))
- return;
+ decode_uevent(buf, rv, uevent_vars, Env_Last, uevent_vals);
- log_debug("uevent: %s", buf);
-
- get_args(buf, &argc, argv, '/', 4);
- if (argc != 4)
- log_error("uevent message has %d args", argc);
- act = argv[0];
- sys = argv[2];
-
- if (!act || !sys || !argv[3])
+ if (!uevent_vals[Env_ACTION] ||
+ !uevent_vals[Env_DEVPATH] ||
+ !uevent_vals[Env_SUBSYSTEM] ||
+ !uevent_vals[Env_LOCKSPACE]) {
+ log_debug("failed to validate uevent, action: %p, devpath: %p, subsystem: %p, lockspace: %p",
+ uevent_vals[Env_ACTION], uevent_vals[Env_DEVPATH],
+ uevent_vals[Env_SUBSYSTEM],
+ uevent_vals[Env_LOCKSPACE]);
return;
+ }
- if (strncmp(sys, "dlm", 3))
+ if (strcmp(uevent_vals[Env_SUBSYSTEM], "dlm")) {
+ log_debug("uevent looks like dlm but came not from dlm subsystem");
return;
+ }
- log_debug("kernel: %s %s", act, argv[3]);
+ log_debug("uevent action: %s, devpath: %s, devpath: %s, lockspace: %s",
+ uevent_vals[Env_ACTION], uevent_vals[Env_SUBSYSTEM],
+ uevent_vals[Env_DEVPATH], uevent_vals[Env_LOCKSPACE]);
rv = 0;
- if (!strcmp(act, "online@")) {
- ls = find_ls(argv[3]);
+ if (!strcmp(uevent_vals[Env_ACTION], "online")) {
+ ls = find_ls(uevent_vals[Env_LOCKSPACE]);
if (ls) {
rv = -EEXIST;
goto out;
}
- ls = create_ls(argv[3]);
+ ls = create_ls(uevent_vals[Env_LOCKSPACE]);
if (!ls) {
rv = -ENOMEM;
goto out;
@@ -747,8 +761,8 @@ static void process_uevent(int ci)
goto out;
}
- } else if (!strcmp(act, "offline@")) {
- ls = find_ls(argv[3]);
+ } else if (!strcmp(uevent_vals[Env_ACTION], "offline")) {
+ ls = find_ls(uevent_vals[Env_LOCKSPACE]);
if (!ls) {
rv = -ENOENT;
goto out;
@@ -758,8 +772,10 @@ static void process_uevent(int ci)
}
out:
if (rv < 0)
- log_error("process_uevent %s error %d errno %d",
- act, rv, errno);
+ log_error("%s action: %s, devpath: %s, devpath: %s, lockspace: %s - error %d errno %d",
+ __func__, uevent_vals[Env_ACTION],
+ uevent_vals[Env_SUBSYSTEM], uevent_vals[Env_DEVPATH],
+ uevent_vals[Env_LOCKSPACE], rv, errno);
}
static int setup_uevent(void)
--
2.43.0

View File

@ -1,75 +0,0 @@
From b6f52406411d2421d0614244080cf7bc668c336b Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Tue, 13 Jan 2026 16:59:25 -0600
Subject: [PATCH dlm/tool] dlm_controld: send plock operations without resource
lookup
When plock_ownership mode is disabled, a plock operation read from
the kernel can be sent to all nodes immediately, without looking up
the local resource struct. This is faster, and it avoids a bug in
cases where multiple threads in a process submit concurrent fcntl
lock ops on a file.
This bug occurs because create/free of the resource struct should
only be done in the context of ordered receive_plock cpg messages.
plock unlock results were being incorrectly returned based on the
non-existence of a struct resource checked in process_plocks (outside
of the ordered message context.) In this case, the existence of the
resource struct was used to imply a lock state ("no locks"), which is
invalid to conclude outside of the message context. The bug would
only appear in the unusual scenario where multiple threads in a
process are running concurrent fcntl lock operations on a file.
This fix does not address the problem when plock_ownership is enabled,
so warnings are added for the plock_ownership setting.
---
dlm_controld/dlm_controld.8 | 2 ++
dlm_controld/main.c | 2 +-
dlm_controld/plock.c | 5 +++++
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/dlm_controld/dlm_controld.8 b/dlm_controld/dlm_controld.8
index 3aab3885..3858be87 100644
--- a/dlm_controld/dlm_controld.8
+++ b/dlm_controld/dlm_controld.8
@@ -50,6 +50,8 @@ For default settings, see dlm_controld -h.
.B --plock_ownership | -o
0|1
enable/disable plock ownership
+.br
+ (WARNING: do not enable if threads perform fcntl locking.)
.B --drop_resources_time | -t
.I int
diff --git a/dlm_controld/main.c b/dlm_controld/main.c
index 2dc6b91b..728b7464 100644
--- a/dlm_controld/main.c
+++ b/dlm_controld/main.c
@@ -1841,7 +1841,7 @@ static void set_opt_defaults(void)
set_opt_default(plock_ownership_ind,
"plock_ownership", 'o', req_arg_bool,
0, NULL, 0,
- "enable/disable plock ownership");
+ "enable/disable plock ownership (do not enable if threads do fcntl locking)");
set_opt_default(drop_resources_time_ind,
"drop_resources_time", 't', req_arg_int,
diff --git a/dlm_controld/plock.c b/dlm_controld/plock.c
index 992fb16f..56ea9765 100644
--- a/dlm_controld/plock.c
+++ b/dlm_controld/plock.c
@@ -1569,6 +1569,11 @@ void process_plocks(int ci)
plock_rate_delays = 0;
}
+ if (!opt(plock_ownership_ind)) {
+ send_plock(ls, NULL, &info);
+ return;
+ }
+
create = (info.optype == DLM_PLOCK_OP_UNLOCK) ? 0 : 1;
rv = find_resource(ls, info.number, create, &r);
--
2.43.0

View File

@ -1,26 +0,0 @@
From 615e7936d39248de09dc9c5e7570463387f7d139 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 15 Aug 2024 11:05:54 -0500
Subject: [PATCH 2/3] dlm_controld: terminate uevent buffer
for checker
---
dlm_controld/main.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dlm_controld/main.c b/dlm_controld/main.c
index 74a5e61b..1828428c 100644
--- a/dlm_controld/main.c
+++ b/dlm_controld/main.c
@@ -715,6 +715,8 @@ static void process_uevent(int ci)
return;
}
+ buf[MAX_LINE_UEVENT-1] = '\0';
+
decode_uevent(buf, rv, uevent_vars, Env_Last, uevent_vals);
if (!uevent_vals[Env_ACTION] ||
--
2.43.0

View File

@ -1,232 +0,0 @@
From d317347643ec2610bbbd390493cf5e920f4ddd79 Mon Sep 17 00:00:00 2001
From: Alexander Aring <aahringo@redhat.com>
Date: Fri, 22 Nov 2024 12:45:36 -0500
Subject: [PATCH 3/3] dlm_controld: handle RELEASE_RECOVER event env
Newer kernels might sending an additional attribute for the leaving lockspace
event "RELEASE_RECOVER" to tell other nodes from the release lockspace
initator to call the recover_slot() callback in their recovery handling
as a membership update triggers in-kernel recovery.
---
dlm_controld/action.c | 33 ++++++++++++++++++
dlm_controld/cpg.c | 72 ++++++++++++++++++++++++++++++++++++++-
dlm_controld/dlm_daemon.h | 6 +++-
dlm_controld/main.c | 4 ++-
4 files changed, 112 insertions(+), 3 deletions(-)
diff --git a/dlm_controld/action.c b/dlm_controld/action.c
index 0eff2799..6d23a330 100644
--- a/dlm_controld/action.c
+++ b/dlm_controld/action.c
@@ -240,6 +240,39 @@ int path_exists(const char *path)
return 1;
}
+int set_configfs_member_release_recover(struct lockspace *ls, int id,
+ uint32_t release_recover)
+{
+ char path[PATH_MAX];
+ char buf[32];
+ int fd, rv;
+
+ memset(path, 0, PATH_MAX);
+ snprintf(path, PATH_MAX, "%s/%s/nodes/%d/release_recover",
+ SPACES_DIR, ls->name, id);
+
+ rv = fd = open(path, O_WRONLY);
+ if (rv < 0) {
+ log_error("%s: open failed: %d", path, errno);
+ goto out;
+ }
+
+ memset(buf, 0, 32);
+ snprintf(buf, 32, "%u", release_recover);
+
+ rv = do_write(fd, buf, strlen(buf));
+ if (rv < 0) {
+ log_error("%s: write failed: %d, %s", path, errno, buf);
+ close(fd);
+ goto out;
+ }
+ close(fd);
+ rv = 0;
+
+out:
+ return rv;
+}
+
/* The "renew" nodes are those that have left and rejoined since the last
call to set_members(). We rmdir/mkdir for these nodes so dlm-kernel
can notice they've left and rejoined. */
diff --git a/dlm_controld/cpg.c b/dlm_controld/cpg.c
index f3365ee4..10139664 100644
--- a/dlm_controld/cpg.c
+++ b/dlm_controld/cpg.c
@@ -1057,6 +1057,23 @@ static void receive_start(struct lockspace *ls, struct dlm_header *hd, int len)
memb->start = 1;
}
+static void receive_release_recover(struct lockspace *ls,
+ struct dlm_header *hd, int len)
+{
+ uint32_t release_recover = hd->msgdata;
+
+ log_dlock(ls, "%s %d: len %d release_recover %u", __func__,
+ hd->nodeid, len, release_recover);
+
+ if (hd->nodeid == our_nodeid)
+ return;
+
+ /* try to set members release recover setting before removing to
+ * tell other nodes the release recover option from the initiator.
+ */
+ set_configfs_member_release_recover(ls, hd->nodeid, release_recover);
+}
+
static void receive_plocks_done(struct lockspace *ls, struct dlm_header *hd,
int len)
{
@@ -1170,6 +1187,43 @@ static void send_info(struct lockspace *ls, struct change *cg, int type,
free(buf);
}
+static void send_release_recover_msg(struct lockspace *ls, int type,
+ unsigned long release_recover)
+{
+ struct dlm_header *hd;
+ char *buf;
+ int len;
+
+ len = sizeof(struct dlm_header);
+
+ buf = malloc(len);
+ if (!buf) {
+ log_error("send_info len %d no mem", len);
+ return;
+ }
+ memset(buf, 0, len);
+
+ hd = (struct dlm_header *)buf;
+
+ /* fill in header (dlm_send_message handles part of header) */
+
+ hd->type = type;
+ hd->msgdata = release_recover;
+
+ dlm_send_message(ls, buf, len);
+
+ free(buf);
+}
+
+static void send_release_recover(struct lockspace *ls,
+ unsigned long release_recover)
+{
+ log_group(ls, "%s %d: counts %u release_recover: %ld", __func__,
+ our_nodeid, ls->started_count, release_recover);
+
+ send_release_recover_msg(ls, DLM_MSG_RELEASE_RECOVER, release_recover);
+}
+
/* fenced used the DUPLICATE_CG flag instead of sending nacks like we
do here. I think the nacks didn't work for fenced for some reason,
but I don't remember why (possibly because the node blocked doing
@@ -1642,6 +1696,10 @@ static void deliver_cb(cpg_handle_t handle,
hd->type, nodeid, enable_plock);
break;
+ case DLM_MSG_RELEASE_RECOVER:
+ receive_release_recover(ls, hd, len);
+ break;
+
#if 0
case DLM_MSG_DEADLK_CYCLE_START:
if (opt(enable_deadlk))
@@ -1809,12 +1867,24 @@ int dlm_join_lockspace(struct lockspace *ls)
/* received an "offline" uevent from dlm-kernel */
-int dlm_leave_lockspace(struct lockspace *ls)
+int dlm_leave_lockspace(struct lockspace *ls, const char *release_recover_str)
{
cs_error_t error;
struct cpg_name name;
+ unsigned long release_recover;
int i = 0;
+ if (release_recover_str) {
+ release_recover = strtoul(release_recover_str, NULL, 0);
+ if (release_recover == ULONG_MAX) {
+ log_error("failed to parse release recover: %s",
+ release_recover_str);
+ return errno;
+ }
+
+ send_release_recover(ls, release_recover);
+ }
+
ls->leaving = 1;
memset(&name, 0, sizeof(name));
diff --git a/dlm_controld/dlm_daemon.h b/dlm_controld/dlm_daemon.h
index 45b295ea..119eb543 100644
--- a/dlm_controld/dlm_daemon.h
+++ b/dlm_controld/dlm_daemon.h
@@ -236,6 +236,7 @@ enum {
DLM_MSG_RUN_REQUEST,
DLM_MSG_RUN_REPLY,
DLM_MSG_RUN_CANCEL,
+ DLM_MSG_RELEASE_RECOVER,
};
/* dlm_header flags */
@@ -367,6 +368,8 @@ int set_sysfs_control(char *name, int val);
int set_sysfs_event_done(char *name, int val);
int set_sysfs_id(char *name, uint32_t id);
int set_sysfs_nodir(char *name, int val);
+int set_configfs_member_release_recover(struct lockspace *ls, int id,
+ uint32_t release_recover);
int set_configfs_members(struct lockspace *ls, char *name,
int new_count, int *new_members,
int renew_count, int *renew_members);
@@ -389,7 +392,8 @@ void setup_lockspace_config(struct lockspace *ls);
void process_lockspace_changes(void);
void process_fencing_changes(void);
int dlm_join_lockspace(struct lockspace *ls);
-int dlm_leave_lockspace(struct lockspace *ls);
+int dlm_leave_lockspace(struct lockspace *ls,
+ const char *release_recover_str);
void update_flow_control_status(void);
int set_node_info(struct lockspace *ls, int nodeid, struct dlmc_node *node);
int set_lockspace_info(struct lockspace *ls, struct dlmc_lockspace *lockspace);
diff --git a/dlm_controld/main.c b/dlm_controld/main.c
index 1828428c..2dc6b91b 100644
--- a/dlm_controld/main.c
+++ b/dlm_controld/main.c
@@ -51,6 +51,7 @@ enum {
Env_DEVPATH,
Env_SUBSYSTEM,
Env_LOCKSPACE,
+ Env_RELEASE_RECOVER,
Env_Last, /* Flag for end of vars */
};
@@ -59,6 +60,7 @@ static const char *uevent_vars[] = {
[Env_DEVPATH] = "DEVPATH=",
[Env_SUBSYSTEM] = "SUBSYSTEM=",
[Env_LOCKSPACE] = "LOCKSPACE=",
+ [Env_RELEASE_RECOVER] = "RELEASE_RECOVER=",
};
static void decode_uevent(const char *buf, unsigned len, const char *vars[],
@@ -770,7 +772,7 @@ static void process_uevent(int ci)
goto out;
}
- dlm_leave_lockspace(ls);
+ dlm_leave_lockspace(ls, uevent_vals[Env_RELEASE_RECOVER]);
}
out:
if (rv < 0)
--
2.43.0

View File

@ -1,6 +1,6 @@
Name: dlm
Version: 4.1.0
Release: 3%{?dist}
Release: 1%{?dist}
License: GPLv2 and GPLv2+ and LGPLv2+
# For a breakdown of the licensing, see README.license
Group: System Environment/Kernel
@ -15,10 +15,6 @@ BuildRequires: systemd-devel
Source0: https://releases.pagure.org/dlm/%{name}-%{version}.tar.gz
# Patch0: 0001-foo.patch
Patch0: 0001-dlm_controld-better-uevent-filtering.patch
Patch1: 0002-dlm_controld-terminate-uevent-buffer.patch
Patch2: 0003-dlm_controld-handle-RELEASE_RECOVER-event-env.patch
Patch3: 0001-dlm_controld-send-plock-operations-without-resource-.patch
%if 0%{?rhel} && 0%{?rhel} <= 7
ExclusiveArch: i686 x86_64
@ -38,10 +34,6 @@ The kernel dlm requires a user daemon to control membership.
%prep
%setup -q
# %patch0 -p1 -b .0001-foo.patch
%patch0 -p1 -b .backup0
%patch1 -p1 -b .backup1
%patch2 -p1 -b .backup2
%patch3 -p1 -b .backup3
%build
# upstream does not require configure
@ -113,14 +105,6 @@ developing applications that use %{name}.
%{_libdir}/pkgconfig/*.pc
%changelog
* Tue Jan 20 2026 Alexander Aring <aahringo@redhat.com> - 4.1.0-3
- Rebuild for posix lock issue fix
Related: RHEL-140243
* Tue Dec 16 2025 Alexander Aring <aahringo@redhat.com> - 4.1.0-2
- Rebuild for recover flag functionality
Related: RHEL-136235
* Wed Jan 13 2021 David Teigland <teigland@redhat.com> - 4.1.0-1
- update to 4.1.0