chiark / gitweb /
unit: don't serialize job state, only unit state across switch-root
[elogind.git] / src / core / unit.c
index f53bdd5a911addb49980da9af5a94fa5042a8e77..ae6f69183d284055ec624391c9670a80a1a8a3e8 100644 (file)
@@ -1144,7 +1144,7 @@ static void retroactively_start_dependencies(Unit *u) {
                     !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
                         manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
 
-        SET_FOREACH(other, u->dependencies[UNIT_BIND_TO], i)
+        SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
                 if (!set_get(u->dependencies[UNIT_AFTER], other) &&
                     !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
                         manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
@@ -1209,7 +1209,7 @@ static void check_unneeded_dependencies(Unit *u) {
         SET_FOREACH(other, u->dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
                 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
                         unit_check_unneeded(other);
-        SET_FOREACH(other, u->dependencies[UNIT_BIND_TO], i)
+        SET_FOREACH(other, u->dependencies[UNIT_BINDS_TO], i)
                 if (!UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(other)))
                         unit_check_unneeded(other);
 }
@@ -1595,11 +1595,11 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
                 [UNIT_WANTS] = UNIT_WANTED_BY,
                 [UNIT_REQUISITE] = UNIT_REQUIRED_BY,
                 [UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
-                [UNIT_BIND_TO] = UNIT_BOUND_BY,
+                [UNIT_BINDS_TO] = UNIT_BOUND_BY,
                 [UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
                 [UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
                 [UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
-                [UNIT_BOUND_BY] = UNIT_BIND_TO,
+                [UNIT_BOUND_BY] = UNIT_BINDS_TO,
                 [UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
                 [UNIT_CONFLICTED_BY] = UNIT_CONFLICTS,
                 [UNIT_BEFORE] = UNIT_AFTER,
@@ -1609,8 +1609,8 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
                 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
                 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
                 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
-                [UNIT_PROPAGATE_RELOAD_TO] = UNIT_PROPAGATE_RELOAD_FROM,
-                [UNIT_PROPAGATE_RELOAD_FROM] = UNIT_PROPAGATE_RELOAD_TO
+                [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
+                [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO
         };
         int r, q = 0, v = 0, w = 0;
 
@@ -1835,20 +1835,12 @@ int set_unit_path(const char *p) {
 }
 
 char *unit_dbus_path(Unit *u) {
-        char *p, *e;
-
         assert(u);
 
         if (!u->id)
                 return NULL;
 
-        if (!(e = bus_path_escape(u->id)))
-                return NULL;
-
-        p = strappend("/org/freedesktop/systemd1/unit/", e);
-        free(e);
-
-        return p;
+        return unit_dbus_path_from_name(u->id);
 }
 
 int unit_add_cgroup(Unit *u, CGroupBonding *b) {
@@ -1899,10 +1891,10 @@ static char *default_cgroup_path(Unit *u) {
                 if (!t)
                         return NULL;
 
-                p = join(u->manager->cgroup_hierarchy, "/", t, "/", u->instance, NULL);
+                p = strjoin(u->manager->cgroup_hierarchy, "/", t, "/", u->instance, NULL);
                 free(t);
         } else
-                p = join(u->manager->cgroup_hierarchy, "/", u->id, NULL);
+                p = strjoin(u->manager->cgroup_hierarchy, "/", u->id, NULL);
 
         return p;
 }
@@ -2229,6 +2221,72 @@ static char *specifier_runtime(char specifier, void *data, void *userdata) {
         return strdup("/run");
 }
 
+static char *specifier_user_name(char specifier, void *data, void *userdata) {
+        Service *s = userdata;
+        int r;
+        const char *username;
+
+        /* get USER env from our own env if set */
+        if (!s->exec_context.user)
+                return getusername_malloc();
+
+        /* fish username from passwd */
+        username = s->exec_context.user;
+        r = get_user_creds(&username, NULL, NULL, NULL, NULL);
+        if (r < 0)
+                return NULL;
+
+        return strdup(username);
+}
+
+static char *specifier_user_home(char specifier, void *data, void *userdata) {
+        Service *s = userdata;
+        int r;
+        const char *username, *home;
+
+        /* return HOME if set, otherwise from passwd */
+        if (!s->exec_context.user) {
+                char *h;
+
+                r = get_home_dir(&h);
+                if (r < 0)
+                        return NULL;
+
+                return h;
+        }
+
+        username = s->exec_context.user;
+        r = get_user_creds(&username, NULL, NULL, &home, NULL);
+        if (r < 0)
+               return NULL;
+
+        return strdup(home);
+}
+
+static char *specifier_user_shell(char specifier, void *data, void *userdata) {
+        Service *s = userdata;
+        int r;
+        const char *username, *shell;
+
+        /* return HOME if set, otherwise from passwd */
+        if (!s->exec_context.user) {
+                char *sh;
+
+                r = get_shell(&sh);
+                if (r < 0)
+                        return strdup("/bin/sh");
+
+                return sh;
+        }
+
+        username = s->exec_context.user;
+        r = get_user_creds(&username, NULL, NULL, NULL, &shell);
+        if (r < 0)
+                return strdup("/bin/sh");
+
+        return strdup(shell);
+}
+
 char *unit_name_printf(Unit *u, const char* format) {
 
         /*
@@ -2264,6 +2322,8 @@ char *unit_full_printf(Unit *u, const char *format) {
          * %r root cgroup path of this systemd instance (e.g. "/user/lennart/shared/systemd-4711")
          * %R parent of root cgroup path (e.g. "/usr/lennart/shared")
          * %t the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR)
+         * %u the username of the configured User or running user
+         * %h the homedir of the configured User or running user
          */
 
         const Specifier table[] = {
@@ -2278,6 +2338,9 @@ char *unit_full_printf(Unit *u, const char *format) {
                 { 'r', specifier_cgroup_root,         NULL },
                 { 'R', specifier_cgroup_root,         NULL },
                 { 't', specifier_runtime,             NULL },
+                { 'u', specifier_user_name,           NULL },
+                { 'h', specifier_user_home,           NULL },
+                { 's', specifier_user_shell,          NULL },
                 { 0, NULL, NULL }
         };
 
@@ -2338,7 +2401,7 @@ bool unit_can_serialize(Unit *u) {
         return UNIT_VTABLE(u)->serialize && UNIT_VTABLE(u)->deserialize_item;
 }
 
-int unit_serialize(Unit *u, FILE *f, FDSet *fds) {
+int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
         int r;
 
         assert(u);
@@ -2351,14 +2414,17 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds) {
         if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0)
                 return r;
 
-        if (u->job) {
-                fprintf(f, "job\n");
-                job_serialize(u->job, f, fds);
-        }
 
-        if (u->nop_job) {
-                fprintf(f, "job\n");
-                job_serialize(u->nop_job, f, fds);
+        if (serialize_jobs) {
+                if (u->job) {
+                        fprintf(f, "job\n");
+                        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);
@@ -2517,7 +2583,8 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) {
         if (!is_device_path(what))
                 return 0;
 
-        if (!(e = unit_name_build_escape(what+1, NULL, ".device")))
+        e = unit_name_from_path(what, ".device");
+        if (!e)
                 return -ENOMEM;
 
         r = manager_load_unit(u->manager, e, NULL, NULL, &device);
@@ -2526,7 +2593,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants) {
         if (r < 0)
                 return r;
 
-        if ((r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BIND_TO, device, true)) < 0)
+        if ((r = unit_add_two_dependencies(u, UNIT_AFTER, UNIT_BINDS_TO, device, true)) < 0)
                 return r;
 
         if (wants)
@@ -2654,28 +2721,6 @@ bool unit_pending_active(Unit *u) {
         return false;
 }
 
-UnitType unit_name_to_type(const char *n) {
-        UnitType t;
-
-        assert(n);
-
-        for (t = 0; t < _UNIT_TYPE_MAX; t++)
-                if (endswith(n, unit_vtable[t]->suffix))
-                        return t;
-
-        return _UNIT_TYPE_INVALID;
-}
-
-bool unit_name_is_valid(const char *n, bool template_ok) {
-        UnitType t;
-
-        t = unit_name_to_type(n);
-        if (t < 0 || t >= _UNIT_TYPE_MAX)
-                return false;
-
-        return unit_name_is_valid_no_type(n, template_ok);
-}
-
 int unit_kill(Unit *u, KillWho w, KillMode m, int signo, DBusError *error) {
         assert(u);
         assert(w >= 0 && w < _KILL_WHO_MAX);
@@ -2775,15 +2820,18 @@ int unit_add_mount_links(Unit *u) {
         return 0;
 }
 
-static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
-        [UNIT_STUB] = "stub",
-        [UNIT_LOADED] = "loaded",
-        [UNIT_ERROR] = "error",
-        [UNIT_MERGED] = "merged",
-        [UNIT_MASKED] = "masked"
-};
+int unit_patch_working_directory(Unit *u, ExecContext *c) {
+        assert(u);
+        assert(c);
+
+        if (u->manager->running_as != MANAGER_USER)
+                return 0;
 
-DEFINE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState);
+        if (c->working_directory)
+                return 0;
+
+        return get_home_dir(&c->working_directory);
+}
 
 static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
         [UNIT_ACTIVE] = "active",
@@ -2804,7 +2852,7 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
         [UNIT_REQUISITE_OVERRIDABLE] = "RequisiteOverridable",
         [UNIT_REQUIRED_BY] = "RequiredBy",
         [UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
-        [UNIT_BIND_TO] = "BindTo",
+        [UNIT_BINDS_TO] = "BindsTo",
         [UNIT_WANTED_BY] = "WantedBy",
         [UNIT_CONFLICTS] = "Conflicts",
         [UNIT_CONFLICTED_BY] = "ConflictedBy",
@@ -2816,8 +2864,8 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
         [UNIT_ON_FAILURE] = "OnFailure",
         [UNIT_TRIGGERS] = "Triggers",
         [UNIT_TRIGGERED_BY] = "TriggeredBy",
-        [UNIT_PROPAGATE_RELOAD_TO] = "PropagateReloadTo",
-        [UNIT_PROPAGATE_RELOAD_FROM] = "PropagateReloadFrom"
+        [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
+        [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom"
 };
 
 DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);