From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from atuin.qyliss.net (localhost [IPv6:::1]) by atuin.qyliss.net (Postfix) with ESMTP id 5E6D261FB; Sun, 28 Sep 2025 23:25:21 +0000 (UTC) Received: by atuin.qyliss.net (Postfix, from userid 993) id 65145628D; Sun, 28 Sep 2025 23:25:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on atuin.qyliss.net X-Spam-Level: X-Spam-Status: No, score=-0.1 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DMARC_PASS,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 Received: from mail-yw1-x112f.google.com (mail-yw1-x112f.google.com [IPv6:2607:f8b0:4864:20::112f]) by atuin.qyliss.net (Postfix) with ESMTPS id 458AA62FB for ; Sun, 28 Sep 2025 23:25:17 +0000 (UTC) Received: by mail-yw1-x112f.google.com with SMTP id 00721157ae682-723ad237d1eso42190897b3.1 for ; Sun, 28 Sep 2025 16:25:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1759101916; x=1759706716; darn=spectrum-os.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=RSNSFXApTkD5/0oiqKfWipgrPYRGVimshmt1M75vrP0=; b=UccrLTtHIneT9Nluhmg2vZlGKquuO0DiyBq9CMOEPtfoqqssttrIHVCze3QSMxHmWg kzqvU13rmw3JK3AMbwS73mViW2HC8A6HJrs2s3L3iCwKE7Oz5VEFm4BqlCE3dHv35jgd RNJuMxpDUL4+2zacnYEnfI/QdXJ0ptUvND+r2kg9h3aJk8xHWVczvlILllJJqQcdxbsC fkEB+AQLTDsyKQw3V3mhf90HzGanFiaQKQVn2tL+rwDY35xaOp98WzEMDIm57goXwiHZ ScQqZ1OWuESGsMuGvLfLSNengyeWQ5k9uLpTw+4XjtgucxWGb7D3qO/tsD3iYbSruQA4 cPUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759101916; x=1759706716; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RSNSFXApTkD5/0oiqKfWipgrPYRGVimshmt1M75vrP0=; b=f2mkg+rH7XqXVxSxGoG2x97ltPdXaVPVLm3ZPE8kA+9VH2MWO35oyjtQQ4R8wOtgSw wMRTOOcf7HskHHHzbxK82Kpw0v6kEkv2bZXzsXCFSBOM6RzxalZxRpCbeJhL3cYhpvn5 9Hc2Fr2jxvnlqbIyHY0QgoNOo5MaxQCpe6B5yfJreSauclKa/TM3xCGsKqU0EzljHk9h bQWH0+RQ6UIC1ONAh2nMCPr7an3BYaOCDDeirF9hn+bLc1FndrnDEQhKR/46LSP3R2qF Wwwbqs2a9TLExZzx2ZIaEJ8lbgG54z/y+FWm7KoGthM4msRtEbfWLmmaPs8903BfeXZF Ftng== X-Gm-Message-State: AOJu0YzyfkxVH01nsizhcp798wWPZYKPgoi0vXlJ8/Pg2XUVOgclKr3z aATdDnp3Hz2Yty1Sv2OF7pZAOLJDRwRinchJwd5TFkyQ42AwGVsp5tAHNNA2AQ== X-Gm-Gg: ASbGnctY2Wl/PdysTvVQ5cS4h9duzB0Ve58mqkUg65KJJPjJJ/QCUM/zIs2v6SXj1AW A9OWc8k3rkPQlkuXo6TViCbFfkY3d7wMvxNakC/UL8UekMmyR34+cNfTt9PlI0GDAkBeQOUzv0q /143lMS51amKKsqTNw8KhPWlF9cNx1z93fvKAE0dlhn7BRiu860Fs5NPt5gGjnYtx/kCIEn1NLh bptdyf7eUSbPqtshihnYwtekK9pBcCNPl2bZXGSkm2nlHCNIfyVNT7dQ3b4CUXb1q5B2WiCrtbC QMlVEi3XBDkK4myqj+l4aD67RTACtZ/dQXj7vBbi5Rb5v0ck816CAK8gR37CbCY59M0VaNg89qq T4AZjasme/QQe1bBQzdX/qY4zqrVhKYO9MsxlLfy9FqP+YeB4kBJQOa6YUPc5c2WnaKnPkLNGCV f8ekXpwnd8D8DLQn1p8C13R8pdbcFfD4IkM36tnTJDvRU= X-Google-Smtp-Source: AGHT+IEAfmJDhLq/9Hxsx54rcz3pOnb5HbvxQACgLi7EL2Yi75LviJt3jb2/3DFI3LKGd24T5S/X/w== X-Received: by 2002:a05:690e:1505:b0:62c:aa66:973e with SMTP id 956f58d0204a3-6361a74cb0emr18566805d50.5.1759101915817; Sun, 28 Sep 2025 16:25:15 -0700 (PDT) Received: from localhost.localdomain (h96-60-249-169.cncrtn.broadband.dynamic.tds.net. [96.60.249.169]) by smtp.gmail.com with UTF8SMTPSA id 3f1490d57ef6-eb38375ee8bsm2990947276.0.2025.09.28.16.25.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Sep 2025 16:25:14 -0700 (PDT) From: Demi Marie Obenour Date: Sun, 28 Sep 2025 18:51:47 -0400 Subject: [PATCH v3 1/2] tools: Add adapter tool for services using sd_notify MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20250928-udev-v3-1-bb0e9612c415@gmail.com> References: <20250928-udev-v3-0-bb0e9612c415@gmail.com> In-Reply-To: <20250928-udev-v3-0-bb0e9612c415@gmail.com> To: Spectrum OS Development X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1759099907; l=5896; i=demiobenour@gmail.com; s=20250729; h=from:subject:message-id; bh=phonv+GI56jR1uy/N3/FgOZ7m3ovJ5y4U6zh4m8vOic=; b=kJlcFGJIS6zeRrRCJFtH7ABDgRfHXfmm0XNYThd8ncN7WVn/Koin79r7kkcszZF+jqd/SSZ3w Ptm3MtF/mhbCVABo4PG/Kwu97Wc9cwheYGKY7c34SwWApugJDCQbBsu X-Developer-Key: i=demiobenour@gmail.com; a=ed25519; pk=X57Q4/YQDj9t4SBeKaDwvXYKB6quZJVx/DE2Ly2out0= Message-ID-Hash: H22VVJVMFOR5O2XES6RMNTOWOHZ7XYU2 X-Message-ID-Hash: H22VVJVMFOR5O2XES6RMNTOWOHZ7XYU2 X-MailFrom: demiobenour@gmail.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-devel.spectrum-os.org-0; header-match-devel.spectrum-os.org-1; header-match-devel.spectrum-os.org-2; header-match-devel.spectrum-os.org-3; header-match-devel.spectrum-os.org-4; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Demi Marie Obenour , Alyssa Ross X-Mailman-Version: 3.3.9 Precedence: list List-Id: Patches and low-level development discussion Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: This adapts programs using sd_notify for use with s6 readiness notification. stdin and stdout are hard-coded for simplicity. Signed-off-by: Demi Marie Obenour --- systemd readiness notification has two strict advantages over the s6 version: 1. It allows reliable reloading. 2. It allows providing a status message that the service manager can show in status output. s6 would actually benefit from both of these features. --- Changes since v1: - Hard-code file descriptors. - Run wrapper as background process. - Massively reduce code size. - Use // instead of /* */ for comments. - Check that the notification FD is a pipe and that the listening socket is a socket. - Rely on s6-ipc-socketbinder to create the listening socket. - Do not unlink the listening socket. --- tools/default.nix | 1 + tools/meson.build | 1 + tools/sd-notify-adapter/meson.build | 4 + tools/sd-notify-adapter/sd-notify-adapter.c | 127 ++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+) diff --git a/tools/default.nix b/tools/default.nix index f1157f0072f58c2ad9e741ca60bab2ed6507b72d..3634ef8ee892697b1bc7fff259eaccd54fddcd2f 100644 --- a/tools/default.nix +++ b/tools/default.nix @@ -74,6 +74,7 @@ stdenv.mkDerivation (finalAttrs: { ./lsvm ./start-vmm ./subprojects + ./sd-notify-adapter ] ++ lib.optionals driverSupport [ ./xdp-forwarder ])); diff --git a/tools/meson.build b/tools/meson.build index 17b4c16c07c9c6847306c47fbb7fe54f5a6e8cc5..d679afa64966d7b237f332096281a9bc9ef76e94 100644 --- a/tools/meson.build +++ b/tools/meson.build @@ -23,6 +23,7 @@ if get_option('host') subdir('lsvm') subdir('start-vmm') + subdir('sd-notify-adapter') endif if get_option('app') diff --git a/tools/sd-notify-adapter/meson.build b/tools/sd-notify-adapter/meson.build new file mode 100644 index 0000000000000000000000000000000000000000..6032a3a7704d49cae0655b43d0189444d3b15e4d --- /dev/null +++ b/tools/sd-notify-adapter/meson.build @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: ISC +# SPDX-FileCopyrightText: 2025 Demi Marie Obenour + +executable('sd-notify-adapter', 'sd-notify-adapter.c', install: true) diff --git a/tools/sd-notify-adapter/sd-notify-adapter.c b/tools/sd-notify-adapter/sd-notify-adapter.c new file mode 100644 index 0000000000000000000000000000000000000000..2767dea30b8db69986d9c2a02d6be28d205b3b4b --- /dev/null +++ b/tools/sd-notify-adapter/sd-notify-adapter.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: MIT +// SPDX-FileCopyrightText: 2025 Demi Marie Obenour + +#define _GNU_SOURCE 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ARRAY_SIZE(s) (sizeof(s)/sizeof(s[0])) + +static bool ready; + +enum { + socket_fd, + notification_fd, +}; + +#define READY "READY=1" +#define READY_SIZE (sizeof(READY) - 1) + +static void +process_notification(struct iovec *const msg) { + ssize_t data = recv(socket_fd, msg->iov_base, msg->iov_len, + MSG_DONTWAIT | MSG_TRUNC | MSG_PEEK); + if (data == -1) { + if (errno == EINTR) { + return; // signal caught + } + if (errno == EAGAIN || errno == EWOULDBLOCK) { + return; // spurious wakeup + } + err(EX_OSERR, "recv from notification socket"); + } + assert(data >= 0 && data <= INT_MAX); + size_t size = (size_t)data; + if (size == 0) + return; // avoid arithmetic on NULL pointer + if (size > msg->iov_len) { + char *b = (size == 0 ? malloc(size) : realloc(msg->iov_base, size)); + if (b == NULL) { + err(EX_OSERR, "allocation failure"); + } + msg->iov_base = b; + msg->iov_len = size; + } + data = recv(socket_fd, msg->iov_base, msg->iov_len, + MSG_CMSG_CLOEXEC | MSG_DONTWAIT | MSG_TRUNC); + if (data < 0) { + if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) + return; + err(EX_OSERR, "recv from notification socket"); + } + for (char *next, *cursor = msg->iov_base, *end = cursor + size; + cursor != NULL; cursor = (next == NULL ? NULL : next + 1)) { + next = memchr(cursor, '\n', (size_t)(end - cursor)); + size_t message_size = (size_t)((next == NULL ? end : next) - cursor); + if (message_size == READY_SIZE && + memcmp(cursor, READY, READY_SIZE) == 0) { + data = write(notification_fd, "\n", 1); + if (data != 1) { + err(EX_OSERR, "writing to notification descriptor"); + } + exit(0); + } + } +} + +int main(int argc, char **argv [[gnu::unused]]) { + if (argc != 1) { + errx(EX_USAGE, "stdin is listening socket, stdout is notification pipe"); + } + // Main event loop. + struct iovec v = { + .iov_base = NULL, + .iov_len = 0, + }; + for (;;) { + struct pollfd p[] = { + { + .fd = socket_fd, + .events = POLLIN, + .revents = 0, + }, + { + .fd = notification_fd, + .events = 0, + .revents = 0, + }, + }; + int r = poll(p, 2, -1); + if (r < 0) { + if (errno == EINTR) + continue; + err(EX_OSERR, "poll"); + } + if (p[0].revents) { + if (p[0].revents & POLLERR) + errx(EX_OSERR, "unexpected POLLERR"); + if (p[0].revents & POLLIN) + process_notification(&v); + break; + } + if (p[1].revents) { + if (ready) { + // Normal exit + return 0; + } + errx(EX_PROTOCOL, "s6 closed its pipe before the child was ready"); + } + } +} -- 2.51.0