]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/manager.c
Add open_memstream_unlocked() wrapper
[thirdparty/systemd.git] / src / core / manager.c
index f8a8ac346b98ce4ff11b001e0a7e71db96c9a118..15df7e5f35cc1405818bbcbd0ec847b8abf95048 100644 (file)
@@ -4,7 +4,6 @@
 #include <fcntl.h>
 #include <linux/kd.h>
 #include <signal.h>
-#include <stdio_ext.h>
 #include <string.h>
 #include <sys/epoll.h>
 #include <sys/inotify.h>
@@ -292,10 +291,10 @@ static int manager_check_ask_password(Manager *m) {
 
                 m->ask_password_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
                 if (m->ask_password_inotify_fd < 0)
-                        return log_error_errno(errno, "inotify_init1() failed: %m");
+                        return log_error_errno(errno, "Failed to create inotify object: %m");
 
                 if (inotify_add_watch(m->ask_password_inotify_fd, "/run/systemd/ask-password", IN_CREATE|IN_DELETE|IN_MOVE) < 0) {
-                        log_error_errno(errno, "Failed to add watch on /run/systemd/ask-password: %m");
+                        log_error_errno(errno, "Failed to watch \"/run/systemd/ask-password\": %m");
                         manager_close_ask_password(m);
                         return -errno;
                 }
@@ -764,6 +763,8 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
                 .have_ask_password = -EINVAL, /* we don't know */
                 .first_boot = -1,
                 .test_run_flags = test_run_flags,
+
+                .default_oom_policy = OOM_STOP,
         };
 
 #if ENABLE_EFI
@@ -992,11 +993,10 @@ static int manager_setup_cgroups_agent(Manager *m) {
                 if (r < 0)
                         return log_error_errno(r, "Failed to allocate cgroups agent event source: %m");
 
-                /* Process cgroups notifications early, but after having processed service notification messages or
-                 * SIGCHLD signals, so that a cgroup running empty is always just the last safety net of notification,
-                 * and we collected the metadata the notification and SIGCHLD stuff offers first. Also see handling of
-                 * cgroup inotify for the unified cgroup stuff. */
-                r = sd_event_source_set_priority(m->cgroups_agent_event_source, SD_EVENT_PRIORITY_NORMAL-4);
+                /* Process cgroups notifications early. Note that when the agent notification is received
+                 * we'll just enqueue the unit in the cgroup empty queue, hence pick a high priority than
+                 * that. Also see handling of cgroup inotify for the unified cgroup stuff. */
+                r = sd_event_source_set_priority(m->cgroups_agent_event_source, SD_EVENT_PRIORITY_NORMAL-9);
                 if (r < 0)
                         return log_error_errno(r, "Failed to set priority of cgroups agent event source: %m");
 
@@ -1619,6 +1619,8 @@ static void manager_ready(Manager *m) {
 
         /* Let's finally catch up with any changes that took place while we were reloading/reexecing */
         manager_catchup(m);
+
+        m->honor_device_enumeration = true;
 }
 
 static Manager* manager_reloading_start(Manager *m) {
@@ -2108,12 +2110,10 @@ int manager_get_dump_string(Manager *m, char **ret) {
         assert(m);
         assert(ret);
 
-        f = open_memstream(&dump, &size);
+        f = open_memstream_unlocked(&dump, &size);
         if (!f)
                 return -errno;
 
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-
         manager_dump(m, f, NULL);
 
         r = fflush_and_check(f);
@@ -3149,6 +3149,9 @@ int manager_serialize(
         (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);
+
         t = show_status_to_string(m->show_status);
         if (t)
                 (void) serialize_item(f, "show-status", t);
@@ -3377,6 +3380,15 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                         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="))) {
                         ShowStatus s;
 
@@ -3567,6 +3579,11 @@ int manager_reload(Manager *m) {
         assert(m->n_reloading > 0);
         m->n_reloading--;
 
+        /* On manager reloading, device tag data should exists, thus, we should honor the results of device
+         * enumeration. The flag should be always set correctly by the serialized data, but it may fail. So,
+         * let's always set the flag here for safety. */
+        m->honor_device_enumeration = true;
+
         manager_ready(m);
 
         m->send_reloading_done = true;
@@ -4696,3 +4713,11 @@ static const char *const manager_timestamp_table[_MANAGER_TIMESTAMP_MAX] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP(manager_timestamp, ManagerTimestamp);
+
+static const char* const oom_policy_table[_OOM_POLICY_MAX] = {
+        [OOM_CONTINUE] = "continue",
+        [OOM_STOP] = "stop",
+        [OOM_KILL] = "kill",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(oom_policy, OOMPolicy);