diff mbox series

[v2,2/4] tools: Import standalone sd_notify() implementation from systemd

Message ID 20240516185804.3309725-3-andrew.cooper3@citrix.com (mailing list archive)
State New
Headers show
Series Drop libsystemd | expand

Commit Message

Andrew Cooper May 16, 2024, 6:58 p.m. UTC
... in order to avoid linking against the whole of libsystemd.

Only minimal changes to the upstream copy, to function as a drop-in
replacement for sd_notify() and as a header-only library.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Anthony PERARD <anthony@xenproject.org>
CC: Juergen Gross <jgross@suse.com>
CC: George Dunlap <George.Dunlap@citrix.com>
CC: Jan Beulich <JBeulich@suse.com>
CC: Stefano Stabellini <sstabellini@kernel.org>
CC: Julien Grall <julien@xen.org>
CC: Christian Lindig <christian.lindig@citrix.com>
CC: Edwin Török <edwin.torok@cloud.com>

v2:
 * New
---
 tools/include/xen-sd-notify.h | 98 +++++++++++++++++++++++++++++++++++
 1 file changed, 98 insertions(+)
 create mode 100644 tools/include/xen-sd-notify.h

Comments

Marek Marczykowski-Górecki May 16, 2024, 11:07 p.m. UTC | #1
On Thu, May 16, 2024 at 07:58:02PM +0100, Andrew Cooper wrote:
> ... in order to avoid linking against the whole of libsystemd.
> 
> Only minimal changes to the upstream copy, to function as a drop-in
> replacement for sd_notify() and as a header-only library.

Maybe add explicit link to the original source?

> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Anthony PERARD <anthony@xenproject.org>
> CC: Juergen Gross <jgross@suse.com>
> CC: George Dunlap <George.Dunlap@citrix.com>
> CC: Jan Beulich <JBeulich@suse.com>
> CC: Stefano Stabellini <sstabellini@kernel.org>
> CC: Julien Grall <julien@xen.org>
> CC: Christian Lindig <christian.lindig@citrix.com>
> CC: Edwin Török <edwin.torok@cloud.com>
> 
> v2:
>  * New
> ---
>  tools/include/xen-sd-notify.h | 98 +++++++++++++++++++++++++++++++++++
>  1 file changed, 98 insertions(+)
>  create mode 100644 tools/include/xen-sd-notify.h
> 
> diff --git a/tools/include/xen-sd-notify.h b/tools/include/xen-sd-notify.h
> new file mode 100644
> index 000000000000..eda9d8b22d9e
> --- /dev/null
> +++ b/tools/include/xen-sd-notify.h
> @@ -0,0 +1,98 @@

...

> +static inline void xen_sd_closep(int *fd) {

Static inline is one of the changes vs upstream, and gitlab-ci is not
happy about it:

/builds/xen-project/patchew/xen/tools/xenstored/../../tools/include/xen-sd-notify.h:45:3: error: cleanup argument not a function
   45 |   int __attribute__((cleanup(sd_closep))) fd = -1;
      |   ^~~
Andrew Cooper May 16, 2024, 11:09 p.m. UTC | #2
On 17/05/2024 12:07 am, Marek Marczykowski-Górecki wrote:
> On Thu, May 16, 2024 at 07:58:02PM +0100, Andrew Cooper wrote:
>> ... in order to avoid linking against the whole of libsystemd.
>>
>> Only minimal changes to the upstream copy, to function as a drop-in
>> replacement for sd_notify() and as a header-only library.
> Maybe add explicit link to the original source?

Well, it is in the top of the file...

> diff --git a/tools/include/xen-sd-notify.h
> b/tools/include/xen-sd-notify.h new file mode 100644 index
> 000000000000..eda9d8b22d9e --- /dev/null +++
> b/tools/include/xen-sd-notify.h @@ -0,0 +1,98 @@ +/*
> SPDX-License-Identifier: MIT-0 */ + +/* + * Implement the systemd
> notify protocol without external dependencies. + * Supports both
> readiness notification on startup and on reloading, + * according to
> the protocol defined at: + *
> https://www.freedesktop.org/software/systemd/man/latest/sd_notify.html+
> * This protocol is guaranteed to be stable as per: + *
> https://systemd.io/PORTABILITY_AND_STABILITY/+ *



>> +static inline void xen_sd_closep(int *fd) {
> Static inline is one of the changes vs upstream, and gitlab-ci is not
> happy about it:
>
> /builds/xen-project/patchew/xen/tools/xenstored/../../tools/include/xen-sd-notify.h:45:3: error: cleanup argument not a function
>    45 |   int __attribute__((cleanup(sd_closep))) fd = -1;
>       |   ^~~
>

Yes - victim of a last minute refactor.  I've fixed it up locally.

~Andrew
Jürgen Groß May 23, 2024, 8:21 a.m. UTC | #3
On 16.05.24 20:58, Andrew Cooper wrote:
> ... in order to avoid linking against the whole of libsystemd.
> 
> Only minimal changes to the upstream copy, to function as a drop-in
> replacement for sd_notify() and as a header-only library.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

With s/cleanup(sd_closep)/cleanup(xen_sd_closep)/

Reviewed-by: Juergen Gross <jgross@suse.com>


Juergen

> ---
> CC: Anthony PERARD <anthony@xenproject.org>
> CC: Juergen Gross <jgross@suse.com>
> CC: George Dunlap <George.Dunlap@citrix.com>
> CC: Jan Beulich <JBeulich@suse.com>
> CC: Stefano Stabellini <sstabellini@kernel.org>
> CC: Julien Grall <julien@xen.org>
> CC: Christian Lindig <christian.lindig@citrix.com>
> CC: Edwin Török <edwin.torok@cloud.com>
> 
> v2:
>   * New
> ---
>   tools/include/xen-sd-notify.h | 98 +++++++++++++++++++++++++++++++++++
>   1 file changed, 98 insertions(+)
>   create mode 100644 tools/include/xen-sd-notify.h
> 
> diff --git a/tools/include/xen-sd-notify.h b/tools/include/xen-sd-notify.h
> new file mode 100644
> index 000000000000..eda9d8b22d9e
> --- /dev/null
> +++ b/tools/include/xen-sd-notify.h
> @@ -0,0 +1,98 @@
> +/* SPDX-License-Identifier: MIT-0 */
> +
> +/*
> + * Implement the systemd notify protocol without external dependencies.
> + * Supports both readiness notification on startup and on reloading,
> + * according to the protocol defined at:
> + * https://www.freedesktop.org/software/systemd/man/latest/sd_notify.html
> + * This protocol is guaranteed to be stable as per:
> + * https://systemd.io/PORTABILITY_AND_STABILITY/
> + *
> + * Differences from the upstream copy:
> + * - Rename/rework as a drop-in replacement for systemd/sd-daemon.h
> + * - Only take the subset Xen cares about
> + * - Respect -Wdeclaration-after-statement
> + */
> +
> +#ifndef XEN_SD_NOTIFY
> +#define XEN_SD_NOTIFY
> +
> +#include <errno.h>
> +#include <stddef.h>
> +#include <stdlib.h>
> +#include <sys/socket.h>
> +#include <sys/un.h>
> +#include <unistd.h>
> +
> +static inline void xen_sd_closep(int *fd) {
> +  if (!fd || *fd < 0)
> +    return;
> +
> +  close(*fd);
> +  *fd = -1;
> +}
> +
> +static inline int xen_sd_notify(const char *message) {
> +  union sockaddr_union {
> +    struct sockaddr sa;
> +    struct sockaddr_un sun;
> +  } socket_addr = {
> +    .sun.sun_family = AF_UNIX,
> +  };
> +  size_t path_length, message_length;
> +  ssize_t written;
> +  const char *socket_path;
> +  int __attribute__((cleanup(sd_closep))) fd = -1;
> +
> +  /* Verify the argument first */
> +  if (!message)
> +    return -EINVAL;
> +
> +  message_length = strlen(message);
> +  if (message_length == 0)
> +    return -EINVAL;
> +
> +  /* If the variable is not set, the protocol is a noop */
> +  socket_path = getenv("NOTIFY_SOCKET");
> +  if (!socket_path)
> +    return 0; /* Not set? Nothing to do */
> +
> +  /* Only AF_UNIX is supported, with path or abstract sockets */
> +  if (socket_path[0] != '/' && socket_path[0] != '@')
> +    return -EAFNOSUPPORT;
> +
> +  path_length = strlen(socket_path);
> +  /* Ensure there is room for NUL byte */
> +  if (path_length >= sizeof(socket_addr.sun.sun_path))
> +    return -E2BIG;
> +
> +  memcpy(socket_addr.sun.sun_path, socket_path, path_length);
> +
> +  /* Support for abstract socket */
> +  if (socket_addr.sun.sun_path[0] == '@')
> +    socket_addr.sun.sun_path[0] = 0;
> +
> +  fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
> +  if (fd < 0)
> +    return -errno;
> +
> +  if (connect(fd, &socket_addr.sa, offsetof(struct sockaddr_un, sun_path) + path_length) != 0)
> +    return -errno;
> +
> +  written = write(fd, message, message_length);
> +  if (written != (ssize_t) message_length)
> +    return written < 0 ? -errno : -EPROTO;
> +
> +  return 1; /* Notified! */
> +}
> +
> +static inline int sd_notify(int unset_environment, const char *message) {
> +    int r = xen_sd_notify(message);
> +
> +    if (unset_environment)
> +        unsetenv("NOTIFY_SOCKET");
> +
> +    return r;
> +}
> +
> +#endif /* XEN_SD_NOTIFY */
diff mbox series

Patch

diff --git a/tools/include/xen-sd-notify.h b/tools/include/xen-sd-notify.h
new file mode 100644
index 000000000000..eda9d8b22d9e
--- /dev/null
+++ b/tools/include/xen-sd-notify.h
@@ -0,0 +1,98 @@ 
+/* SPDX-License-Identifier: MIT-0 */
+
+/*
+ * Implement the systemd notify protocol without external dependencies.
+ * Supports both readiness notification on startup and on reloading,
+ * according to the protocol defined at:
+ * https://www.freedesktop.org/software/systemd/man/latest/sd_notify.html
+ * This protocol is guaranteed to be stable as per:
+ * https://systemd.io/PORTABILITY_AND_STABILITY/
+ *
+ * Differences from the upstream copy:
+ * - Rename/rework as a drop-in replacement for systemd/sd-daemon.h
+ * - Only take the subset Xen cares about
+ * - Respect -Wdeclaration-after-statement
+ */
+
+#ifndef XEN_SD_NOTIFY
+#define XEN_SD_NOTIFY
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+static inline void xen_sd_closep(int *fd) {
+  if (!fd || *fd < 0)
+    return;
+
+  close(*fd);
+  *fd = -1;
+}
+
+static inline int xen_sd_notify(const char *message) {
+  union sockaddr_union {
+    struct sockaddr sa;
+    struct sockaddr_un sun;
+  } socket_addr = {
+    .sun.sun_family = AF_UNIX,
+  };
+  size_t path_length, message_length;
+  ssize_t written;
+  const char *socket_path;
+  int __attribute__((cleanup(sd_closep))) fd = -1;
+
+  /* Verify the argument first */
+  if (!message)
+    return -EINVAL;
+
+  message_length = strlen(message);
+  if (message_length == 0)
+    return -EINVAL;
+
+  /* If the variable is not set, the protocol is a noop */
+  socket_path = getenv("NOTIFY_SOCKET");
+  if (!socket_path)
+    return 0; /* Not set? Nothing to do */
+
+  /* Only AF_UNIX is supported, with path or abstract sockets */
+  if (socket_path[0] != '/' && socket_path[0] != '@')
+    return -EAFNOSUPPORT;
+
+  path_length = strlen(socket_path);
+  /* Ensure there is room for NUL byte */
+  if (path_length >= sizeof(socket_addr.sun.sun_path))
+    return -E2BIG;
+
+  memcpy(socket_addr.sun.sun_path, socket_path, path_length);
+
+  /* Support for abstract socket */
+  if (socket_addr.sun.sun_path[0] == '@')
+    socket_addr.sun.sun_path[0] = 0;
+
+  fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+  if (fd < 0)
+    return -errno;
+
+  if (connect(fd, &socket_addr.sa, offsetof(struct sockaddr_un, sun_path) + path_length) != 0)
+    return -errno;
+
+  written = write(fd, message, message_length);
+  if (written != (ssize_t) message_length)
+    return written < 0 ? -errno : -EPROTO;
+
+  return 1; /* Notified! */
+}
+
+static inline int sd_notify(int unset_environment, const char *message) {
+    int r = xen_sd_notify(message);
+
+    if (unset_environment)
+        unsetenv("NOTIFY_SOCKET");
+
+    return r;
+}
+
+#endif /* XEN_SD_NOTIFY */