Compare commits

...

2 Commits

Author SHA1 Message Date
ea6214f636 import UBI lvm2-2.03.14-15.el8_10.2 2025-07-15 08:51:37 +00:00
48dfb805f0 import UBI lvm2-2.03.14-15.el8_10 2025-03-11 09:31:57 +00:00
12 changed files with 1159 additions and 3 deletions

View File

@ -0,0 +1,31 @@
From 068897bbd15e16b666079952f465239d933d2228 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Thu, 31 Aug 2023 18:45:30 +0200
Subject: [PATCH 131/139] dmeventd: move var set to locked section
It should not change the actual code flow, however make the
set of the current_event variable inside locked section.
(cherry picked from commit 29630b2d7fcb28827f0c928edd6cd638f6ea2591)
---
daemons/dmeventd/dmeventd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
index d89ab4af8..fa60b6f31 100644
--- a/daemons/dmeventd/dmeventd.c
+++ b/daemons/dmeventd/dmeventd.c
@@ -1043,9 +1043,9 @@ static void *_monitor_thread(void *arg)
_unlock_mutex();
_do_process_event(thread);
- thread->current_events = 0; /* Current events processed */
_lock_mutex();
+ thread->current_events = 0; /* Current events processed */
thread->processing = 0;
/*
--
2.48.1

View File

@ -0,0 +1,50 @@
From d7f61ce3933f75f3ebcd74c2a815cdcea28ea8d5 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Mon, 25 Sep 2023 11:51:25 +0200
Subject: [PATCH 132/139] dmeventd: use return
Use 'return' instead of calling exit() when possible.
(cherry picked from commit c31dcf3632988ef4e8d1c62a685f4c436b5f115e)
---
daemons/dmeventd/dmeventd.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
index fa60b6f31..9d7118ced 100644
--- a/daemons/dmeventd/dmeventd.c
+++ b/daemons/dmeventd/dmeventd.c
@@ -2169,17 +2169,17 @@ int main(int argc, char *argv[])
.server_path = DM_EVENT_FIFO_SERVER
};
time_t now, idle_exit_timeout = DMEVENTD_IDLE_EXIT_TIMEOUT;
- opterr = 0;
- optind = 0;
+ optopt = optind = opterr = 0;
+ optarg = (char*) "";
while ((opt = getopt(argc, argv, "?fhVdlR")) != EOF) {
switch (opt) {
case 'h':
_usage(argv[0], stdout);
- exit(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
case '?':
_usage(argv[0], stderr);
- exit(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
case 'R':
_restart++;
break;
@@ -2194,7 +2194,7 @@ int main(int argc, char *argv[])
break;
case 'V':
printf("dmeventd version: %s\n", DM_LIB_VERSION);
- exit(EXIT_SUCCESS);
+ return EXIT_SUCCESS;
}
}
--
2.48.1

View File

@ -0,0 +1,117 @@
From bc94a75dc4705023d7e074363867129563b0d469 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Mon, 25 Sep 2023 11:42:53 +0200
Subject: [PATCH 133/139] dmeventd: unregister all devices on restart
Instead of just exiting in the middle of monitoring,
unregisted all monitored devices first and then exit.
To speedup this path, all send internal SIGINT when thread
unregiters itself, to wakup-up main sleeping loop.
(cherry picked from commit 637d812df56440d792ab403f63e50583d78cdfef)
---
daemons/dmeventd/dmeventd.c | 55 ++++++++++++++++++++++++++++---------
1 file changed, 42 insertions(+), 13 deletions(-)
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
index 9d7118ced..e05545403 100644
--- a/daemons/dmeventd/dmeventd.c
+++ b/daemons/dmeventd/dmeventd.c
@@ -997,6 +997,8 @@ static void _monitor_unregister(void *arg)
_lock_mutex();
thread->status = DM_THREAD_DONE; /* Last access to thread memory! */
_unlock_mutex();
+ if (_exit_now) /* Exit is already in-progress, wake-up sleeping select() */
+ kill(getpid(), SIGINT);
}
/* Device monitoring thread. */
@@ -1161,6 +1163,36 @@ static int _unregister_for_event(struct message_data *message_data)
return ret;
}
+static void _unregister_all_threads(void)
+{
+ struct thread_status *thread, *tmp;
+
+ _lock_mutex();
+
+ dm_list_iterate_items_safe(thread, tmp, &_thread_registry)
+ _update_events(thread, 0);
+
+ _unlock_mutex();
+}
+
+static void _wait_for_new_pid(void)
+{
+ unsigned long st_ino = 0;
+ struct stat st;
+ int i;
+
+ for (i = 0; i < 400000; ++i) {
+ if (lstat(DMEVENTD_PIDFILE, &st) == 0) {
+ if (!st_ino)
+ st_ino = st.st_ino;
+ else if (st_ino != st.st_ino)
+ break; /* different pidfile */
+ } else if (errno == ENOENT)
+ break; /* pidfile is removed */
+ usleep(100);
+ }
+}
+
/*
* Register for an event.
*
@@ -1677,9 +1709,9 @@ static void _process_request(struct dm_event_fifos *fifos)
free(msg.data);
if (cmd == DM_EVENT_CMD_DIE) {
- if (unlink(DMEVENTD_PIDFILE))
- log_sys_error("unlink", DMEVENTD_PIDFILE);
- _exit(0);
+ _unregister_all_threads();
+ _exit_now = DM_SCHEDULED_EXIT;
+ log_info("dmeventd exiting for restart.");
}
}
@@ -1769,7 +1801,8 @@ static void _init_thread_signals(void)
*/
static void _exit_handler(int sig __attribute__((unused)))
{
- _exit_now = DM_SIGNALED_EXIT;
+ if (!_exit_now)
+ _exit_now = DM_SIGNALED_EXIT;
}
#ifdef __linux__
@@ -2116,19 +2149,15 @@ static void _restart_dmeventd(void)
((e = getenv(SD_ACTIVATION_ENV_VAR_NAME)) && strcmp(e, "1")))
_systemd_activation = 1;
- for (i = 0; i < 10; ++i) {
- if ((access(DMEVENTD_PIDFILE, F_OK) == -1) && (errno == ENOENT))
- break;
- usleep(10);
- }
+ fini_fifos(&fifos);
- if (!_systemd_activation) {
- fini_fifos(&fifos);
+ /* Give a few seconds dmeventd to finish */
+ _wait_for_new_pid();
+
+ if (!_systemd_activation)
return;
- }
/* Reopen fifos. */
- fini_fifos(&fifos);
if (!init_fifos(&fifos)) {
fprintf(stderr, "Could not initiate communication with new instance of dmeventd.\n");
exit(EXIT_FAILURE);
--
2.48.1

View File

@ -0,0 +1,149 @@
From 7dfa1f3d0d03cc682bb3bb503d2ad44ff4e836a6 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Mon, 25 Sep 2023 11:49:14 +0200
Subject: [PATCH 134/139] dmeventd: info status report
To quickly get info about some internal dmeventd status,
implment 'dmeventd -i' support.
Reported messages are some 'raw' internal informations mainly
useful to developers.
(cherry picked from commit 80d34abf4974e45471f947fb2b85146a30feb87d)
---
daemons/dmeventd/dmeventd.c | 69 +++++++++++++++++++++++++++++++++++--
man/dmeventd.8_main | 7 ++++
2 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
index e05545403..46c34ada2 100644
--- a/daemons/dmeventd/dmeventd.c
+++ b/daemons/dmeventd/dmeventd.c
@@ -2063,6 +2063,68 @@ static int _reinstate_registrations(struct dm_event_fifos *fifos)
return 1;
}
+static int _info_dmeventd(const char *name, struct dm_event_fifos *fifos)
+{
+ struct dm_event_daemon_message msg = { 0 };
+ int i, count = 0;
+ char *line;
+ int version;
+ int ret = 0;
+
+ /* Get the list of registrations from the running daemon. */
+ if (!init_fifos(fifos)) {
+ fprintf(stderr, "Could not initiate communication with existing dmeventd.\n");
+ return 0;
+ }
+
+ if (!dm_event_get_version(fifos, &version)) {
+ fprintf(stderr, "Could not communicate with existing dmeventd.\n");
+ goto out;
+ }
+
+ if (version < 1) {
+ fprintf(stderr, "The running dmeventd instance is too old.\n"
+ "Protocol version %d (required: 1). Action cancelled.\n", version);
+ goto out;
+ }
+
+ if (daemon_talk(fifos, &msg, DM_EVENT_CMD_GET_STATUS, "-", "-", 0, 0)) {
+ fprintf(stderr, "Failed to acquire status from existing dmeventd.\n");
+ goto out;
+ }
+
+ line = strchr(msg.data, ' ') + 1;
+ for (i = 0; msg.data[i]; ++i)
+ if (msg.data[i] == ';') {
+ msg.data[i] = 0;
+ if (!count)
+ printf("%s is monitoring:\n", name);
+ printf("%s\n", line);
+ line = msg.data + i + 1;
+ ++count;
+ }
+
+ free(msg.data);
+
+ if (!count)
+ printf("%s does not monitor any device.\n", name);
+
+ if (version >= 2) {
+ if (daemon_talk(fifos, &msg, DM_EVENT_CMD_GET_PARAMETERS, "-", "-", 0, 0)) {
+ fprintf(stderr, "Failed to acquire parameters from existing dmeventd.\n");
+ goto out;
+ }
+ printf("%s internal status: %s\n", name, msg.data);
+ free(msg.data);
+ }
+
+ ret = 1;
+out:
+ fini_fifos(fifos);
+
+ return ret;
+}
+
static void _restart_dmeventd(void)
{
struct dm_event_fifos fifos = {
@@ -2178,10 +2240,11 @@ bad:
static void _usage(char *prog, FILE *file)
{
fprintf(file, "Usage:\n"
- "%s [-d [-d [-d]]] [-f] [-h] [-l] [-R] [-V] [-?]\n\n"
+ "%s [-d [-d [-d]]] [-f] [-h] [i] [-l] [-R] [-V] [-?]\n\n"
" -d Log debug messages to syslog (-d, -dd, -ddd)\n"
" -f Don't fork, run in the foreground\n"
" -h Show this help information\n"
+ " -i Query running instance of dmeventd for info\n"
" -l Log to stdout,stderr instead of syslog\n"
" -? Show this help information on stderr\n"
" -R Restart dmeventd\n"
@@ -2201,7 +2264,7 @@ int main(int argc, char *argv[])
optopt = optind = opterr = 0;
optarg = (char*) "";
- while ((opt = getopt(argc, argv, "?fhVdlR")) != EOF) {
+ while ((opt = getopt(argc, argv, "?fhiVdlR")) != EOF) {
switch (opt) {
case 'h':
_usage(argv[0], stdout);
@@ -2209,6 +2272,8 @@ int main(int argc, char *argv[])
case '?':
_usage(argv[0], stderr);
return EXIT_SUCCESS;
+ case 'i':
+ return _info_dmeventd(argv[0], &fifos) ? EXIT_SUCCESS : EXIT_FAILURE;
case 'R':
_restart++;
break;
diff --git a/man/dmeventd.8_main b/man/dmeventd.8_main
index 77b07e4d8..75926bae5 100644
--- a/man/dmeventd.8_main
+++ b/man/dmeventd.8_main
@@ -12,6 +12,7 @@ dmeventd \(em Device-mapper event daemon
.RB [ -d ]]]
.RB [ -f ]
.RB [ -h ]
+.RB [ -i ]
.RB [ -l ]
.RB [ -R ]
.RB [ -V ]
@@ -44,6 +45,12 @@ Don't fork, run in the foreground.
Show help information.
.
.TP
+.B -i
+Query the running daemon instance for the status informations. The format is
+internal and unstable and it is targeted for developers.
+Format may change between versions.
+.
+.TP
.B -l
Log through stdout and stderr instead of syslog.
This option works only with option -f, otherwise it is ignored.
--
2.48.1

View File

@ -0,0 +1,68 @@
From ebe966020d2378bcc1a7f61551d4278bde6b8f6c Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Mon, 25 Sep 2023 15:48:06 +0200
Subject: [PATCH 135/139] configure.ac: add --with-dmeventd-exit-on-path
(cherry picked from commit 744cdc3ba885f9dc8e1444cb77a190d5ea0007ed)
---
configure.ac | 32 +++++++++++++++++++-------------
1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/configure.ac b/configure.ac
index 6cdf1a7e6..01e0b4d51 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1715,24 +1715,29 @@ AC_DEFINE_UNQUOTED(LVMIMPORTVDO_PATH, ["$LVMIMPORTVDO_PATH"], [Path to lvm_impor
################################################################################
dnl -- dmeventd pidfile and executable path
+AC_ARG_WITH(dmeventd-pidfile,
+ AS_HELP_STRING([--with-dmeventd-pidfile=PATH],
+ [dmeventd pidfile [PID_DIR/dmeventd.pid]]),
+ DMEVENTD_PIDFILE=$withval,
+ DMEVENTD_PIDFILE="$DEFAULT_PID_DIR/dmeventd.pid")
+AC_ARG_WITH(dmeventd-path,
+ AS_HELP_STRING([--with-dmeventd-path=PATH],
+ [dmeventd path [EPREFIX/sbin/dmeventd]]),
+ DMEVENTD_PATH=$withval,
+ DMEVENTD_PATH="$SBINDIR/dmeventd")
+AC_ARG_WITH(dmeventd-exit-on-path,
+ AS_HELP_STRING([--with-dmeventd-exit-on-path=PATH],
+ [Default path to exit-on file in dmeventd [/run/nologin]]),
+ DEFAULT_DMEVENTD_EXIT_ON_PATH=$withval,
+ DEFAULT_DMEVENTD_EXIT_ON_PATH="/run/nologin")
+
if test "$BUILD_DMEVENTD" = yes; then
- AC_ARG_WITH(dmeventd-pidfile,
- AS_HELP_STRING([--with-dmeventd-pidfile=PATH],
- [dmeventd pidfile [PID_DIR/dmeventd.pid]]),
- DMEVENTD_PIDFILE=$withval,
- DMEVENTD_PIDFILE="$DEFAULT_PID_DIR/dmeventd.pid")
AC_DEFINE_UNQUOTED(DMEVENTD_PIDFILE, ["$DMEVENTD_PIDFILE"],
[Path to dmeventd pidfile.])
-fi
-
-if test "$BUILD_DMEVENTD" = yes; then
- AC_ARG_WITH(dmeventd-path,
- AS_HELP_STRING([--with-dmeventd-path=PATH],
- [dmeventd path [EPREFIX/sbin/dmeventd]]),
- DMEVENTD_PATH=$withval,
- DMEVENTD_PATH="$SBINDIR/dmeventd")
AC_DEFINE_UNQUOTED(DMEVENTD_PATH, ["$DMEVENTD_PATH"],
[Path to dmeventd binary.])
+ AC_DEFINE_UNQUOTED(DEFAULT_DMEVENTD_EXIT_ON_PATH, ["$DEFAULT_DMEVENTD_EXIT_ON_PATH"],
+ [Path to exit-on dmeventd file.])
fi
################################################################################
@@ -1861,6 +1866,7 @@ AC_SUBST(DEFAULT_ARCHIVE_SUBDIR)
AC_SUBST(DEFAULT_BACKUP_SUBDIR)
AC_SUBST(DEFAULT_CACHE_SUBDIR)
AC_SUBST(DEFAULT_DM_RUN_DIR)
+AC_SUBST(DEFAULT_DMEVENTD_EXIT_ON_PATH)
AC_SUBST(DEFAULT_LOCK_DIR)
AC_SUBST(DEFAULT_MIRROR_SEGTYPE)
AC_SUBST(DEFAULT_PID_DIR)
--
2.48.1

View File

@ -0,0 +1,111 @@
From c499428897b8ea51eefd7a90f4141e532ec9fbb9 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Mon, 25 Sep 2023 15:49:52 +0200
Subject: [PATCH 136/139] configure: autoreconf
(cherry picked from commit 3da18a06d8e0671374f9bf8b841017cfd5d1e5ea)
---
configure | 33 +++++++++++++++++++++++----------
include/configure.h.in | 3 +++
2 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/configure b/configure
index cfad36e51..17083e7ff 100755
--- a/configure
+++ b/configure
@@ -730,6 +730,7 @@ DEFAULT_PROFILE_SUBDIR
DEFAULT_PID_DIR
DEFAULT_MIRROR_SEGTYPE
DEFAULT_LOCK_DIR
+DEFAULT_DMEVENTD_EXIT_ON_PATH
DEFAULT_DM_RUN_DIR
DEFAULT_CACHE_SUBDIR
DEFAULT_BACKUP_SUBDIR
@@ -989,6 +990,7 @@ with_systemdsystemunitdir
with_tmpfilesdir
with_dmeventd_pidfile
with_dmeventd_path
+with_dmeventd_exit_on_path
with_default_system_dir
with_default_profile_subdir
with_default_archive_subdir
@@ -1793,6 +1795,9 @@ Optional Packages:
dmeventd pidfile [PID_DIR/dmeventd.pid]
--with-dmeventd-path=PATH
dmeventd path [EPREFIX/sbin/dmeventd]
+ --with-dmeventd-exit-on-path=PATH
+ Default path to exit-on file in dmeventd
+ [/run/nologin]
--with-default-system-dir=DIR
default LVM system directory [/etc/lvm]
--with-default-profile-subdir=SUBDIR
@@ -14081,8 +14086,6 @@ _ACEOF
################################################################################
-if test "$BUILD_DMEVENTD" = yes; then
-
# Check whether --with-dmeventd-pidfile was given.
if test "${with_dmeventd_pidfile+set}" = set; then :
withval=$with_dmeventd_pidfile; DMEVENTD_PIDFILE=$withval
@@ -14091,14 +14094,6 @@ else
fi
-cat >>confdefs.h <<_ACEOF
-#define DMEVENTD_PIDFILE "$DMEVENTD_PIDFILE"
-_ACEOF
-
-fi
-
-if test "$BUILD_DMEVENTD" = yes; then
-
# Check whether --with-dmeventd-path was given.
if test "${with_dmeventd_path+set}" = set; then :
withval=$with_dmeventd_path; DMEVENTD_PATH=$withval
@@ -14107,10 +14102,28 @@ else
fi
+# Check whether --with-dmeventd-exit-on-path was given.
+if test "${with_dmeventd_exit_on_path+set}" = set; then :
+ withval=$with_dmeventd_exit_on_path; DEFAULT_DMEVENTD_EXIT_ON_PATH=$withval
+else
+ DEFAULT_DMEVENTD_EXIT_ON_PATH="/run/nologin"
+fi
+
+
+if test "$BUILD_DMEVENTD" = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define DMEVENTD_PIDFILE "$DMEVENTD_PIDFILE"
+_ACEOF
+
cat >>confdefs.h <<_ACEOF
#define DMEVENTD_PATH "$DMEVENTD_PATH"
_ACEOF
+cat >>confdefs.h <<_ACEOF
+#define DEFAULT_DMEVENTD_EXIT_ON_PATH "$DEFAULT_DMEVENTD_EXIT_ON_PATH"
+_ACEOF
+
fi
################################################################################
diff --git a/include/configure.h.in b/include/configure.h.in
index e0d971bbf..b8b728b73 100644
--- a/include/configure.h.in
+++ b/include/configure.h.in
@@ -48,6 +48,9 @@
/* Name of default metadata cache subdirectory. */
#undef DEFAULT_CACHE_SUBDIR
+/* Path to exit-on dmeventd file. */
+#undef DEFAULT_DMEVENTD_EXIT_ON_PATH
+
/* Define default node creation behavior with dmsetup create */
#undef DEFAULT_DM_ADD_NODE
--
2.48.1

View File

@ -0,0 +1,196 @@
From b7dd2a9e5973544f248aeeb7bc0b5e7afbd27d9b Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Mon, 25 Sep 2023 13:07:00 +0200
Subject: [PATCH 137/139] dmeventd: implement exit_on file check
When exit on file is present in a system and term/break signal is
catched, them dmeventd is no longger refusing to exit.
For the correct shutdown, there should be ideally unmonitoring call,
however in some case it's very hard to implement this correct procedure.
With this 'exit on' file dmeventd at least avoid 'blocking' shutdown,
before systemd kills use with -9 anyway possibly even in some unwanted
stated of internal dmeventd processing (i.e. in the middle of some lvm
command processing).
(cherry picked from commit a9d7a9d1289d7cafa1db5fd1e41417bf4f7709d1)
---
daemons/dmeventd/dmeventd.c | 57 ++++++++++++++++++++++++++++---------
make.tmpl.in | 1 +
man/Makefile.in | 1 +
man/dmeventd.8_main | 12 ++++++++
4 files changed, 58 insertions(+), 13 deletions(-)
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
index 46c34ada2..828bc0c7a 100644
--- a/daemons/dmeventd/dmeventd.c
+++ b/daemons/dmeventd/dmeventd.c
@@ -98,6 +98,7 @@ static int _systemd_activation = 0;
static int _foreground = 0;
static int _restart = 0;
static time_t _idle_since = 0;
+static const char *_exit_on = DEFAULT_DMEVENTD_EXIT_ON_PATH;
static char **_initial_registrations = 0;
/* FIXME Make configurable at runtime */
@@ -723,12 +724,18 @@ static int _get_status(struct message_data *message_data)
static int _get_parameters(struct message_data *message_data) {
struct dm_event_daemon_message *msg = message_data->msg;
int size;
+ char idle_buf[32] = "";
+
+ if (_idle_since)
+ (void)dm_snprintf(idle_buf, sizeof(idle_buf), " idle=%lu", (long unsigned) (time(NULL) - _idle_since));
free(msg->data);
- if ((size = dm_asprintf(&msg->data, "%s pid=%d daemon=%s exec_method=%s",
+ if ((size = dm_asprintf(&msg->data, "%s pid=%d daemon=%s exec_method=%s exit_on=\"%s\"%s",
message_data->id, getpid(),
_foreground ? "no" : "yes",
- _systemd_activation ? "systemd" : "direct")) < 0) {
+ _systemd_activation ? "systemd" : "direct",
+ _exit_on,
+ idle_buf)) < 0) {
stack;
return -ENOMEM;
}
@@ -2240,8 +2247,9 @@ bad:
static void _usage(char *prog, FILE *file)
{
fprintf(file, "Usage:\n"
- "%s [-d [-d [-d]]] [-f] [-h] [i] [-l] [-R] [-V] [-?]\n\n"
+ "%s [-d [-d [-d]]] [-e path] [-f] [-h] [i] [-l] [-R] [-V] [-?]\n\n"
" -d Log debug messages to syslog (-d, -dd, -ddd)\n"
+ " -e Select a file path checked on exit\n"
" -f Don't fork, run in the foreground\n"
" -h Show this help information\n"
" -i Query running instance of dmeventd for info\n"
@@ -2264,7 +2272,7 @@ int main(int argc, char *argv[])
optopt = optind = opterr = 0;
optarg = (char*) "";
- while ((opt = getopt(argc, argv, "?fhiVdlR")) != EOF) {
+ while ((opt = getopt(argc, argv, ":?e:fhiVdlR")) != EOF) {
switch (opt) {
case 'h':
_usage(argv[0], stdout);
@@ -2277,6 +2285,13 @@ int main(int argc, char *argv[])
case 'R':
_restart++;
break;
+ case 'e':
+ if (strchr(optarg, '"')) {
+ fprintf(stderr, "dmeventd: option -e does not accept path \"%s\" with '\"' character.\n", optarg);
+ return EXIT_FAILURE;
+ }
+ _exit_on=optarg;
+ break;
case 'f':
_foreground++;
break;
@@ -2289,6 +2304,9 @@ int main(int argc, char *argv[])
case 'V':
printf("dmeventd version: %s\n", DM_LIB_VERSION);
return EXIT_SUCCESS;
+ case ':':
+ fprintf(stderr, "dmeventd: option -%c requires an argument.\n", optopt);
+ return EXIT_FAILURE;
}
}
@@ -2379,15 +2397,28 @@ int main(int argc, char *argv[])
break;
}
}
- } else if (_exit_now == DM_SIGNALED_EXIT) {
- _exit_now = DM_SCHEDULED_EXIT;
- /*
- * When '_exit_now' is set, signal has been received,
- * but can not simply exit unless all
- * threads are done processing.
- */
- log_info("dmeventd received break, scheduling exit.");
- }
+ } else
+ switch (_exit_now) {
+ case DM_SIGNALED_EXIT:
+ _exit_now = DM_SCHEDULED_EXIT;
+ /*
+ * When '_exit_now' is set, signal has been received,
+ * but can not simply exit unless all
+ * threads are done processing.
+ */
+ log_info("dmeventd received break, scheduling exit.");
+ /* fall through */
+ case DM_SCHEDULED_EXIT:
+ /* While exit is scheduled, check for exit_on file */
+ DEBUGLOG("Checking exit on file \"%s\".", _exit_on);
+ if (_exit_on[0] && (access(_exit_on, F_OK) == 0)) {
+ log_info("dmeventd detected exit on file %s, unregistering all monitored devices.",
+ _exit_on);
+ _unregister_all_threads();
+ }
+ break;
+ }
+
_process_request(&fifos);
_cleanup_unused_threads();
}
diff --git a/make.tmpl.in b/make.tmpl.in
index 7799a8adb..99170ca7f 100644
--- a/make.tmpl.in
+++ b/make.tmpl.in
@@ -147,6 +147,7 @@ DEFAULT_LOCK_DIR = @DEFAULT_LOCK_DIR@
DEFAULT_RUN_DIR = @DEFAULT_RUN_DIR@
DEFAULT_PID_DIR = @DEFAULT_PID_DIR@
DEFAULT_MANGLING = @MANGLING@
+DEFAULT_DMEVENTD_EXIT_ON_PATH = @DEFAULT_DMEVENTD_EXIT_ON_PATH@
# Setup vpath search paths for some suffixes
vpath %.c $(srcdir)
diff --git a/man/Makefile.in b/man/Makefile.in
index ba6f2046f..f324150de 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -181,6 +181,7 @@ $(SED) -e "s+#VERSION#+$(LVM_VERSION)+" \
-e "s+#DEFAULT_PID_DIR#+$(DEFAULT_PID_DIR)+" \
-e "s+#SYSTEMD_GENERATOR_DIR#+$(SYSTEMD_GENERATOR_DIR)+" \
-e "s+#DEFAULT_LIBLINE#+$(DEFAULT_LIBLINE)+" \
+ -e "s+#DEFAULT_DMEVENTD_EXIT_ON_PATH#+$(DEFAULT_DMEVENTD_EXIT_ON_PATH)+" \
-e "s+#DEFAULT_MANGLING#+$(DEFAULT_MANGLING)+" $< > $@
endef
diff --git a/man/dmeventd.8_main b/man/dmeventd.8_main
index 75926bae5..7a780da7c 100644
--- a/man/dmeventd.8_main
+++ b/man/dmeventd.8_main
@@ -10,6 +10,8 @@ dmeventd \(em Device-mapper event daemon
.RB [ -d
.RB [ -d
.RB [ -d ]]]
+.RB [ -e
+.BR exit_on_path ]
.RB [ -f ]
.RB [ -h ]
.RB [ -i ]
@@ -37,6 +39,16 @@ debug messages sent to syslog.
Each extra d adds more debugging information.
.
.TP
+.B -e exit_on_path
+Specifies the file path whose presence is checked by the daemon when it
+receives a signal (SIGINT, SIGTERM) and allows to exit even if there are still
+monitored devices.
+This can help with system shutdown where devices
+have not been unmonitored properly.
+To disable this behavior set this to the empty string "".
+Default value is "\fI#DEFAULT_DMEVENTD_EXIT_ON_PATH#\fP".
+.
+.TP
.B -f
Don't fork, run in the foreground.
.
--
2.48.1

View File

@ -0,0 +1,118 @@
From 490631e2cd0947116f21192837703b2e563b863c Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Wed, 20 Sep 2023 15:36:54 +0200
Subject: [PATCH 138/139] debug: correct level
No error for just tracing message.
(cherry picked from commit e930ee93f7361a7b0b7a357acc4187bf630b7f14)
---
daemons/dmeventd/dmeventd.c | 20 ++++++++++----------
device_mapper/ioctl/libdm-iface.c | 2 +-
libdm/ioctl/libdm-iface.c | 2 +-
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
index 828bc0c7a..f529f8ac5 100644
--- a/daemons/dmeventd/dmeventd.c
+++ b/daemons/dmeventd/dmeventd.c
@@ -1765,7 +1765,7 @@ static void _cleanup_unused_threads(void)
DEBUGLOG("Destroying Thr %x.", (int)thread->thread);
if (pthread_join(thread->thread, NULL))
- log_sys_error("pthread_join", "");
+ log_sys_debug("pthread_join", "");
_free_thread_status(thread);
_lock_mutex();
@@ -1796,7 +1796,7 @@ static void _init_thread_signals(void)
sigdelset(&my_sigset, SIGQUIT);
if (pthread_sigmask(SIG_BLOCK, &my_sigset, NULL))
- log_sys_error("pthread_sigmask", "SIG_BLOCK");
+ log_sys_debug("pthread_sigmask", "SIG_BLOCK");
}
/*
@@ -1825,7 +1825,7 @@ static int _set_oom_adj(const char *oom_adj_path, int val)
fprintf(fp, "%i", val);
if (dm_fclose(fp))
- log_sys_error("fclose", oom_adj_path);
+ log_sys_debug("fclose", oom_adj_path);
return 1;
}
@@ -1839,11 +1839,11 @@ static int _protect_against_oom_killer(void)
if (stat(OOM_ADJ_FILE, &st) == -1) {
if (errno != ENOENT)
- log_sys_error("stat", OOM_ADJ_FILE);
+ log_sys_debug("stat", OOM_ADJ_FILE);
/* Try old oom_adj interface as a fallback */
if (stat(OOM_ADJ_FILE_OLD, &st) == -1) {
- log_sys_error("stat", OOM_ADJ_FILE_OLD);
+ log_sys_debug("stat", OOM_ADJ_FILE_OLD);
return 1;
}
@@ -1932,14 +1932,14 @@ out:
static void _remove_files_on_exit(void)
{
if (unlink(DMEVENTD_PIDFILE))
- log_sys_error("unlink", DMEVENTD_PIDFILE);
+ log_sys_debug("unlink", DMEVENTD_PIDFILE);
if (!_systemd_activation) {
if (unlink(DM_EVENT_FIFO_CLIENT))
- log_sys_error("unlink", DM_EVENT_FIFO_CLIENT);
+ log_sys_debug("unlink", DM_EVENT_FIFO_CLIENT);
if (unlink(DM_EVENT_FIFO_SERVER))
- log_sys_error("unlink", DM_EVENT_FIFO_SERVER);
+ log_sys_debug("unlink", DM_EVENT_FIFO_SERVER);
}
}
@@ -2428,9 +2428,9 @@ int main(int argc, char *argv[])
log_notice("dmeventd shutting down.");
if (fifos.client >= 0 && close(fifos.client))
- log_sys_error("client close", fifos.client_path);
+ log_sys_debug("client close", fifos.client_path);
if (fifos.server >= 0 && close(fifos.server))
- log_sys_error("server close", fifos.server_path);
+ log_sys_debug("server close", fifos.server_path);
if (_use_syslog)
closelog();
diff --git a/device_mapper/ioctl/libdm-iface.c b/device_mapper/ioctl/libdm-iface.c
index 533bb9eea..b09284118 100644
--- a/device_mapper/ioctl/libdm-iface.c
+++ b/device_mapper/ioctl/libdm-iface.c
@@ -397,7 +397,7 @@ static void _close_control_fd(void)
{
if (_control_fd != -1) {
if (close(_control_fd) < 0)
- log_sys_error("close", "_control_fd");
+ log_sys_debug("close", "_control_fd");
_control_fd = -1;
}
}
diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c
index 28589a15c..7c7259874 100644
--- a/libdm/ioctl/libdm-iface.c
+++ b/libdm/ioctl/libdm-iface.c
@@ -396,7 +396,7 @@ static void _close_control_fd(void)
{
if (_control_fd != -1) {
if (close(_control_fd) < 0)
- log_sys_error("close", "_control_fd");
+ log_sys_debug("close", "_control_fd");
_control_fd = -1;
}
}
--
2.48.1

View File

@ -0,0 +1,54 @@
From 4f4a5c39ae768714925809970598b15268cd4ddb Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Tue, 26 Sep 2023 01:21:41 +0200
Subject: [PATCH 139/139] tests: check exit_on works
(cherry picked from commit cb8486a9b2d6f3c73749f98287cad6adbc4f857f)
---
test/shell/dmeventd-restart.sh | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/test/shell/dmeventd-restart.sh b/test/shell/dmeventd-restart.sh
index 0def8c1fa..96e4c7cff 100644
--- a/test/shell/dmeventd-restart.sh
+++ b/test/shell/dmeventd-restart.sh
@@ -46,8 +46,8 @@ rm LOCAL_DMEVENTD debug.log*
dmeventd -R -f &
echo $! >LOCAL_DMEVENTD
-# wait longer as tries to communicate with killed daemon
-sleep 9
+# wait longer as tries 5s to communicate with killed daemon
+sleep 7
# now dmeventd should not be running
not pgrep dmeventd
rm LOCAL_DMEVENTD
@@ -63,4 +63,24 @@ test -e LOCAL_CLVMD || not grep 'already monitored' lvchange.out
lvchange --monitor y --verbose $vg/$lv2 2>&1 | tee lvchange.out
test -e LOCAL_CLVMD || not grep 'already monitored' lvchange.out
-vgremove -ff $vg
+rm -f debug.log*
+dmeventd -R -f -e "$PWD/test_nologin" -ldddd > debug.log_DMEVENTD_$RANDOM 2>&1 &
+echo $! >LOCAL_DMEVENTD
+
+pgrep -o dmeventd
+kill -INT "$(< LOCAL_DMEVENTD)"
+sleep 1
+
+# dmeventd should be still present (although in 'exit-mode')
+pgrep -o dmeventd
+
+# Create a file simulating 'shutdown in progress'
+touch test_nologin
+sleep 1.1
+
+# Should be now dead (within 1 second)
+not pgrep -o dmeventd
+rm -f LOCAL_DMEVENTD
+
+# Do not run dmeventd here again
+vgremove -ff --config 'activation/monitoring = 0' $vg
--
2.48.1

View File

@ -0,0 +1,196 @@
From ae515916c05218a49b40afaaf26f9c4c0bb55e53 Mon Sep 17 00:00:00 2001
From: Zdenek Kabelac <zkabelac@redhat.com>
Date: Sat, 8 Feb 2025 21:51:09 +0100
Subject: [PATCH] mirror: enhance error path for pvmove finish
When the pvmove operation is completing, it attempts to deactivate
the temporary mirror and remove its mirror legs. However,
if an external tool holds these volumes open, the operation would
previously abort entirely, leaving the LVM2 metadata in a partially
unusable state that required manual administrative fixes.
To improve this, the code has been enhanced to handle such scenarios
more gracefully. It will now complete the pvmove operation even
if some volumes cannot be deactivated, marking them in the metadata
with an error segment. While the command will report errors,
the metadata will remain in a usable state. The administrator
can then remove the orphaned volumes when they are no longer in use.
(cherry picked from commit ed9468153ec3d9cec8d6fbb9f6b8e09e10427416)
---
lib/metadata/mirror.c | 93 ++++++++++++++++++++++++++++++++++++++++---
tools/pvmove_poll.c | 13 ++++++
2 files changed, 101 insertions(+), 5 deletions(-)
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index 46da57948..d5c988372 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -398,6 +398,59 @@ static int _activate_lv_like_model(struct logical_volume *model,
return 1;
}
+/*
+ * Inherit tags @from_lv to @to_lv, tags maybe needed for activation
+ */
+static int _inherit_lv_tags(const struct logical_volume *from_lv, struct logical_volume *to_lv)
+{
+ struct dm_str_list *sl;
+
+ if (to_lv && !str_list_match_list(&from_lv->tags, &to_lv->tags, NULL))
+ dm_list_iterate_items(sl, &from_lv->tags)
+ if (!str_list_add(from_lv->vg->cmd->mem, &to_lv->tags, sl->str)) {
+ log_error("Aborting. Unable to inherit tag.");
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Deactivates and removes an 'orphan' temporary @lv,
+ * which is expected to already have an 'error' segment.
+ * Sets @updated_mda (!NULL) to 1 when LV is removed.
+ * Sets @deactivation_failed (!NULL) to 1 when deactivation fails.
+ *
+ * Note: An external tool might still have the volume open, preventing
+ * immediate deactivation. If deactivation fails (even after retrying),
+ * it is safer to proceed with the command and leave the LV visible.
+ * This allows the user to manually remove it when it is no longer in use.
+ *
+ * Any errors will be detected later in the process, as there will be
+ * more visible LVs than expected.
+ */
+static int _deactivate_and_remove_lv(struct logical_volume *lv,
+ int *updated_mda,
+ int *deactivation_failed)
+{
+ if (lv) {
+ /* FIXME: convert to use lv_active_change() */
+ if (!deactivate_lv(lv->vg->cmd, lv)) {
+ /* Note: still returns success here and fails later */
+ log_warn("WARNING: Can't deactivate temporary volume %s.",
+ display_lvname(lv));
+ if (deactivation_failed)
+ *deactivation_failed = 1;
+ } else if (!lv_remove(lv)) {
+ /* Can't continue with internal metadata problems */
+ return_0;
+ } else if (updated_mda)
+ *updated_mda = 1;
+ }
+
+ return 1;
+}
+
/*
* Delete independent/orphan LV, it must acquire lock.
*/
@@ -803,7 +856,6 @@ static int _remove_mirror_images(struct logical_volume *lv,
struct lv_list *lvl;
struct dm_list tmp_orphan_lvs;
uint32_t orig_removed = num_removed;
- int reactivate;
if (removed)
*removed = 0;
@@ -967,6 +1019,19 @@ static int _remove_mirror_images(struct logical_volume *lv,
return_0;
}
+ if (!collapse) {
+ dm_list_iterate_items(lvl, &tmp_orphan_lvs) {
+ if (!_inherit_lv_tags(lv, lvl->lv))
+ return_0;
+ if (!replace_lv_with_error_segment(lvl->lv))
+ return_0;
+ }
+ }
+
+ if (!_inherit_lv_tags(lv, temp_layer_lv) ||
+ !_inherit_lv_tags(lv, detached_log_lv))
+ return_0;
+
/*
* To successfully remove these unwanted LVs we need to
* remove the LVs from the mirror set, commit that metadata
@@ -976,17 +1041,35 @@ static int _remove_mirror_images(struct logical_volume *lv,
return_0;
/* Save or delete the 'orphan' LVs */
- reactivate = lv_is_active(lv_lock_holder(lv));
+ if (lv_is_active(lv_lock_holder(lv))) {
+ if (!collapse) {
+ dm_list_iterate_items(lvl, &tmp_orphan_lvs)
+ if (!_activate_lv_like_model(lv, lvl->lv))
+ return_0;
+ }
+
+ if (temp_layer_lv &&
+ !_activate_lv_like_model(lv, temp_layer_lv))
+ return_0;
+
+ if (detached_log_lv &&
+ !_activate_lv_like_model(lv, detached_log_lv))
+ return_0;
+
+ if (!sync_local_dev_names(lv->vg->cmd))
+ stack;
+ }
+
if (!collapse) {
dm_list_iterate_items(lvl, &tmp_orphan_lvs)
- if (!_delete_lv(lv, lvl->lv, reactivate))
+ if (!_deactivate_and_remove_lv(lvl->lv, NULL, NULL))
return_0;
}
- if (temp_layer_lv && !_delete_lv(lv, temp_layer_lv, reactivate))
+ if (!_deactivate_and_remove_lv(temp_layer_lv, NULL, NULL))
return_0;
- if (detached_log_lv && !_delete_lv(lv, detached_log_lv, reactivate))
+ if (!_deactivate_and_remove_lv(detached_log_lv, NULL, NULL))
return_0;
/* Mirror with only 1 area is 'in sync'. */
diff --git a/tools/pvmove_poll.c b/tools/pvmove_poll.c
index 751313cd7..8b97905c0 100644
--- a/tools/pvmove_poll.c
+++ b/tools/pvmove_poll.c
@@ -87,6 +87,8 @@ int pvmove_update_metadata(struct cmd_context *cmd, struct volume_group *vg,
int pvmove_finish(struct cmd_context *cmd, struct volume_group *vg,
struct logical_volume *lv_mirr, struct dm_list *lvs_changed)
{
+ uint32_t visible = vg_visible_lvs(lv_mirr->vg);
+
if (!dm_list_empty(lvs_changed) &&
(!_detach_pvmove_mirror(cmd, lv_mirr) ||
!replace_lv_with_error_segment(lv_mirr))) {
@@ -94,6 +96,8 @@ int pvmove_finish(struct cmd_context *cmd, struct volume_group *vg,
return 0;
}
+ lv_set_visible(lv_mirr);
+
if (!lv_update_and_reload(lv_mirr))
return_0;
@@ -120,5 +124,14 @@ int pvmove_finish(struct cmd_context *cmd, struct volume_group *vg,
return 0;
}
+ /* Allows the pvmove operation to complete even if 'orphaned' temporary volumes
+ * cannot be deactivated due to being held open by another process.
+ * The user can manually remove these volumes later when they are no longer in use. */
+ if (visible < vg_visible_lvs(lv_mirr->vg)) {
+ log_error("ABORTING: Failed to remove temporary logical volume(s).");
+ log_print_unless_silent("Please remove orphan temporary logical volume(s) when possible.");
+ return 0;
+ }
+
return 1;
}
--
2.48.1

View File

@ -0,0 +1,42 @@
From 97aa5f67547f150b5f8f511249b200a41561a3c9 Mon Sep 17 00:00:00 2001
From: David Teigland <teigland@redhat.com>
Date: Thu, 27 Jun 2024 12:46:15 -0500
Subject: [PATCH 1/2] lvmlockd: vgchange systemid doen't need global lock
The comment explained that the ex global lock was just
used to trigger global cache invalidation, which is no
longer needed. This extra locking can cause problems
with LVM-activate when local and shared VGs are mixed
(and the incorrect exit code for errors was causing
problems.)
(cherry picked from commit 680f7bd676526771b7a26e35105af3bccb95e4a1)
---
tools/vgchange.c | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/tools/vgchange.c b/tools/vgchange.c
index e4b57dbd2..b0e2b2d2a 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -1231,17 +1231,6 @@ int vgchange_systemid_cmd(struct cmd_context *cmd, int argc, char **argv)
struct processing_handle *handle;
int ret;
- /*
- * This is a special case where taking the global lock is
- * not needed to protect global state, because the change is
- * only to an existing VG. But, taking the global lock ex is
- * helpful in this case to trigger a global cache validation
- * on other hosts, to cause them to see the new system_id or
- * lock_type.
- */
- if (!lockd_global(cmd, "ex"))
- return 0;
-
if (!(handle = init_processing_handle(cmd, NULL))) {
log_error("Failed to initialize processing handle.");
return ECMD_FAILED;
--
2.49.0

View File

@ -55,7 +55,7 @@
%global commit 4dc5d4ac7e7a9457ccc46ff04796b347e58bf4da
%global shortcommit %(c=%{commit}; echo ${c:0:7})
%endif
#%%global rel_suffix .bz2233901_1
%global rel_suffix .2
# Do not reset Release to 1 unless both lvm2 and device-mapper
# versions are increased together.
@ -68,7 +68,7 @@ Version: 2.03.14
%if 0%{?from_snapshot}
Release: 0.1.20210426git%{shortcommit}%{?dist}%{?rel_suffix}
%else
Release: 14%{?dist}%{?rel_suffix}
Release: 15%{?dist}%{?rel_suffix}
%endif
License: GPLv2
URL: http://sourceware.org/lvm2
@ -227,6 +227,20 @@ Patch126: 0125-raid-add-messages-to-lvs-command-output-in-case-Raid.patch
#Patch130: 0129-remove-unused-variable.patch
#
Patch131: 0130-spec-Install-and-package-etc-lvm-devices.patch
# RHEL-8288:
Patch132: 0131-dmeventd-move-var-set-to-locked-section.patch
Patch133: 0132-dmeventd-use-return.patch
Patch134: 0133-dmeventd-unregister-all-devices-on-restart.patch
Patch135: 0134-dmeventd-info-status-report.patch
Patch136: 0135-configure.ac-add-with-dmeventd-exit-on-path.patch
Patch137: 0136-configure-autoreconf.patch
Patch138: 0137-dmeventd-implement-exit_on-file-check.patch
Patch139: 0138-debug-correct-level.patch
Patch140: 0139-tests-check-exit_on-works.patch
# RHEL-62764:
Patch141: 0140-mirror-enhance-error-path-for-pvmove-finish.patch
# RHEL-66486:
Patch142: 0141-lvmlockd-vgchange-systemid-doen-t-need-global-lock.patch
BuildRequires: gcc
%if %{enable_testsuite}
@ -892,7 +906,7 @@ the device-mapper event library.
%package testsuite
Summary: LVM2 Testsuite
# Most of the code is GPLv2, the harness in test/lib/{brick-shelltest.h,runner.cpp} is BSD, and C files in test/api are LGPLv2...
License: LGPLv2 and GPLv2 and BSD-2-Clause
License: GPL-2.0-only AND LGPL-2.1-only AND BSD-2-Clause
%description testsuite
An extensive functional testsuite for LVM2.
@ -905,6 +919,16 @@ An extensive functional testsuite for LVM2.
%endif
%changelog
* Mon Jun 02 2025 Marian Csontos <mcsontos@redhat.com> - 2.03.14-15.el8_10.2
- Fix vgchange exit code when lvmlockd is not running and no change is done.
* Wed Apr 30 2025 Marian Csontos <mcsontos@redhat.com> - 2.03.14-15.el8_10.1
- Fix incomplete pvmove write bad metadata requiring manual intervention.
* Wed Jan 22 2025 Marian Csontos <mcsontos@redhat.com> - 2.03.14-15
- Fix dmeventd blocking on shutdown.
- Force exit dmeventd when /run/nologin is present.
* Fri Feb 02 2024 Marian Csontos <mcsontos@redhat.com> - 2.03.14-14
- Fix multisegment RAID1 allocator using one disk for both legs.
- Fix lvconvert -m 0 taking rimage_0 even if it is out of sync.