Skip to content

Commit 7f78d34

Browse files
committed
sd-daemon: Add vsock fallback to SOCK_STREAM
SOCK_SEQPACKET is only supported on recent kernels. Let's add a fallback to SOCK_STREAM if it is not supported. To accomodate SOCK_STREAM, we also modify pid_notify_with_fds_internal() to do sendmsg() in a loop as with SOCK_STREAM, sendmsg() is not guaranteed to write all data in a single syscall or fail otherwise.
1 parent 56d02f2 commit 7f78d34

File tree

1 file changed

+29
-13
lines changed

1 file changed

+29
-13
lines changed

src/libsystemd/sd-daemon/sd-daemon.c

+29-13
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ static int pid_notify_with_fds_internal(
466466
struct cmsghdr *cmsg = NULL;
467467
const char *e;
468468
bool send_ucred;
469+
ssize_t n;
469470
int type, r;
470471

471472
if (!state)
@@ -502,6 +503,10 @@ static int pid_notify_with_fds_internal(
502503

503504
type = SOCK_SEQPACKET;
504505
fd = socket(address.sockaddr.sa.sa_family, type|SOCK_CLOEXEC, 0);
506+
if (fd < 0 && ERRNO_IS_NOT_SUPPORTED(errno)) {
507+
type = SOCK_STREAM;
508+
fd = socket(address.sockaddr.sa.sa_family, type|SOCK_CLOEXEC, 0);
509+
}
505510
if (fd < 0)
506511
return log_debug_errno(errno, "Failed to open %s socket to '%s': %m", socket_address_type_to_string(type), e);
507512
}
@@ -563,21 +568,32 @@ static int pid_notify_with_fds_internal(
563568
}
564569
}
565570

566-
/* First try with fake ucred data, as requested */
567-
if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) >= 0)
568-
return 1;
569-
570-
/* If that failed, try with our own ucred instead */
571-
if (send_ucred) {
572-
msghdr.msg_controllen -= CMSG_SPACE(sizeof(struct ucred));
573-
if (msghdr.msg_controllen == 0)
571+
do {
572+
/* First try with fake ucred data, as requested */
573+
n = sendmsg(fd, &msghdr, MSG_NOSIGNAL);
574+
if (n < 0) {
575+
if (!send_ucred)
576+
return log_debug_errno(errno, "Failed to send notify message to '%s': %m", e);
577+
578+
/* If that failed, try with our own ucred instead */
579+
msghdr.msg_controllen -= CMSG_SPACE(sizeof(struct ucred));
580+
if (msghdr.msg_controllen == 0)
581+
msghdr.msg_control = NULL;
582+
583+
n = 0;
584+
send_ucred = false;
585+
} else {
586+
/* Unless we're using SOCK_STREAM, we expect to write all the contents immediately. */
587+
if (type != SOCK_STREAM && (size_t) n < IOVEC_TOTAL_SIZE(msghdr.msg_iov, msghdr.msg_iovlen))
588+
return -EIO;
589+
590+
/* Make sure we only send fds and ucred once, even if we're using SOCK_STREAM. */
574591
msghdr.msg_control = NULL;
592+
msghdr.msg_controllen = 0;
593+
}
594+
} while (!IOVEC_INCREMENT(msghdr.msg_iov, msghdr.msg_iovlen, n));
575595

576-
if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) >= 0)
577-
return 1;
578-
}
579-
580-
return log_debug_errno(errno, "Failed to send notify message to '%s': %m", e);
596+
return 1;
581597
}
582598

583599
_public_ int sd_pid_notify_with_fds(

0 commit comments

Comments
 (0)