[PATCH v3 06/10] multipathd: allow receiving two socket fds from systemd

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add another ListenStream directive in multipathd.socket for a Unix pathname
socket. In multipathd, read both socket fds from systemd, and open both
when they are defined.

Signed-off-by: Martin Wilck <mwilck@xxxxxxxx>
---
 Makefile.inc                    |  4 +++-
 multipathd/main.c               | 18 ++++++++++++------
 multipathd/multipathd.socket.in |  3 ++-
 multipathd/uxlsnr.c             | 33 ++++++++++++++++++++++-----------
 4 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/Makefile.inc b/Makefile.inc
index 4015006..d0fecc3 100644
--- a/Makefile.inc
+++ b/Makefile.inc
@@ -80,6 +80,7 @@ kernel_incdir	:= /usr/include
 sysdir_bin      := $(sys_execprefix)bin
 
 abstract_socket := @/org/kernel/linux/storage/multipathd
+pathname_socket := /run/multipathd.socket
 
 ifeq ($(V),)
 Q		:= @
@@ -172,5 +173,6 @@ NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version)
 		-e 's:@SYSDIR_BIN@:'$(sysdir_bin)': g' \
 		-e 's:@RUNTIME_DIR@:'$(runtimedir)':g' \
 		-e 's/@MODPROBE_UNIT@/'$(MODPROBE_UNIT)'/g' \
-		-e 's,@MPATH_SOCKET@,'$(abstract_socket)',g' \
+		-e 's,@ABSTRACT_SOCKET@,'$(abstract_socket)',g' \
+		-e 's,@PATHNAME_SOCKET@,'$(pathname_socket)',g' \
 		$< >$@
diff --git a/multipathd/main.c b/multipathd/main.c
index 602215c..ac204b2 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1869,9 +1869,13 @@ static int get_systemd_sockets(long *ux_sock)
 {
 	int num = sd_listen_fds(0);
 
-	if (num > 1) {
+	if (num > 2) {
 		condlog(3, "sd_listen_fds returned %d fds", num);
 		return -1;
+	} else if (num == 2) {
+		ux_sock[0] = SD_LISTEN_FDS_START + 0;
+		ux_sock[1] = SD_LISTEN_FDS_START + 1;
+		condlog(3, "using fd %ld and %ld from sd_listen_fds", ux_sock[0], ux_sock[1]);
 	} else if (num == 1) {
 		ux_sock[0] = SD_LISTEN_FDS_START + 0;
 		condlog(3, "using fd %ld from sd_listen_fds", ux_sock[0]);
@@ -1889,16 +1893,18 @@ static int get_systemd_sockets(long *ux_sock __attribute__((unused)))
 static void *
 uxlsnrloop (void * ap)
 {
-	long ux_sock;
+	long ux_sock[2] = {-1, -1};
 	int num;
 
 	pthread_cleanup_push(rcu_unregister, NULL);
 	rcu_register_thread();
 
 	num = get_systemd_sockets(&ux_sock);
-	if (num < 1)
-		ux_sock = ux_socket_listen(DEFAULT_SOCKET);
-	if (ux_sock == -1) {
+	if (num < 1) {
+		ux_sock[0] = ux_socket_listen(DEFAULT_SOCKET);
+		num = 1;
+	}
+	if (ux_sock[0] == -1) {
 		condlog(1, "could not create uxsock: %d", errno);
 		exit_daemon();
 		goto out;
@@ -1924,7 +1930,7 @@ uxlsnrloop (void * ap)
 	       == DAEMON_CONFIGURE)
 		handle_signals(false);
 
-	uxsock_listen(1, &ux_sock, ap);
+	uxsock_listen(num, ux_sock, ap);
 
 out_sock:
 	pthread_cleanup_pop(1); /* uxsock_cleanup */
diff --git a/multipathd/multipathd.socket.in b/multipathd/multipathd.socket.in
index c0e86c3..11002fc 100644
--- a/multipathd/multipathd.socket.in
+++ b/multipathd/multipathd.socket.in
@@ -7,7 +7,8 @@ ConditionVirtualization=!container
 Before=sockets.target
 
 [Socket]
-ListenStream=@MPATH_SOCKET@
+ListenStream=@ABSTRACT_SOCKET@
+ListenStream=@PATHNAME_SOCKET@
 
 [Install]
 # Socket activation for multipathd is disabled by default.
diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c
index 79e28e4..aa6aae7 100644
--- a/multipathd/uxlsnr.c
+++ b/multipathd/uxlsnr.c
@@ -69,7 +69,8 @@ struct client {
 
 /* Indices for array of poll fds */
 enum {
-	POLLFD_UX = 0,
+	POLLFD_UX1 = 0,
+	POLLFD_UX2,
 	POLLFD_NOTIFY,
 	POLLFD_IDLE,
 	POLLFDS_BASE,
@@ -164,9 +165,10 @@ void uxsock_cleanup(void *arg)
 {
 	struct client *client_loop;
 	struct client *client_tmp;
-	long ux_sock = (long)arg;
+	long *ux_sock = (long *)arg;
 
-	close(ux_sock);
+	close(ux_sock[0]);
+	close(ux_sock[1]);
 	close(notify_fd);
 
 	list_for_each_entry_safe(client_loop, client_tmp, &clients, node) {
@@ -614,20 +616,24 @@ static void handle_client(struct client *c, struct vectors *vecs, short revents)
 /*
  * entry point
  */
-void *uxsock_listen(int n_socks, long *ux_sock, void *trigger_data)
+void *uxsock_listen(int n_socks, long *ux_sock_in, void *trigger_data)
 {
 	sigset_t mask;
 	int max_pfds = MIN_POLLS + POLLFDS_BASE;
+	long ux_sock[2] = {-1, -1};
 	/* conf->sequence_nr will be 1 when uxsock_listen is first called */
 	unsigned int sequence_nr = 0;
 	struct watch_descriptors wds = { .conf_wd = -1, .dir_wd = -1, .mp_wd = -1, };
 	struct vectors *vecs = trigger_data;
 
-	if (n_socks != 1) {
-		condlog(0, "uxsock: no socket fds");
+	if (n_socks < 1 || n_socks > 2) {
+		condlog(0, "uxsock: unsupported number of socket fds");
 		exit_daemon();
 		return NULL;
-	}
+	} else if (n_socks == 2)
+		ux_sock[1] = ux_sock_in[1];
+	ux_sock[0] = ux_sock_in[0];
+
 	condlog(3, "uxsock: startup listener");
 	polls = calloc(1, max_pfds * sizeof(*polls));
 	if (!polls) {
@@ -678,8 +684,10 @@ void *uxsock_listen(int n_socks, long *ux_sock, void *trigger_data)
 			}
 		}
 		if (num_clients < MAX_CLIENTS) {
-			polls[POLLFD_UX].fd = ux_sock[0];
-			polls[POLLFD_UX].events = POLLIN;
+			polls[POLLFD_UX1].fd = ux_sock[0];
+			polls[POLLFD_UX1].events = POLLIN;
+			polls[POLLFD_UX2].fd = ux_sock[1];
+			polls[POLLFD_UX2].events = POLLIN;
 		} else {
 			/*
 			 * New clients can't connect, num_clients won't grow
@@ -687,7 +695,7 @@ void *uxsock_listen(int n_socks, long *ux_sock, void *trigger_data)
 			 */
 			condlog(1, "%s: max client connections reached, pausing polling",
 				__func__);
-			polls[POLLFD_UX].fd = -1;
+			polls[POLLFD_UX1].fd = polls[POLLFD_UX2].fd = -1;
 		}
 
 		reset_watch(notify_fd, &wds, &sequence_nr);
@@ -771,9 +779,12 @@ void *uxsock_listen(int n_socks, long *ux_sock, void *trigger_data)
 		handle_signals(true);
 
 		/* see if we got a new client */
-		if (polls[POLLFD_UX].revents & POLLIN) {
+		if (polls[POLLFD_UX1].revents & POLLIN) {
 			new_client(ux_sock[0]);
 		}
+		if (polls[POLLFD_UX2].revents & POLLIN) {
+			new_client(ux_sock[1]);
+		}
 
 		/* handle inotify events on config files */
 		if (polls[POLLFD_NOTIFY].revents & POLLIN)
-- 
2.48.1





[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux