chiark / gitweb /
unit: print the color status marks on the left
[elogind.git] / src / core / unit.c
index c5fde63afb7727a9e776252553373a8f92b89a8a..ddcfad59128031e0c21ac21ac3c84c62f60d2b47 100644 (file)
@@ -33,6 +33,7 @@
 #include "unit.h"
 #include "macro.h"
 #include "strv.h"
+#include "path-util.h"
 #include "load-fragment.h"
 #include "load-dropin.h"
 #include "log.h"
@@ -249,6 +250,9 @@ bool unit_check_gc(Unit *u) {
         if (u->job)
                 return true;
 
+        if (u->nop_job)
+                return true;
+
         if (unit_active_state(u) != UNIT_INACTIVE)
                 return true;
 
@@ -358,9 +362,20 @@ void unit_free(Unit *u) {
                 job_free(j);
         }
 
+        if (u->nop_job) {
+                Job *j = u->nop_job;
+                job_uninstall(j);
+                job_free(j);
+        }
+
         for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
                 bidi_set_free(u, u->dependencies[d]);
 
+        if (u->requires_mounts_for) {
+                LIST_REMOVE(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u);
+                strv_free(u->requires_mounts_for);
+        }
+
         if (u->type != _UNIT_TYPE_INVALID)
                 LIST_REMOVE(Unit, units_by_type, u->manager->units_by_type[u->type], u);
 
@@ -501,6 +516,9 @@ int unit_merge(Unit *u, Unit *other) {
         if (other->job)
                 return -EEXIST;
 
+        if (other->nop_job)
+                return -EEXIST;
+
         if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other)))
                 return -EEXIST;
 
@@ -679,6 +697,18 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
                         fprintf(f, "%s\t%s: %s\n", prefix, unit_dependency_to_string(d), other->id);
         }
 
+        if (!strv_isempty(u->requires_mounts_for)) {
+                char **j;
+
+                fprintf(f,
+                        "%s\tRequiresMountsFor:", prefix);
+
+                STRV_FOREACH(j, u->requires_mounts_for)
+                        fprintf(f, " %s", *j);
+
+                fputs("\n", f);
+        }
+
         if (u->load_state == UNIT_LOADED) {
                 CGroupBonding *b;
                 CGroupAttribute *a;
@@ -729,6 +759,9 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
         if (u->job)
                 job_dump(u->job, f, prefix2);
 
+        if (u->nop_job)
+                job_dump(u->nop_job, f, prefix2);
+
         free(p2);
 }
 
@@ -854,6 +887,12 @@ int unit_load(Unit *u) {
                 if ((r = unit_add_default_dependencies(u)) < 0)
                         goto fail;
 
+        if (u->load_state == UNIT_LOADED) {
+                r = unit_add_mount_links(u);
+                if (r < 0)
+                        return r;
+        }
+
         if (u->on_failure_isolate &&
             set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
 
@@ -942,7 +981,7 @@ int unit_start(Unit *u) {
 
         unit_add_to_dbus_queue(u);
 
-        unit_status_printf(u, NULL, "Starting %s...", unit_description(u));
+        unit_status_printf(u, "", "Starting %s...", unit_description(u));
         return UNIT_VTABLE(u)->start(u);
 }
 
@@ -984,7 +1023,7 @@ int unit_stop(Unit *u) {
 
         unit_add_to_dbus_queue(u);
 
-        unit_status_printf(u, NULL, "Stopping %s...", unit_description(u));
+        unit_status_printf(u, "", "Stopping %s...", unit_description(u));
         return UNIT_VTABLE(u)->stop(u);
 }
 
@@ -1507,6 +1546,7 @@ bool unit_job_is_applicable(Unit *u, JobType j) {
         case JOB_VERIFY_ACTIVE:
         case JOB_START:
         case JOB_STOP:
+        case JOB_NOP:
                 return true;
 
         case JOB_RESTART:
@@ -1631,7 +1671,7 @@ static const char *resolve_template(Unit *u, const char *name, const char*path,
         assert(name || path);
 
         if (!name)
-                name = file_name_from_path(path);
+                name = path_get_file_name(path);
 
         if (!unit_name_is_template(name)) {
                 *p = NULL;
@@ -2140,7 +2180,7 @@ static char *specifier_cgroup_root(char specifier, void *data, void *userdata) {
         if (specifier == 'r')
                 return strdup(u->manager->cgroup_hierarchy);
 
-        if (parent_of_path(u->manager->cgroup_hierarchy, &p) < 0)
+        if (path_get_parent(u->manager->cgroup_hierarchy, &p) < 0)
                 return strdup("");
 
         if (streq(p, "/")) {
@@ -2293,6 +2333,11 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds) {
                 job_serialize(u->job, f, fds);
         }
 
+        if (u->nop_job) {
+                fprintf(f, "job\n");
+                job_serialize(u->nop_job, f, fds);
+        }
+
         dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->inactive_exit_timestamp);
         dual_timestamp_serialize(f, "active-enter-timestamp", &u->active_enter_timestamp);
         dual_timestamp_serialize(f, "active-exit-timestamp", &u->active_exit_timestamp);
@@ -2382,12 +2427,18 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
                                         return r;
                                 }
 
-                                job_install_deserialized(j);
                                 r = hashmap_put(u->manager->jobs, UINT32_TO_PTR(j->id), j);
                                 if (r < 0) {
                                         job_free(j);
                                         return r;
                                 }
+
+                                r = job_install_deserialized(j);
+                                if (r < 0) {
+                                        hashmap_remove(u->manager->jobs, UINT32_TO_PTR(j->id));
+                                        job_free(j);
+                                        return r;
+                                }
                         } else {
                                 /* legacy */
                                 JobType type = job_type_from_string(v);
@@ -2631,7 +2682,7 @@ UnitFileState unit_get_unit_file_state(Unit *u) {
         if (u->unit_file_state < 0 && u->fragment_path)
                 u->unit_file_state = unit_file_get_state(
                                 u->manager->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER,
-                                NULL, file_name_from_path(u->fragment_path));
+                                NULL, path_get_file_name(u->fragment_path));
 
         return u->unit_file_state;
 }
@@ -2658,6 +2709,45 @@ void unit_ref_unset(UnitRef *ref) {
         ref->unit = NULL;
 }
 
+int unit_add_one_mount_link(Unit *u, Mount *m) {
+        char **i;
+
+        assert(u);
+        assert(m);
+
+        if (u->load_state != UNIT_LOADED ||
+            UNIT(m)->load_state != UNIT_LOADED)
+                return 0;
+
+        STRV_FOREACH(i, u->requires_mounts_for) {
+
+                if (UNIT(m) == u)
+                        continue;
+
+                if (!path_startswith(*i, m->where))
+                        continue;
+
+                return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
+        }
+
+        return 0;
+}
+
+int unit_add_mount_links(Unit *u) {
+        Unit *other;
+        int r;
+
+        assert(u);
+
+        LIST_FOREACH(units_by_type, other, u->manager->units_by_type[UNIT_MOUNT]) {
+                r = unit_add_one_mount_link(u, MOUNT(other));
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
 static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
         [UNIT_STUB] = "stub",
         [UNIT_LOADED] = "loaded",