Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libdlm for openSUSE:Factory checked in at 2021-10-20 20:22:59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libdlm (Old) and /work/SRC/openSUSE:Factory/.libdlm.new.1890 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libdlm" Wed Oct 20 20:22:59 2021 rev:53 rq:926153 version:4.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/libdlm/libdlm.changes 2020-10-18 16:19:52.328449454 +0200 +++ /work/SRC/openSUSE:Factory/.libdlm.new.1890/libdlm.changes 2021-10-20 20:23:24.345345536 +0200 @@ -1,0 +2,30 @@ +Mon Oct 18 08:29:00 UTC 2021 - [email protected] + +- Update to v4.1.0+ (bsc#1191734) + * include some fixes/enhancements upstream patches based on 4.1.0 tag + + bug-1191734_0001-libdlm-add-stdint.h-to-api-header.patch + + bug-1191734_0002-dlm_controld-create-var-parent-directories.patch + + bug-1191734_0003-stonith_helper-fix-build.patch + + bug-1191734_0004-plock-move-clear-waiter-to-debug-info.patch + + bug-1191734_0005-treewide-try-to-resolve-symbols-at-linking-time.patch + + bug-1191734_0006-dlm_controld-add-version-check-for-libquorum.patch + + bug-1191734_0007-dlm_tool-man-add-command-joinleave-USAGE.patch + + bug-1191734_0008-man-add-reload_config-in-dlm_tool-dlm.conf.patch + + bug-1191734_0009-add-new-dlm_tool-command-reload_config.patch + + bug-1191734_0010-dlm_tool-man-add-new-command-set_config.patch + + bug-1191734_0011-dlm_tool-dlm_controld-add-new-feature-set_config.patch + + bug-1191734_0012-fix-some-minor-bugs.patch + + bug-1191734_0013-dlm_controld-fix-string-copies.patch + + bug-1191734_0014-man-page-updates.patch + * patch for compatible with corosync-2.4.5+ + + bug-1191734_0015-Revert-dlm_controld-add-version-check-for-libquorum.patch + + bug-1191734_0016-Revert-dlm_controld-use-new-quorum-api-to-detect-mis.patch + * drop 2 patches which are already included in upstream code + - cluster-ringid-seq.patch + - sysmacros.patch + * change name and modify patch for code changed + - dlm_controld-add-note-that-the-dlm-file-is-not-creat.patch + + 0004-man-dlm.conf-add-note-that-the-file-is-not-creat.patch + * change libdlm.spec to seperate upsteam patch and suse special patch + +------------------------------------------------------------------- Old: ---- cluster-ringid-seq.patch dlm-4.0.9.tar.gz dlm_controld-add-note-that-the-dlm-file-is-not-creat.patch sysmacros.patch New: ---- 0004-man-dlm.conf-add-note-that-the-file-is-not-creat.patch bug-1191734_0001-libdlm-add-stdint.h-to-api-header.patch bug-1191734_0002-dlm_controld-create-var-parent-directories.patch bug-1191734_0003-stonith_helper-fix-build.patch bug-1191734_0004-plock-move-clear-waiter-to-debug-info.patch bug-1191734_0005-treewide-try-to-resolve-symbols-at-linking-time.patch bug-1191734_0006-dlm_controld-add-version-check-for-libquorum.patch bug-1191734_0007-dlm_tool-man-add-command-joinleave-USAGE.patch bug-1191734_0008-man-add-reload_config-in-dlm_tool-dlm.conf.patch bug-1191734_0009-add-new-dlm_tool-command-reload_config.patch bug-1191734_0010-dlm_tool-man-add-new-command-set_config.patch bug-1191734_0011-dlm_tool-dlm_controld-add-new-feature-set_config.patch bug-1191734_0012-fix-some-minor-bugs.patch bug-1191734_0013-dlm_controld-fix-string-copies.patch bug-1191734_0014-man-page-updates.patch bug-1191734_0015-Revert-dlm_controld-add-version-check-for-libquorum.patch bug-1191734_0016-Revert-dlm_controld-use-new-quorum-api-to-detect-mis.patch dlm-4.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libdlm.spec ++++++ --- /var/tmp/diff_new_pack.ITu25V/_old 2021-10-20 20:23:25.089345996 +0200 +++ /var/tmp/diff_new_pack.ITu25V/_new 2021-10-20 20:23:25.093345998 +0200 @@ -1,7 +1,7 @@ # # spec file for package libdlm # -# Copyright (c) 2020 SUSE LLC +# Copyright (c) 2021 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -34,16 +34,34 @@ Summary: Application interface to the kernel's distributed lock manager License: GPL-2.0-only AND GPL-2.0-or-later AND LGPL-2.1-or-later Group: Productivity/Clustering/HA -Version: 4.0.9 +Version: 4.1.0 Release: 0 URL: https://pagure.io/dlm/ Source: https://releases.pagure.org/dlm/dlm-%{version}.tar.gz -Patch1: 0001-makefile-for-diff-arch.patch -Patch2: 0002-remove-sd-notify.patch -Patch3: 0003-bnc#874705-nodes-without-quorum.patch -Patch4: sysmacros.patch -Patch5: cluster-ringid-seq.patch -Patch6: dlm_controld-add-note-that-the-dlm-file-is-not-creat.patch +#################### +# upstream patch +Patch001: bug-1191734_0001-libdlm-add-stdint.h-to-api-header.patch +Patch002: bug-1191734_0002-dlm_controld-create-var-parent-directories.patch +Patch003: bug-1191734_0003-stonith_helper-fix-build.patch +Patch004: bug-1191734_0004-plock-move-clear-waiter-to-debug-info.patch +Patch005: bug-1191734_0005-treewide-try-to-resolve-symbols-at-linking-time.patch +Patch006: bug-1191734_0006-dlm_controld-add-version-check-for-libquorum.patch +Patch007: bug-1191734_0007-dlm_tool-man-add-command-joinleave-USAGE.patch +Patch008: bug-1191734_0008-man-add-reload_config-in-dlm_tool-dlm.conf.patch +Patch009: bug-1191734_0009-add-new-dlm_tool-command-reload_config.patch +Patch010: bug-1191734_0010-dlm_tool-man-add-new-command-set_config.patch +Patch011: bug-1191734_0011-dlm_tool-dlm_controld-add-new-feature-set_config.patch +Patch012: bug-1191734_0012-fix-some-minor-bugs.patch +Patch013: bug-1191734_0013-dlm_controld-fix-string-copies.patch +Patch014: bug-1191734_0014-man-page-updates.patch +# suse special patch +Patch101: 0001-makefile-for-diff-arch.patch +Patch102: 0002-remove-sd-notify.patch +Patch103: 0003-bnc#874705-nodes-without-quorum.patch +Patch104: 0004-man-dlm.conf-add-note-that-the-file-is-not-creat.patch +Patch105: bug-1191734_0015-Revert-dlm_controld-add-version-check-for-libquorum.patch +Patch106: bug-1191734_0016-Revert-dlm_controld-use-new-quorum-api-to-detect-mis.patch +################### BuildRequires: fdupes BuildRequires: glib2-devel BuildRequires: libcorosync-devel ++++++ 0004-man-dlm.conf-add-note-that-the-file-is-not-creat.patch ++++++ >From 74595a9400f20c4d4fd83c0a748ddb875d39f578 Mon Sep 17 00:00:00 2001 From: Gang He <[email protected]> Date: Mon, 14 Sep 2020 15:51:01 +0800 Subject: [PATCH] man dlm.conf: add note that the file is not created /etc/dlm/dlm.conf file is not created during installation. we need to tell the user this configuration file does not exist. Signed-off-by: Gang He <[email protected]> --- dlm_controld/dlm.conf.5 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dlm_controld/dlm.conf.5 b/dlm_controld/dlm.conf.5 index 0eb226358100..02a52e977f54 100644 --- a/dlm_controld/dlm.conf.5 +++ b/dlm_controld/dlm.conf.5 @@ -422,6 +422,12 @@ node id=1 mark=42 For local nodes this value doesn't have any effect. +.SH NOTES +.B /etc/dlm/dlm.conf +file is not created during installation. +.br +If you want to modify any default configuration items, you need to create and edit the file. + .SH SEE ALSO .BR dlm_controld (8), .BR dlm_tool (8) -- 2.12.3 ++++++ bug-1191734_0001-libdlm-add-stdint.h-to-api-header.patch ++++++ >From 2baadda85cdc3d5d1e247732b736dc4897ac1556 Mon Sep 17 00:00:00 2001 From: Alexander Aring <[email protected]> Date: Thu, 11 Feb 2021 16:40:11 -0500 Subject: [PATCH 01/14] libdlm: add stdint.h to api header This patch adds a include of stdint.h to the libdlm api header, otherwise application linking to it need to be sure to include the stdint header before libdlm header as a workaround. --- libdlm/libdlm.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libdlm/libdlm.h b/libdlm/libdlm.h index d025ef8cf0f0..9255181cdb6f 100644 --- a/libdlm/libdlm.h +++ b/libdlm/libdlm.h @@ -10,6 +10,8 @@ #ifndef __LIBDLM_H #define __LIBDLM_H +#include <stdint.h> + /* * Typedefs for things that are compatible with the kernel but replicated here * so that users only need the libdlm include file. libdlm itself needs the -- 2.33.0 ++++++ bug-1191734_0002-dlm_controld-create-var-parent-directories.patch ++++++ >From 4c774ebe7358d4ce773502d1703046c29371b4ec Mon Sep 17 00:00:00 2001 From: Alexander Aring <[email protected]> Date: Wed, 31 Mar 2021 16:20:42 -0400 Subject: [PATCH 02/14] dlm_controld: create var parent directories This patch creates /var/log/dlm_controld and /var/run/dlm_controld and it's parents if not exists before. In case of logging there was a likely issue no log file is created when /var/log/dlm_controld didn't exists before starting dlm_controld. Reported-by: Bob Peterson <[email protected]> --- dlm_controld/dlm_daemon.h | 8 ++++++-- dlm_controld/logging.c | 24 ++++++++++++++++++++++++ dlm_controld/main.c | 20 ++++++++++++++++---- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/dlm_controld/dlm_daemon.h b/dlm_controld/dlm_daemon.h index 45b295eafe2b..436fc9109aa6 100644 --- a/dlm_controld/dlm_daemon.h +++ b/dlm_controld/dlm_daemon.h @@ -65,8 +65,12 @@ /* TODO: get CONFDIR, LOGDIR, RUNDIR from build */ -#define RUNDIR "/var/run/dlm_controld" -#define LOGDIR "/var/log/dlm_controld" +#define SYS_VARDIR "/var" +#define SYS_RUNDIR SYS_VARDIR "/run" +#define SYS_LOGDIR SYS_VARDIR "/log" + +#define RUNDIR SYS_RUNDIR "/dlm_controld" +#define LOGDIR SYS_LOGDIR "/dlm_controld" #define CONFDIR "/etc/dlm" #define RUN_FILE_NAME "dlm_controld.pid" diff --git a/dlm_controld/logging.c b/dlm_controld/logging.c index 4aa3406c0725..d48b8aebc237 100644 --- a/dlm_controld/logging.c +++ b/dlm_controld/logging.c @@ -16,6 +16,9 @@ static FILE *logfile_fp; void init_logging(void) { + mode_t old_umask; + int rv; + syslog_facility = DEFAULT_SYSLOG_FACILITY; syslog_priority = DEFAULT_SYSLOG_PRIORITY; logfile_priority = DEFAULT_LOGFILE_PRIORITY; @@ -28,6 +31,26 @@ void init_logging(void) logfile_priority = LOG_DEBUG; if (logfile[0]) { + old_umask = umask(0077); + rv = mkdir(SYS_VARDIR, 0700); + if (rv < 0 && errno != EEXIST) { + umask(old_umask); + goto skip_logfile; + } + + rv = mkdir(SYS_LOGDIR, 0700); + if (rv < 0 && errno != EEXIST) { + umask(old_umask); + goto skip_logfile; + } + + rv = mkdir(LOGDIR, 0700); + if (rv < 0 && errno != EEXIST) { + umask(old_umask); + goto skip_logfile; + } + umask(old_umask); + logfile_fp = fopen(logfile, "a+"); if (logfile_fp != NULL) { int fd = fileno(logfile_fp); @@ -35,6 +58,7 @@ void init_logging(void) } } +skip_logfile: openlog(DAEMON_NAME, LOG_CONS | LOG_PID, syslog_facility); } diff --git a/dlm_controld/main.c b/dlm_controld/main.c index c35756d48c0b..504cafa12ec6 100644 --- a/dlm_controld/main.c +++ b/dlm_controld/main.c @@ -1598,7 +1598,7 @@ static int loop(void) return rv; } -static int lockfile(const char *dir, const char *name) +static int lockfile(const char *name) { char path[PATH_MAX]; char buf[16]; @@ -1607,14 +1607,26 @@ static int lockfile(const char *dir, const char *name) int fd, rv; old_umask = umask(0022); - rv = mkdir(dir, 0775); + rv = mkdir(SYS_VARDIR, 0775); + if (rv < 0 && errno != EEXIST) { + umask(old_umask); + return rv; + } + + rv = mkdir(SYS_RUNDIR, 0775); + if (rv < 0 && errno != EEXIST) { + umask(old_umask); + return rv; + } + + rv = mkdir(RUNDIR, 0775); if (rv < 0 && errno != EEXIST) { umask(old_umask); return rv; } umask(old_umask); - snprintf(path, PATH_MAX, "%s/%s", dir, name); + snprintf(path, PATH_MAX, "%s/%s", RUNDIR, name); fd = open(path, O_CREAT|O_WRONLY|O_CLOEXEC, 0644); if (fd < 0) { @@ -2125,7 +2137,7 @@ int main(int argc, char **argv) init_logging(); - fd = lockfile(RUNDIR, RUN_FILE_NAME); + fd = lockfile(RUN_FILE_NAME); if (fd < 0) return 1; -- 2.33.0 ++++++ bug-1191734_0003-stonith_helper-fix-build.patch ++++++ >From 5afd9fdc0ef202633f57abc063a5a2c6cef1d61d Mon Sep 17 00:00:00 2001 From: David Teigland <[email protected]> Date: Wed, 28 Jul 2021 16:12:43 -0500 Subject: [PATCH 03/14] stonith_helper: fix build include stdlib use pkg-config to get pacemaker headers --- fence/Makefile | 1 + fence/stonith_helper.c | 1 + 2 files changed, 2 insertions(+) diff --git a/fence/Makefile b/fence/Makefile index b927879eb141..1f6dd6b2c40e 100644 --- a/fence/Makefile +++ b/fence/Makefile @@ -20,6 +20,7 @@ CFLAGS += -D_GNU_SOURCE -O2 -ggdb \ CFLAGS += -fPIE -DPIE CFLAGS += `xml2-config --cflags` CFLAGS += -I../include +CFLAGS += $(shell pkg-config --cflags pacemaker-fencing) LDFLAGS += -Wl,-z,relro -pie LDFLAGS += `xml2-config --libs` diff --git a/fence/stonith_helper.c b/fence/stonith_helper.c index 3a0768af2830..b1db352ae04f 100644 --- a/fence/stonith_helper.c +++ b/fence/stonith_helper.c @@ -8,6 +8,7 @@ #include <stdio.h> #include <stdint.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> #include <syslog.h> -- 2.33.0 ++++++ bug-1191734_0004-plock-move-clear-waiter-to-debug-info.patch ++++++ >From 52c7bf79d447d9d015d676239cf1f2f9b2e5860c Mon Sep 17 00:00:00 2001 From: Alexander Aring <[email protected]> Date: Wed, 4 Aug 2021 10:15:37 -0400 Subject: [PATCH 04/14] plock: move clear waiter to debug info This patch moves the clear waiter log message for a killed/interrupted posix lock of a user space from error to debug. It can be confused to see it as error in the log but it's necessary to cleanup all waiters who are waiting for the lock. Reported-by: Shane Bradley <[email protected]> --- dlm_controld/plock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlm_controld/plock.c b/dlm_controld/plock.c index 992fb16fef1f..692787e2b758 100644 --- a/dlm_controld/plock.c +++ b/dlm_controld/plock.c @@ -660,7 +660,7 @@ static void clear_waiters(struct lockspace *ls, struct resource *r, list_del(&w->list); - log_elock(ls, "clear waiter %llx %llx-%llx %d/%u/%llx", + log_dlock(ls, "clear waiter %llx %llx-%llx %d/%u/%llx", (unsigned long long)in->number, (unsigned long long)in->start, (unsigned long long)in->end, -- 2.33.0 ++++++ bug-1191734_0005-treewide-try-to-resolve-symbols-at-linking-time.patch ++++++ >From 7bb5570aa5b215ebbcd2f8cce88d112d17c0e998 Mon Sep 17 00:00:00 2001 From: Alexander Aring <[email protected]> Date: Tue, 7 Sep 2021 11:44:41 -0400 Subject: [PATCH 05/14] treewide: try to resolve symbols at linking time This patch passes linker flags to the linker that all symbols should be resolved at linking time. If this is not possible the linker will fail to link. --- dlm_controld/Makefile | 4 ++-- dlm_tool/Makefile | 2 +- fence/Makefile | 2 +- libdlm/Makefile | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dlm_controld/Makefile b/dlm_controld/Makefile index fbc8926c8676..667998076acc 100644 --- a/dlm_controld/Makefile +++ b/dlm_controld/Makefile @@ -49,9 +49,9 @@ BIN_CFLAGS += $(CFLAGS) -fPIE -DPIE BIN_CFLAGS += -I../include -I../libdlm LIB_CFLAGS += $(CFLAGS) -fPIC -BIN_LDFLAGS += $(LDFLAGS) -Wl,-z,relro -pie +BIN_LDFLAGS += $(LDFLAGS) -Wl,-z,relro -Wl,-z,defs -pie BIN_LDFLAGS += -lpthread -lrt -lcpg -lcmap -lcfg -lquorum -luuid -LIB_LDFLAGS += $(LDFLAGS) -Wl,-z,relro -pie +LIB_LDFLAGS += $(LDFLAGS) -Wl,-z,relro -Wl,-z,defs -pie PKG_CONFIG ?= pkg-config ifeq ($(USE_SD_NOTIFY),yes) diff --git a/dlm_tool/Makefile b/dlm_tool/Makefile index 80d7725791f3..7b42638c0e4a 100644 --- a/dlm_tool/Makefile +++ b/dlm_tool/Makefile @@ -20,7 +20,7 @@ CFLAGS += -D_GNU_SOURCE -O2 -ggdb \ CFLAGS += -fPIE -DPIE CFLAGS += -I../include -I../libdlm -I../dlm_controld -LDFLAGS += -Wl,-z,relro -pie +LDFLAGS += -Wl,-z,relro -Wl,-z,defs -pie LDFLAGS += -L../libdlm -L../dlm_controld LDFLAGS += -lpthread -ldlm -ldlmcontrol diff --git a/fence/Makefile b/fence/Makefile index 1f6dd6b2c40e..2b080468eaa0 100644 --- a/fence/Makefile +++ b/fence/Makefile @@ -22,7 +22,7 @@ CFLAGS += `xml2-config --cflags` CFLAGS += -I../include CFLAGS += $(shell pkg-config --cflags pacemaker-fencing) -LDFLAGS += -Wl,-z,relro -pie +LDFLAGS += -Wl,-z,relro -Wl,-z,defs -pie LDFLAGS += `xml2-config --libs` LDFLAGS += -ldl diff --git a/libdlm/Makefile b/libdlm/Makefile index ab32761912b3..313c2a08f17e 100644 --- a/libdlm/Makefile +++ b/libdlm/Makefile @@ -84,8 +84,8 @@ CFLAGS += -D_GNU_SOURCE -O2 -ggdb \ LIB_CFLAGS += $(CFLAGS) -D_REENTRANT LLT_CFLAGS += $(CFLAGS) -LIB_LDFLAGS += $(LDFLAGS) -lpthread -LLT_LDFLAGS += $(LDFLAGS) +LIB_LDFLAGS += $(LDFLAGS) -lpthread -Wl,-z,defs +LLT_LDFLAGS += $(LDFLAGS) -Wl,-z,defs all: $(LIB_TARGET) $(LLT_TARGET) $(LIB_PC) $(LLT_PC) -- 2.33.0 ++++++ bug-1191734_0006-dlm_controld-add-version-check-for-libquorum.patch ++++++ >From 3201db3835c85a1d9a407e621bff7902896e8a82 Mon Sep 17 00:00:00 2001 From: Alexander Aring <[email protected]> Date: Tue, 7 Sep 2021 12:06:00 -0400 Subject: [PATCH 06/14] dlm_controld: add version check for libquorum This patch adds a simple version check for libquorum. Since commit 2e893b98 ("dlm_controld: use new quorum api to detect missed failures") dlm_controld uses functionality which is only available in libquorum 3.1.0 and upwards. --- dlm_controld/Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dlm_controld/Makefile b/dlm_controld/Makefile index 667998076acc..8cfc97e6909a 100644 --- a/dlm_controld/Makefile +++ b/dlm_controld/Makefile @@ -60,6 +60,10 @@ ifeq ($(USE_SD_NOTIFY),yes) BIN_LDFLAGS += $(shell $(PKG_CONFIG) --libs libsystemd) endif +ifeq (, $(shell $(PKG_CONFIG) --libs "libquorum >= 3.1.0")) + $(error "Requires libquorum at least version 3.1.0") +endif + all: $(LIB_TARGET) $(BIN_TARGET) $(LIB_PC) $(BIN_TARGET): $(BIN_SOURCE) -- 2.33.0 ++++++ bug-1191734_0007-dlm_tool-man-add-command-joinleave-USAGE.patch ++++++ >From c4828edd9dae2d606a693788d7724b8411722f19 Mon Sep 17 00:00:00 2001 From: Heming Zhao <[email protected]> Date: Fri, 8 Oct 2021 09:33:35 +0800 Subject: [PATCH 07/14] dlm_tool man: add command "joinleave" & "USAGE" add missing command "joinleave". add "USAGE" section to show detail usage. Signed-off-by: Heming Zhao <[email protected]> --- dlm_tool/dlm_tool.8 | 80 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/dlm_tool/dlm_tool.8 b/dlm_tool/dlm_tool.8 index bbc11c261b7e..7e82f8908ed6 100644 --- a/dlm_tool/dlm_tool.8 +++ b/dlm_tool/dlm_tool.8 @@ -48,6 +48,10 @@ dlm_tool \- a utility for the dlm and dlm_controld daemon .br Leave a lockspace. +.BI joinleave " name" +.br + Do two actions: first Join then Leave a lockspace. (mainly for test) + .BI lockdebug " name" .br Complete display of locks from the lockspace. @@ -112,6 +116,82 @@ Print help, then exit .B \-V Print program version information, then exit +.SH USAGE + +.B dlm_tool ls [-n] [ls_name] + +- + +.B dlm_tool status [-v] + +- + +.B dlm_tool dump + +- + +.B dlm_tool dump_config + +- + +.B dlm_tool fence_ack \fInodeid\fP + +* run "dlm_tool status -v" to get \fInodeid\fP + +- + +.B dlm_tool log_plock + +- + +.B dlm_tool plocks \fIls-name\fP + +- + +.B dlm_tool join [-e 0|1] [-f 0|1] \fIls-name\fP + +- + +.B dlm_tool leave \fIls-name\fP + +- + +.B dlm_tool joinleave [-e 0|1] [-f 0|1] \fIls-name\fP + +- + +.B dlm_tool lockdebug [-s] [-v] [-w] \fIls-name\fP + +- + +.B dlm_tool lockdump [-M] \fIls-name\fP + +- + +.B dlm_tool run|run_start [-n] \fIcommand\fP + +* current run & run_start support \fIcommand\fP: +.br + - "lvm lvchange --refresh" +.br + - "lvm lvs" + +- + +.B dlm_tool run_check|run_cancel [-i "sec"] \fIuuid\fP + +- + +.B dlm_tool run_list + +- + +.B dlm_tool -h + +- + +.B dlm_tool -V + .SH SEE ALSO .BR dlm_controld (8), .BR dlm.conf (5) -- 2.33.0 ++++++ bug-1191734_0008-man-add-reload_config-in-dlm_tool-dlm.conf.patch ++++++ >From 6f764cceeb7350d8da33765da07462578f07e988 Mon Sep 17 00:00:00 2001 From: Heming Zhao <[email protected]> Date: Fri, 8 Oct 2021 09:33:36 +0800 Subject: [PATCH 08/14] man: add reload_config in dlm_tool & dlm.conf reload_config is a new command of dlm_tool. We could use this command to change dlm_controld some settings on the fly. This patch modifies man page to add usage for this new command. Signed-off-by: Heming Zhao <[email protected]> --- dlm_controld/dlm.conf.5 | 42 ++++++++++++++++++++++++++++++----------- dlm_tool/dlm_tool.8 | 10 ++++++++++ 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/dlm_controld/dlm.conf.5 b/dlm_controld/dlm.conf.5 index 1ce0c6445ee1..99e302a92bd2 100644 --- a/dlm_controld/dlm.conf.5 +++ b/dlm_controld/dlm.conf.5 @@ -34,7 +34,9 @@ protocol=tcp Options: -log_debug +daemon_debug(*) +.br +log_debug(*) .br protocol .br @@ -42,23 +44,23 @@ bind_all .br mark .br -debug_logfile +debug_logfile(*) .br enable_plock .br -plock_debug +plock_debug(*) .br -plock_rate_limit +plock_rate_limit(*) .br plock_ownership .br -drop_resources_time +drop_resources_time(*) .br -drop_resources_count +drop_resources_count(*) .br -drop_resources_age +drop_resources_age(*) .br -post_join_delay +post_join_delay(*) .br enable_fencing .br @@ -66,15 +68,33 @@ enable_concurrent_fencing .br enable_startup_fencing .br -enable_quorum_fencing +enable_quorum_fencing(*) .br -enable_quorum_lockspace +enable_quorum_lockspace(*) .br -repeat_failed_fencing +repeat_failed_fencing(*) .br enable_helper .br +Option with tail (*) means this item can be reload on the fly by "dlm_tool reload_config". See \fB"Reload config"\fP for more examples. + +.SH Reload config + +dlm.conf can be changed then reloaded some settings on the fly, it gives users more flexible and powerful ability to manage dlm. + +The supported reload operations: +.br +- add a new item +.br +- remove an exist item +.br +- commented out an item +.br +- change an item value + +After modifying settings in dlm.conf, run "dlm_tool reload_config" to take effect. User can use "dlm_tool dump_config" to check the result. Again, only reloadable item can be changed. + .SH Fencing A fence device definition begins with a diff --git a/dlm_tool/dlm_tool.8 b/dlm_tool/dlm_tool.8 index 7e82f8908ed6..6c1d471abe68 100644 --- a/dlm_tool/dlm_tool.8 +++ b/dlm_tool/dlm_tool.8 @@ -28,6 +28,10 @@ dlm_tool \- a utility for the dlm and dlm_controld daemon .br Dump dlm_controld config settings. +.B reload_config +.br + Reload dlm_controld config settings from dlm.conf. + .BI fence_ack " nodeid" .br Quit trying to fence a node. @@ -134,6 +138,12 @@ Print program version information, then exit - +.B dlm_tool reload_config + +* see examples in \fBdlm.conf(5)\fP + +- + .B dlm_tool fence_ack \fInodeid\fP * run "dlm_tool status -v" to get \fInodeid\fP -- 2.33.0 ++++++ bug-1191734_0009-add-new-dlm_tool-command-reload_config.patch ++++++ ++++ 729 lines (skipped) ++++++ bug-1191734_0010-dlm_tool-man-add-new-command-set_config.patch ++++++ >From 041c136eb5f843369ec3fa5f0bbebde621121397 Mon Sep 17 00:00:00 2001 From: Heming Zhao <[email protected]> Date: Fri, 8 Oct 2021 09:33:38 +0800 Subject: [PATCH 10/14] dlm_tool man: add new command set_config add new command set_config and examples Signed-off-by: Heming Zhao <[email protected]> --- dlm_tool/dlm_tool.8 | 131 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 3 deletions(-) diff --git a/dlm_tool/dlm_tool.8 b/dlm_tool/dlm_tool.8 index 6c1d471abe68..f6d869620822 100644 --- a/dlm_tool/dlm_tool.8 +++ b/dlm_tool/dlm_tool.8 @@ -32,6 +32,10 @@ dlm_tool \- a utility for the dlm and dlm_controld daemon .br Reload dlm_controld config settings from dlm.conf. +.B set_config +.br + Set dlm_controld config settings on the fly. + .BI fence_ack " nodeid" .br Quit trying to fence a node. @@ -144,6 +148,12 @@ Print program version information, then exit - +.B dlm_tool set_config "dlm_controld-config-item=x" + +* see below \fBset_config EXAMPLES\fP section + +- + .B dlm_tool fence_ack \fInodeid\fP * run "dlm_tool status -v" to get \fInodeid\fP @@ -181,9 +191,9 @@ Print program version information, then exit .B dlm_tool run|run_start [-n] \fIcommand\fP * current run & run_start support \fIcommand\fP: -.br +. - "lvm lvchange --refresh" -.br +. - "lvm lvs" - @@ -202,7 +212,122 @@ Print program version information, then exit .B dlm_tool -V +.SH set_config EXAMPLES + +\fIdlm_tool set_config "xxx"\fP can do the dynamic config job. It makes possible to debug, or to do flexible operations on the fly. + +supported option items + +.RS +.EX +daemon_debug +log_debug +debug_logfile +plock_debug +plock_rate_limit +drop_resources_time +drop_resources_count +drop_resources_age +post_join_delay +enable_quorum_fencing +enable_quorum_lockspace +repeat_failed_fencing +.EE +.RE + +.SS display style + +Currently, there are 5 ways of setting: default, cli, dlm.conf, reload_config, set_config + +The "dlm_tool dump_config" shows the config item by 4 styles. + +.TP +key=val +For default values that have not been set by cli or config file or dynamically. + +.TP +key=val (cli option) +For values that have been last set from a command line option. + +.TP +key=val (dlm.conf) +For values that have been last set from dlm.conf. (reload_config also belongs to this style) + +.TP +key=val (set_config) +For values that have been last set by dlm_tool set_config. + +.TP +i.e. + +.EX +# dlm_tool dump_config | head -n 5 +daemon_debug=1 (set_config) +foreground=0 +log_debug=1 (dlm.conf) +timewarn=0 +protocol=detect +.EE + +In this case, the "daemon_debug" is set by set_config, the "log_debug" is set by dlm.conf. +meanwhile foreground, timewarn & protocol are using default values. + +.SS set_config usage + +log_debug is set by dlm.conf (value is 1), then run "set_config" to change to 0. at last use "restore" to restore to dlm.conf setting. + +.RS +.EX +# dlm_tool dump_config | grep log_debug +log_debug=1 (dlm.conf) + +# dlm_tool set_config "log_debug=0" +set_config done + +# dlm_tool dump_config | grep log_debug +log_debug=0 (set_config) + +# dlm_tool set_config "log_debug=restore" +set_config done + +# dlm_tool dump_config | grep log_debug +log_debug=1 (dlm.conf) +.EE +.RE + +restore method + +Once user uses "set_config key=val" to change value, whatever user sets 0 or 1, the related item belongs to "set_config" type. There are 2 ways to do restoration job: key=restore, restore_all + +restore - to reset single option item (see above example) + +restore_all - to reset all set_config items. + +.RS +.EX +# dlm_tool dump_config | grep _debug +daemon_debug=0 +log_debug=1 (dlm.conf) +plock_debug=0 + +# dlm_tool set_config "daemon_debug=1 log_debug=1 plock_debug=1" +set_config done + +# dlm_tool dump_config | grep _debug +daemon_debug=1 (set_config) +log_debug=1 (set_config) +plock_debug=1 (set_config) + +# dlm_tool set_config "restore_all" +set_config done + +# dlm_tool dump_config | grep _debug +daemon_debug=0 +log_debug=1 (dlm.conf) +plock_debug=0 +.EE +.RE + .SH SEE ALSO .BR dlm_controld (8), .BR dlm.conf (5) - -- 2.33.0 ++++++ bug-1191734_0011-dlm_tool-dlm_controld-add-new-feature-set_config.patch ++++++ >From 0e814226e081d228c96a8cc43e5cec484dc78306 Mon Sep 17 00:00:00 2001 From: Heming Zhao <[email protected]> Date: Fri, 8 Oct 2021 09:33:39 +0800 Subject: [PATCH 11/14] dlm_tool dlm_controld: add new feature set_config set_config command makes dlm_controld could change options value dynamically. Signed-off-by: Heming Zhao <[email protected]> --- dlm_controld/config.c | 169 +++++++++++++++++++++++++++++++++++ dlm_controld/dlm_controld.h | 1 + dlm_controld/dlm_daemon.h | 11 +++ dlm_controld/helper.c | 4 - dlm_controld/lib.c | 38 +++++++- dlm_controld/libdlmcontrol.h | 1 + dlm_controld/main.c | 22 ++++- dlm_tool/main.c | 29 +++++- 8 files changed, 264 insertions(+), 11 deletions(-) diff --git a/dlm_controld/config.c b/dlm_controld/config.c index c60be8d47ef0..a7ebb120a6b8 100644 --- a/dlm_controld/config.c +++ b/dlm_controld/config.c @@ -387,3 +387,172 @@ void set_opt_file(int update) fclose(file); } +/* + * do the clean/restore job: + * - clean up dlm_options[].dynamic_xx + * - using top priority item to set use option + */ +static void reset_dynamic(int index) +{ + struct dlm_option *o = &dlm_options[index]; + + if (!o->reload) + return; + + o->dynamic_set = 0; + o->dynamic_int = 0; + if (o->dynamic_str){ + free(o->dynamic_str); + o->dynamic_str = NULL; + } + o->dynamic_uint = 0; + reset_opt_value(index); + + return; +} + +/* copy code from exec_command() */ +void set_opt_online(char *cmd_str, int cmd_len) +{ + int i, ind, val = 0; + int av_count = 0; + int arg_len; + unsigned int uval = 0; + struct dlm_option *o; + char str[MAX_LINE]; + char arg[ONE_ARG_LEN]; + char *av[MAX_AV_COUNT + 1]; /* +1 for NULL */ + + if (cmd_len > RUN_COMMAND_LEN) + return; + + for (i = 0; i < MAX_AV_COUNT + 1; i++) + av[i] = NULL; + + if (!cmd_str[0]) + return; + + /* this should already be done, but make sure */ + cmd_str[cmd_len - 1] = '\0'; + + memset(&arg, 0, sizeof(arg)); + arg_len = 0; + cmd_len = strlen(cmd_str); + + for (i = 0; i < cmd_len; i++) { + if (!cmd_str[i]) + break; + + if (av_count == MAX_AV_COUNT) + break; + + if (cmd_str[i] == '\\') { + if (i == (cmd_len - 1)) + break; + i++; + + if (cmd_str[i] == '\\') { + arg[arg_len++] = cmd_str[i]; + continue; + } + if (isspace(cmd_str[i])) { + arg[arg_len++] = cmd_str[i]; + continue; + } else { + break; + } + } + + if (isalnum(cmd_str[i]) || ispunct(cmd_str[i])) { + arg[arg_len++] = cmd_str[i]; + } else if (isspace(cmd_str[i])) { + if (arg_len) + av[av_count++] = strdup(arg); + + memset(arg, 0, sizeof(arg)); + arg_len = 0; + } else { + break; + } + } + + if ((av_count < MAX_AV_COUNT) && arg_len) { + av[av_count++] = strdup(arg); + } + + /* + for (i = 0; i < MAX_AV_COUNT + 1; i++) { + if (!av[i]) + break; + + syslog(LOG_ERR, "command av[%d] \"%s\"", i, av[i]); + } + */ + + if (!strcmp(av[0], "restore_all")) { + for (i = 0; i < dlm_options_max; i++) + reset_dynamic(i); + return; + } + + i = -1; + while (++i < av_count) { + + ind = get_ind_name(av[i]); + if (ind < 0) + continue; + o = &dlm_options[ind]; + if (!o || !o->reload) + continue; + + get_val_str(av[i], str); + if (!strcmp(str, "restore")) { + reset_dynamic(ind); + continue; + } + + o->dynamic_set++; + + if (!o->req_arg || o->req_arg == req_arg_int) { + get_val_int(av[i], &val); + if (!o->req_arg) + val = val ? 1 : 0; + + o->dynamic_int = val; + + log_debug("config dynamic %s = %d previous use %d", + o->name, o->dynamic_int, o->use_int); + o->use_int = o->dynamic_int; + + } else if (o->req_arg == req_arg_uint) { + get_val_uint(av[i], &uval); + o->dynamic_uint = uval; + + log_debug("config dynamic %s = %u previous use %u", + o->name, o->dynamic_uint, o->use_uint); + o->use_uint = o->dynamic_uint; + + } else if (o->req_arg == req_arg_bool) { + get_val_int(av[i], &val); + o->dynamic_int = val ? 1 : 0; + + log_debug("config dynamic %s = %d previous use %d", + o->name, o->dynamic_int, o->use_int); + o->use_int = o->dynamic_int; + + } else if (o->req_arg == req_arg_str) { + memset(str, 0, sizeof(str)); + get_val_str(av[i], str); + + o->dynamic_str = strdup(str); + + log_debug("config dynamic %s = %s previous use %s", + o->name, o->dynamic_str, o->use_str); + o->use_str = o->dynamic_str; + } + + reload_setting(ind); + } + + return; +} diff --git a/dlm_controld/dlm_controld.h b/dlm_controld/dlm_controld.h index 0ea3548fce7d..94e5c49e88bd 100644 --- a/dlm_controld/dlm_controld.h +++ b/dlm_controld/dlm_controld.h @@ -36,6 +36,7 @@ #define DLMC_CMD_RUN_CHECK 16 #define DLMC_CMD_DUMP_RUN 17 #define DLMC_CMD_RELOAD_CONFIG 18 +#define DLMC_CMD_SET_CONFIG 19 struct dlmc_header { unsigned int magic; diff --git a/dlm_controld/dlm_daemon.h b/dlm_controld/dlm_daemon.h index 9e68f8257cb5..da261774bee0 100644 --- a/dlm_controld/dlm_daemon.h +++ b/dlm_controld/dlm_daemon.h @@ -25,6 +25,7 @@ #include <arpa/inet.h> #include <net/if.h> #include <stdio.h> +#include <ctype.h> #include <errno.h> #include <string.h> #include <stdlib.h> @@ -133,6 +134,7 @@ struct dlm_option { char letter; int req_arg; char reload; + char dynamic; const char *desc; int use_int; @@ -152,6 +154,11 @@ struct dlm_option { int file_int; char *file_str; unsigned int file_uint; + + int dynamic_set; + int dynamic_int; + char *dynamic_str; + unsigned int dynamic_uint; }; EXTERN struct dlm_option dlm_options[dlm_options_max]; @@ -328,6 +335,9 @@ struct lockspace { #define RUN_COMMAND_LEN DLMC_RUN_COMMAND_LEN /* 1024 */ +#define MAX_AV_COUNT 32 +#define ONE_ARG_LEN 256 + struct run_info { int dest_nodeid; int start_nodeid; @@ -390,6 +400,7 @@ int set_configfs_opt(const char *name, char *str, int num); void set_opt_file(int update); int get_weight(struct lockspace *ls, int nodeid); void setup_lockspace_config(struct lockspace *ls); +void set_opt_online(char *cmd_str, int cmd_len); /* cpg.c */ void process_lockspace_changes(void); diff --git a/dlm_controld/helper.c b/dlm_controld/helper.c index a20965b76195..469dd22095f0 100644 --- a/dlm_controld/helper.c +++ b/dlm_controld/helper.c @@ -20,7 +20,6 @@ #include <time.h> #include <stdarg.h> #include <signal.h> -#include <ctype.h> #include <sys/time.h> #include <sys/types.h> #include <sys/wait.h> @@ -29,9 +28,6 @@ #include "dlm_daemon.h" -#define MAX_AV_COUNT 32 -#define ONE_ARG_LEN 256 - static int _log_stderr; diff --git a/dlm_controld/lib.c b/dlm_controld/lib.c index 951eb6561ba9..8cbdd27f15e2 100644 --- a/dlm_controld/lib.c +++ b/dlm_controld/lib.c @@ -189,7 +189,43 @@ int dlmc_reload_config(void) rv = do_write(fd, &h, sizeof(h)); close(fd); - out: +out: + return rv; +} + +int dlmc_set_config(char *command) +{ + struct dlmc_header h; + char *cmdbuf; + int fd, rv; + + cmdbuf = malloc(DLMC_RUN_COMMAND_LEN); + if (!cmdbuf) + return -1; + + memset(cmdbuf, 0, DLMC_RUN_COMMAND_LEN); + strncpy(cmdbuf, command, DLMC_RUN_COMMAND_LEN-1); + + init_header(&h, DLMC_CMD_SET_CONFIG, NULL, DLMC_RUN_COMMAND_LEN); + + fd = do_connect(DLMC_SOCK_PATH); + if (fd < 0) { + rv = fd; + goto out; + } + + rv = do_write(fd, &h, sizeof(h)); + if (rv < 0) + goto out_close; + + rv = do_write(fd, cmdbuf, DLMC_RUN_COMMAND_LEN); + if (rv < 0) + goto out_close; + +out_close: + close(fd); +out: + free(cmdbuf); return rv; } diff --git a/dlm_controld/libdlmcontrol.h b/dlm_controld/libdlmcontrol.h index ac84e702fb58..a106171b1073 100644 --- a/dlm_controld/libdlmcontrol.h +++ b/dlm_controld/libdlmcontrol.h @@ -92,6 +92,7 @@ int dlmc_lockspace_nodes(char *lsname, int type, int max, int *count, struct dlmc_node *nodes); int dlmc_print_status(uint32_t flags); int dlmc_reload_config(void); +int dlmc_set_config(char *command); #define DLMC_RESULT_REGISTER 1 #define DLMC_RESULT_NOTIFIED 2 diff --git a/dlm_controld/main.c b/dlm_controld/main.c index 8104d8f906ac..3a081c802056 100644 --- a/dlm_controld/main.c +++ b/dlm_controld/main.c @@ -919,7 +919,7 @@ static void copy_options(char *buf, int *len) { struct dlm_option *o; char tmp[256]; - int i, ret, pos = 0; + int i, ret, pos = 0, l = 0; for (i = 0; i < dlm_options_max; i++) { o = &dlm_options[i]; @@ -927,9 +927,20 @@ static void copy_options(char *buf, int *len) memset(tmp, 0, sizeof(tmp)); if (o->req_arg == req_arg_str) - snprintf(tmp, 255, "%s=%s\n", o->name, o->use_str); + l = snprintf(tmp, 250, "%s=%s", o->name, o->use_str); + else if (o->req_arg == req_arg_uint) + l = snprintf(tmp, 250, "%s=%u", o->name, o->use_uint); + else + l = snprintf(tmp, 250, "%s=%d", o->name, o->use_int); + + if (o->dynamic_set) + snprintf(tmp + l, 15, " (set_config)\n"); + else if (o->cli_set) + snprintf(tmp + l, 15, " (cli option)\n"); + else if (o->file_set) + snprintf(tmp + l, 15, " (dlm.conf)\n"); else - snprintf(tmp, 255, "%s=%d\n", o->name, o->use_int); + snprintf(tmp + l, 15, "\n"); if (pos + strlen(tmp) >= LOG_DUMP_SIZE) break; @@ -1234,6 +1245,11 @@ static void process_connection(int ci) set_opt_file(1); break; + case DLMC_CMD_SET_CONFIG: + if (extra_len) + set_opt_online(extra, extra_len); + break; + default: log_error("process_connection %d unknown command %d", ci, h.command); diff --git a/dlm_tool/main.c b/dlm_tool/main.c index 774835192bbf..bce5c1da3c95 100644 --- a/dlm_tool/main.c +++ b/dlm_tool/main.c @@ -48,6 +48,7 @@ #define OP_RUN_LIST 18 #define OP_DUMP_RUN 19 #define OP_RELOAD_CONFIG 20 +#define OP_SET_CONFIG 21 static char *prog_name; static char *lsname; @@ -197,7 +198,8 @@ static void print_usage(void) printf("dlm_tool [command] [options] [name]\n"); printf("\n"); printf("Commands:\n"); - printf("ls, status, dump, dump_config, reload_config, fence_ack\n"); + printf("ls, status, dump, fence_ack\n"); + printf("dump_config, reload_config, set_config\n"); printf("log_plock, plocks\n"); printf("join, leave, lockdebug\n"); printf("run, run_start, run_check, run_cancel, run_list\n"); @@ -370,6 +372,13 @@ static void decode_arguments(int argc, char **argv) opt_ind = optind + 1; need_lsname = 0; break; + } else if (!strncmp(argv[optind], "set_config", 10) && + (strlen(argv[optind]) == 10)) { + operation = OP_SET_CONFIG; + opt_ind = optind + 1; + need_lsname = 0; + need_command = 1; + break; } else if (!strncmp(argv[optind], "plocks", 6) && (strlen(argv[optind]) == 6)) { operation = OP_PLOCKS; @@ -477,8 +486,10 @@ static void decode_arguments(int argc, char **argv) exit(EXIT_FAILURE); } - strcat(run_command, argv[i]); - strcat(run_command, " "); + if (strlen(argv[i])) { + strcat(run_command, argv[i]); + strcat(run_command, " "); + } } } @@ -1487,6 +1498,14 @@ static void do_reload_config(void) printf("reload_config done\n"); } +static void do_set_config(void) +{ + if (dlmc_set_config(run_command) < 0) + printf("set_config failed\n"); + else + printf("set_config done\n"); +} + static void do_log_plock(void) { char buf[DLMC_DUMP_SIZE]; @@ -1589,6 +1608,10 @@ int main(int argc, char **argv) do_reload_config(); break; + case OP_SET_CONFIG: + do_set_config(); + break; + case OP_LOG_PLOCK: do_log_plock(); break; -- 2.33.0 ++++++ bug-1191734_0012-fix-some-minor-bugs.patch ++++++ >From cf99a9770359cef56a5aabce8c5bf2d4aeb4f2f8 Mon Sep 17 00:00:00 2001 From: Heming Zhao <[email protected]> Date: Fri, 8 Oct 2021 09:33:40 +0800 Subject: [PATCH 12/14] fix some minor bugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1> log_config() should print "0" when m_buf or j_buf or l_buf is empty. 2> parameter "%d" lacks object in confchg_cb_daemon(). 3> in run_helper(): running_count doesn't work for run_helper process. running_count limits cmd numbers not to beyond 32. This assessment should be put in run_helper while(1). 4> fix decode_arguments() naming mistake for fence_ack command. 5> removing a gcc warning for decode_arguments() message: ``` /usr/include/bits/string_fortified.h:95:10: warning: ???__builtin_strncpy??? specified bound 64 equals destination size [-Wstringop-truncation] 95 | return __builtin___strncpy_chk (__dest, __src, __len, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 96 | __glibc_objsize (__dest)); | ~~~~~~~~~~~~~~~~~~~~~~~~~ ``` uuid is generated by uuid_generate(), which is 37-byte (36-byte uuid plus tailing '\0'). In exist code, uuid[] is 64-byte array, which has enough space to fill 37-byte string. So we could safely do one-byte less copy in strncpy(). Signed-off-by: Heming Zhao <[email protected]> --- dlm_controld/daemon_cpg.c | 5 +++-- dlm_controld/helper.c | 10 +++++----- dlm_tool/main.c | 12 ++++++++---- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/dlm_controld/daemon_cpg.c b/dlm_controld/daemon_cpg.c index 392e0ff63cd8..65593e80dec4 100644 --- a/dlm_controld/daemon_cpg.c +++ b/dlm_controld/daemon_cpg.c @@ -174,7 +174,8 @@ void log_config(const struct cpg_name *group_name, log_debug("%s conf %zu %zu %zu memb%s join%s left%s", group_name->value, member_list_entries, joined_list_entries, left_list_entries, - m_buf, j_buf, l_buf); + strlen(m_buf) ? m_buf : " 0", strlen(j_buf) ? j_buf : " 0", + strlen(l_buf) ? l_buf : " 0"); } void log_ringid(const char *name, @@ -2335,7 +2336,7 @@ static void confchg_cb_daemon(cpg_handle_t handle, valid proto from it (is_clean_daemon_member) */ log_error("daemon joined %d needs fencing", node->nodeid); } else { - log_debug("daemon joined %d"); + log_debug("daemon joined %d", node->nodeid); } } else { if (!node->daemon_member) diff --git a/dlm_controld/helper.c b/dlm_controld/helper.c index 469dd22095f0..f31ccd954826 100644 --- a/dlm_controld/helper.c +++ b/dlm_controld/helper.c @@ -286,11 +286,6 @@ int run_helper(int in_fd, int out_fd, int log_stderr) _log_stderr = log_stderr; - if (running_count >= MAX_RUNNING) { - log_helper("too many running commands"); - return -1; - } - rv = setgroups(0, NULL); if (rv < 0) log_helper("error clearing helper groups errno %i", errno); @@ -335,6 +330,11 @@ int run_helper(int in_fd, int out_fd, int log_stderr) if (hd->type == DLM_MSG_RUN_REQUEST) { int cmd_pipe[2]; + if (running_count >= MAX_RUNNING) { + log_helper("too many running commands"); + exit(1); + } + /* * Child writes cmd_buf to cmd_pipe, parent reads * cmd_buf from cmd_pipe. cmd_buf contains the diff --git a/dlm_tool/main.c b/dlm_tool/main.c index bce5c1da3c95..04ff40f874c8 100644 --- a/dlm_tool/main.c +++ b/dlm_tool/main.c @@ -461,12 +461,16 @@ static void decode_arguments(int argc, char **argv) if (optind < argc - 1) { if (need_lsname) lsname = argv[opt_ind]; - else if (need_uuid) - strncpy(run_uuid, argv[opt_ind], DLMC_RUN_UUID_LEN); - else if (need_command) + else if (need_uuid) { + strncpy(run_uuid, argv[opt_ind], DLMC_RUN_UUID_LEN - 1); + run_uuid[DLMC_RUN_UUID_LEN - 1] = '\0'; + } else if (need_command) goto copy_command; } else if (need_lsname) { - fprintf(stderr, "lockspace name required\n"); + if (operation == OP_FENCE_ACK) + fprintf(stderr, "nodeid required\n"); + else + fprintf(stderr, "lockspace name required\n"); exit(EXIT_FAILURE); } else if (need_command) { fprintf(stderr, "command required\n"); -- 2.33.0 ++++++ bug-1191734_0013-dlm_controld-fix-string-copies.patch ++++++ >From a877e55c4661cfceabcb566ad49afd27b245cb65 Mon Sep 17 00:00:00 2001 From: David Teigland <[email protected]> Date: Fri, 15 Oct 2021 12:02:34 -0500 Subject: [PATCH 13/14] dlm_controld fix string copies --- dlm_controld/config.c | 4 +--- dlm_controld/main.c | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/dlm_controld/config.c b/dlm_controld/config.c index a7ebb120a6b8..b15527b949b1 100644 --- a/dlm_controld/config.c +++ b/dlm_controld/config.c @@ -495,9 +495,7 @@ void set_opt_online(char *cmd_str, int cmd_len) return; } - i = -1; - while (++i < av_count) { - + for (i = 0; i < av_count; i++) { ind = get_ind_name(av[i]); if (ind < 0) continue; diff --git a/dlm_controld/main.c b/dlm_controld/main.c index 3a081c802056..57844dc10129 100644 --- a/dlm_controld/main.c +++ b/dlm_controld/main.c @@ -927,11 +927,11 @@ static void copy_options(char *buf, int *len) memset(tmp, 0, sizeof(tmp)); if (o->req_arg == req_arg_str) - l = snprintf(tmp, 250, "%s=%s", o->name, o->use_str); + l = snprintf(tmp, 240, "%s=%s", o->name, o->use_str); else if (o->req_arg == req_arg_uint) - l = snprintf(tmp, 250, "%s=%u", o->name, o->use_uint); + l = snprintf(tmp, 240, "%s=%u", o->name, o->use_uint); else - l = snprintf(tmp, 250, "%s=%d", o->name, o->use_int); + l = snprintf(tmp, 240, "%s=%d", o->name, o->use_int); if (o->dynamic_set) snprintf(tmp + l, 15, " (set_config)\n"); -- 2.33.0 ++++++ bug-1191734_0014-man-page-updates.patch ++++++ >From 694237c7b7857ff18b5057758b5550162cc85149 Mon Sep 17 00:00:00 2001 From: David Teigland <[email protected]> Date: Fri, 15 Oct 2021 12:12:18 -0500 Subject: [PATCH 14/14] man page updates --- dlm_controld/dlm.conf.5 | 21 ++-- dlm_tool/dlm_tool.8 | 224 ++++++++++++++-------------------------- 2 files changed, 81 insertions(+), 164 deletions(-) diff --git a/dlm_controld/dlm.conf.5 b/dlm_controld/dlm.conf.5 index 99e302a92bd2..0eb226358100 100644 --- a/dlm_controld/dlm.conf.5 +++ b/dlm_controld/dlm.conf.5 @@ -22,7 +22,7 @@ for descriptions and dlm_controld -h for defaults. Format: -key=val +setting=value Example: @@ -77,23 +77,14 @@ repeat_failed_fencing(*) enable_helper .br -Option with tail (*) means this item can be reload on the fly by "dlm_tool reload_config". See \fB"Reload config"\fP for more examples. +Options with (*) can be reloaded, see Reload config. .SH Reload config -dlm.conf can be changed then reloaded some settings on the fly, it gives users more flexible and powerful ability to manage dlm. - -The supported reload operations: -.br -- add a new item -.br -- remove an exist item -.br -- commented out an item -.br -- change an item value - -After modifying settings in dlm.conf, run "dlm_tool reload_config" to take effect. User can use "dlm_tool dump_config" to check the result. Again, only reloadable item can be changed. +Some dlm.conf settings can be changed while dlm_controld is running using +dlm_tool reload_config. Edit dlm.conf, adding, removing, commenting or +changing values, then run dlm_tool reload_config to apply the changes in +dlm_controld. dlm_tool dump_config will show the new settings. .SH Fencing diff --git a/dlm_tool/dlm_tool.8 b/dlm_tool/dlm_tool.8 index f6d869620822..2a14fe0292a7 100644 --- a/dlm_tool/dlm_tool.8 +++ b/dlm_tool/dlm_tool.8 @@ -32,45 +32,45 @@ dlm_tool \- a utility for the dlm and dlm_controld daemon .br Reload dlm_controld config settings from dlm.conf. -.B set_config +.BI set_config " setting" = "value" .br - Set dlm_controld config settings on the fly. + Set dlm_controld config settings in the currently running daemon. .BI fence_ack " nodeid" .br - Quit trying to fence a node. + Cancel a waiting fencing operation and consider it successful. .B log_plock .br Dump dlm_controld plock debug buffer. -.BI plocks " name" +.BI plocks " lockspace_name" .br Dump posix locks from dlm_controld for the lockspace. -.BI join " name" +.BI join " lockspace_name" .br Join a lockspace. -.BI leave " name" +.BI leave " lockspace_name" .br Leave a lockspace. -.BI joinleave " name" +.BI joinleave " lockspace_name" .br - Do two actions: first Join then Leave a lockspace. (mainly for test) + Join then immediately leave a lockspace (for testing only.) -.BI lockdebug " name" +.BI lockdebug " lockspace_name" .br Complete display of locks from the lockspace. -.BI lockdump " name" +.BI lockdump " lockspace_name" .br Minimal display of locks from the lockspace (deprecated). .BI run " command" .br - Run command and check for result. + Run command and check for result (for lvmlockd only.) .BI run_start " command" .br @@ -92,7 +92,7 @@ dlm_tool \- a utility for the dlm and dlm_controld daemon .SH OPTIONS .B \-n -Show all node information in ls. +Show all node information from dlm_tool ls. .B \-d 0|1 Resource directory off/on in join, default 0 @@ -103,6 +103,9 @@ Show all node information in ls. .B \-f 0|1 FS (filesystem) flag off/on in join, default 0 +.BI \-i " sec" +Seconds to wait in run_check. + .BI \-m " mode" Permission mode for lockspace device (octal), default 0600 @@ -110,7 +113,7 @@ Permission mode for lockspace device (octal), default 0600 Summary following lockdebug output (experiemental) .B \-v -Verbose lockdebug output +Verbose lockdebug or status output .B \-w Wide lockdebug output @@ -124,102 +127,20 @@ Print help, then exit .B \-V Print program version information, then exit -.SH USAGE - -.B dlm_tool ls [-n] [ls_name] - -- - -.B dlm_tool status [-v] - -- - -.B dlm_tool dump - -- - -.B dlm_tool dump_config - -- - -.B dlm_tool reload_config - -* see examples in \fBdlm.conf(5)\fP - -- - -.B dlm_tool set_config "dlm_controld-config-item=x" - -* see below \fBset_config EXAMPLES\fP section - -- - -.B dlm_tool fence_ack \fInodeid\fP - -* run "dlm_tool status -v" to get \fInodeid\fP - -- - -.B dlm_tool log_plock - -- - -.B dlm_tool plocks \fIls-name\fP - -- - -.B dlm_tool join [-e 0|1] [-f 0|1] \fIls-name\fP - -- - -.B dlm_tool leave \fIls-name\fP -- - -.B dlm_tool joinleave [-e 0|1] [-f 0|1] \fIls-name\fP - -- - -.B dlm_tool lockdebug [-s] [-v] [-w] \fIls-name\fP - -- - -.B dlm_tool lockdump [-M] \fIls-name\fP - -- - -.B dlm_tool run|run_start [-n] \fIcommand\fP - -* current run & run_start support \fIcommand\fP: -. - - "lvm lvchange --refresh" -. - - "lvm lvs" - -- - -.B dlm_tool run_check|run_cancel [-i "sec"] \fIuuid\fP - -- - -.B dlm_tool run_list - -- - -.B dlm_tool -h - -- +.SH USAGE -.B dlm_tool -V +.SS fence_ack -.SH set_config EXAMPLES +See dlm_tool status for information about waiting fencing operations for +specific nodeid's. -\fIdlm_tool set_config "xxx"\fP can do the dynamic config job. It makes possible to debug, or to do flexible operations on the fly. +.SS set_config -supported option items +dlm_tool set_config can change certain config settings in the currently +running dlm_controld. Supported options: -.RS -.EX +.nf daemon_debug log_debug debug_logfile @@ -232,101 +153,106 @@ post_join_delay enable_quorum_fencing enable_quorum_lockspace repeat_failed_fencing -.EE -.RE +.fi -.SS display style +Special cases to revert a previous set_config and restore the previous +value (from default or dlm.conf): -Currently, there are 5 ways of setting: default, cli, dlm.conf, reload_config, set_config +\fBdlm_tool set_config\fP \fIsetting\fP=\fBrestore\fP +.br +restores a single setting. -The "dlm_tool dump_config" shows the config item by 4 styles. +\fBdlm_tool set_config restore_all\fP +.br +restores all settings. -.TP -key=val -For default values that have not been set by cli or config file or dynamically. +.SS dump_config + +A config setting may have been set from: the default, the dlm_controld +command line, dlm.conf at startup, dlm.conf from reload_config, dlm_tool +set_config. The dump_config output indicates how values were set: .TP -key=val (cli option) -For values that have been last set from a command line option. +setting=value +default value. .TP -key=val (dlm.conf) -For values that have been last set from dlm.conf. (reload_config also belongs to this style) +setting=value (cli option) +Set from a dlm_controld command line option. .TP -key=val (set_config) -For values that have been last set by dlm_tool set_config. +setting=value (dlm.conf) +Set from dlm.conf (at startup or reload.) .TP -i.e. +setting=value (set_config) +Set from dlm_tool set_config. -.EX -# dlm_tool dump_config | head -n 5 + +.SH EXAMPLES + +.SS dump_config + +.nf +$ dlm_tool dump_config | head -n 5 daemon_debug=1 (set_config) foreground=0 log_debug=1 (dlm.conf) timewarn=0 protocol=detect -.EE +.fi -In this case, the "daemon_debug" is set by set_config, the "log_debug" is set by dlm.conf. -meanwhile foreground, timewarn & protocol are using default values. +In this case, daemon_debug is set by set_config, log_debug is set from +dlm.conf, foreground, timewarn and protocol are using default values. -.SS set_config usage +.SS set_config -log_debug is set by dlm.conf (value is 1), then run "set_config" to change to 0. at last use "restore" to restore to dlm.conf setting. - -.RS -.EX -# dlm_tool dump_config | grep log_debug +.nf +$ dlm_tool dump_config | grep log_debug log_debug=1 (dlm.conf) -# dlm_tool set_config "log_debug=0" +$ dlm_tool set_config "log_debug=0" set_config done -# dlm_tool dump_config | grep log_debug +$ dlm_tool dump_config | grep log_debug log_debug=0 (set_config) -# dlm_tool set_config "log_debug=restore" +$ dlm_tool set_config "log_debug=restore" set_config done -# dlm_tool dump_config | grep log_debug +$ dlm_tool dump_config | grep log_debug log_debug=1 (dlm.conf) -.EE -.RE - -restore method +.fi -Once user uses "set_config key=val" to change value, whatever user sets 0 or 1, the related item belongs to "set_config" type. There are 2 ways to do restoration job: key=restore, restore_all +log_debug is set by dlm.conf (value is 1), then run set_config to change +to 0, then use restore to restore to dlm.conf setting. -restore - to reset single option item (see above example) -restore_all - to reset all set_config items. +.SS set_config -.RS -.EX -# dlm_tool dump_config | grep _debug +.nf +$ dlm_tool dump_config | grep _debug daemon_debug=0 log_debug=1 (dlm.conf) plock_debug=0 -# dlm_tool set_config "daemon_debug=1 log_debug=1 plock_debug=1" +$ dlm_tool set_config "daemon_debug=1 log_debug=1 plock_debug=1" set_config done -# dlm_tool dump_config | grep _debug +$ dlm_tool dump_config | grep _debug daemon_debug=1 (set_config) log_debug=1 (set_config) plock_debug=1 (set_config) -# dlm_tool set_config "restore_all" +$ dlm_tool set_config "restore_all" set_config done -# dlm_tool dump_config | grep _debug +$ dlm_tool dump_config | grep _debug daemon_debug=0 log_debug=1 (dlm.conf) plock_debug=0 -.EE -.RE +.fi + .SH SEE ALSO .BR dlm_controld (8), -- 2.33.0 ++++++ bug-1191734_0015-Revert-dlm_controld-add-version-check-for-libquorum.patch ++++++ >From 6579bebc5c8843c4b7dfc3252267708990b097fc Mon Sep 17 00:00:00 2001 From: Heming Zhao <[email protected]> Date: Mon, 18 Oct 2021 16:19:32 +0800 Subject: [PATCH 1/2] Revert "dlm_controld: add version check for libquorum" This reverts commit 3201db3835c85a1d9a407e621bff7902896e8a82. --- dlm_controld/Makefile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dlm_controld/Makefile b/dlm_controld/Makefile index 8cfc97e6909a..667998076acc 100644 --- a/dlm_controld/Makefile +++ b/dlm_controld/Makefile @@ -60,10 +60,6 @@ ifeq ($(USE_SD_NOTIFY),yes) BIN_LDFLAGS += $(shell $(PKG_CONFIG) --libs libsystemd) endif -ifeq (, $(shell $(PKG_CONFIG) --libs "libquorum >= 3.1.0")) - $(error "Requires libquorum at least version 3.1.0") -endif - all: $(LIB_TARGET) $(BIN_TARGET) $(LIB_PC) $(BIN_TARGET): $(BIN_SOURCE) -- 2.33.0 ++++++ bug-1191734_0016-Revert-dlm_controld-use-new-quorum-api-to-detect-mis.patch ++++++ >From fd4aa4e5eec8477b08b279fbf6ed0eb1406c8fa8 Mon Sep 17 00:00:00 2001 From: Heming Zhao <[email protected]> Date: Mon, 18 Oct 2021 16:20:32 +0800 Subject: [PATCH 2/2] Revert "dlm_controld: use new quorum api to detect missed failures" This reverts commit 2e893b981b19430aeca983dd63fb3ac0979d0b35. --- dlm_controld/member.c | 106 ++++++------------------------------------ 1 file changed, 15 insertions(+), 91 deletions(-) diff --git a/dlm_controld/member.c b/dlm_controld/member.c index d567c114b259..1d5bfa3d9166 100644 --- a/dlm_controld/member.c +++ b/dlm_controld/member.c @@ -20,8 +20,6 @@ static int old_node_count; static uint32_t quorum_nodes[MAX_NODES]; static int quorum_node_count; static struct list_head cluster_nodes; -static uint32_t leavejoin_nodes[MAX_NODES]; -static int leavejoin_count; struct node_cluster { struct list_head list; @@ -105,51 +103,15 @@ int is_cluster_member(uint32_t nodeid) return is_member(quorum_nodes, quorum_node_count, nodeid); } -static int is_leavejoin_node(uint32_t nodeid) -{ - return is_member(leavejoin_nodes, leavejoin_count, nodeid); -} - -static void quorum_nodelist_callback(quorum_handle_t cbhandle, struct quorum_ring_id ring_id, - uint32_t member_list_entries, const uint32_t *member_list, - uint32_t joined_list_entries, const uint32_t *joined_list, - uint32_t left_list_entries, const uint32_t *left_list) -{ - uint64_t ring_seq = ring_id.seq; - int i, j; - - for (i = 0; i < left_list_entries; i++) { - log_debug("cluster left_list %u seq %llu", - left_list[i], (unsigned long long)ring_seq); - } - - for (j = 0; j < joined_list_entries; j++) { - log_debug("cluster joined_list %u seq %llu", - joined_list[j], (unsigned long long)ring_seq); - } - - for (i = 0; i < left_list_entries; i++) { - for (j = 0; j < joined_list_entries; j++) { - if (joined_list[j] == left_list[i]) { - log_debug("cluster node %d left and joined", joined_list[j]); - if (!is_leavejoin_node(joined_list[j])) - leavejoin_nodes[leavejoin_count++] = joined_list[j]; - } - } - } -} - -static void quorum_callback(quorum_handle_t cbhandle, uint32_t quorate, - struct quorum_ring_id ring_id, uint32_t node_list_entries, - const uint32_t *node_list) +static void quorum_callback(quorum_handle_t h, uint32_t quorate, + uint64_t ring_seq, uint32_t node_list_entries, + uint32_t *node_list) { corosync_cfg_node_address_t addrs[MAX_NODE_ADDRESSES]; corosync_cfg_node_address_t *addrptr = addrs; const struct node_config *nc; cs_error_t err; int i, j, num_addrs; - uint32_t nodeid; - uint64_t ring_seq = ring_id.seq; uint64_t now = monotime(); if (!cluster_joined_monotime) { @@ -180,55 +142,15 @@ static void quorum_callback(quorum_handle_t cbhandle, uint32_t quorate, if (!is_cluster_member(old_nodes[i])) { log_debug("cluster node %u removed seq %llu", old_nodes[i], (unsigned long long)cluster_ringid_seq); - rem_cluster_node(old_nodes[i], now); del_configfs_node(old_nodes[i]); } } - for (i = 0; i < leavejoin_count; i++) { - nodeid = leavejoin_nodes[i]; - - log_debug("cluster node %u leavejoin seq %llu", - nodeid, (unsigned long long)cluster_ringid_seq); - - /* remove */ - - rem_cluster_node(nodeid, now); - del_configfs_node(nodeid); - - /* add */ - - add_cluster_node(nodeid, now); - - fence_delay_begin = now; - - err = corosync_cfg_get_node_addrs(ch, nodeid, - MAX_NODE_ADDRESSES, - &num_addrs, addrs); - if (err != CS_OK) { - log_error("corosync_cfg_get_node_addrs failed nodeid %u", nodeid); - continue; - } - - nc = node_config_get(nodeid); - - for (j = 0; j < num_addrs; j++) { - add_configfs_node(nodeid, - addrptr[j].address, - addrptr[j].address_length, - (nodeid == our_nodeid), - nc->mark); - } - } - for (i = 0; i < quorum_node_count; i++) { - if (is_leavejoin_node(quorum_nodes[i])) - continue; if (!is_old_member(quorum_nodes[i])) { log_debug("cluster node %u added seq %llu", quorum_nodes[i], (unsigned long long)cluster_ringid_seq); - add_cluster_node(quorum_nodes[i], now); fence_delay_begin = now; @@ -254,11 +176,13 @@ static void quorum_callback(quorum_handle_t cbhandle, uint32_t quorate, } } } - - memset(leavejoin_nodes, 0, sizeof(leavejoin_nodes)); - leavejoin_count = 0; } +static quorum_callbacks_t quorum_callbacks = +{ + .quorum_notify_fn = quorum_callback, +}; + void process_cluster(int ci) { cs_error_t err; @@ -284,23 +208,23 @@ void update_cluster(void) int setup_cluster(void) { - quorum_model_v1_data_t model_data; cs_error_t err; int fd; - uint32_t quorum_type = 0; + uint32_t quorum_type; INIT_LIST_HEAD(&cluster_nodes); - memset(&model_data, 0, sizeof(model_data)); - model_data.quorum_notify_fn = quorum_callback; - model_data.nodelist_notify_fn = quorum_nodelist_callback; - - err = quorum_model_initialize(&qh, QUORUM_MODEL_V1, (quorum_model_data_t *)&model_data, &quorum_type, NULL); + err = quorum_initialize(&qh, &quorum_callbacks, &quorum_type); if (err != CS_OK) { log_error("quorum init error %d", err); return -1; } + if (quorum_type == QUORUM_FREE) { + log_error("no quorum provider configured in corosync, unable to operate"); + goto fail; + } + err = quorum_fd_get(qh, &fd); if (err != CS_OK) { log_error("quorum fd_get error %d", err); -- 2.33.0 ++++++ dlm-4.0.9.tar.gz -> dlm-4.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_controld/Makefile new/dlm-4.1.0/dlm_controld/Makefile --- old/dlm-4.0.9/dlm_controld/Makefile 2019-06-11 18:59:32.000000000 +0200 +++ new/dlm-4.1.0/dlm_controld/Makefile 2021-01-12 21:24:20.000000000 +0100 @@ -32,7 +32,8 @@ config.c \ member.c \ logging.c \ - rbtree.c + rbtree.c \ + node_config.c LIB_SOURCE = lib.c CFLAGS += -D_GNU_SOURCE -O2 -ggdb \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_controld/action.c new/dlm-4.1.0/dlm_controld/action.c --- old/dlm-4.0.9/dlm_controld/action.c 2019-06-11 18:59:32.000000000 +0200 +++ new/dlm-4.1.0/dlm_controld/action.c 2021-01-12 21:24:20.000000000 +0100 @@ -570,15 +570,16 @@ return rv; } -int add_configfs_node(int nodeid, char *addr, int addrlen, int local) +int add_configfs_node(int nodeid, char *addr, int addrlen, int local, + uint32_t mark) { char path[PATH_MAX]; char padded_addr[sizeof(struct sockaddr_storage)]; char buf[32]; int rv, fd; - log_debug("set_configfs_node %d %s local %d", - nodeid, str_ip(addr), local); + log_debug("set_configfs_node %d %s local %d mark %" PRIu32, + nodeid, str_ip(addr), local, mark); /* * create comm dir for this node @@ -640,6 +641,35 @@ close(fd); /* + * set skb mark for nodeid + * + * If open() fails we skip it because kernel doesn't support it. + * It's not a required confiuration. It will show up in the log. + */ + + memset(path, 0, PATH_MAX); + snprintf(path, PATH_MAX, "%s/%d/mark", COMMS_DIR, nodeid); + + fd = open(path, O_WRONLY); + if (fd < 0) { + log_error("%s: open failed: %d", path, errno); + goto skip_non_required; + } + + memset(buf, 0, sizeof(buf)); + snprintf(buf, 32, "%" PRIu32, mark); + + rv = do_write(fd, buf, strlen(buf)); + if (rv < 0) { + log_error("%s: write failed: %d, %s", path, errno, buf); + close(fd); + return -1; + } + close(fd); + +skip_non_required: + + /* * set local */ @@ -851,6 +881,12 @@ dlm_options[timewarn_ind].file_set) set_configfs_cluster("timewarn_cs", NULL, opt(timewarn_ind)); + if (dlm_options[port_ind].cli_set || + dlm_options[port_ind].file_set) + set_configfs_cluster("tcp_port", NULL, optu(port_ind)); + + set_configfs_cluster("mark", NULL, optu(mark_ind)); + proto_name = opts(protocol_ind); proto_num = -1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_controld/config.c new/dlm-4.1.0/dlm_controld/config.c --- old/dlm-4.0.9/dlm_controld/config.c 2019-06-11 18:59:32.000000000 +0200 +++ new/dlm-4.1.0/dlm_controld/config.c 2021-01-12 21:24:20.000000000 +0100 @@ -150,12 +150,29 @@ int rv; rv = sscanf(line, "%[^=]=%s", key, val); - if (rv != 2) + if (rv != 2) { + log_error("Failed to parse config line %s", line); return; + } *val_out = atoi(val); } +static void get_val_uint(char *line, unsigned int *val_out) +{ + char key[MAX_LINE]; + char val[MAX_LINE]; + int rv; + + rv = sscanf(line, "%[^=]=%s", key, val); + if (rv != 2) { + log_error("Failed to parse config line %s", line); + return; + } + + *val_out = strtoul(val, NULL, 0); +} + static void get_val_str(char *line, char *val_out) { char key[MAX_LINE]; @@ -163,19 +180,22 @@ int rv; rv = sscanf(line, "%[^=]=%s", key, val); - if (rv != 2) + if (rv != 2) { + log_error("Failed to parse config line %s", line); return; + } strcpy(val_out, val); } void set_opt_file(int update) { + unsigned int uval = 0; struct dlm_option *o; FILE *file; char line[MAX_LINE]; char str[MAX_LINE]; - int i, val; + int i, val = 0; if (!path_exists(CONF_FILE_PATH)) return; @@ -238,6 +258,17 @@ log_debug("config file %s = %d cli_set %d use %d", o->name, o->file_int, o->cli_set, o->use_int); + } else if (o->req_arg == req_arg_uint) { + get_val_uint(line, &uval); + + o->file_uint = uval; + + if (!o->cli_set) + o->use_uint = o->file_uint; + + log_debug("config file %s = %u cli_set %d use %u", + o->name, o->file_uint, o->cli_set, o->use_uint); + } else if (o->req_arg == req_arg_bool) { get_val_int(line, &val); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_controld/cpg.c new/dlm-4.1.0/dlm_controld/cpg.c --- old/dlm-4.0.9/dlm_controld/cpg.c 2019-06-11 18:59:32.000000000 +0200 +++ new/dlm-4.1.0/dlm_controld/cpg.c 2021-01-12 21:24:20.000000000 +0100 @@ -450,21 +450,24 @@ but that's probably not guaranteed.) */ if (ls->cpg_ringid_wait) { - log_group(ls, "check_ringid wait cluster %u cpg %u:%llu", - cluster_ringid_seq, ls->cpg_ringid.nodeid, + log_group(ls, "check_ringid wait cluster %u cpg %llu:%llu", + (unsigned long long)cluster_ringid_seq, + ls->cpg_ringid.nodeid, (unsigned long long)ls->cpg_ringid.seq); return 0; } - if (cluster_ringid_seq != (uint32_t)ls->cpg_ringid.seq) { - log_group(ls, "check_ringid cluster %u cpg %u:%llu", - cluster_ringid_seq, ls->cpg_ringid.nodeid, + if (cluster_ringid_seq != ls->cpg_ringid.seq) { + log_group(ls, "check_ringid cluster %llu cpg %u:%llu", + (unsigned long long)cluster_ringid_seq, + ls->cpg_ringid.nodeid, (unsigned long long)ls->cpg_ringid.seq); return 0; } - log_limit(ls, "check_ringid done cluster %u cpg %u:%llu", - cluster_ringid_seq, ls->cpg_ringid.nodeid, + log_limit(ls, "check_ringid done cluster %llu cpg %u:%llu", + (unsigned long long)cluster_ringid_seq, + ls->cpg_ringid.nodeid, (unsigned long long)ls->cpg_ringid.seq); return 1; @@ -1864,7 +1867,8 @@ { struct change *cg, *last = NULL; - strncpy(lockspace->name, ls->name, DLM_LOCKSPACE_LEN); + strncpy(lockspace->name, ls->name, DLM_LOCKSPACE_LEN + 1); + lockspace->name[DLM_LOCKSPACE_LEN] = '\0'; lockspace->global_id = ls->global_id; if (ls->joining) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_controld/daemon_cpg.c new/dlm-4.1.0/dlm_controld/daemon_cpg.c --- old/dlm-4.0.9/dlm_controld/daemon_cpg.c 2019-06-11 18:59:32.000000000 +0200 +++ new/dlm-4.1.0/dlm_controld/daemon_cpg.c 2021-01-12 21:24:20.000000000 +0100 @@ -2115,7 +2115,7 @@ int receive_run_request(struct dlm_header *hd, int len) { struct run_request *req = (struct run_request *)hd; - struct run *run; + struct run *run = NULL; run_request_in(req); @@ -2153,7 +2153,7 @@ return 0; } - if (!opt(enable_helper_ind)) { + if (!opt(enable_helper_ind) && run) { log_debug("receive_run_request %s helper not enabled", req->uuid); run->info.reply_count++; run->info.need_replies--; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_controld/dlm.conf.5 new/dlm-4.1.0/dlm_controld/dlm.conf.5 --- old/dlm-4.0.9/dlm_controld/dlm.conf.5 2019-06-11 18:59:32.000000000 +0200 +++ new/dlm-4.1.0/dlm_controld/dlm.conf.5 2021-01-12 21:24:20.000000000 +0100 @@ -40,6 +40,8 @@ .br bind_all .br +mark +.br debug_logfile .br enable_plock @@ -390,6 +392,25 @@ In which case node 1 will master 2/3 of the total resources and node 2 will master the other 1/3. +.SS Node configuration + +Node configurations can be set by the node keyword followed of key-value +pairs. + +.B Keys: + +.B mark +The mark key can be used to set a specific mark value which is then used +by the in-kernel DLM socket creation. This can be used to match for DLM +specfic packets for e.g. routing. + +Example of setting a per socket value for nodeid 1 and a mark value +of 42: + +node id=1 mark=42 + +For local nodes this value doesn't have any effect. + .SH SEE ALSO .BR dlm_controld (8), .BR dlm_tool (8) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_controld/dlm_daemon.h new/dlm-4.1.0/dlm_controld/dlm_daemon.h --- old/dlm-4.0.9/dlm_controld/dlm_daemon.h 2019-06-11 18:59:32.000000000 +0200 +++ new/dlm-4.1.0/dlm_controld/dlm_daemon.h 2021-01-12 21:24:20.000000000 +0100 @@ -40,6 +40,7 @@ #include <sched.h> #include <signal.h> #include <dirent.h> +#include <inttypes.h> #include <sys/sysmacros.h> #include <corosync/cpg.h> @@ -48,6 +49,7 @@ #include "libdlmcontrol.h" #include "dlm_controld.h" #include "fence_config.h" +#include "node_config.h" #include "list.h" #include "rbtree.h" #include "linux_endian.h" @@ -81,11 +83,14 @@ #define DEFAULT_LOGFILE_PRIORITY LOG_INFO #define DEFAULT_LOGFILE LOG_FILE_PATH +#define DEFAULT_NETLINK_RCVBUF (2 * 1024 * 1024) + enum { no_arg = 0, req_arg_bool = 1, req_arg_int = 2, req_arg_str = 3, + req_arg_uint = 4, }; enum { @@ -94,8 +99,10 @@ log_debug_ind, timewarn_ind, protocol_ind, + port_ind, debug_logfile_ind, bind_all_ind, + mark_ind, enable_fscontrol_ind, enable_plock_ind, plock_debug_ind, @@ -125,22 +132,27 @@ int use_int; char *use_str; + unsigned int use_uint; int default_int; const char *default_str; + unsigned int default_uint; int cli_set; int cli_int; char *cli_str; + unsigned int cli_uint; int file_set; int file_int; char *file_str; + unsigned int file_uint; }; EXTERN struct dlm_option dlm_options[dlm_options_max]; #define opt(x) dlm_options[x].use_int #define opts(x) dlm_options[x].use_str +#define optu(x) dlm_options[x].use_uint /* DLM_LOCKSPACE_LEN: maximum lockspace name length, from linux/dlmconstants.h. @@ -179,7 +191,7 @@ EXTERN uint64_t cluster_quorate_monotime; EXTERN uint64_t cluster_joined_monotime; EXTERN uint64_t cluster_joined_walltime; -EXTERN uint32_t cluster_ringid_seq; +EXTERN uint64_t cluster_ringid_seq; EXTERN char cluster_name[DLM_LOCKSPACE_LEN+1]; EXTERN int our_nodeid; EXTERN uint32_t control_minor; @@ -358,7 +370,8 @@ int set_configfs_members(struct lockspace *ls, char *name, int new_count, int *new_members, int renew_count, int *renew_members); -int add_configfs_node(int nodeid, char *addr, int addrlen, int local); +int add_configfs_node(int nodeid, char *addr, int addrlen, int local, + uint32_t mark); void del_configfs_node(int nodeid); void clear_configfs(void); int setup_configfs_options(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_controld/fence_config.c new/dlm-4.1.0/dlm_controld/fence_config.c --- old/dlm-4.0.9/dlm_controld/fence_config.c 2019-06-11 18:59:32.000000000 +0200 +++ new/dlm-4.1.0/dlm_controld/fence_config.c 2021-01-12 21:24:20.000000000 +0100 @@ -180,11 +180,21 @@ memset(dev, 0, sizeof(struct fence_device)); memset(con, 0, sizeof(struct fence_connect)); - strncpy(dev->name, dev_name, FENCE_CONFIG_NAME_MAX-1); - strncpy(dev->agent, agent, FENCE_CONFIG_NAME_MAX-1); - strncpy(dev->args, dev_args, FENCE_CONFIG_ARGS_MAX-1); - strncpy(con->name, con_name, FENCE_CONFIG_NAME_MAX-1); - strncpy(con->args, con_args, FENCE_CONFIG_ARGS_MAX-1); + strncpy(dev->name, dev_name, FENCE_CONFIG_NAME_MAX); + dev->name[FENCE_CONFIG_NAME_MAX - 1] = '\0'; + + strncpy(dev->agent, agent, FENCE_CONFIG_NAME_MAX); + dev->agent[FENCE_CONFIG_NAME_MAX - 1] = '\0'; + + strncpy(dev->args, dev_args, FENCE_CONFIG_ARGS_MAX); + dev->args[FENCE_CONFIG_ARGS_MAX - 1] = '\0'; + + strncpy(con->name, con_name, FENCE_CONFIG_NAME_MAX); + con->name[FENCE_CONFIG_NAME_MAX - 1] = '\0'; + + strncpy(con->args, con_args, FENCE_CONFIG_ARGS_MAX); + con->args[FENCE_CONFIG_ARGS_MAX - 1] = '\0'; + dev->unfence = unfence; *dev_out = dev; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_controld/lib.c new/dlm-4.1.0/dlm_controld/lib.c --- old/dlm-4.0.9/dlm_controld/lib.c 2019-06-11 18:59:32.000000000 +0200 +++ new/dlm-4.1.0/dlm_controld/lib.c 2021-01-12 21:24:20.000000000 +0100 @@ -81,6 +81,17 @@ return fd; } +static inline void init_header_name(struct dlmc_header *h, + const char *name, size_t len) +{ +#pragma GCC diagnostic push +#if __GNUC__ >= 8 +#pragma GCC diagnostic ignored "-Wstringop-truncation" +#endif + strncpy(h->name, name, len); +#pragma GCC diagnostic pop +} + static void init_header(struct dlmc_header *h, int cmd, char *name, int extra_len) { @@ -92,7 +103,7 @@ h->command = cmd; if (name) - strncpy(h->name, name, DLM_LOCKSPACE_LEN); + init_header_name(h, name, DLM_LOCKSPACE_LEN); } static char copy_buf[DLMC_DUMP_SIZE]; @@ -881,7 +892,7 @@ init_header(&h, DLMC_CMD_RUN_CHECK, NULL, 0); h.flags = flags; - strncpy(h.name, run_uuid, DLMC_RUN_UUID_LEN); + init_header_name(&h, run_uuid, DLMC_RUN_UUID_LEN); memset(&rh, 0, sizeof(rh)); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_controld/main.c new/dlm-4.1.0/dlm_controld/main.c --- old/dlm-4.0.9/dlm_controld/main.c 2019-06-11 18:59:32.000000000 +0200 +++ new/dlm-4.1.0/dlm_controld/main.c 2021-01-12 21:24:20.000000000 +0100 @@ -765,7 +765,7 @@ static int setup_uevent(void) { struct sockaddr_nl snl; - int s, rv; + int s, rv, val; s = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); if (s < 0) { @@ -773,6 +773,41 @@ return s; } + /* man 7 netlink: + * + * However, reliable transmissions from kernel to user are impossible in + * any case. The kernel can't send a netlink message if the socket buffer + * is full: the message will be dropped and the kernel and the user-space + * process will no longer have the same view of kernel state. It is up to + * the application to detect when this happens (via the ENOBUFS error + * returned by recvmsg(2)) and resynchronize. + * + * To avoid ENOBUFS errors we set the netlink socket to realiable + * transmission mode which can be turned on by NETLINK_NO_ENOBUFS + * option. This option is available since kernel 2.6.30. If this setting + * fails we fallback to increase the netlink socket receive buffer. + */ + val = 1; + rv = setsockopt(s, SOL_NETLINK, NETLINK_NO_ENOBUFS, &val, sizeof(val)); + if (rv == -1) { + /* Fallback handling if NETLINK_NO_ENOBUFS fails to set. + * + * To prevent ENOBUFS errors we just set the receive buffer to + * two megabyte as other applications do it. This will not + * ensure that we never receive ENOBUFS but it's more unlikely. + */ + val = DEFAULT_NETLINK_RCVBUF; + log_error("uevent netlink NETLINK_NO_ENOBUFS errno %d, will set rcvbuf to %d bytes", errno, val); + + rv = setsockopt(s, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)); + if (rv == -1) + log_error("uevent netlink SO_RCVBUF errno %d", errno); + + rv = setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &val, sizeof(val)); + if (rv == -1) + log_error("uevent netlink SO_RCVBUFFORCE errno %d", errno); + } + memset(&snl, 0, sizeof(snl)); snl.nl_family = AF_NETLINK; snl.nl_pid = getpid(); @@ -788,6 +823,17 @@ return s; } +static inline void init_header_name(struct dlmc_header *h, + const char *name, size_t len) +{ +#pragma GCC diagnostic push +#if __GNUC__ >= 8 +#pragma GCC diagnostic ignored "-Wstringop-truncation" +#endif + strncpy(h->name, name, len); +#pragma GCC diagnostic pop +} + static void init_header(struct dlmc_header *h, int cmd, char *name, int result, int extra_len) { @@ -800,7 +846,7 @@ h->data = result; if (name) - strncpy(h->name, name, DLM_LOCKSPACE_LEN); + init_header_name(h, name, DLM_LOCKSPACE_LEN); } static char copy_buf[LOG_DUMP_SIZE]; @@ -1678,6 +1724,8 @@ printf(" [%d]\n", o->default_int); else if (o->req_arg == req_arg_bool) printf(" [%d]\n", o->default_int); + else if (o->req_arg == req_arg_uint) + printf(" [%u]\n", o->default_uint); else if (o->req_arg == no_arg && !o->default_int) printf(" [0]\n"); else @@ -1688,7 +1736,8 @@ } static void set_opt_default(int ind, const char *name, char letter, int arg_type, - int default_int, const char *default_str, const char *desc) + int default_int, const char *default_str, + unsigned int default_uint, const char *desc) { dlm_options[ind].name = name; dlm_options[ind].letter = letter; @@ -1696,135 +1745,147 @@ dlm_options[ind].desc = desc; dlm_options[ind].default_int = default_int; dlm_options[ind].default_str = default_str; + dlm_options[ind].default_uint = default_uint; dlm_options[ind].use_int = default_int; dlm_options[ind].use_str = (char *)default_str; + dlm_options[ind].use_uint = default_uint; } static void set_opt_defaults(void) { set_opt_default(daemon_debug_ind, "daemon_debug", 'D', no_arg, - 0, NULL, + 0, NULL, 0, "enable debugging to stderr and don't fork"); set_opt_default(foreground_ind, "foreground", '\0', no_arg, - 0, NULL, + 0, NULL, 0, "don't fork"); set_opt_default(log_debug_ind, "log_debug", 'K', no_arg, - 0, NULL, + 0, NULL, 0, "enable kernel dlm debugging messages"); set_opt_default(timewarn_ind, "timewarn", '\0', req_arg_int, - 0, NULL, + 0, NULL, 0, ""); /* do not advertise */ set_opt_default(protocol_ind, "protocol", 'r', req_arg_str, - -1, "detect", + -1, "detect", 0, "dlm kernel lowcomms protocol: tcp, sctp, detect"); + set_opt_default(port_ind, + "port", 'R', req_arg_uint, + -1, NULL, 21064, + "dlm kernel lowcomms protocol port"); + set_opt_default(bind_all_ind, "bind_all", '\0', req_arg_int, - 0, NULL, + 0, NULL, 0, ""); /* do not advertise */ + set_opt_default(mark_ind, + "mark", '\0', req_arg_uint, + 0, NULL, 0, + "set mark value for DLM if not explicit by nodeid specified"); + set_opt_default(debug_logfile_ind, "debug_logfile", 'L', no_arg, - 0, NULL, + 0, NULL, 0, "write debugging to log file"); set_opt_default(enable_fscontrol_ind, "enable_fscontrol", '\0', req_arg_bool, - 0, NULL, + 0, NULL, 0, ""); /* do not advertise */ set_opt_default(enable_plock_ind, "enable_plock", 'p', req_arg_bool, - 1, NULL, + 1, NULL, 0, "enable/disable posix lock support for cluster fs"); set_opt_default(plock_debug_ind, "plock_debug", 'P', no_arg, - 0, NULL, + 0, NULL, 0, "enable plock debugging"); set_opt_default(plock_rate_limit_ind, "plock_rate_limit", 'l', req_arg_int, - 0, NULL, + 0, NULL, 0, "limit rate of plock operations (0 for none)"); set_opt_default(plock_ownership_ind, "plock_ownership", 'o', req_arg_bool, - 0, NULL, + 0, NULL, 0, "enable/disable plock ownership"); set_opt_default(drop_resources_time_ind, "drop_resources_time", 't', req_arg_int, - 10000, NULL, + 10000, NULL, 0, "plock ownership drop resources time (milliseconds)"); set_opt_default(drop_resources_count_ind, "drop_resources_count", 'c', req_arg_int, - 10, NULL, + 10, NULL, 0, "plock ownership drop resources count"); set_opt_default(drop_resources_age_ind, "drop_resources_age", 'a', req_arg_int, - 10000, NULL, + 10000, NULL, 0, "plock ownership drop resources age (milliseconds)"); set_opt_default(post_join_delay_ind, "post_join_delay", 'j', req_arg_int, - 30, NULL, + 30, NULL, 0, "seconds to delay fencing after cluster join"); set_opt_default(enable_fencing_ind, "enable_fencing", 'f', req_arg_bool, - 1, NULL, + 1, NULL, 0, "enable/disable fencing"); set_opt_default(enable_concurrent_fencing_ind, "enable_concurrent_fencing", '\0', req_arg_bool, - 0, NULL, + 0, NULL, 0, "enable/disable concurrent fencing"); set_opt_default(enable_startup_fencing_ind, "enable_startup_fencing", 's', req_arg_bool, - 1, NULL, + 1, NULL, 0, "enable/disable startup fencing"); set_opt_default(repeat_failed_fencing_ind, "repeat_failed_fencing", '\0', req_arg_bool, - 1, NULL, + 1, NULL, 0, "enable/disable retrying after fencing fails"); set_opt_default(enable_quorum_fencing_ind, "enable_quorum_fencing", 'q', req_arg_bool, - 1, NULL, + 1, NULL, 0, "enable/disable quorum requirement for fencing"); set_opt_default(enable_quorum_lockspace_ind, "enable_quorum_lockspace", '\0', req_arg_bool, - 1, NULL, + 1, NULL, 0, "enable/disable quorum requirement for lockspace operations"); set_opt_default(enable_helper_ind, "enable_helper", '\0', req_arg_bool, - 1, NULL, + 1, NULL, 0, "enable/disable helper process for running commands"); set_opt_default(help_ind, "help", 'h', no_arg, - -1, NULL, + -1, NULL, 0, "print this help, then exit"); set_opt_default(version_ind, "version", 'V', no_arg, - -1, NULL, + -1, NULL, 0, "Print program version information, then exit"); } @@ -1972,6 +2033,9 @@ } else if (o->req_arg == req_arg_bool) { o->cli_int = atoi(arg_str) ? 1 : 0; o->use_int = o->cli_int; + } else if (o->req_arg == req_arg_uint) { + o->cli_uint = strtoul(arg_str, NULL, 0); + o->use_uint = o->cli_uint; } } @@ -2039,6 +2103,10 @@ set_opt_cli(argc, argv); set_opt_file(0); + rv = node_config_init(CONF_FILE_PATH); + if (rv) + return 1; + strcpy(fence_all_device.name, "fence_all"); strcpy(fence_all_device.agent, "dlm_stonith"); fence_all_device.unfence = 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_controld/member.c new/dlm-4.1.0/dlm_controld/member.c --- old/dlm-4.0.9/dlm_controld/member.c 2019-06-11 18:59:32.000000000 +0200 +++ new/dlm-4.1.0/dlm_controld/member.c 2021-01-12 21:24:20.000000000 +0100 @@ -20,6 +20,8 @@ static uint32_t quorum_nodes[MAX_NODES]; static int quorum_node_count; static struct list_head cluster_nodes; +static uint32_t leavejoin_nodes[MAX_NODES]; +static int leavejoin_count; struct node_cluster { struct list_head list; @@ -103,14 +105,51 @@ return is_member(quorum_nodes, quorum_node_count, nodeid); } -static void quorum_callback(quorum_handle_t h, uint32_t quorate, - uint64_t ring_seq, uint32_t node_list_entries, - uint32_t *node_list) +static int is_leavejoin_node(uint32_t nodeid) +{ + return is_member(leavejoin_nodes, leavejoin_count, nodeid); +} + +static void quorum_nodelist_callback(quorum_handle_t cbhandle, struct quorum_ring_id ring_id, + uint32_t member_list_entries, const uint32_t *member_list, + uint32_t joined_list_entries, const uint32_t *joined_list, + uint32_t left_list_entries, const uint32_t *left_list) +{ + uint64_t ring_seq = ring_id.seq; + int i, j; + + for (i = 0; i < left_list_entries; i++) { + log_debug("cluster left_list %u seq %llu", + left_list[i], (unsigned long long)ring_seq); + } + + for (j = 0; j < joined_list_entries; j++) { + log_debug("cluster joined_list %u seq %llu", + joined_list[j], (unsigned long long)ring_seq); + } + + for (i = 0; i < left_list_entries; i++) { + for (j = 0; j < joined_list_entries; j++) { + if (joined_list[j] == left_list[i]) { + log_debug("cluster node %d left and joined", joined_list[j]); + if (!is_leavejoin_node(joined_list[j])) + leavejoin_nodes[leavejoin_count++] = joined_list[j]; + } + } + } +} + +static void quorum_callback(quorum_handle_t cbhandle, uint32_t quorate, + struct quorum_ring_id ring_id, uint32_t node_list_entries, + const uint32_t *node_list) { corosync_cfg_node_address_t addrs[MAX_NODE_ADDRESSES]; corosync_cfg_node_address_t *addrptr = addrs; + const struct node_config *nc; cs_error_t err; int i, j, num_addrs; + uint32_t nodeid; + uint64_t ring_seq = ring_id.seq; uint64_t now = monotime(); if (!cluster_joined_monotime) { @@ -122,10 +161,10 @@ cluster_quorate_monotime = now; cluster_quorate = quorate; - cluster_ringid_seq = (uint32_t)ring_seq; + cluster_ringid_seq = ring_seq; - log_debug("cluster quorum %u seq %u nodes %u", - cluster_quorate, cluster_ringid_seq, node_list_entries); + log_debug("cluster quorum %u seq %llu nodes %u", + cluster_quorate, (unsigned long long)cluster_ringid_seq, node_list_entries); old_node_count = quorum_node_count; memcpy(&old_nodes, &quorum_nodes, sizeof(old_nodes)); @@ -139,17 +178,57 @@ for (i = 0; i < old_node_count; i++) { if (!is_cluster_member(old_nodes[i])) { - log_debug("cluster node %u removed seq %u", - old_nodes[i], cluster_ringid_seq); + log_debug("cluster node %u removed seq %llu", + old_nodes[i], (unsigned long long)cluster_ringid_seq); + rem_cluster_node(old_nodes[i], now); del_configfs_node(old_nodes[i]); } } + for (i = 0; i < leavejoin_count; i++) { + nodeid = leavejoin_nodes[i]; + + log_debug("cluster node %u leavejoin seq %llu", + nodeid, (unsigned long long)cluster_ringid_seq); + + /* remove */ + + rem_cluster_node(nodeid, now); + del_configfs_node(nodeid); + + /* add */ + + add_cluster_node(nodeid, now); + + fence_delay_begin = now; + + err = corosync_cfg_get_node_addrs(ch, nodeid, + MAX_NODE_ADDRESSES, + &num_addrs, addrs); + if (err != CS_OK) { + log_error("corosync_cfg_get_node_addrs failed nodeid %u", nodeid); + continue; + } + + nc = node_config_get(nodeid); + + for (j = 0; j < num_addrs; j++) { + add_configfs_node(nodeid, + addrptr[j].address, + addrptr[j].address_length, + (nodeid == our_nodeid), + nc->mark); + } + } + for (i = 0; i < quorum_node_count; i++) { + if (is_leavejoin_node(quorum_nodes[i])) + continue; if (!is_old_member(quorum_nodes[i])) { - log_debug("cluster node %u added seq %u", - quorum_nodes[i], cluster_ringid_seq); + log_debug("cluster node %u added seq %llu", + quorum_nodes[i], (unsigned long long)cluster_ringid_seq); + add_cluster_node(quorum_nodes[i], now); fence_delay_begin = now; @@ -163,21 +242,22 @@ continue; } + nc = node_config_get(quorum_nodes[i]); + for (j = 0; j < num_addrs; j++) { add_configfs_node(quorum_nodes[i], addrptr[j].address, addrptr[j].address_length, (quorum_nodes[i] == - our_nodeid)); + our_nodeid), + nc->mark); } } } -} -static quorum_callbacks_t quorum_callbacks = -{ - .quorum_notify_fn = quorum_callback, -}; + memset(leavejoin_nodes, 0, sizeof(leavejoin_nodes)); + leavejoin_count = 0; +} void process_cluster(int ci) { @@ -204,23 +284,23 @@ int setup_cluster(void) { + quorum_model_v1_data_t model_data; cs_error_t err; int fd; - uint32_t quorum_type; + uint32_t quorum_type = 0; INIT_LIST_HEAD(&cluster_nodes); - err = quorum_initialize(&qh, &quorum_callbacks, &quorum_type); + memset(&model_data, 0, sizeof(model_data)); + model_data.quorum_notify_fn = quorum_callback; + model_data.nodelist_notify_fn = quorum_nodelist_callback; + + err = quorum_model_initialize(&qh, QUORUM_MODEL_V1, (quorum_model_data_t *)&model_data, &quorum_type, NULL); if (err != CS_OK) { log_error("quorum init error %d", err); return -1; } - if (quorum_type == QUORUM_FREE) { - log_error("no quorum provider configured in corosync, unable to operate"); - goto fail; - } - err = quorum_fd_get(qh, &fd); if (err != CS_OK) { log_error("quorum fd_get error %d", err); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_controld/node_config.c new/dlm-4.1.0/dlm_controld/node_config.c --- old/dlm-4.0.9/dlm_controld/node_config.c 1970-01-01 01:00:00.000000000 +0100 +++ new/dlm-4.1.0/dlm_controld/node_config.c 2021-01-12 21:24:20.000000000 +0100 @@ -0,0 +1,82 @@ +/* + * Copyright 2020 Red Hat, Inc. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v2 or (at your option) any later version. + */ + +#include "dlm_daemon.h" + +#define MAX_LINE 4096 + +static struct node_config nc[MAX_NODES]; + +static const struct node_config nc_default = { + .mark = 0, +}; + +int node_config_init(const char *path) +{ + char line[MAX_LINE], tmp[MAX_LINE]; + unsigned long mark; + FILE *file; + int nodeid; + int rv; + + /* if no config file is given we assume default node configuration */ + file = fopen(path, "r"); + if (!file) { + log_debug("No config file %s, we assume default node configuration: mark %" PRIu32, + path, nc_default.mark); + return 0; + } + + while (fgets(line, MAX_LINE, file)) { + if (line[0] == '#') + continue; + if (line[0] == '\n') + continue; + + if (!strncmp(line, "node", strlen("node"))) { + rv = sscanf(line, "node id=%d mark=%s", &nodeid, tmp); + if (rv < 2) { + log_error("Invalid configuration line: %s", line); + rv = -EINVAL; + goto out; + } + + /* skip invalid nodeid's */ + if (nodeid <= 0 || nodeid > MAX_NODES - 1) + continue; + + mark = strtoul(tmp, NULL, 0); + if (mark == ULONG_MAX) { + log_error("Failed to pars mark value %s will use %" PRIu32, + tmp, nc_default.mark); + mark = nc_default.mark; + } + nc[nodeid].mark = mark; + + log_debug("parsed node config id=%d mark=%" PRIu32, + nodeid, mark); + } + } + + fclose(file); + return 0; + +out: + fclose(file); + return rv; +} + +const struct node_config *node_config_get(int nodeid) +{ + if (nodeid <= 0 || nodeid > MAX_NODES - 1) { + log_debug("node config requested for id=%d returning defaults", nodeid); + return &nc_default; + } + + return &nc[nodeid]; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_controld/node_config.h new/dlm-4.1.0/dlm_controld/node_config.h --- old/dlm-4.0.9/dlm_controld/node_config.h 1970-01-01 01:00:00.000000000 +0100 +++ new/dlm-4.1.0/dlm_controld/node_config.h 2021-01-12 21:24:20.000000000 +0100 @@ -0,0 +1,31 @@ +/* + * Copyright 2020 Red Hat, Inc. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU General Public License v2 or (at your option) any later version. + */ + +#ifndef _NODE_CONFIG_H_ +#define _NODE_CONFIG_H_ + +#include <stdint.h> + +struct node_config { + uint32_t mark; +}; + +/* + * Returns -ENOENT if path does not exist or there is no + * config for nodeid in the file. + * + * Returns -EXYZ if there's a problem with the config. + * + * Returns 0 if a config was found with no problems. + */ + +int node_config_init(const char *path); + +const struct node_config *node_config_get(int nodeid); + +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/dlm_tool/main.c new/dlm-4.1.0/dlm_tool/main.c --- old/dlm-4.0.9/dlm_tool/main.c 2019-06-11 18:59:32.000000000 +0200 +++ new/dlm-4.1.0/dlm_tool/main.c 2021-01-12 21:24:20.000000000 +0100 @@ -224,6 +224,7 @@ int need_lsname; int need_command = 0; int need_uuid = 0; + int optional_lsname = 0; int i; char modebuf[8]; @@ -332,6 +333,7 @@ operation = OP_LIST; opt_ind = optind + 1; need_lsname = 0; + optional_lsname = 1; break; } else if (!strncmp(argv[optind], "status", 6) && (strlen(argv[optind]) == 6)) { @@ -428,8 +430,17 @@ exit(EXIT_FAILURE); } - if (!need_lsname && !need_uuid && !need_command) + /* + * The operation does not require an arg, but may + * accept an optional arg, i.e. dlm_tool ls [name] + */ + if (!need_lsname && !need_uuid && !need_command) { + if (optind < argc - 1) { + if (optional_lsname) + lsname = argv[opt_ind]; + } return; + } if (optind < argc - 1) { if (need_lsname) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dlm-4.0.9/include/version.cf new/dlm-4.1.0/include/version.cf --- old/dlm-4.0.9/include/version.cf 2019-06-11 18:59:32.000000000 +0200 +++ new/dlm-4.1.0/include/version.cf 2021-01-12 21:24:20.000000000 +0100 @@ -1,6 +1,6 @@ #ifndef _RELEASE_VERSION_CF_ #define _RELEASE_VERSION_CF_ -#define RELEASE_VERSION "4.0.9" +#define RELEASE_VERSION "4.1.0" #endif
