From 389cd296ecad9969df46063604197c19bb3f7620 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Fri, 13 Feb 2026 20:22:13 +0100 Subject: [PATCH] core: serialize metrics varlink server as well --- src/core/manager-serialize.c | 19 ++++++++- src/shared/varlink-serialize.c | 71 ++++++++++++++++------------------ src/shared/varlink-serialize.h | 2 +- 3 files changed, 52 insertions(+), 40 deletions(-) diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c index f40df69764f..2357b9277c6 100644 --- a/src/core/manager-serialize.c +++ b/src/core/manager-serialize.c @@ -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; diff --git a/src/shared/varlink-serialize.c b/src/shared/varlink-serialize.c index d9199f28695..7ea8ca7552f 100644 --- a/src/shared/varlink-serialize.c +++ b/src/shared/varlink-serialize.c @@ -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; } diff --git a/src/shared/varlink-serialize.h b/src/shared/varlink-serialize.h index db5de521614..99bf046f044 100644 --- a/src/shared/varlink-serialize.h +++ b/src/shared/varlink-serialize.h @@ -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); -- 2.47.3