X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Funit.c;h=2d18976c262032f7e0db45a3e27345864dd4e905;hp=491ba3f33f846996e68b3f4925c80c7f59cd412a;hb=5f73969991fa765f2826975c0fc5e47438b5e9ea;hpb=e0209d83e7b30153f43b1a633c955f66eb2c2e4a diff --git a/src/core/unit.c b/src/core/unit.c index 491ba3f33..2d18976c2 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -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" @@ -370,6 +371,11 @@ void unit_free(Unit *u) { 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); @@ -391,7 +397,9 @@ void unit_free(Unit *u) { cgroup_attribute_free_list(u->cgroup_attributes); free(u->description); + strv_free(u->documentation); free(u->fragment_path); + free(u->source_path); free(u->instance); set_free_free(u->names); @@ -618,7 +626,7 @@ const char *unit_description(Unit *u) { } void unit_dump(Unit *u, FILE *f, const char *prefix) { - char *t; + char *t, **j; UnitDependency d; Iterator i; char *p2; @@ -666,12 +674,18 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { SET_FOREACH(t, u->names, i) fprintf(f, "%s\tName: %s\n", prefix, t); + STRV_FOREACH(j, u->documentation) + fprintf(f, "%s\tDocumentation: %s\n", prefix, *j); + if ((following = unit_following(u))) fprintf(f, "%s\tFollowing: %s\n", prefix, following->id); if (u->fragment_path) fprintf(f, "%s\tFragment Path: %s\n", prefix, u->fragment_path); + if (u->source_path) + fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path); + if (u->job_timeout > 0) fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout)); @@ -691,6 +705,16 @@ 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)) { + 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; @@ -869,6 +893,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) { @@ -906,6 +936,21 @@ bool unit_condition_test(Unit *u) { return u->condition_result; } +static void unit_status_print_starting_stopping(Unit *u, bool stopping) { + const UnitStatusMessageFormats *format_table; + const char *format; + + format_table = &UNIT_VTABLE(u)->status_message_formats; + if (!format_table) + return; + + format = format_table->starting_stopping[stopping]; + if (!format) + return; + + unit_status_printf(u, "", format, unit_description(u)); +} + /* Errors: * -EBADR: This unit type does not support starting. * -EALREADY: Unit is already started. @@ -945,6 +990,8 @@ int unit_start(Unit *u) { return unit_start(following); } + unit_status_print_starting_stopping(u, false); + /* If it is stopped, but we cannot start it, then fail */ if (!UNIT_VTABLE(u)->start) return -EBADR; @@ -957,7 +1004,6 @@ int unit_start(Unit *u) { unit_add_to_dbus_queue(u); - unit_status_printf(u, NULL, "Starting %s...", unit_description(u)); return UNIT_VTABLE(u)->start(u); } @@ -994,12 +1040,13 @@ int unit_stop(Unit *u) { return unit_stop(following); } + unit_status_print_starting_stopping(u, true); + if (!UNIT_VTABLE(u)->stop) return -EBADR; unit_add_to_dbus_queue(u); - unit_status_printf(u, NULL, "Stopping %s...", unit_description(u)); return UNIT_VTABLE(u)->stop(u); } @@ -1647,7 +1694,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; @@ -1788,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) { @@ -2156,7 +2195,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, "/")) { @@ -2470,7 +2509,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); @@ -2520,9 +2560,6 @@ void unit_status_printf(Unit *u, const char *status, const char *format, ...) { assert(u); assert(format); - if (!UNIT_VTABLE(u)->show_status) - return; - if (!manager_get_show_status(u->manager)) return; @@ -2535,11 +2572,11 @@ void unit_status_printf(Unit *u, const char *status, const char *format, ...) { } bool unit_need_daemon_reload(Unit *u) { + struct stat st; + assert(u); if (u->fragment_path) { - struct stat st; - zero(st); if (stat(u->fragment_path, &st) < 0) /* What, cannot access this anymore? */ @@ -2550,8 +2587,15 @@ bool unit_need_daemon_reload(Unit *u) { return true; } - if (UNIT_VTABLE(u)->need_daemon_reload) - return UNIT_VTABLE(u)->need_daemon_reload(u); + if (u->source_path) { + zero(st); + if (stat(u->source_path, &st) < 0) + return true; + + if (u->source_mtime > 0 && + timespec_load(&st.st_mtim) != u->source_mtime) + return true; + } return false; } @@ -2603,28 +2647,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); @@ -2658,7 +2680,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; } @@ -2685,6 +2707,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",