[lvm2] More systemd support.

Peter Rajnoha prajnoha at fedoraproject.org
Thu Jul 28 17:54:27 UTC 2011


commit 056a28e80778f0b1be02906a986d94642be1bfe7
Author: Peter Rajnoha <prajnoha at redhat.com>
Date:   Thu Jul 28 19:49:05 2011 +0200

    More systemd support.

 lvm2-add-systemd-units.patch     |   44 ++++++++--
 lvm2-new-oom-adj-interface.patch |  116 ++++++++++++++++++++++++++
 lvm2-systemd-fds-handover.patch  |  167 ++++++++++++++++++++++++++++++++++++++
 lvm2.spec                        |   22 ++++-
 4 files changed, 337 insertions(+), 12 deletions(-)
---
diff --git a/lvm2-add-systemd-units.patch b/lvm2-add-systemd-units.patch
index e2755c7..49bba6b 100644
--- a/lvm2-add-systemd-units.patch
+++ b/lvm2-add-systemd-units.patch
@@ -1,14 +1,40 @@
- scripts/dm_event_systemd_red_hat.service.in        |   13 +++++++++++++
- scripts/dm_event_systemd_red_hat.socket            |   10 ++++++++++
+ WHATS_NEW                                          |    4 ++++
+ WHATS_NEW_DM                                       |    4 ++++
+ scripts/dm_event_systemd_red_hat.service.in        |   14 ++++++++++++++
+ scripts/dm_event_systemd_red_hat.socket            |   11 +++++++++++
  scripts/lvm2_monitoring_systemd_red_hat.service.in |   17 +++++++++++++++++
- 3 files changed, 40 insertions(+), 0 deletions(-)
+ 5 files changed, 50 insertions(+), 0 deletions(-)
 
+diff --git a/WHATS_NEW b/WHATS_NEW
+index ddb04ad..f8bb79e 100644
+--- a/WHATS_NEW
++++ b/WHATS_NEW
+@@ -1,3 +1,7 @@
++Version 2.02.87 -
++===============================
++  Add systemd unit file to provide lvm2 monitoring.
++
+ Version 2.02.86 - 8th July 2011
+ ===============================
+   Remove unnecessary warning in pvcreate for MD linear devices.
+diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
+index 5e4aeaf..b6a5360 100644
+--- a/WHATS_NEW_DM
++++ b/WHATS_NEW_DM
+@@ -1,3 +1,7 @@
++Version 1.02.66 -
++===============================
++  Add systemd unit files for dmeventd.
++
+ Version 1.02.65 - 8th July 2011
+ ===============================
+   Remove dev name prefix from dmsetup line output if exactly one dev requested.
 diff --git a/scripts/dm_event_systemd_red_hat.service.in b/scripts/dm_event_systemd_red_hat.service.in
 new file mode 100644
-index 0000000..3e18c69
+index 0000000..32295d3
 --- /dev/null
 +++ b/scripts/dm_event_systemd_red_hat.service.in
-@@ -0,0 +1,13 @@
+@@ -0,0 +1,14 @@
 +[Unit]
 +Description=Device-mapper event daemon
 +After=fedora-storage-init.service fedora-storage-init-late.service
@@ -19,15 +45,16 @@ index 0000000..3e18c69
 +Type=forking
 +ExecStart=@sbindir@/dmeventd
 +PIDFile=@DMEVENTD_PIDFILE@
++OOMScoreAdjust=-1000
 +
 +[Install]
 +WantedBy=sysinit.target
 diff --git a/scripts/dm_event_systemd_red_hat.socket b/scripts/dm_event_systemd_red_hat.socket
 new file mode 100644
-index 0000000..45c02dd
+index 0000000..c580555
 --- /dev/null
 +++ b/scripts/dm_event_systemd_red_hat.socket
-@@ -0,0 +1,10 @@
+@@ -0,0 +1,11 @@
 +[Unit]
 +Description=Device-mapper event daemon FIFOs
 +DefaultDependencies=no
@@ -35,12 +62,13 @@ index 0000000..45c02dd
 +[Socket]
 +ListenFIFO=/var/run/dmeventd-server
 +ListenFIFO=/var/run/dmeventd-client
++SocketMode=0600
 +
 +[Install]
 +WantedBy=sockets.target
 diff --git a/scripts/lvm2_monitoring_systemd_red_hat.service.in b/scripts/lvm2_monitoring_systemd_red_hat.service.in
 new file mode 100644
-index 0000000..c284bbb
+index 0000000..4715416
 --- /dev/null
 +++ b/scripts/lvm2_monitoring_systemd_red_hat.service.in
 @@ -0,0 +1,17 @@
diff --git a/lvm2-new-oom-adj-interface.patch b/lvm2-new-oom-adj-interface.patch
new file mode 100644
index 0000000..50b2014
--- /dev/null
+++ b/lvm2-new-oom-adj-interface.patch
@@ -0,0 +1,116 @@
+ WHATS_NEW_DM                |    1 +
+ daemons/dmeventd/dmeventd.c |   61 +++++++++++++++++++++++++++++-------------
+ 2 files changed, 43 insertions(+), 19 deletions(-)
+
+diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
+index b6a5360..868a469 100644
+--- a/WHATS_NEW_DM
++++ b/WHATS_NEW_DM
+@@ -1,5 +1,6 @@
+ Version 1.02.66 -
+ ===============================
++  Add support for new oom killer adjustment interface (oom_score_adj).
+   Add systemd unit files for dmeventd.
+ 
+ Version 1.02.65 - 8th July 2011
+diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
+index 1a91cb8..a6956cb 100644
+--- a/daemons/dmeventd/dmeventd.c
++++ b/daemons/dmeventd/dmeventd.c
+@@ -41,11 +41,19 @@
+ #ifdef linux
+ #  include <malloc.h>
+ 
+-#  define OOM_ADJ_FILE "/proc/self/oom_adj"
++/*
++ * Kernel version 2.6.36 and higher has
++ * new OOM killer adjustment interface.
++ */
++#  define OOM_ADJ_FILE_OLD "/proc/self/oom_adj"
++#  define OOM_ADJ_FILE "/proc/self/oom_score_adj"
+ 
+ /* From linux/oom.h */
++/* Old interface */
+ #  define OOM_DISABLE (-17)
+ #  define OOM_ADJUST_MIN (-16)
++/* New interface */
++#  define OOM_SCORE_ADJ_MIN (-1000)
+ 
+ #endif
+ 
+@@ -1594,33 +1602,48 @@ static void _exit_handler(int sig __attribute__((unused)))
+ }
+ 
+ #ifdef linux
++static int _set_oom_adj(const char *oom_adj_path, int val)
++{
++	FILE *fp;
++
++	if (!(fp = fopen(oom_adj_path, "w"))) {
++		perror("oom_adj: fopen failed");
++		return 0;
++	}
++
++	fprintf(fp, "%i", val);
++
++	if (dm_fclose(fp))
++		perror("oom_adj: fclose failed");
++
++	return 1;
++}
++
+ /*
+  * Protection against OOM killer if kernel supports it
+  */
+-static int _set_oom_adj(int val)
++static int _protect_against_oom_killer()
+ {
+-	FILE *fp;
+-
+ 	struct stat st;
+ 
+ 	if (stat(OOM_ADJ_FILE, &st) == -1) {
+-		if (errno == ENOENT)
+-			perror(OOM_ADJ_FILE " not found");
+-		else
++		if (errno != ENOENT)
+ 			perror(OOM_ADJ_FILE ": stat failed");
+-		return 1;
+-	}
+ 
+-	if (!(fp = fopen(OOM_ADJ_FILE, "w"))) {
+-		perror(OOM_ADJ_FILE ": fopen failed");
+-		return 0;
+-	}
++		/* Try old oom_adj interface as a fallback */
++		if (stat(OOM_ADJ_FILE_OLD, &st) == -1) {
++			if (errno == ENOENT)
++				perror(OOM_ADJ_FILE_OLD " not found");
++			else
++				perror(OOM_ADJ_FILE_OLD ": stat failed");
++			return 1;
++		}
+ 
+-	fprintf(fp, "%i", val);
+-	if (dm_fclose(fp))
+-		perror(OOM_ADJ_FILE ": fclose failed");
++		return _set_oom_adj(OOM_ADJ_FILE_OLD, OOM_DISABLE) ||
++		       _set_oom_adj(OOM_ADJ_FILE_OLD, OOM_ADJUST_MIN);
++	}
+ 
+-	return 1;
++	return _set_oom_adj(OOM_ADJ_FILE, OOM_SCORE_ADJ_MIN);
+ }
+ #endif
+ 
+@@ -1829,8 +1852,8 @@ int main(int argc, char *argv[])
+ 	signal(SIGQUIT, &_exit_handler);
+ 
+ #ifdef linux
+-	if (!_set_oom_adj(OOM_DISABLE) && !_set_oom_adj(OOM_ADJUST_MIN))
+-		syslog(LOG_ERR, "Failed to set oom_adj to protect against OOM killer");
++	if (!_protect_against_oom_killer())
++		syslog(LOG_ERR, "Failed to protect against OOM killer");
+ #endif
+ 
+ 	_init_thread_signals();
diff --git a/lvm2-systemd-fds-handover.patch b/lvm2-systemd-fds-handover.patch
new file mode 100644
index 0000000..5487fa6
--- /dev/null
+++ b/lvm2-systemd-fds-handover.patch
@@ -0,0 +1,167 @@
+ WHATS_NEW_DM                |    1 +
+ daemons/dmeventd/dmeventd.c |   95 +++++++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 92 insertions(+), 4 deletions(-)
+
+diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
+index 868a469..d09a50c 100644
+--- a/WHATS_NEW_DM
++++ b/WHATS_NEW_DM
+@@ -1,5 +1,6 @@
+ Version 1.02.66 -
+ ===============================
++  Add support for systemd file descriptor handover to dmeventd.
+   Add support for new oom killer adjustment interface (oom_score_adj).
+   Add systemd unit files for dmeventd.
+ 
+diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
+index a6956cb..ec514ee 100644
+--- a/daemons/dmeventd/dmeventd.c
++++ b/daemons/dmeventd/dmeventd.c
+@@ -55,6 +55,13 @@
+ /* New interface */
+ #  define OOM_SCORE_ADJ_MIN (-1000)
+ 
++/* Systemd on-demand activation support */
++#  define SD_LISTEN_PID_ENV_VAR_NAME "LISTEN_PID"
++#  define SD_LISTEN_FDS_ENV_VAR_NAME "LISTEN_FDS"
++#  define SD_LISTEN_FDS_START 3
++#  define SD_FD_FIFO_SERVER SD_LISTEN_FDS_START
++#  define SD_FD_FIFO_CLIENT (SD_LISTEN_FDS_START + 1)
++
+ #endif
+ 
+ /* FIXME We use syslog for now, because multilog is not yet implemented */
+@@ -104,6 +111,7 @@ static pthread_mutex_t _global_mutex;
+ #define THREAD_STACK_SIZE (300*1024)
+ 
+ int dmeventd_debug = 0;
++static int _systemd_activation = 0;
+ static int _foreground = 0;
+ static int _restart = 0;
+ static char **_initial_registrations = 0;
+@@ -1710,8 +1718,13 @@ static void _daemonize(void)
+ 	else
+ 		fd = rlim.rlim_cur;
+ 
+-	for (--fd; fd >= 0; fd--)
++	for (--fd; fd >= 0; fd--) {
++		/* Do not close fds preloaded by systemd! */
++		if (_systemd_activation &&
++		    (fd == SD_FD_FIFO_SERVER || fd == SD_FD_FIFO_CLIENT))
++			continue;
+ 		close(fd);
++	}
+ 
+ 	if ((open("/dev/null", O_RDONLY) < 0) ||
+ 	    (open("/dev/null", O_WRONLY) < 0) ||
+@@ -1780,6 +1793,76 @@ static void restart(void)
+ 	fini_fifos(&fifos);
+ }
+ 
++static int _handle_preloaded_fifo(int fd, const char *path)
++{
++	struct stat st_fd, st_path;
++	int flags;
++
++	if ((flags = fcntl(fd, F_GETFD)) < 0)
++		return 0;
++
++	if (flags & FD_CLOEXEC)
++		return 0;
++
++	if (fstat(fd, &st_fd) < 0 || !S_ISFIFO(st_fd.st_mode))
++		return 0;
++
++	if (stat(path, &st_path) < 0 ||
++	    st_path.st_dev != st_fd.st_dev ||
++	    st_path.st_ino != st_fd.st_ino)
++		return 0;
++
++	if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
++		return 0;
++
++	return 1;
++}
++
++static int _systemd_handover(struct dm_event_fifos *fifos)
++{
++	const char *e;
++	char *p;
++	unsigned long env_pid, env_listen_fds;
++	int r = 0;
++
++	memset(fifos, 0, sizeof(*fifos));
++
++	/* LISTEN_PID must be equal to our PID! */
++	if (!(e = getenv(SD_LISTEN_PID_ENV_VAR_NAME)))
++		goto out;
++
++	errno = 0;
++	env_pid = strtoul(e, &p, 10);
++	if (errno || !p || *p || env_pid <= 0 ||
++	    getpid() != (pid_t) env_pid)
++		goto out;
++
++	/* LISTEN_FDS must be 2 and the fds must be FIFOSs! */
++	if (!(e = getenv(SD_LISTEN_FDS_ENV_VAR_NAME)))
++		goto out;
++
++	errno = 0;
++	env_listen_fds = strtoul(e, &p, 10);
++	if (errno || !p || *p || env_listen_fds != 2)
++		goto out;
++
++	/* Check and handle the FIFOs passed in */
++	r = (_handle_preloaded_fifo(SD_FD_FIFO_SERVER, DM_EVENT_FIFO_SERVER) &&
++	     _handle_preloaded_fifo(SD_FD_FIFO_CLIENT, DM_EVENT_FIFO_CLIENT));
++
++	if (r) {
++		fifos->server = SD_FD_FIFO_SERVER;
++		fifos->server_path = DM_EVENT_FIFO_SERVER;
++		fifos->client = SD_FD_FIFO_CLIENT;
++		fifos->client_path = DM_EVENT_FIFO_CLIENT;
++	}
++
++out:
++	unsetenv(SD_LISTEN_PID_ENV_VAR_NAME);
++	unsetenv(SD_LISTEN_FDS_ENV_VAR_NAME);
++	return r;
++}
++
+ static void usage(char *prog, FILE *file)
+ {
+ 	fprintf(file, "Usage:\n"
+@@ -1834,6 +1917,8 @@ int main(int argc, char *argv[])
+ 	if (_restart)
+ 		restart();
+ 
++	_systemd_activation = _systemd_handover(&fifos);
++
+ 	if (!_foreground)
+ 		_daemonize();
+ 
+@@ -1852,7 +1937,8 @@ int main(int argc, char *argv[])
+ 	signal(SIGQUIT, &_exit_handler);
+ 
+ #ifdef linux
+-	if (!_protect_against_oom_killer())
++	/* Systemd has adjusted oom killer for us already */
++	if (!_systemd_activation && !_protect_against_oom_killer())
+ 		syslog(LOG_ERR, "Failed to protect against OOM killer");
+ #endif
+ 
+@@ -1863,11 +1949,12 @@ int main(int argc, char *argv[])
+ 	//multilog_init_verbose(std_syslog, _LOG_DEBUG);
+ 	//multilog_async(1);
+ 
+-	_init_fifos(&fifos);
++	if (!_systemd_activation)
++		_init_fifos(&fifos);
+ 
+ 	pthread_mutex_init(&_global_mutex, NULL);
+ 
+-	if (_open_fifos(&fifos))
++	if (!_systemd_activation && _open_fifos(&fifos))
+ 		exit(EXIT_FIFO_FAILURE);
+ 
+ 	/* Signal parent, letting them know we are ready to go. */
diff --git a/lvm2.spec b/lvm2.spec
index 128d4ea..3636b35 100644
--- a/lvm2.spec
+++ b/lvm2.spec
@@ -39,7 +39,7 @@
 Summary: Userland logical volume management tools 
 Name: lvm2
 Version: 2.02.86
-Release: 3%{?dist}
+Release: 4%{?dist}
 License: GPLv2
 Group: System Environment/Base
 URL: http://sources.redhat.com/lvm2
@@ -51,6 +51,8 @@ Patch0: lvm2-set-default-preferred_names.patch
 Patch1: lvm2-add-systemd-units.patch
 Patch2: lvm2-systemd-conf-make-support.patch
 Patch3: lvm2-autoreconf.patch
+Patch4: lvm2-new-oom-adj-interface.patch
+Patch5: lvm2-systemd-fds-handover.patch
 
 BuildRequires: libselinux-devel >= 1.30.19-4, libsepol-devel
 BuildRequires: ncurses-devel
@@ -93,6 +95,8 @@ or more physical volumes and creating one or more logical volumes
 %patch1 -p1 -b .systemd_units
 %patch2 -p1 -b .systemd_conf_make
 %patch3 -p1 -b .autoreconf
+%patch4 -p1 -b .oom_adj
+%patch5 -p1 -b .systemd_fds
 
 %build
 %define _exec_prefix ""
@@ -528,9 +532,15 @@ fi
 %postun -n device-mapper-event
 %if %{enable_systemd}
 /bin/systemctl daemon-reload > /dev/null 2>&1 || :
-if [ $1 -ge 1 ]; then
-	/bin/systemctl try-restart dm-event.service > /dev/null 2>&1 || :
-fi
+#
+# We'd need systemd to call specific restart command (dmeventd -R) instead
+# of simple 'stop and start' - we need to keep any existing dmeventd
+# registrations. Also, we can't kill dmeventd with existing registrations
+# with SIGTERM, we would need to use SIGKILL instead (but losing registrations).
+#
+# if [ $1 -ge 1 ]; then
+# 	/bin/systemctl try-restart dm-event.service > /dev/null 2>&1 || :
+# fi
 %endif
 
 %files -n device-mapper-event
@@ -583,6 +593,10 @@ the device-mapper event library.
 /usr%{_libdir}/pkgconfig/devmapper-event.pc
 
 %changelog
+* Thu Jul 28 2011 Peter Rajnoha <prajnoha at redhat.com> - 2.02.86-4
+- Add support for systemd file descriptor handover to dmeventd.
+- Add support for new oom killer adjustment interface (oom_score_adj).
+
 * Wed Jul 20 2011 Peter Rajnoha <prajnoha at redhat.com> - 2.02.86-3
 - Fix broken lvm2-sysinit Requires: lvm2 dependency.
 


More information about the scm-commits mailing list