chiark / gitweb /
systemd: record the timestamps as early as possible
[elogind.git] / src / core / manager.c
index e26522a4dd0944460c9e3baca37ee05522eace40..2265ef7173716d0be419b7853e027a974137a396 100644 (file)
@@ -70,7 +70,6 @@
 #include "cgroup-util.h"
 #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 */
@@ -93,12 +92,15 @@ static int manager_setup_notify(Manager *m) {
         union {
                 struct sockaddr sa;
                 struct sockaddr_un un;
-        } sa;
-        struct epoll_event ev;
+        } sa = {
+                .sa.sa_family = AF_UNIX,
+        };
+        struct epoll_event ev = {
+                .events = EPOLLIN,
+                .data.ptr = &m->notify_watch,
+        };
         int one = 1, r;
 
-        assert(m);
-
         m->notify_watch.type = WATCH_NOTIFY;
         m->notify_watch.fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
         if (m->notify_watch.fd < 0) {
@@ -106,9 +108,6 @@ static int manager_setup_notify(Manager *m) {
                 return -errno;
         }
 
-        zero(sa);
-        sa.sa.sa_family = AF_UNIX;
-
         if (getpid() != 1 || detect_container(NULL) > 0)
                 snprintf(sa.un.sun_path, sizeof(sa.un.sun_path), NOTIFY_SOCKET "/%llu", random_ull());
         else
@@ -129,10 +128,6 @@ static int manager_setup_notify(Manager *m) {
                 return -errno;
         }
 
-        zero(ev);
-        ev.events = EPOLLIN;
-        ev.data.ptr = &m->notify_watch;
-
         r = epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev);
         if (r < 0) {
                 log_error("Failed to add notification socket fd to epoll: %m");
@@ -150,16 +145,14 @@ static int manager_setup_notify(Manager *m) {
 }
 
 static int manager_jobs_in_progress_mod_timer(Manager *m) {
-        struct itimerspec its;
+        struct itimerspec its = {
+                .it_value.tv_sec = JOBS_IN_PROGRESS_WAIT_SEC,
+                .it_interval.tv_sec = JOBS_IN_PROGRESS_PERIOD_SEC,
+        };
 
         if (m->jobs_in_progress_watch.type != WATCH_JOBS_IN_PROGRESS)
                 return 0;
 
-        zero(its);
-
-        its.it_value.tv_sec = JOBS_IN_PROGRESS_WAIT_SEC;
-        its.it_interval.tv_sec = JOBS_IN_PROGRESS_PERIOD_SEC;
-
         if (timerfd_settime(m->jobs_in_progress_watch.fd, 0, &its, NULL) < 0)
                 return -errno;
 
@@ -167,11 +160,12 @@ static int manager_jobs_in_progress_mod_timer(Manager *m) {
 }
 
 static int manager_watch_jobs_in_progress(Manager *m) {
-        struct epoll_event ev;
+        struct epoll_event ev = {
+                .events = EPOLLIN,
+                .data.ptr = &m->jobs_in_progress_watch,
+        };
         int r;
 
-        assert(m);
-
         if (m->jobs_in_progress_watch.type != WATCH_INVALID)
                 return 0;
 
@@ -189,10 +183,6 @@ static int manager_watch_jobs_in_progress(Manager *m) {
                 goto err;
         }
 
-        zero(ev);
-        ev.events = EPOLLIN;
-        ev.data.ptr = &m->jobs_in_progress_watch;
-
         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->jobs_in_progress_watch.fd, &ev) < 0) {
                 log_error("Failed to add jobs progress timer fd to epoll: %m");
                 r = -errno;
@@ -287,10 +277,18 @@ static void manager_print_jobs_in_progress(Manager *m) {
 }
 
 static int manager_setup_time_change(Manager *m) {
-        struct epoll_event ev;
-        struct itimerspec its;
+        struct epoll_event ev = {
+                .events = EPOLLIN,
+                .data.ptr = &m->time_change_watch,
+        };
+
+        /* We only care for the cancellation event, hence we set the
+         * timeout to the latest possible value. */
+        struct itimerspec its = {
+                .it_value.tv_sec = TIME_T_MAX,
+        };
+        assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
 
-        assert(m);
         assert(m->time_change_watch.type == WATCH_INVALID);
 
         /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever
@@ -303,13 +301,6 @@ static int manager_setup_time_change(Manager *m) {
                 return -errno;
         }
 
-        zero(its);
-
-        /* We only care for the cancellation event, hence we set the
-         * timeout to the latest possible value. */
-        assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX));
-        its.it_value.tv_sec = TIME_T_MAX;
-
         if (timerfd_settime(m->time_change_watch.fd, TFD_TIMER_ABSTIME|TFD_TIMER_CANCEL_ON_SET, &its, NULL) < 0) {
                 log_debug("Failed to set up TFD_TIMER_CANCEL_ON_SET, ignoring: %m");
                 close_nointr_nofail(m->time_change_watch.fd);
@@ -317,10 +308,6 @@ static int manager_setup_time_change(Manager *m) {
                 return 0;
         }
 
-        zero(ev);
-        ev.events = EPOLLIN;
-        ev.data.ptr = &m->time_change_watch;
-
         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->time_change_watch.fd, &ev) < 0) {
                 log_error("Failed to add timer change fd to epoll: %m");
                 return -errno;
@@ -360,15 +347,18 @@ static int enable_special_signals(Manager *m) {
 
 static int manager_setup_signals(Manager *m) {
         sigset_t mask;
-        struct epoll_event ev;
-        struct sigaction sa;
+        struct epoll_event ev = {
+                .events = EPOLLIN,
+                .data.ptr = &m->signal_watch,
+        };
+        struct sigaction sa = {
+                .sa_handler = SIG_DFL,
+                .sa_flags = SA_NOCLDSTOP|SA_RESTART,
+        };
 
         assert(m);
 
         /* We are not interested in SIGSTOP and friends. */
-        zero(sa);
-        sa.sa_handler = SIG_DFL;
-        sa.sa_flags = SA_NOCLDSTOP|SA_RESTART;
         assert_se(sigaction(SIGCHLD, &sa, NULL) == 0);
 
         assert_se(sigemptyset(&mask) == 0);
@@ -410,10 +400,6 @@ static int manager_setup_signals(Manager *m) {
         if (m->signal_watch.fd < 0)
                 return -errno;
 
-        zero(ev);
-        ev.events = EPOLLIN;
-        ev.data.ptr = &m->signal_watch;
-
         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->signal_watch.fd, &ev) < 0)
                 return -errno;
 
@@ -453,12 +439,6 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) {
         if (!m)
                 return -ENOMEM;
 
-        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;
         m->exit_code = _MANAGER_EXIT_CODE_INVALID;
@@ -779,7 +759,7 @@ int manager_coldplug(Manager *m) {
 
 static void manager_build_unit_path_cache(Manager *m) {
         char **i;
-        DIR _cleanup_free_ *d = NULL;
+        _cleanup_free_ DIR *d = NULL;
         int r;
 
         assert(m);
@@ -817,11 +797,9 @@ static void manager_build_unit_path_cache(Manager *m) {
                                 goto fail;
                         }
 
-                        r = set_put(m->unit_path_cache, p);
-                        if (r < 0) {
-                                free(p);
+                        r = set_consume(m->unit_path_cache, p);
+                        if (r < 0)
                                 goto fail;
-                        }
                 }
 
                 closedir(d);
@@ -1184,30 +1162,29 @@ static int manager_process_notify_fd(Manager *m) {
 
         for (;;) {
                 char buf[4096];
-                struct msghdr msghdr;
-                struct iovec iovec;
-                struct ucred *ucred;
+                struct iovec iovec = {
+                        .iov_base = buf,
+                        .iov_len = sizeof(buf)-1,
+                };
+
                 union {
                         struct cmsghdr cmsghdr;
                         uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
-                } control;
+                } control = {};
+
+                struct msghdr msghdr = {
+                        .msg_iov = &iovec,
+                        .msg_iovlen = 1,
+                        .msg_control = &control,
+                        .msg_controllen = sizeof(control),
+                };
+                struct ucred *ucred;
                 Unit *u;
-                char _cleanup_strv_free_ **tags = NULL;
-
-                zero(iovec);
-                iovec.iov_base = buf;
-                iovec.iov_len = sizeof(buf)-1;
-
-                zero(control);
-                zero(msghdr);
-                msghdr.msg_iov = &iovec;
-                msghdr.msg_iovlen = 1;
-                msghdr.msg_control = &control;
-                msghdr.msg_controllen = sizeof(control);
+                _cleanup_strv_free_ char **tags = NULL;
 
                 n = recvmsg(m->notify_watch.fd, &msghdr, MSG_DONTWAIT);
                 if (n <= 0) {
-                        if (n >= 0)
+                        if (n == 0)
                                 return -EIO;
 
                         if (errno == EAGAIN || errno == EINTR)
@@ -1254,12 +1231,10 @@ static int manager_dispatch_sigchld(Manager *m) {
         assert(m);
 
         for (;;) {
-                siginfo_t si;
+                siginfo_t si = {};
                 Unit *u;
                 int r;
 
-                zero(si);
-
                 /* First we call waitd() for a PID and do not reap the
                  * zombie. That way we can still access /proc/$PID for
                  * it while it is a zombie. */
@@ -1278,7 +1253,7 @@ static int manager_dispatch_sigchld(Manager *m) {
                         break;
 
                 if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
-                        char _cleanup_free_ *name = NULL;
+                        _cleanup_free_ char *name = NULL;
 
                         get_process_comm(si.si_pid, &name);
                         log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name));
@@ -2020,7 +1995,7 @@ int manager_open_serialization(Manager *m, FILE **_f) {
         return 0;
 }
 
-int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool serialize_jobs) {
+int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
         Iterator i;
         Unit *u;
         const char *t;
@@ -2048,12 +2023,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;
+        if (!switching_root) {
+                STRV_FOREACH(e, m->environment) {
+                        _cleanup_free_ char *ce;
 
-                ce = cescape(*e);
-                if (ce)
-                        fprintf(f, "env=%s\n", *e);
+                        ce = cescape(*e);
+                        if (ce)
+                                fprintf(f, "env=%s\n", *e);
+                }
         }
 
         fputc('\n', f);
@@ -2069,7 +2046,7 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool serialize_jobs) {
                 fputs(u->id, f);
                 fputc('\n', f);
 
-                if ((r = unit_serialize(u, f, fds, serialize_jobs)) < 0) {
+                if ((r = unit_serialize(u, f, fds, !switching_root)) < 0) {
                         m->n_reloading --;
                         return r;
                 }
@@ -2257,7 +2234,7 @@ int manager_reload(Manager *m) {
                 goto finish;
         }
 
-        r = manager_serialize(m, f, fds, true);
+        r = manager_serialize(m, f, fds, false);
         if (r < 0) {
                 m->n_reloading --;
                 goto finish;