]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: split out manager-serialize.[ch]
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 2 Jul 2021 13:53:38 +0000 (15:53 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 19 Jul 2021 09:27:11 +0000 (11:27 +0200)
The file is super long, so let's split this out one subject to a new file.

src/core/main.c
src/core/manager-serialize.c [new file with mode: 0644]
src/core/manager-serialize.h [new file with mode: 0644]
src/core/manager.c
src/core/manager.h
src/core/meson.build

index 72d7c6b1165c3944191300f997bb775caa0bc64e..57d4f033dd49e556d749447cdad707e7e8cc6887 100644 (file)
@@ -55,6 +55,7 @@
 #include "machine-id-setup.h"
 #include "manager.h"
 #include "manager-dump.h"
+#include "manager-serialize.h"
 #include "mkdir.h"
 #include "mount-setup.h"
 #include "os-util.h"
diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c
new file mode 100644 (file)
index 0000000..60a35f4
--- /dev/null
@@ -0,0 +1,536 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "clean-ipc.h"
+#include "dbus.h"
+#include "fd-util.h"
+#include "fileio.h"
+#include "format-util.h"
+#include "macro.h"
+#include "manager-serialize.h"
+#include "manager.h"
+#include "parse-util.h"
+#include "serialize.h"
+#include "syslog-util.h"
+#include "unit-serialize.h"
+#include "user-util.h"
+
+int manager_open_serialization(Manager *m, FILE **ret_f) {
+        _cleanup_close_ int fd = -1;
+        FILE *f;
+
+        assert(ret_f);
+
+        fd = open_serialization_fd("systemd-state");
+        if (fd < 0)
+                return fd;
+
+        f = take_fdopen(&fd, "w+");
+        if (!f)
+                return -errno;
+
+        *ret_f = f;
+        return 0;
+}
+
+static bool manager_timestamp_shall_serialize(ManagerTimestamp t) {
+        if (!in_initrd())
+                return true;
+
+        /* The following timestamps only apply to the host system, hence only serialize them there */
+        return !IN_SET(t,
+                       MANAGER_TIMESTAMP_USERSPACE, MANAGER_TIMESTAMP_FINISH,
+                       MANAGER_TIMESTAMP_SECURITY_START, MANAGER_TIMESTAMP_SECURITY_FINISH,
+                       MANAGER_TIMESTAMP_GENERATORS_START, MANAGER_TIMESTAMP_GENERATORS_FINISH,
+                       MANAGER_TIMESTAMP_UNITS_LOAD_START, MANAGER_TIMESTAMP_UNITS_LOAD_FINISH);
+}
+
+static void manager_serialize_uid_refs_internal(
+                FILE *f,
+                Hashmap *uid_refs,
+                const char *field_name) {
+
+        void *p, *k;
+
+        assert(f);
+        assert(field_name);
+
+        /* Serialize the UID reference table. Or actually, just the IPC destruction flag of it, as
+         * the actual counter of it is better rebuild after a reload/reexec. */
+
+        HASHMAP_FOREACH_KEY(p, k, uid_refs) {
+                uint32_t c;
+                uid_t uid;
+
+                uid = PTR_TO_UID(k);
+                c = PTR_TO_UINT32(p);
+
+                if (!(c & DESTROY_IPC_FLAG))
+                        continue;
+
+                (void) serialize_item_format(f, field_name, UID_FMT, uid);
+        }
+}
+
+static void manager_serialize_uid_refs(Manager *m, FILE *f) {
+        manager_serialize_uid_refs_internal(f, m->uid_refs, "destroy-ipc-uid");
+}
+
+static void manager_serialize_gid_refs(Manager *m, FILE *f) {
+        manager_serialize_uid_refs_internal(f, m->gid_refs, "destroy-ipc-gid");
+}
+
+int manager_serialize(
+                Manager *m,
+                FILE *f,
+                FDSet *fds,
+                bool switching_root) {
+
+        const char *t;
+        Unit *u;
+        int r;
+
+        assert(m);
+        assert(f);
+        assert(fds);
+
+        _cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
+
+        (void) serialize_item_format(f, "current-job-id", "%" PRIu32, m->current_job_id);
+        (void) serialize_item_format(f, "n-installed-jobs", "%u", m->n_installed_jobs);
+        (void) serialize_item_format(f, "n-failed-jobs", "%u", m->n_failed_jobs);
+        (void) serialize_bool(f, "taint-usr", m->taint_usr);
+        (void) serialize_bool(f, "ready-sent", m->ready_sent);
+        (void) serialize_bool(f, "taint-logged", m->taint_logged);
+        (void) serialize_bool(f, "service-watchdogs", m->service_watchdogs);
+
+        /* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
+        (void) serialize_bool(f, "honor-device-enumeration", !switching_root);
+
+        if (m->show_status_overridden != _SHOW_STATUS_INVALID)
+                (void) serialize_item(f, "show-status-overridden",
+                                      show_status_to_string(m->show_status_overridden));
+
+        if (m->log_level_overridden)
+                (void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level());
+        if (m->log_target_overridden)
+                (void) serialize_item(f, "log-target-override", log_target_to_string(log_get_target()));
+
+        (void) serialize_usec(f, "runtime-watchdog-overridden", m->watchdog_overridden[WATCHDOG_RUNTIME]);
+        (void) serialize_usec(f, "reboot-watchdog-overridden", m->watchdog_overridden[WATCHDOG_REBOOT]);
+        (void) serialize_usec(f, "kexec-watchdog-overridden", m->watchdog_overridden[WATCHDOG_KEXEC]);
+
+        for (ManagerTimestamp q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
+                _cleanup_free_ char *joined = NULL;
+
+                if (!manager_timestamp_shall_serialize(q))
+                        continue;
+
+                joined = strjoin(manager_timestamp_to_string(q), "-timestamp");
+                if (!joined)
+                        return log_oom();
+
+                (void) serialize_dual_timestamp(f, joined, m->timestamps + q);
+        }
+
+        if (!switching_root)
+                (void) serialize_strv(f, "env", m->client_environment);
+
+        if (m->notify_fd >= 0) {
+                r = serialize_fd(f, fds, "notify-fd", m->notify_fd);
+                if (r < 0)
+                        return r;
+
+                (void) serialize_item(f, "notify-socket", m->notify_socket);
+        }
+
+        if (m->cgroups_agent_fd >= 0) {
+                r = serialize_fd(f, fds, "cgroups-agent-fd", m->cgroups_agent_fd);
+                if (r < 0)
+                        return r;
+        }
+
+        if (m->user_lookup_fds[0] >= 0) {
+                int copy0, copy1;
+
+                copy0 = fdset_put_dup(fds, m->user_lookup_fds[0]);
+                if (copy0 < 0)
+                        return log_error_errno(copy0, "Failed to add user lookup fd to serialization: %m");
+
+                copy1 = fdset_put_dup(fds, m->user_lookup_fds[1]);
+                if (copy1 < 0)
+                        return log_error_errno(copy1, "Failed to add user lookup fd to serialization: %m");
+
+                (void) serialize_item_format(f, "user-lookup", "%i %i", copy0, copy1);
+        }
+
+        bus_track_serialize(m->subscribed, f, "subscribed");
+
+        r = dynamic_user_serialize(m, f, fds);
+        if (r < 0)
+                return r;
+
+        manager_serialize_uid_refs(m, f);
+        manager_serialize_gid_refs(m, f);
+
+        r = exec_runtime_serialize(m, f, fds);
+        if (r < 0)
+                return r;
+
+        (void) fputc('\n', f);
+
+        HASHMAP_FOREACH_KEY(u, t, m->units) {
+                if (u->id != t)
+                        continue;
+
+                r = unit_serialize(u, f, fds, switching_root);
+                if (r < 0)
+                        return r;
+        }
+
+        r = fflush_and_check(f);
+        if (r < 0)
+                return log_error_errno(r, "Failed to flush serialization: %m");
+
+        r = bus_fdset_add_all(m, fds);
+        if (r < 0)
+                return log_error_errno(r, "Failed to add bus sockets to serialization: %m");
+
+        return 0;
+}
+
+static int manager_deserialize_one_unit(Manager *m, const char *name, FILE *f, FDSet *fds) {
+        Unit *u;
+        int r;
+
+        r = manager_load_unit(m, name, NULL, NULL, &u);
+        if (r < 0) {
+                if (r == -ENOMEM)
+                        return r;
+                return log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", name);
+        }
+
+        r = unit_deserialize(u, f, fds);
+        if (r < 0) {
+                if (r == -ENOMEM)
+                        return r;
+                return log_notice_errno(r, "Failed to deserialize unit \"%s\", skipping: %m", name);
+        }
+
+        return 0;
+}
+
+static int manager_deserialize_units(Manager *m, FILE *f, FDSet *fds) {
+        const char *unit_name;
+        int r;
+
+        for (;;) {
+                _cleanup_free_ char *line = NULL;
+                /* Start marker */
+                r = read_line(f, LONG_LINE_MAX, &line);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to read serialization line: %m");
+                if (r == 0)
+                        break;
+
+                unit_name = strstrip(line);
+
+                r = manager_deserialize_one_unit(m, unit_name, f, fds);
+                if (r == -ENOMEM)
+                        return r;
+                if (r < 0) {
+                        r = unit_deserialize_skip(f);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
+        return 0;
+}
+
+static void manager_deserialize_uid_refs_one_internal(
+                Hashmap** uid_refs,
+                const char *value) {
+
+        uid_t uid;
+        uint32_t c;
+        int r;
+
+        assert(uid_refs);
+        assert(value);
+
+        r = parse_uid(value, &uid);
+        if (r < 0 || uid == 0) {
+                log_debug("Unable to parse UID/GID reference serialization: " UID_FMT, uid);
+                return;
+        }
+
+        if (hashmap_ensure_allocated(uid_refs, &trivial_hash_ops) < 0) {
+                log_oom();
+                return;
+        }
+
+        c = PTR_TO_UINT32(hashmap_get(*uid_refs, UID_TO_PTR(uid)));
+        if (c & DESTROY_IPC_FLAG)
+                return;
+
+        c |= DESTROY_IPC_FLAG;
+
+        r = hashmap_replace(*uid_refs, UID_TO_PTR(uid), UINT32_TO_PTR(c));
+        if (r < 0) {
+                log_debug_errno(r, "Failed to add UID/GID reference entry: %m");
+                return;
+        }
+}
+
+static void manager_deserialize_uid_refs_one(Manager *m, const char *value) {
+        manager_deserialize_uid_refs_one_internal(&m->uid_refs, value);
+}
+
+static void manager_deserialize_gid_refs_one(Manager *m, const char *value) {
+        manager_deserialize_uid_refs_one_internal(&m->gid_refs, value);
+}
+
+int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
+        int r = 0;
+
+        assert(m);
+        assert(f);
+
+        if (DEBUG_LOGGING) {
+                if (fdset_isempty(fds))
+                        log_debug("No file descriptors passed");
+                else {
+                        int fd;
+
+                        FDSET_FOREACH(fd, fds) {
+                                _cleanup_free_ char *fn = NULL;
+
+                                r = fd_get_path(fd, &fn);
+                                if (r < 0)
+                                        log_debug_errno(r, "Received serialized fd %i → %m", fd);
+                                else
+                                        log_debug("Received serialized fd %i → %s", fd, strna(fn));
+                        }
+                }
+        }
+
+        log_debug("Deserializing state...");
+
+        /* If we are not in reload mode yet, enter it now. Not that this is recursive, a caller might already have
+         * increased it to non-zero, which is why we just increase it by one here and down again at the end of this
+         * call. */
+        _cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
+
+        for (;;) {
+                _cleanup_free_ char *line = NULL;
+                const char *val, *l;
+
+                r = read_line(f, LONG_LINE_MAX, &line);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to read serialization line: %m");
+                if (r == 0)
+                        break;
+
+                l = strstrip(line);
+                if (isempty(l)) /* end marker */
+                        break;
+
+                if ((val = startswith(l, "current-job-id="))) {
+                        uint32_t id;
+
+                        if (safe_atou32(val, &id) < 0)
+                                log_notice("Failed to parse current job id value '%s', ignoring.", val);
+                        else
+                                m->current_job_id = MAX(m->current_job_id, id);
+
+                } else if ((val = startswith(l, "n-installed-jobs="))) {
+                        uint32_t n;
+
+                        if (safe_atou32(val, &n) < 0)
+                                log_notice("Failed to parse installed jobs counter '%s', ignoring.", val);
+                        else
+                                m->n_installed_jobs += n;
+
+                } else if ((val = startswith(l, "n-failed-jobs="))) {
+                        uint32_t n;
+
+                        if (safe_atou32(val, &n) < 0)
+                                log_notice("Failed to parse failed jobs counter '%s', ignoring.", val);
+                        else
+                                m->n_failed_jobs += n;
+
+                } else if ((val = startswith(l, "taint-usr="))) {
+                        int b;
+
+                        b = parse_boolean(val);
+                        if (b < 0)
+                                log_notice("Failed to parse taint /usr flag '%s', ignoring.", val);
+                        else
+                                m->taint_usr = m->taint_usr || b;
+
+                } else if ((val = startswith(l, "ready-sent="))) {
+                        int b;
+
+                        b = parse_boolean(val);
+                        if (b < 0)
+                                log_notice("Failed to parse ready-sent flag '%s', ignoring.", val);
+                        else
+                                m->ready_sent = m->ready_sent || b;
+
+                } else if ((val = startswith(l, "taint-logged="))) {
+                        int b;
+
+                        b = parse_boolean(val);
+                        if (b < 0)
+                                log_notice("Failed to parse taint-logged flag '%s', ignoring.", val);
+                        else
+                                m->taint_logged = m->taint_logged || b;
+
+                } else if ((val = startswith(l, "service-watchdogs="))) {
+                        int b;
+
+                        b = parse_boolean(val);
+                        if (b < 0)
+                                log_notice("Failed to parse service-watchdogs flag '%s', ignoring.", val);
+                        else
+                                m->service_watchdogs = b;
+
+                } else if ((val = startswith(l, "honor-device-enumeration="))) {
+                        int b;
+
+                        b = parse_boolean(val);
+                        if (b < 0)
+                                log_notice("Failed to parse honor-device-enumeration flag '%s', ignoring.", val);
+                        else
+                                m->honor_device_enumeration = b;
+
+                } else if ((val = startswith(l, "show-status-overridden="))) {
+                        ShowStatus s;
+
+                        s = show_status_from_string(val);
+                        if (s < 0)
+                                log_notice("Failed to parse show-status-overridden flag '%s', ignoring.", val);
+                        else
+                                manager_override_show_status(m, s, "deserialize");
+
+                } else if ((val = startswith(l, "log-level-override="))) {
+                        int level;
+
+                        level = log_level_from_string(val);
+                        if (level < 0)
+                                log_notice("Failed to parse log-level-override value '%s', ignoring.", val);
+                        else
+                                manager_override_log_level(m, level);
+
+                } else if ((val = startswith(l, "log-target-override="))) {
+                        LogTarget target;
+
+                        target = log_target_from_string(val);
+                        if (target < 0)
+                                log_notice("Failed to parse log-target-override value '%s', ignoring.", val);
+                        else
+                                manager_override_log_target(m, target);
+
+                } else if ((val = startswith(l, "runtime-watchdog-overridden="))) {
+                        usec_t t;
+
+                        if (deserialize_usec(val, &t) < 0)
+                                log_notice("Failed to parse runtime-watchdog-overridden value '%s', ignoring.", val);
+                        else
+                                manager_override_watchdog(m, WATCHDOG_RUNTIME, t);
+
+                } else if ((val = startswith(l, "reboot-watchdog-overridden="))) {
+                        usec_t t;
+
+                        if (deserialize_usec(val, &t) < 0)
+                                log_notice("Failed to parse reboot-watchdog-overridden value '%s', ignoring.", val);
+                        else
+                                manager_override_watchdog(m, WATCHDOG_REBOOT, t);
+
+                } else if ((val = startswith(l, "kexec-watchdog-overridden="))) {
+                        usec_t t;
+
+                        if (deserialize_usec(val, &t) < 0)
+                                log_notice("Failed to parse kexec-watchdog-overridden value '%s', ignoring.", val);
+                        else
+                                manager_override_watchdog(m, WATCHDOG_KEXEC, t);
+
+                } else if (startswith(l, "env=")) {
+                        r = deserialize_environment(l + 4, &m->client_environment);
+                        if (r < 0)
+                                log_notice_errno(r, "Failed to parse environment entry: \"%s\", ignoring: %m", l);
+
+                } else if ((val = startswith(l, "notify-fd="))) {
+                        int fd;
+
+                        if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+                                log_notice("Failed to parse notify fd, ignoring: \"%s\"", val);
+                        else {
+                                m->notify_event_source = sd_event_source_disable_unref(m->notify_event_source);
+                                safe_close(m->notify_fd);
+                                m->notify_fd = fdset_remove(fds, fd);
+                        }
+
+                } else if ((val = startswith(l, "notify-socket="))) {
+                        r = free_and_strdup(&m->notify_socket, val);
+                        if (r < 0)
+                                return r;
+
+                } else if ((val = startswith(l, "cgroups-agent-fd="))) {
+                        int fd;
+
+                        if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+                                log_notice("Failed to parse cgroups agent fd, ignoring.: %s", val);
+                        else {
+                                m->cgroups_agent_event_source = sd_event_source_disable_unref(m->cgroups_agent_event_source);
+                                safe_close(m->cgroups_agent_fd);
+                                m->cgroups_agent_fd = fdset_remove(fds, fd);
+                        }
+
+                } else if ((val = startswith(l, "user-lookup="))) {
+                        int fd0, fd1;
+
+                        if (sscanf(val, "%i %i", &fd0, &fd1) != 2 || fd0 < 0 || fd1 < 0 || fd0 == fd1 || !fdset_contains(fds, fd0) || !fdset_contains(fds, fd1))
+                                log_notice("Failed to parse user lookup fd, ignoring: %s", val);
+                        else {
+                                m->user_lookup_event_source = sd_event_source_disable_unref(m->user_lookup_event_source);
+                                safe_close_pair(m->user_lookup_fds);
+                                m->user_lookup_fds[0] = fdset_remove(fds, fd0);
+                                m->user_lookup_fds[1] = fdset_remove(fds, fd1);
+                        }
+
+                } else if ((val = startswith(l, "dynamic-user=")))
+                        dynamic_user_deserialize_one(m, val, fds);
+                else if ((val = startswith(l, "destroy-ipc-uid=")))
+                        manager_deserialize_uid_refs_one(m, val);
+                else if ((val = startswith(l, "destroy-ipc-gid=")))
+                        manager_deserialize_gid_refs_one(m, val);
+                else if ((val = startswith(l, "exec-runtime=")))
+                        (void) exec_runtime_deserialize_one(m, val, fds);
+                else if ((val = startswith(l, "subscribed="))) {
+
+                        if (strv_extend(&m->deserialized_subscribed, val) < 0)
+                                return -ENOMEM;
+
+                } else {
+                        ManagerTimestamp q;
+
+                        for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
+                                val = startswith(l, manager_timestamp_to_string(q));
+                                if (!val)
+                                        continue;
+
+                                val = startswith(val, "-timestamp=");
+                                if (val)
+                                        break;
+                        }
+
+                        if (q < _MANAGER_TIMESTAMP_MAX) /* found it */
+                                (void) deserialize_dual_timestamp(val, m->timestamps + q);
+                        else if (!startswith(l, "kdbus-fd=")) /* ignore kdbus */
+                                log_notice("Unknown serialization item '%s', ignoring.", l);
+                }
+        }
+
+        return manager_deserialize_units(m, f, fds);
+}
diff --git a/src/core/manager-serialize.h b/src/core/manager-serialize.h
new file mode 100644 (file)
index 0000000..c52261e
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <stdbool.h>
+
+#include "manager.h"
+#include "fdset.h"
+
+#define DESTROY_IPC_FLAG (UINT32_C(1) << 31)
+
+int manager_open_serialization(Manager *m, FILE **ret_f);
+int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root);
+int manager_deserialize(Manager *m, FILE *f, FDSet *fds);
index 18bdd8334250a970fd0b2bed1bc0d9dbf9b012ff..72f1e109d79365e23a8ecc350581a8e5d230a925 100644 (file)
@@ -56,6 +56,7 @@
 #include "macro.h"
 #include "manager.h"
 #include "manager-dump.h"
+#include "manager-serialize.h"
 #include "memory-util.h"
 #include "mkdir.h"
 #include "parse-util.h"
@@ -66,7 +67,6 @@
 #include "rlimit-util.h"
 #include "rm-rf.h"
 #include "selinux-util.h"
-#include "serialize.h"
 #include "signal-util.h"
 #include "socket-util.h"
 #include "special.h"
@@ -82,7 +82,6 @@
 #include "transaction.h"
 #include "umask-util.h"
 #include "unit-name.h"
-#include "unit-serialize.h"
 #include "user-util.h"
 #include "virt.h"
 #include "watchdog.h"
@@ -1686,11 +1685,11 @@ static void manager_ready(Manager *m) {
         m->honor_device_enumeration = true;
 }
 
-static Manager* manager_reloading_start(Manager *m) {
+Manager* manager_reloading_start(Manager *m) {
         m->n_reloading++;
         return m;
 }
-static void manager_reloading_stopp(Manager **m) {
+void manager_reloading_stopp(Manager **m) {
         if (*m) {
                 assert((*m)->n_reloading > 0);
                 (*m)->n_reloading--;
@@ -3154,242 +3153,6 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) {
                         log_error_errno(errno, "Failed to write Plymouth message: %m");
 }
 
-int manager_open_serialization(Manager *m, FILE **_f) {
-        _cleanup_close_ int fd = -1;
-        FILE *f;
-
-        assert(_f);
-
-        fd = open_serialization_fd("systemd-state");
-        if (fd < 0)
-                return fd;
-
-        f = take_fdopen(&fd, "w+");
-        if (!f)
-                return -errno;
-
-        *_f = f;
-        return 0;
-}
-
-static bool manager_timestamp_shall_serialize(ManagerTimestamp t) {
-
-        if (!in_initrd())
-                return true;
-
-        /* The following timestamps only apply to the host system, hence only serialize them there */
-        return !IN_SET(t,
-                       MANAGER_TIMESTAMP_USERSPACE, MANAGER_TIMESTAMP_FINISH,
-                       MANAGER_TIMESTAMP_SECURITY_START, MANAGER_TIMESTAMP_SECURITY_FINISH,
-                       MANAGER_TIMESTAMP_GENERATORS_START, MANAGER_TIMESTAMP_GENERATORS_FINISH,
-                       MANAGER_TIMESTAMP_UNITS_LOAD_START, MANAGER_TIMESTAMP_UNITS_LOAD_FINISH);
-}
-
-#define DESTROY_IPC_FLAG (UINT32_C(1) << 31)
-
-static void manager_serialize_uid_refs_internal(
-                FILE *f,
-                Hashmap *uid_refs,
-                const char *field_name) {
-
-        void *p, *k;
-
-        assert(f);
-        assert(field_name);
-
-        /* Serialize the UID reference table. Or actually, just the IPC destruction flag of it, as
-         * the actual counter of it is better rebuild after a reload/reexec. */
-
-        HASHMAP_FOREACH_KEY(p, k, uid_refs) {
-                uint32_t c;
-                uid_t uid;
-
-                uid = PTR_TO_UID(k);
-                c = PTR_TO_UINT32(p);
-
-                if (!(c & DESTROY_IPC_FLAG))
-                        continue;
-
-                (void) serialize_item_format(f, field_name, UID_FMT, uid);
-        }
-}
-
-static void manager_serialize_uid_refs(Manager *m, FILE *f) {
-        manager_serialize_uid_refs_internal(f, m->uid_refs, "destroy-ipc-uid");
-}
-
-static void manager_serialize_gid_refs(Manager *m, FILE *f) {
-        manager_serialize_uid_refs_internal(f, m->gid_refs, "destroy-ipc-gid");
-}
-
-int manager_serialize(
-                Manager *m,
-                FILE *f,
-                FDSet *fds,
-                bool switching_root) {
-
-        const char *t;
-        Unit *u;
-        int r;
-
-        assert(m);
-        assert(f);
-        assert(fds);
-
-        _cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
-
-        (void) serialize_item_format(f, "current-job-id", "%" PRIu32, m->current_job_id);
-        (void) serialize_item_format(f, "n-installed-jobs", "%u", m->n_installed_jobs);
-        (void) serialize_item_format(f, "n-failed-jobs", "%u", m->n_failed_jobs);
-        (void) serialize_bool(f, "taint-usr", m->taint_usr);
-        (void) serialize_bool(f, "ready-sent", m->ready_sent);
-        (void) serialize_bool(f, "taint-logged", m->taint_logged);
-        (void) serialize_bool(f, "service-watchdogs", m->service_watchdogs);
-
-        /* After switching root, udevd has not been started yet. So, enumeration results should not be emitted. */
-        (void) serialize_bool(f, "honor-device-enumeration", !switching_root);
-
-        if (m->show_status_overridden != _SHOW_STATUS_INVALID)
-                (void) serialize_item(f, "show-status-overridden",
-                                      show_status_to_string(m->show_status_overridden));
-
-        if (m->log_level_overridden)
-                (void) serialize_item_format(f, "log-level-override", "%i", log_get_max_level());
-        if (m->log_target_overridden)
-                (void) serialize_item(f, "log-target-override", log_target_to_string(log_get_target()));
-
-        (void) serialize_usec(f, "runtime-watchdog-overridden", m->watchdog_overridden[WATCHDOG_RUNTIME]);
-        (void) serialize_usec(f, "reboot-watchdog-overridden", m->watchdog_overridden[WATCHDOG_REBOOT]);
-        (void) serialize_usec(f, "kexec-watchdog-overridden", m->watchdog_overridden[WATCHDOG_KEXEC]);
-
-        for (ManagerTimestamp q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
-                _cleanup_free_ char *joined = NULL;
-
-                if (!manager_timestamp_shall_serialize(q))
-                        continue;
-
-                joined = strjoin(manager_timestamp_to_string(q), "-timestamp");
-                if (!joined)
-                        return log_oom();
-
-                (void) serialize_dual_timestamp(f, joined, m->timestamps + q);
-        }
-
-        if (!switching_root)
-                (void) serialize_strv(f, "env", m->client_environment);
-
-        if (m->notify_fd >= 0) {
-                r = serialize_fd(f, fds, "notify-fd", m->notify_fd);
-                if (r < 0)
-                        return r;
-
-                (void) serialize_item(f, "notify-socket", m->notify_socket);
-        }
-
-        if (m->cgroups_agent_fd >= 0) {
-                r = serialize_fd(f, fds, "cgroups-agent-fd", m->cgroups_agent_fd);
-                if (r < 0)
-                        return r;
-        }
-
-        if (m->user_lookup_fds[0] >= 0) {
-                int copy0, copy1;
-
-                copy0 = fdset_put_dup(fds, m->user_lookup_fds[0]);
-                if (copy0 < 0)
-                        return log_error_errno(copy0, "Failed to add user lookup fd to serialization: %m");
-
-                copy1 = fdset_put_dup(fds, m->user_lookup_fds[1]);
-                if (copy1 < 0)
-                        return log_error_errno(copy1, "Failed to add user lookup fd to serialization: %m");
-
-                (void) serialize_item_format(f, "user-lookup", "%i %i", copy0, copy1);
-        }
-
-        bus_track_serialize(m->subscribed, f, "subscribed");
-
-        r = dynamic_user_serialize(m, f, fds);
-        if (r < 0)
-                return r;
-
-        manager_serialize_uid_refs(m, f);
-        manager_serialize_gid_refs(m, f);
-
-        r = exec_runtime_serialize(m, f, fds);
-        if (r < 0)
-                return r;
-
-        (void) fputc('\n', f);
-
-        HASHMAP_FOREACH_KEY(u, t, m->units) {
-                if (u->id != t)
-                        continue;
-
-                r = unit_serialize(u, f, fds, switching_root);
-                if (r < 0)
-                        return r;
-        }
-
-        r = fflush_and_check(f);
-        if (r < 0)
-                return log_error_errno(r, "Failed to flush serialization: %m");
-
-        r = bus_fdset_add_all(m, fds);
-        if (r < 0)
-                return log_error_errno(r, "Failed to add bus sockets to serialization: %m");
-
-        return 0;
-}
-
-static int manager_deserialize_one_unit(Manager *m, const char *name, FILE *f, FDSet *fds) {
-        Unit *u;
-        int r;
-
-        r = manager_load_unit(m, name, NULL, NULL, &u);
-        if (r < 0) {
-                if (r == -ENOMEM)
-                        return r;
-                return log_notice_errno(r, "Failed to load unit \"%s\", skipping deserialization: %m", name);
-        }
-
-        r = unit_deserialize(u, f, fds);
-        if (r < 0) {
-                if (r == -ENOMEM)
-                        return r;
-                return log_notice_errno(r, "Failed to deserialize unit \"%s\", skipping: %m", name);
-        }
-
-        return 0;
-}
-
-static int manager_deserialize_units(Manager *m, FILE *f, FDSet *fds) {
-        const char *unit_name;
-        int r;
-
-        for (;;) {
-                _cleanup_free_ char *line = NULL;
-                /* Start marker */
-                r = read_line(f, LONG_LINE_MAX, &line);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to read serialization line: %m");
-                if (r == 0)
-                        break;
-
-                unit_name = strstrip(line);
-
-                r = manager_deserialize_one_unit(m, unit_name, f, fds);
-                if (r == -ENOMEM)
-                        return r;
-                if (r < 0) {
-                        r = unit_deserialize_skip(f);
-                        if (r < 0)
-                                return r;
-                }
-        }
-
-        return 0;
-}
-
 usec_t manager_get_watchdog(Manager *m, WatchdogType t) {
         assert(m);
 
@@ -3474,294 +3237,6 @@ void manager_retry_runtime_watchdog(Manager *m) {
                 m->runtime_watchdog_running = true;
 }
 
-static void manager_deserialize_uid_refs_one_internal(
-                Hashmap** uid_refs,
-                const char *value) {
-
-        uid_t uid;
-        uint32_t c;
-        int r;
-
-        assert(uid_refs);
-        assert(value);
-
-        r = parse_uid(value, &uid);
-        if (r < 0 || uid == 0) {
-                log_debug("Unable to parse UID/GID reference serialization: " UID_FMT, uid);
-                return;
-        }
-
-        if (hashmap_ensure_allocated(uid_refs, &trivial_hash_ops) < 0) {
-                log_oom();
-                return;
-        }
-
-        c = PTR_TO_UINT32(hashmap_get(*uid_refs, UID_TO_PTR(uid)));
-        if (c & DESTROY_IPC_FLAG)
-                return;
-
-        c |= DESTROY_IPC_FLAG;
-
-        r = hashmap_replace(*uid_refs, UID_TO_PTR(uid), UINT32_TO_PTR(c));
-        if (r < 0) {
-                log_debug_errno(r, "Failed to add UID/GID reference entry: %m");
-                return;
-        }
-}
-
-static void manager_deserialize_uid_refs_one(Manager *m, const char *value) {
-        manager_deserialize_uid_refs_one_internal(&m->uid_refs, value);
-}
-
-static void manager_deserialize_gid_refs_one(Manager *m, const char *value) {
-        manager_deserialize_uid_refs_one_internal(&m->gid_refs, value);
-}
-
-int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
-        int r = 0;
-
-        assert(m);
-        assert(f);
-
-        if (DEBUG_LOGGING) {
-                if (fdset_isempty(fds))
-                        log_debug("No file descriptors passed");
-                else {
-                        int fd;
-
-                        FDSET_FOREACH(fd, fds) {
-                                _cleanup_free_ char *fn = NULL;
-
-                                r = fd_get_path(fd, &fn);
-                                if (r < 0)
-                                        log_debug_errno(r, "Received serialized fd %i → %m", fd);
-                                else
-                                        log_debug("Received serialized fd %i → %s", fd, strna(fn));
-                        }
-                }
-        }
-
-        log_debug("Deserializing state...");
-
-        /* If we are not in reload mode yet, enter it now. Not that this is recursive, a caller might already have
-         * increased it to non-zero, which is why we just increase it by one here and down again at the end of this
-         * call. */
-        _cleanup_(manager_reloading_stopp) _unused_ Manager *reloading = manager_reloading_start(m);
-
-        for (;;) {
-                _cleanup_free_ char *line = NULL;
-                const char *val, *l;
-
-                r = read_line(f, LONG_LINE_MAX, &line);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to read serialization line: %m");
-                if (r == 0)
-                        break;
-
-                l = strstrip(line);
-                if (isempty(l)) /* end marker */
-                        break;
-
-                if ((val = startswith(l, "current-job-id="))) {
-                        uint32_t id;
-
-                        if (safe_atou32(val, &id) < 0)
-                                log_notice("Failed to parse current job id value '%s', ignoring.", val);
-                        else
-                                m->current_job_id = MAX(m->current_job_id, id);
-
-                } else if ((val = startswith(l, "n-installed-jobs="))) {
-                        uint32_t n;
-
-                        if (safe_atou32(val, &n) < 0)
-                                log_notice("Failed to parse installed jobs counter '%s', ignoring.", val);
-                        else
-                                m->n_installed_jobs += n;
-
-                } else if ((val = startswith(l, "n-failed-jobs="))) {
-                        uint32_t n;
-
-                        if (safe_atou32(val, &n) < 0)
-                                log_notice("Failed to parse failed jobs counter '%s', ignoring.", val);
-                        else
-                                m->n_failed_jobs += n;
-
-                } else if ((val = startswith(l, "taint-usr="))) {
-                        int b;
-
-                        b = parse_boolean(val);
-                        if (b < 0)
-                                log_notice("Failed to parse taint /usr flag '%s', ignoring.", val);
-                        else
-                                m->taint_usr = m->taint_usr || b;
-
-                } else if ((val = startswith(l, "ready-sent="))) {
-                        int b;
-
-                        b = parse_boolean(val);
-                        if (b < 0)
-                                log_notice("Failed to parse ready-sent flag '%s', ignoring.", val);
-                        else
-                                m->ready_sent = m->ready_sent || b;
-
-                } else if ((val = startswith(l, "taint-logged="))) {
-                        int b;
-
-                        b = parse_boolean(val);
-                        if (b < 0)
-                                log_notice("Failed to parse taint-logged flag '%s', ignoring.", val);
-                        else
-                                m->taint_logged = m->taint_logged || b;
-
-                } else if ((val = startswith(l, "service-watchdogs="))) {
-                        int b;
-
-                        b = parse_boolean(val);
-                        if (b < 0)
-                                log_notice("Failed to parse service-watchdogs flag '%s', ignoring.", val);
-                        else
-                                m->service_watchdogs = b;
-
-                } else if ((val = startswith(l, "honor-device-enumeration="))) {
-                        int b;
-
-                        b = parse_boolean(val);
-                        if (b < 0)
-                                log_notice("Failed to parse honor-device-enumeration flag '%s', ignoring.", val);
-                        else
-                                m->honor_device_enumeration = b;
-
-                } else if ((val = startswith(l, "show-status-overridden="))) {
-                        ShowStatus s;
-
-                        s = show_status_from_string(val);
-                        if (s < 0)
-                                log_notice("Failed to parse show-status-overridden flag '%s', ignoring.", val);
-                        else
-                                manager_override_show_status(m, s, "deserialize");
-
-                } else if ((val = startswith(l, "log-level-override="))) {
-                        int level;
-
-                        level = log_level_from_string(val);
-                        if (level < 0)
-                                log_notice("Failed to parse log-level-override value '%s', ignoring.", val);
-                        else
-                                manager_override_log_level(m, level);
-
-                } else if ((val = startswith(l, "log-target-override="))) {
-                        LogTarget target;
-
-                        target = log_target_from_string(val);
-                        if (target < 0)
-                                log_notice("Failed to parse log-target-override value '%s', ignoring.", val);
-                        else
-                                manager_override_log_target(m, target);
-
-                } else if ((val = startswith(l, "runtime-watchdog-overridden="))) {
-                        usec_t t;
-
-                        if (deserialize_usec(val, &t) < 0)
-                                log_notice("Failed to parse runtime-watchdog-overridden value '%s', ignoring.", val);
-                        else
-                                manager_override_watchdog(m, WATCHDOG_RUNTIME, t);
-
-                } else if ((val = startswith(l, "reboot-watchdog-overridden="))) {
-                        usec_t t;
-
-                        if (deserialize_usec(val, &t) < 0)
-                                log_notice("Failed to parse reboot-watchdog-overridden value '%s', ignoring.", val);
-                        else
-                                manager_override_watchdog(m, WATCHDOG_REBOOT, t);
-
-                } else if ((val = startswith(l, "kexec-watchdog-overridden="))) {
-                        usec_t t;
-
-                        if (deserialize_usec(val, &t) < 0)
-                                log_notice("Failed to parse kexec-watchdog-overridden value '%s', ignoring.", val);
-                        else
-                                manager_override_watchdog(m, WATCHDOG_KEXEC, t);
-
-                } else if (startswith(l, "env=")) {
-                        r = deserialize_environment(l + 4, &m->client_environment);
-                        if (r < 0)
-                                log_notice_errno(r, "Failed to parse environment entry: \"%s\", ignoring: %m", l);
-
-                } else if ((val = startswith(l, "notify-fd="))) {
-                        int fd;
-
-                        if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
-                                log_notice("Failed to parse notify fd, ignoring: \"%s\"", val);
-                        else {
-                                m->notify_event_source = sd_event_source_disable_unref(m->notify_event_source);
-                                safe_close(m->notify_fd);
-                                m->notify_fd = fdset_remove(fds, fd);
-                        }
-
-                } else if ((val = startswith(l, "notify-socket="))) {
-                        r = free_and_strdup(&m->notify_socket, val);
-                        if (r < 0)
-                                return r;
-
-                } else if ((val = startswith(l, "cgroups-agent-fd="))) {
-                        int fd;
-
-                        if (safe_atoi(val, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
-                                log_notice("Failed to parse cgroups agent fd, ignoring.: %s", val);
-                        else {
-                                m->cgroups_agent_event_source = sd_event_source_disable_unref(m->cgroups_agent_event_source);
-                                safe_close(m->cgroups_agent_fd);
-                                m->cgroups_agent_fd = fdset_remove(fds, fd);
-                        }
-
-                } else if ((val = startswith(l, "user-lookup="))) {
-                        int fd0, fd1;
-
-                        if (sscanf(val, "%i %i", &fd0, &fd1) != 2 || fd0 < 0 || fd1 < 0 || fd0 == fd1 || !fdset_contains(fds, fd0) || !fdset_contains(fds, fd1))
-                                log_notice("Failed to parse user lookup fd, ignoring: %s", val);
-                        else {
-                                m->user_lookup_event_source = sd_event_source_disable_unref(m->user_lookup_event_source);
-                                safe_close_pair(m->user_lookup_fds);
-                                m->user_lookup_fds[0] = fdset_remove(fds, fd0);
-                                m->user_lookup_fds[1] = fdset_remove(fds, fd1);
-                        }
-
-                } else if ((val = startswith(l, "dynamic-user=")))
-                        dynamic_user_deserialize_one(m, val, fds);
-                else if ((val = startswith(l, "destroy-ipc-uid=")))
-                        manager_deserialize_uid_refs_one(m, val);
-                else if ((val = startswith(l, "destroy-ipc-gid=")))
-                        manager_deserialize_gid_refs_one(m, val);
-                else if ((val = startswith(l, "exec-runtime=")))
-                        (void) exec_runtime_deserialize_one(m, val, fds);
-                else if ((val = startswith(l, "subscribed="))) {
-
-                        if (strv_extend(&m->deserialized_subscribed, val) < 0)
-                                return -ENOMEM;
-
-                } else {
-                        ManagerTimestamp q;
-
-                        for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
-                                val = startswith(l, manager_timestamp_to_string(q));
-                                if (!val)
-                                        continue;
-
-                                val = startswith(val, "-timestamp=");
-                                if (val)
-                                        break;
-                        }
-
-                        if (q < _MANAGER_TIMESTAMP_MAX) /* found it */
-                                (void) deserialize_dual_timestamp(val, m->timestamps + q);
-                        else if (!startswith(l, "kdbus-fd=")) /* ignore kdbus */
-                                log_notice("Unknown serialization item '%s', ignoring.", l);
-                }
-        }
-
-        return manager_deserialize_units(m, f, fds);
-}
-
 int manager_reload(Manager *m) {
         _cleanup_(manager_reloading_stopp) Manager *reloading = NULL;
         _cleanup_fdset_free_ FDSet *fds = NULL;
index b3e7c68e6ddd0bff0021baee7dd8b111a15f59cf..6b1ed48bebfa636b90604dbea91fb148a113e62d 100644 (file)
@@ -500,12 +500,9 @@ int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit);
 
 int manager_loop(Manager *m);
 
-int manager_open_serialization(Manager *m, FILE **_f);
-
-int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root);
-int manager_deserialize(Manager *m, FILE *f, FDSet *fds);
-
 int manager_reload(Manager *m);
+Manager* manager_reloading_start(Manager *m);
+void manager_reloading_stopp(Manager **m);
 
 void manager_reset_failed(Manager *m);
 
index f0d2c6f642318132bf3ed0d17dfe7adb5251d58e..1c364a53e2d2f6d2801222f0d50e93d0920c4be7 100644 (file)
@@ -87,6 +87,8 @@ libcore_sources = '''
         locale-setup.h
         manager-dump.c
         manager-dump.h
+        manager-serialize.c
+        manager-serialize.h
         manager.c
         manager.h
         mount.c