chiark / gitweb /
core: add manager_status_printf()
[elogind.git] / src / core / manager.c
index aaf66970cf11e7a6e94d83fdd2919ad9ee01aaec..d6c6e2de6d2dfe6823dc01057d9a9a61f4a72b28 100644 (file)
@@ -71,6 +71,7 @@
 #include "path-util.h"
 #include "audit-fd.h"
 #include "efivars.h"
+#include "env-util.h"
 
 /* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
 #define GC_QUEUE_ENTRIES_MAX 16
@@ -81,6 +82,8 @@
 /* Where clients shall send notification messages to */
 #define NOTIFY_SOCKET "@/org/freedesktop/systemd1/notify"
 
+#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
+
 static int manager_setup_notify(Manager *m) {
         union {
                 struct sockaddr sa;
@@ -123,7 +126,7 @@ static int manager_setup_notify(Manager *m) {
         ev.data.ptr = &m->notify_watch;
 
         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev) < 0) {
-                log_error("Failed to add timer change fd to epoll: %m");
+                log_error("Failed to add notification socket fd to epoll: %m");
                 return -errno;
         }
 
@@ -287,6 +290,9 @@ static void manager_strip_environment(Manager *m) {
          * the initrd interface:
          * http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface */
         strv_remove_prefix(m->environment, "RD_");
+
+        /* Drop invalid entries */
+        strv_env_clean(m->environment);
 }
 
 int manager_new(SystemdRunningAs running_as, Manager **_m) {
@@ -303,7 +309,9 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) {
 
         dual_timestamp_get(&m->userspace_timestamp);
         dual_timestamp_from_monotonic(&m->kernel_timestamp, 0);
+#ifdef ENABLE_EFI
         efi_get_boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
+#endif
 
         m->running_as = running_as;
         m->name_data_slot = m->conn_data_slot = m->subscribed_data_slot = -1;
@@ -619,14 +627,15 @@ int manager_coldplug(Manager *m) {
 
 static void manager_build_unit_path_cache(Manager *m) {
         char **i;
-        DIR *d = NULL;
+        DIR _cleanup_free_ *d = NULL;
         int r;
 
         assert(m);
 
         set_free_free(m->unit_path_cache);
 
-        if (!(m->unit_path_cache = set_new(string_hash_func, string_compare_func))) {
+        m->unit_path_cache = set_new(string_hash_func, string_compare_func);
+        if (!m->unit_path_cache) {
                 log_error("Failed to allocate unit path cache.");
                 return;
         }
@@ -639,7 +648,8 @@ static void manager_build_unit_path_cache(Manager *m) {
 
                 d = opendir(*i);
                 if (!d) {
-                        log_error("Failed to open directory: %m");
+                        if (errno != ENOENT)
+                                log_error("Failed to open directory %s: %m", *i);
                         continue;
                 }
 
@@ -655,7 +665,8 @@ static void manager_build_unit_path_cache(Manager *m) {
                                 goto fail;
                         }
 
-                        if ((r = set_put(m->unit_path_cache, p)) < 0) {
+                        r = set_put(m->unit_path_cache, p);
+                        if (r < 0) {
                                 free(p);
                                 goto fail;
                         }
@@ -672,9 +683,6 @@ fail:
 
         set_free_free(m->unit_path_cache);
         m->unit_path_cache = NULL;
-
-        if (d)
-                closedir(d);
 }
 
 int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
@@ -758,7 +766,7 @@ int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool ove
 
         job_type_collapse(&type, unit);
 
-        tr = transaction_new();
+        tr = transaction_new(mode == JOB_REPLACE_IRREVERSIBLY);
         if (!tr)
                 return -ENOMEM;
 
@@ -1850,6 +1858,7 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool serialize_jobs) {
         Iterator i;
         Unit *u;
         const char *t;
+        char **e;
         int r;
 
         assert(m);
@@ -1873,6 +1882,14 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool serialize_jobs) {
                 dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp);
         }
 
+        STRV_FOREACH(e, m->environment) {
+                _cleanup_free_ char *ce;
+
+                ce = cescape(*e);
+                if (ce)
+                        fprintf(f, "env=%s\n", *e);
+        }
+
         fputc('\n', f);
 
         HASHMAP_FOREACH_KEY(u, t, m->units, i) {
@@ -1973,7 +1990,25 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
                         dual_timestamp_deserialize(l+20, &m->userspace_timestamp);
                 else if (startswith(l, "finish-timestamp="))
                         dual_timestamp_deserialize(l+17, &m->finish_timestamp);
-                else
+                else if (startswith(l, "env=")) {
+                        _cleanup_free_ char *uce = NULL;
+                        char **e;
+
+                        uce = cunescape(l+4);
+                        if (!uce) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        e = strv_env_set(m->environment, uce);
+                        if (!e) {
+                                r = -ENOMEM;
+                                goto finish;
+                        }
+
+                        strv_free(m->environment);
+                        m->environment = e;
+                } else
                         log_debug("Unknown serialization item '%s'", l);
         }
 
@@ -2261,7 +2296,8 @@ static int create_generator_dir(Manager *m, char **generator, const char *name)
 
                 r = mkdir_p_label(p, 0755);
                 if (r < 0) {
-                        log_error("Failed to create generator directory: %s", strerror(-r));
+                        log_error("Failed to create generator directory %s: %s",
+                                  p, strerror(-r));
                         free(p);
                         return r;
                 }
@@ -2272,7 +2308,8 @@ static int create_generator_dir(Manager *m, char **generator, const char *name)
 
                 if (!mkdtemp(p)) {
                         free(p);
-                        log_error("Failed to create generator directory: %m");
+                        log_error("Failed to create generator directory %s: %m",
+                                  p);
                         return -errno;
                 }
         }
@@ -2311,7 +2348,8 @@ void manager_run_generators(Manager *m) {
                 if (errno == ENOENT)
                         return;
 
-                log_error("Failed to enumerate generator directory: %m");
+                log_error("Failed to enumerate generator directory %s: %m",
+                          generator_path);
                 return;
         }
 
@@ -2456,6 +2494,20 @@ bool manager_get_show_status(Manager *m) {
         return plymouth_running();
 }
 
+void manager_status_printf(Manager *m, const char *status, const char *format, ...) {
+        va_list ap;
+
+        if (!manager_get_show_status(m))
+                return;
+
+        if (!manager_is_booting_or_shutting_down(m))
+                return;
+
+        va_start(ap, format);
+        status_vprintf(status, true, format, ap);
+        va_end(ap);
+}
+
 void watch_init(Watch *w) {
         assert(w);