@@ -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' \
$< >$@
@@ -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 */
@@ -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.
@@ -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)
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@suse.com> --- Makefile.inc | 4 +++- multipathd/main.c | 18 ++++++++++++------ multipathd/multipathd.socket.in | 3 ++- multipathd/uxlsnr.c | 33 ++++++++++++++++++++++----------- 4 files changed, 39 insertions(+), 19 deletions(-)