]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: serialize metrics varlink server as well 40687/head
authorMike Yuan <me@yhndnzj.com>
Fri, 13 Feb 2026 19:22:13 +0000 (20:22 +0100)
committerMike Yuan <me@yhndnzj.com>
Mon, 16 Feb 2026 08:44:58 +0000 (09:44 +0100)
src/core/manager-serialize.c
src/shared/varlink-serialize.c
src/shared/varlink-serialize.h

index f40df69764f5d387f7f02412dd42f387582cc5ac..2357b9277c616ceab5170ee3f56a74b5cc5477c2 100644 (file)
@@ -171,7 +171,11 @@ int manager_serialize(
         if (r < 0)
                 return r;
 
-        r = varlink_server_serialize(m->varlink_server, f, fds);
+        r = varlink_server_serialize(m->varlink_server, /* name = */ NULL, f, fds);
+        if (r < 0)
+                return r;
+
+        r = varlink_server_serialize(m->metrics_varlink_server, "metrics", f, fds);
         if (r < 0)
                 return r;
 
@@ -489,7 +493,18 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                         r = strv_extend(&m->subscribed_as_strv, val);
                         if (r < 0)
                                 return r;
-                } else if ((val = startswith(l, "varlink-server-socket-address="))) {
+                } else if ((val = startswith(l, "varlink-server-metrics-"))) {
+                        if (m->objective == MANAGER_RELOAD)
+                                /* We don't destroy varlink server on daemon-reload (in contrast to reexec) -> skip! */
+                                continue;
+
+                        r = manager_setup_varlink_metrics_server(m);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to setup metrics varlink server, ignoring: %m");
+                        else
+                                (void) varlink_server_deserialize_one(m->metrics_varlink_server, val, fds);
+
+                } else if ((val = startswith(l, "varlink-server-"))) {
                         if (m->objective == MANAGER_RELOAD)
                                 /* We don't destroy varlink server on daemon-reload (in contrast to reexec) -> skip! */
                                 continue;
index d9199f286959010929e59c5c824dc22819df4028..7ea8ca7552fb02964da389bf0ab780f88ce10a43 100644 (file)
@@ -1,78 +1,73 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include "sd-event.h"
-
 #include "alloc-util.h"
+#include "extract-word.h"
+#include "fd-util.h"
 #include "fdset.h"
 #include "log.h"
-#include "parse-util.h"
+#include "serialize.h"
 #include "socket-util.h"
 #include "string-util.h"
 #include "varlink-internal.h"
 #include "varlink-serialize.h"
 
-int varlink_server_serialize(sd_varlink_server *s, FILE *f, FDSet *fds) {
+int varlink_server_serialize(sd_varlink_server *s, const char *name, FILE *f, FDSet *fds) {
         assert(f);
         assert(fds);
 
         if (!s)
                 return 0;
 
-        LIST_FOREACH(sockets, ss, s->sockets) {
-                int copy;
+        const char *prefix = name ? strjoina("varlink-server-", name) : "varlink-server";
 
+        LIST_FOREACH(sockets, ss, s->sockets) {
                 assert(ss->address);
                 assert(ss->fd >= 0);
 
-                fprintf(f, "varlink-server-socket-address=%s", ss->address);
-
                 /* If we fail to serialize the fd, it will be considered an error during deserialization */
-                copy = fdset_put_dup(fds, ss->fd);
+                int copy = fdset_put_dup(fds, ss->fd);
                 if (copy < 0)
                         return copy;
 
-                fprintf(f, " varlink-server-socket-fd=%i", copy);
-
-                fputc('\n', f);
+                fprintf(f, "%s-socket-address=%s varlink-server-socket-fd=%d\n", prefix, ss->address, copy);
         }
 
         return 0;
 }
 
 int varlink_server_deserialize_one(sd_varlink_server *s, const char *value, FDSet *fds) {
-        _cleanup_(varlink_server_socket_freep) VarlinkServerSocket *ss = NULL;
         _cleanup_free_ char *address = NULL;
-        const char *v = ASSERT_PTR(value);
-        int r, fd = -EBADF;
-        char *buf;
-        size_t n;
+        _cleanup_close_ int fd = -EBADF;
+        const char *v;
+        int r;
+
+        /* This function expects a serialization line with "varlink-server(-name)-" prefix stripped! */
 
         assert(s);
+        assert(value);
         assert(fds);
 
-        n = strcspn(v, " ");
-        address = strndup(v, n);
-        if (!address)
-                return log_oom_debug();
-
-        if (v[n] != ' ')
-                return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EINVAL),
-                                       "Failed to deserialize sd_varlink_server_socket: %s", value);
-        v = startswith(v + n + 1, "varlink-server-socket-fd=");
+        v = startswith(value, "socket-address=");
         if (!v)
-                return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EINVAL),
-                                       "Failed to deserialize VarlinkServerSocket fd: %s", value);
-
-        n = strcspn(v, " ");
-        buf = strndupa_safe(v, n);
+                return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "Invalid varlink server serialization entry: %s", value);
+
+        r = extract_first_word(&v, &address, " ", /* flags = */ 0);
+        if (r <= 0)
+                return varlink_server_log_errno(s, r < 0 ? r : SYNTHETIC_ERRNO(ENODATA),
+                                                "Failed to extract socket address from varlink serialization: %s", value);
+        if (v)
+                v = startswith(v, "varlink-server-socket-fd=");
+        if (!v)
+                return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EBADF),
+                                                "Got varlink serialization without socket fd, refusing.");
 
-        fd = parse_fd(buf);
+        fd = deserialize_fd(fds, v);
         if (fd < 0)
-                return varlink_server_log_errno(s, fd, "Unable to parse VarlinkServerSocket varlink-server-socket-fd=%s: %m", buf);
-        if (!fdset_contains(fds, fd))
-                return varlink_server_log_errno(s, SYNTHETIC_ERRNO(EBADF),
-                                       "VarlinkServerSocket varlink-server-socket-fd= has unknown fd: %d", fd);
+                return varlink_server_log_errno(s, fd, "Failed to deserialize varlink socket fd: %m");
 
+        /* NB: varlink_server_socket_free() does not close the fd! */
+        _cleanup_(varlink_server_socket_freep) VarlinkServerSocket *ss = NULL;
         ss = new(VarlinkServerSocket, 1);
         if (!ss)
                 return log_oom_debug();
@@ -80,7 +75,7 @@ int varlink_server_deserialize_one(sd_varlink_server *s, const char *value, FDSe
         *ss = (VarlinkServerSocket) {
                 .server = s,
                 .address = TAKE_PTR(address),
-                .fd = fdset_remove(fds, fd),
+                .fd = fd,
         };
 
         r = varlink_server_add_socket_event_source(s, ss);
@@ -88,6 +83,8 @@ int varlink_server_deserialize_one(sd_varlink_server *s, const char *value, FDSe
                 return varlink_server_log_errno(s, r, "Failed to add VarlinkServerSocket event source to the event loop: %m");
 
         LIST_PREPEND(sockets, s->sockets, TAKE_PTR(ss));
+        TAKE_FD(fd); /* ownership is now transferred to varlink server */
+
         return 0;
 }
 
index db5de5216145ffa2b6fb09c0019efe546e2597d4..99bf046f0447f2e8f11cf5bbbecf31cc795b86f9 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "shared-forward.h"
 
-int varlink_server_serialize(sd_varlink_server *s, FILE *f, FDSet *fds);
+int varlink_server_serialize(sd_varlink_server *s, const char *name, FILE *f, FDSet *fds);
 int varlink_server_deserialize_one(sd_varlink_server *s, const char *value, FDSet *fds);
 
 bool varlink_server_contains_socket(sd_varlink_server *s, const char *address);