chiark / gitweb /
Fix possible lack of status messages on shutdown/reboot
[elogind.git] / src / core / job.c
index d5b7987a00734c62b8465efd993481c3342684a6..0dd161c1c58104313214d6b01c2bef7fca019276 100644 (file)
@@ -35,7 +35,7 @@
 #include "log.h"
 #include "dbus-job.h"
 #include "special.h"
-#include "sync.h"
+#include "async.h"
 #include "virt.h"
 
 JobBusClient* job_bus_client_new(DBusConnection *connection, const char *name) {
@@ -99,10 +99,10 @@ void job_free(Job *j) {
         assert(!j->object_list);
 
         if (j->in_run_queue)
-                LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
+                LIST_REMOVE(run_queue, j->manager->run_queue, j);
 
         if (j->in_dbus_queue)
-                LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j);
+                LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
 
         if (j->timer_watch.type != WATCH_INVALID) {
                 assert(j->timer_watch.type == WATCH_JOB_TIMER);
@@ -114,7 +114,7 @@ void job_free(Job *j) {
         }
 
         while ((cl = j->bus_client_list)) {
-                LIST_REMOVE(JobBusClient, client, j->bus_client_list, cl);
+                LIST_REMOVE(client, j->bus_client_list, cl);
                 free(cl);
         }
         free(j);
@@ -267,9 +267,9 @@ JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool
         l->conflicts = conflicts;
 
         if (subject)
-                LIST_PREPEND(JobDependency, subject, subject->subject_list, l);
+                LIST_PREPEND(subject, subject->subject_list, l);
 
-        LIST_PREPEND(JobDependency, object, object->object_list, l);
+        LIST_PREPEND(object, object->object_list, l);
 
         return l;
 }
@@ -278,9 +278,9 @@ void job_dependency_free(JobDependency *l) {
         assert(l);
 
         if (l->subject)
-                LIST_REMOVE(JobDependency, subject, l->subject->subject_list, l);
+                LIST_REMOVE(subject, l->subject->subject_list, l);
 
-        LIST_REMOVE(JobDependency, object, l->object->object_list, l);
+        LIST_REMOVE(object, l->object->object_list, l);
 
         free(l);
 }
@@ -416,7 +416,7 @@ int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) {
         return 0;
 }
 
-bool job_is_runnable(Job *j) {
+static bool job_is_runnable(Job *j) {
         Iterator i;
         Unit *other;
 
@@ -491,7 +491,7 @@ int job_run_and_invalidate(Job *j) {
         assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
         assert(j->in_run_queue);
 
-        LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
+        LIST_REMOVE(run_queue, j->manager->run_queue, j);
         j->in_run_queue = false;
 
         if (j->state != JOB_WAITING)
@@ -569,7 +569,7 @@ int job_run_and_invalidate(Job *j) {
         return r;
 }
 
-static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) {
+_pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) {
         const UnitStatusMessageFormats *format_table;
 
         assert(u);
@@ -588,7 +588,7 @@ static const char *job_get_status_message_format(Unit *u, JobType t, JobResult r
         return NULL;
 }
 
-static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) {
+_pure_ static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) {
         const char *format;
 
         assert(u);
@@ -840,9 +840,11 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
                            job_result_to_string(result),
                            NULL);
 
-                unit_trigger_on_failure(u);
+                unit_start_on_failure(u);
         }
 
+        unit_trigger_notify(u);
+
 finish:
         /* Try to start the next jobs that can be started */
         SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
@@ -858,10 +860,12 @@ finish:
 }
 
 int job_start_timer(Job *j) {
-        struct itimerspec its;
-        struct epoll_event ev;
+        struct itimerspec its = {};
+        struct epoll_event ev = {
+                .data.ptr = &j->timer_watch,
+                .events = EPOLLIN,
+        };
         int fd, r;
-        assert(j);
 
         if (j->unit->job_timeout <= 0 ||
             j->timer_watch.type == WATCH_JOB_TIMER)
@@ -874,7 +878,6 @@ int job_start_timer(Job *j) {
                 goto fail;
         }
 
-        zero(its);
         timespec_store(&its.it_value, j->unit->job_timeout);
 
         if (timerfd_settime(fd, 0, &its, NULL) < 0) {
@@ -882,10 +885,6 @@ int job_start_timer(Job *j) {
                 goto fail;
         }
 
-        zero(ev);
-        ev.data.ptr = &j->timer_watch;
-        ev.events = EPOLLIN;
-
         if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
                 r = -errno;
                 goto fail;
@@ -911,7 +910,7 @@ void job_add_to_run_queue(Job *j) {
         if (j->in_run_queue)
                 return;
 
-        LIST_PREPEND(Job, run_queue, j->manager->run_queue, j);
+        LIST_PREPEND(run_queue, j->manager->run_queue, j);
         j->in_run_queue = true;
 }
 
@@ -926,7 +925,7 @@ void job_add_to_dbus_queue(Job *j) {
          * job might just have been created and not yet assigned to a
          * connection/client. */
 
-        LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
+        LIST_PREPEND(dbus_queue, j->manager->dbus_job_queue, j);
         j->in_dbus_queue = true;
 }
 
@@ -1064,15 +1063,14 @@ int job_deserialize(Job *j, FILE *f, FDSet *fds) {
 }
 
 int job_coldplug(Job *j) {
-        struct epoll_event ev;
+        struct epoll_event ev = {
+                .data.ptr = &j->timer_watch,
+                .events = EPOLLIN,
+        };
 
         if (j->timer_watch.type != WATCH_JOB_TIMER)
                 return 0;
 
-        zero(ev);
-        ev.data.ptr = &j->timer_watch;
-        ev.events = EPOLLIN;
-
         if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, j->timer_watch.fd, &ev) < 0)
                 return -errno;
 
@@ -1090,12 +1088,18 @@ void job_shutdown_magic(Job *j) {
          * asynchronous sync() would cause their exit to be
          * delayed. */
 
-        if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET))
+        if (j->type != JOB_START)
                 return;
 
-        if (j->type != JOB_START)
+        if (j->unit->manager->running_as != SYSTEMD_SYSTEM)
                 return;
 
+        if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET))
+                return;
+
+        /* In case messages on console has been disabled on boot */
+        j->unit->manager->no_console_output = false;
+
         if (detect_container(NULL) > 0)
                 return;