/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "clean-ipc.h"
+#include "core-varlink.h"
#include "dbus.h"
#include "fd-util.h"
#include "fileio.h"
#include "syslog-util.h"
#include "unit-serialize.h"
#include "user-util.h"
+#include "varlink-internal.h"
int manager_open_serialization(Manager *m, FILE **ret_f) {
_cleanup_close_ int fd = -1;
if (r < 0)
return r;
+ r = varlink_server_serialize(m->varlink_server, f, fds);
+ if (r < 0)
+ return r;
+
(void) fputc('\n', f);
HASHMAP_FOREACH_KEY(u, t, m->units) {
}
int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
+ bool deserialize_varlink_sockets = false;
int r = 0;
assert(m);
if (strv_extend(&m->deserialized_subscribed, val) < 0)
return -ENOMEM;
+ } else if ((val = startswith(l, "varlink-server-socket-address="))) {
+ if (!m->varlink_server && MANAGER_IS_SYSTEM(m)) {
+ _cleanup_(varlink_server_unrefp) VarlinkServer *s = NULL;
+
+ r = manager_setup_varlink_server(m, &s);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to setup varlink server, ignoring: %m");
+ continue;
+ }
+
+ r = varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to attach varlink connection to event loop, ignoring: %m");
+ continue;
+ }
+
+ m->varlink_server = TAKE_PTR(s);
+ deserialize_varlink_sockets = true;
+ }
+ /* To void unnecessary deserialization (i.e. during reload vs. reexec) we only deserialize
+ * the FDs if we had to create a new m->varlink_server. The deserialize_varlink_sockets flag
+ * is initialized outside of the loop, is flipped after the VarlinkServer is setup, and
+ * remains set until all serialized contents are handled. */
+ if (deserialize_varlink_sockets)
+ (void) varlink_server_deserialize_one(m->varlink_server, val, fds);
} else {
ManagerTimestamp q;
#include "list.h"
#include "process-util.h"
#include "selinux-util.h"
+#include "serialize.h"
#include "set.h"
#include "socket-util.h"
#include "string-table.h"
#include "umask-util.h"
#include "user-util.h"
#include "varlink.h"
+#include "varlink-internal.h"
#define VARLINK_DEFAULT_CONNECTIONS_MAX 4096U
#define VARLINK_DEFAULT_CONNECTIONS_PER_UID_MAX 1024U
return free_and_strdup(&s->description, description);
}
+
+int varlink_server_serialize(VarlinkServer *s, FILE *f, FDSet *fds) {
+ assert(f);
+ assert(fds);
+
+ if (!s)
+ return 0;
+
+ LIST_FOREACH(sockets, ss, s->sockets) {
+ int copy;
+
+ 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);
+ if (copy < 0)
+ return copy;
+
+ fprintf(f, " varlink-server-socket-fd=%i", copy);
+
+ fputc('\n', f);
+ }
+
+ return 0;
+}
+
+int varlink_server_deserialize_one(VarlinkServer *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 = -1;
+ char *buf;
+ size_t n;
+
+ assert(s);
+ assert(fds);
+
+ n = strcspn(v, " ");
+ address = strndup(v, n);
+ if (!address)
+ return log_oom_debug();
+
+ if (v[n] != ' ')
+ return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+ "Failed to deserialize VarlinkServerSocket: %s: %m", value);
+ v = startswith(v + n + 1, "varlink-server-socket-fd=");
+ if (!v)
+ return log_debug_errno(SYNTHETIC_ERRNO(EINVAL),
+ "Failed to deserialize VarlinkServerSocket fd %s: %m", value);
+
+ n = strcspn(v, " ");
+ buf = strndupa_safe(v, n);
+
+ r = safe_atoi(buf, &fd);
+ if (r < 0)
+ return log_debug_errno(r, "Unable to parse VarlinkServerSocket varlink-server-socket-fd=%s: %m", buf);
+
+ if (!fdset_contains(fds, fd))
+ return log_debug_errno(SYNTHETIC_ERRNO(EBADF),
+ "VarlinkServerSocket varlink-server-socket-fd= has unknown fd %d: %m", fd);
+
+ ss = new(VarlinkServerSocket, 1);
+ if (!ss)
+ return log_oom_debug();
+
+ *ss = (VarlinkServerSocket) {
+ .server = s,
+ .address = TAKE_PTR(address),
+ .fd = fdset_remove(fds, fd),
+ };
+
+ r = varlink_server_add_socket_event_source(s, ss, SD_EVENT_PRIORITY_NORMAL);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to add VarlinkServerSocket event source to the event loop: %m");
+
+ LIST_PREPEND(sockets, s->sockets, TAKE_PTR(ss));
+ return 0;
+}