core: serialize metrics varlink server as well

This commit is contained in:
Mike Yuan
2026-02-13 20:22:13 +01:00
parent 5561623ef4
commit 389cd296ec
3 changed files with 52 additions and 40 deletions

View 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;

View 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);
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
"Invalid varlink server serialization entry: %s", value);
n = strcspn(v, " ");
buf = strndupa_safe(v, n);
fd = parse_fd(buf);
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))
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),
"VarlinkServerSocket varlink-server-socket-fd= has unknown fd: %d", fd);
"Got varlink serialization without socket fd, refusing.");
fd = deserialize_fd(fds, v);
if (fd < 0)
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;
}

View 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);