diff options
Diffstat (limited to 'src/core/unit.c')
-rw-r--r-- | src/core/unit.c | 242 |
1 files changed, 109 insertions, 133 deletions
diff --git a/src/core/unit.c b/src/core/unit.c index 3a6313e4a2..6c130d4cd1 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -20,36 +20,43 @@ ***/ #include <errno.h> -#include <string.h> #include <stdlib.h> -#include <unistd.h> +#include <string.h> #include <sys/stat.h> +#include <unistd.h> #include "sd-id128.h" #include "sd-messages.h" -#include "set.h" -#include "macro.h" -#include "strv.h" -#include "path-util.h" -#include "log.h" + +#include "alloc-util.h" +#include "bus-common-errors.h" +#include "bus-util.h" #include "cgroup-util.h" -#include "missing.h" -#include "mkdir.h" +#include "dbus-unit.h" +#include "dbus.h" +#include "dropin.h" +#include "escape.h" +#include "execute.h" #include "fileio-label.h" #include "formats-util.h" +#include "load-dropin.h" +#include "load-fragment.h" +#include "log.h" +#include "macro.h" +#include "missing.h" +#include "mkdir.h" +#include "parse-util.h" +#include "path-util.h" #include "process-util.h" -#include "virt.h" -#include "bus-common-errors.h" -#include "bus-util.h" -#include "dropin.h" -#include "unit-name.h" +#include "set.h" #include "special.h" +#include "stat-util.h" +#include "string-util.h" +#include "strv.h" +#include "unit-name.h" #include "unit.h" -#include "load-fragment.h" -#include "load-dropin.h" -#include "dbus.h" -#include "dbus-unit.h" -#include "execute.h" +#include "user-util.h" +#include "virt.h" const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = { [UNIT_SERVICE] = &service_vtable, @@ -412,12 +419,11 @@ static void unit_remove_transient(Unit *u) { STRV_FOREACH(i, u->dropin_paths) { _cleanup_free_ char *p = NULL; - int r; (void) unlink(*i); - r = path_get_parent(*i, &p); - if (r >= 0) + p = dirname_malloc(*i); + if (p) (void) rmdir(p); } } @@ -1129,12 +1135,12 @@ static int unit_add_slice_dependencies(Unit *u) { return 0; if (UNIT_ISSET(u->slice)) - return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true); + return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_REQUIRES, UNIT_DEREF(u->slice), true); - if (streq(u->id, SPECIAL_ROOT_SLICE)) + if (unit_has_name(u, SPECIAL_ROOT_SLICE)) return 0; - return unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, SPECIAL_ROOT_SLICE, NULL, true); + return unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_ROOT_SLICE, NULL, true); } static int unit_add_mount_dependencies(Unit *u) { @@ -1147,13 +1153,23 @@ static int unit_add_mount_dependencies(Unit *u) { char prefix[strlen(*i) + 1]; PATH_FOREACH_PREFIX_MORE(prefix, *i) { + _cleanup_free_ char *p = NULL; Unit *m; - r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m); + r = unit_name_from_path(prefix, ".mount", &p); if (r < 0) return r; - if (r == 0) + + m = manager_get_unit(u->manager, p); + if (!m) { + /* Make sure to load the mount unit if + * it exists. If so the dependencies + * on this unit will be added later + * during the loading of the mount + * unit. */ + (void) manager_load_unit_prepare(u->manager, p, NULL, NULL, &m); continue; + } if (m == u) continue; @@ -2310,47 +2326,9 @@ int unit_add_two_dependencies_by_name(Unit *u, UnitDependency d, UnitDependency return unit_add_two_dependencies(u, d, e, other, add_reference); } -int unit_add_dependency_by_name_inverse(Unit *u, UnitDependency d, const char *name, const char *path, bool add_reference) { - _cleanup_free_ char *buf = NULL; - Unit *other; - int r; - - assert(u); - assert(name || path); - - r = resolve_template(u, name, path, &buf, &name); - if (r < 0) - return r; - - r = manager_load_unit(u->manager, name, path, NULL, &other); - if (r < 0) - return r; - - return unit_add_dependency(other, d, u, add_reference); -} - -int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDependency e, const char *name, const char *path, bool add_reference) { - _cleanup_free_ char *buf = NULL; - Unit *other; - int r; - - assert(u); - assert(name || path); - - r = resolve_template(u, name, path, &buf, &name); - if (r < 0) - return r; - - r = manager_load_unit(u->manager, name, path, NULL, &other); - if (r < 0) - return r; - - return unit_add_two_dependencies(other, d, e, u, add_reference); -} - int set_unit_path(const char *p) { /* This is mostly for debug purposes */ - if (setenv("SYSTEMD_UNIT_PATH", p, 0) < 0) + if (setenv("SYSTEMD_UNIT_PATH", p, 1) < 0) return -errno; return 0; @@ -2498,26 +2476,23 @@ static int signal_name_owner_changed(sd_bus_message *message, void *userdata, sd return 0; } -int unit_install_bus_match(sd_bus *bus, Unit *u, const char *name) { - _cleanup_free_ char *match = NULL; - Manager *m = u->manager; +int unit_install_bus_match(Unit *u, sd_bus *bus, const char *name) { + const char *match; - assert(m); + assert(u); + assert(bus); + assert(name); if (u->match_bus_slot) return -EBUSY; - match = strjoin("type='signal'," + match = strjoina("type='signal'," "sender='org.freedesktop.DBus'," "path='/org/freedesktop/DBus'," "interface='org.freedesktop.DBus'," "member='NameOwnerChanged'," - "arg0='", - name, - "'", + "arg0='", name, "'", NULL); - if (!match) - return -ENOMEM; return sd_bus_add_match(bus, &u->match_bus_slot, match, signal_name_owner_changed, u); } @@ -2534,9 +2509,9 @@ int unit_watch_bus_name(Unit *u, const char *name) { if (u->manager->api_bus) { /* If the bus is already available, install the match directly. * Otherwise, just put the name in the list. bus_setup_api() will take care later. */ - r = unit_install_bus_match(u->manager->api_bus, u, name); + r = unit_install_bus_match(u, u->manager->api_bus, name); if (r < 0) - return log_warning_errno(r, "Failed to subscribe to NameOwnerChanged signal: %m"); + return log_warning_errno(r, "Failed to subscribe to NameOwnerChanged signal for '%s': %m", name); } r = hashmap_put(u->manager->watch_bus, name, u); @@ -2624,6 +2599,62 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) { return 0; } +int unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) { + assert(u); + assert(f); + assert(key); + + if (!value) + return 0; + + fputs(key, f); + fputc('=', f); + fputs(value, f); + fputc('\n', f); + + return 1; +} + +int unit_serialize_item_escaped(Unit *u, FILE *f, const char *key, const char *value) { + _cleanup_free_ char *c = NULL; + + assert(u); + assert(f); + assert(key); + + if (!value) + return 0; + + c = cescape(value); + if (!c) + return -ENOMEM; + + fputs(key, f); + fputc('=', f); + fputs(c, f); + fputc('\n', f); + + return 1; +} + +int unit_serialize_item_fd(Unit *u, FILE *f, FDSet *fds, const char *key, int fd) { + int copy; + + assert(u); + assert(f); + assert(key); + + if (fd < 0) + return 0; + + copy = fdset_put_dup(fds, fd); + if (copy < 0) + return copy; + + fprintf(f, "%s=%i\n", key, copy); + return 1; +} + void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *format, ...) { va_list ap; @@ -2642,15 +2673,6 @@ void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *f fputc('\n', f); } -void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value) { - assert(u); - assert(f); - assert(key); - assert(value); - - fprintf(f, "%s=%s\n", key, value); -} - int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { ExecRuntime **rt = NULL; size_t offset; @@ -3311,19 +3333,6 @@ static int unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode, bool transient, return 0; } -static int unit_drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **p, char **q) { - _cleanup_free_ char *dir = NULL; - int r; - - assert(u); - - r = unit_drop_in_dir(u, mode, u->transient, &dir); - if (r < 0) - return r; - - return drop_in_file(dir, u->id, 50, name, p, q); -} - int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) { _cleanup_free_ char *dir = NULL, *p = NULL, *q = NULL; @@ -3422,28 +3431,6 @@ int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const return unit_write_drop_in_private(u, mode, name, p); } -int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) { - _cleanup_free_ char *p = NULL, *q = NULL; - int r; - - assert(u); - - if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) - return 0; - - r = unit_drop_in_file(u, mode, name, &p, &q); - if (r < 0) - return r; - - if (unlink(q) < 0) - r = errno == ENOENT ? 0 : -errno; - else - r = 1; - - rmdir(p); - return r; -} - int unit_make_transient(Unit *u) { assert(u); @@ -3729,14 +3716,3 @@ int unit_fail_if_symlink(Unit *u, const char* where) { return -ELOOP; } - -static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = { - [UNIT_ACTIVE] = "active", - [UNIT_RELOADING] = "reloading", - [UNIT_INACTIVE] = "inactive", - [UNIT_FAILED] = "failed", - [UNIT_ACTIVATING] = "activating", - [UNIT_DEACTIVATING] = "deactivating" -}; - -DEFINE_STRING_TABLE_LOOKUP(unit_active_state, UnitActiveState); |