chiark / gitweb /
units: introduce and explain sysinit.target
[elogind.git] / src / unit.c
index bcb95b2adc1740e1d87cdee8e1c8f0dcd556c8b2..bb2b8c2fe010cb917b2f1df95b622528b332cf81 100644 (file)
@@ -48,7 +48,8 @@ const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
         [UNIT_MOUNT] = &mount_vtable,
         [UNIT_AUTOMOUNT] = &automount_vtable,
         [UNIT_SNAPSHOT] = &snapshot_vtable,
-        [UNIT_SWAP] = &swap_vtable
+        [UNIT_SWAP] = &swap_vtable,
+        [UNIT_PATH] = &path_vtable
 };
 
 Unit *unit_new(Manager *m) {
@@ -66,6 +67,7 @@ Unit *unit_new(Manager *m) {
 
         u->meta.manager = m;
         u->meta.type = _UNIT_TYPE_INVALID;
+        u->meta.deserialized_job = _JOB_TYPE_INVALID;
 
         return u;
 }
@@ -534,7 +536,10 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
         assert(u);
         assert(c);
 
-        if (c->std_output != EXEC_OUTPUT_KMSG && c->std_output != EXEC_OUTPUT_SYSLOG)
+        if (c->std_output != EXEC_OUTPUT_KMSG &&
+            c->std_output != EXEC_OUTPUT_SYSLOG &&
+            c->std_error != EXEC_OUTPUT_KMSG &&
+            c->std_error != EXEC_OUTPUT_SYSLOG)
                 return 0;
 
         /* If syslog or kernel logging is requested, make sure our own
@@ -590,17 +595,19 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
                 "%s\tActive Enter Timestamp: %s\n"
                 "%s\tActive Exit Timestamp: %s\n"
                 "%s\tInactive Enter Timestamp: %s\n"
-                "%s\tGC Check Good: %s\n",
+                "%s\tGC Check Good: %s\n"
+                "%s\tOnly By Dependency: %s\n",
                 prefix, u->meta.id,
                 prefix, unit_description(u),
                 prefix, strna(u->meta.instance),
                 prefix, unit_load_state_to_string(u->meta.load_state),
                 prefix, unit_active_state_to_string(unit_active_state(u)),
-                prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->meta.inactive_exit_timestamp)),
-                prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->meta.active_enter_timestamp)),
-                prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->meta.active_exit_timestamp)),
-                prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->meta.inactive_enter_timestamp)),
-                prefix, yes_no(unit_check_gc(u)));
+                prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->meta.inactive_exit_timestamp.realtime)),
+                prefix, strna(format_timestamp(timestamp2, sizeof(timestamp2), u->meta.active_enter_timestamp.realtime)),
+                prefix, strna(format_timestamp(timestamp3, sizeof(timestamp3), u->meta.active_exit_timestamp.realtime)),
+                prefix, strna(format_timestamp(timestamp4, sizeof(timestamp4), u->meta.inactive_enter_timestamp.realtime)),
+                prefix, yes_no(unit_check_gc(u)),
+                prefix, yes_no(u->meta.only_by_dependency));
 
         SET_FOREACH(t, u->meta.names, i)
                 fprintf(f, "%s\tName: %s\n", prefix, t);
@@ -925,7 +932,7 @@ static void retroactively_stop_dependencies(Unit *u) {
 
 void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
         bool unexpected = false;
-        usec_t ts;
+        timestamp ts;
 
         assert(u);
         assert(os < _UNIT_ACTIVE_STATE_MAX);
@@ -938,7 +945,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
          * this function will be called too and the utmp code below
          * relies on that! */
 
-        ts = now(CLOCK_REALTIME);
+        timestamp_get(&ts);
 
         if (os == UNIT_INACTIVE && ns != UNIT_INACTIVE)
                 u->meta.inactive_exit_timestamp = ts;
@@ -950,6 +957,9 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
         else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
                 u->meta.active_exit_timestamp = ts;
 
+        timer_unit_notify(u, ns);
+        path_unit_notify(u, ns);
+
         if (u->meta.job) {
 
                 if (u->meta.job->state == JOB_WAITING)
@@ -1785,6 +1795,9 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds) {
         if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0)
                 return r;
 
+        if (u->meta.job)
+                unit_serialize_item(u, f, "job", job_type_to_string(u->meta.job->type));
+
         /* End marker */
         fputc('\n', f);
         return 0;
@@ -1851,6 +1864,17 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
                 } else
                         v = l+k;
 
+                if (streq(l, "job")) {
+                        JobType type;
+
+                        if ((type = job_type_from_string(v)) < 0)
+                                log_debug("Failed to parse job type value %s", v);
+                        else
+                                u->meta.deserialized_job = type;
+
+                        continue;
+                }
+
                 if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0)
                         return r;
         }
@@ -1893,6 +1917,25 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) {
         return 0;
 }
 
+int unit_coldplug(Unit *u) {
+        int r;
+
+        assert(u);
+
+        if (UNIT_VTABLE(u)->coldplug)
+                if ((r = UNIT_VTABLE(u)->coldplug(u)) < 0)
+                        return r;
+
+        if (u->meta.deserialized_job >= 0) {
+                if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_FAIL, false, NULL)) < 0)
+                        return r;
+
+                u->meta.deserialized_job = _JOB_TYPE_INVALID;
+        }
+
+        return 0;
+}
+
 static const char* const unit_type_table[_UNIT_TYPE_MAX] = {
         [UNIT_SERVICE] = "service",
         [UNIT_TIMER] = "timer",