Updated using 'UNIT_REQUIRES' instead 'true'. --- src/core/automount.c | 2 +- src/core/dbus-unit.c | 3 +- src/core/load-fragment-gperf.gperf.m4 | 3 +- src/core/load-fragment.c | 8 +-- src/core/load-fragment.h | 2 +- src/core/manager.c | 11 ++-- src/core/manager.h | 8 ++- src/core/mount.c | 40 ++++++++------ src/core/path.c | 2 +- src/core/socket.c | 2 +- src/core/swap.c | 2 +- src/core/timer.c | 2 +- src/core/unit.c | 101 ++++++++++++++++++++-------------- src/core/unit.h | 7 +-- src/cryptsetup/cryptsetup-generator.c | 3 +- 15 files changed, 111 insertions(+), 85 deletions(-)
diff --git a/src/core/automount.c b/src/core/automount.c index 65e6d6f..6cfe7b6 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -124,7 +124,7 @@ static int automount_add_mount_links(Automount *a) { if (r < 0) return r; - return unit_require_mounts_for(UNIT(a), parent); + return unit_needs_mounts_for(UNIT(a), parent, UNIT_REQUIRES); } static int automount_add_default_dependencies(Automount *a) { diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 07e7f20..18d21ff 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -515,7 +515,8 @@ const sd_bus_vtable bus_unit_vtable[] = { SD_BUS_PROPERTY("PropagatesReloadTo", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_PROPAGATES_RELOAD_TO]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("ReloadPropagatedFrom", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_RELOAD_PROPAGATED_FROM]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("JoinsNamespaceOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_JOINS_NAMESPACE_OF]), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("RequiresMountsFor", "as", NULL, offsetof(Unit, requires_mounts_for), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("RequiresMountsFor", "as", NULL, offsetof(Unit, needs_mounts_for[0]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("WantsMountsFor", "as", NULL, offsetof(Unit, needs_mounts_for[1]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Documentation", "as", NULL, offsetof(Unit, documentation), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Description", "s", property_get_description, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LoadState", "s", property_get_load_state, offsetof(Unit, load_state), SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 21bccbb..7b9406b 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -138,7 +138,8 @@ Unit.ReloadPropagatedFrom, config_parse_unit_deps, UNIT_RELOAD Unit.PropagateReloadFrom, config_parse_unit_deps, UNIT_RELOAD_PROPAGATED_FROM, 0 Unit.PartOf, config_parse_unit_deps, UNIT_PART_OF, 0 Unit.JoinsNamespaceOf, config_parse_unit_deps, UNIT_JOINS_NAMESPACE_OF, 0 -Unit.RequiresMountsFor, config_parse_unit_requires_mounts_for, 0, 0 +Unit.RequiresMountsFor, config_parse_unit_needs_mounts_for, UNIT_REQUIRES, 0 +Unit.WantsMountsFor, config_parse_unit_needs_mounts_for, UNIT_WANTS, 0 Unit.StopWhenUnneeded, config_parse_bool, 0, offsetof(Unit, stop_when_unneeded) Unit.RefuseManualStart, config_parse_bool, 0, offsetof(Unit, refuse_manual_start) Unit.RefuseManualStop, config_parse_bool, 0, offsetof(Unit, refuse_manual_stop) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 3b36d15..aadc930 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2002,7 +2002,7 @@ int config_parse_unit_condition_null(const char *unit, DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier"); DEFINE_CONFIG_PARSE_ENUM(config_parse_failure_action, failure_action, FailureAction, "Failed to parse failure action specifier"); -int config_parse_unit_requires_mounts_for( +int config_parse_unit_needs_mounts_for( const char *unit, const char *filename, unsigned line, @@ -2037,10 +2037,10 @@ int config_parse_unit_requires_mounts_for( continue; } - r = unit_require_mounts_for(u, n); + r = unit_needs_mounts_for(u, n, ltype); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, - "Failed to add required mount for, ignoring: %s", rvalue); + "Failed to add %s mount for, ignoring: %s", ltype == UNIT_REQUIRES ? "required" : "wanted", rvalue); continue; } } @@ -3421,7 +3421,7 @@ void unit_dump_config_items(FILE *f) { { config_parse_sec, "SECONDS" }, { config_parse_nsec, "NANOSECONDS" }, { config_parse_namespace_path_strv, "PATH [...]" }, - { config_parse_unit_requires_mounts_for, "PATH [...]" }, + { config_parse_unit_needs_mounts_for, "PATH [...]" }, { config_parse_exec_mount_flags, "MOUNTFLAG [...]" }, { config_parse_unit_string_printf, "STRING" }, { config_parse_trigger_unit, "UNIT" }, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index 242fd27..05aba1d 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -73,7 +73,7 @@ int config_parse_unit_condition_null(const char *unit, const char *filename, uns int config_parse_kill_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_notify_access(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_failure_action(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); -int config_parse_unit_requires_mounts_for(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); +int config_parse_unit_needs_mounts_for(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_syscall_filter(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_syscall_archs(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_syscall_errno(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/core/manager.c b/src/core/manager.c index 5772f40..9e239d8 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -827,8 +827,11 @@ void manager_free(Manager *m) { for (i = 0; i < _RLIMIT_MAX; i++) free(m->rlimit[i]); - assert(hashmap_isempty(m->units_requiring_mounts_for)); - hashmap_free(m->units_requiring_mounts_for); + assert(hashmap_isempty(m->units_need_mounts_for[0])); + hashmap_free(m->units_need_mounts_for[0]); + + assert(hashmap_isempty(m->units_need_mounts_for[1])); + hashmap_free(m->units_need_mounts_for[1]); free(m); } @@ -2837,7 +2840,7 @@ int manager_get_unit_by_path(Manager *m, const char *path, const char *suffix, U return 1; } -Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) { +Set *manager_get_units_need_mounts_for(Manager *m, const char *path, bool strong) { char p[strlen(path)+1]; assert(m); @@ -2846,7 +2849,7 @@ Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) { strcpy(p, path); path_kill_slashes(p); - return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p); + return hashmap_get(m->units_need_mounts_for[!strong], streq(p, "/") ? "" : p); } const char *manager_get_runtime_prefix(Manager *m) { diff --git a/src/core/manager.h b/src/core/manager.h index a3de351..e80fc26 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -266,8 +266,10 @@ struct Manager { /* This maps all possible path prefixes to the units needing * them. It's a hashmap with a path string as key and a Set as - * value where Unit objects are contained. */ - Hashmap *units_requiring_mounts_for; + * value where Unit objects are contained. + * [0] - map of required (strong) paths + * [1] - map of wanted (weak) paths */ + Hashmap *units_need_mounts_for[2]; /* Reference to the kdbus bus control fd */ int kdbus_fd; @@ -334,7 +336,7 @@ void manager_set_show_status(Manager *m, ShowStatus mode); void manager_status_printf(Manager *m, bool ephemeral, const char *status, const char *format, ...) _printf_(4,5); void manager_flip_auto_status(Manager *m, bool enable); -Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path); +Set *manager_get_units_need_mounts_for(Manager *m, const char *path, bool strong); const char *manager_get_runtime_prefix(Manager *m); diff --git a/src/core/mount.c b/src/core/mount.c index a979837..c1fdaf4 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -236,6 +236,7 @@ static int mount_add_mount_links(Mount *m) { Iterator i; Set *s; int r; + bool strong = false; assert(m); @@ -246,7 +247,7 @@ static int mount_add_mount_links(Mount *m) { if (r < 0) return r; - r = unit_require_mounts_for(UNIT(m), parent); + r = unit_needs_mounts_for(UNIT(m), parent, UNIT_REQUIRES); if (r < 0) return r; } @@ -259,33 +260,36 @@ static int mount_add_mount_links(Mount *m) { path_is_absolute(pm->what) && !mount_is_network(pm)) { - r = unit_require_mounts_for(UNIT(m), pm->what); + r = unit_needs_mounts_for(UNIT(m), pm->what, UNIT_REQUIRES); if (r < 0) return r; } - /* Adds in links to other units that use this path or paths - * further down in the hierarchy */ - s = manager_get_units_requiring_mounts_for(UNIT(m)->manager, m->where); - SET_FOREACH(other, s, i) { + do { + /* Adds in links to other units that use this path or paths + * further down in the hierarchy */ + s = manager_get_units_need_mounts_for(UNIT(m)->manager, m->where, strong); + SET_FOREACH(other, s, i) { - if (other->load_state != UNIT_LOADED) - continue; - - if (other == UNIT(m)) - continue; + if (other->load_state != UNIT_LOADED) + continue; - r = unit_add_dependency(other, UNIT_AFTER, UNIT(m), true); - if (r < 0) - return r; + if (other == UNIT(m)) + continue; - if (UNIT(m)->fragment_path) { - /* If we have fragment configuration, then make this dependency required */ - r = unit_add_dependency(other, UNIT_REQUIRES, UNIT(m), true); + r = unit_add_dependency(other, UNIT_AFTER, UNIT(m), true); if (r < 0) return r; + + if (UNIT(m)->fragment_path) { + /* If we have fragment configuration, then make this dependency needed */ + r = unit_add_dependency(other, strong ? UNIT_REQUIRES : UNIT_WANTS, UNIT(m), true); + if (r < 0) + return r; + } } - } + strong = !strong; + } while (strong); return 0; } diff --git a/src/core/path.c b/src/core/path.c index 20e454d..3743920 100644 --- a/src/core/path.c +++ b/src/core/path.c @@ -304,7 +304,7 @@ static int path_add_mount_links(Path *p) { assert(p); LIST_FOREACH(spec, s, p->specs) { - r = unit_require_mounts_for(UNIT(p), s->path); + r = unit_needs_mounts_for(UNIT(p), s->path, UNIT_REQUIRES); if (r < 0) return r; } diff --git a/src/core/socket.c b/src/core/socket.c index 536904f..bb825a3 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -255,7 +255,7 @@ static int socket_add_mount_links(Socket *s) { if (!path) continue; - r = unit_require_mounts_for(UNIT(s), path); + r = unit_needs_mounts_for(UNIT(s), path, UNIT_REQUIRES); if (r < 0) return r; } diff --git a/src/core/swap.c b/src/core/swap.c index 10eed6d..3a16366 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -327,7 +327,7 @@ static int swap_load(Unit *u) { return r; } - r = unit_require_mounts_for(UNIT(s), s->what); + r = unit_needs_mounts_for(UNIT(s), s->what, UNIT_REQUIRES); if (r < 0) return r; diff --git a/src/core/timer.c b/src/core/timer.c index b0a9023..b7440fa 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -138,7 +138,7 @@ static int timer_setup_persistent(Timer *t) { if (UNIT(t)->manager->running_as == SYSTEMD_SYSTEM) { - r = unit_require_mounts_for(UNIT(t), "/var/lib/systemd/timers"); + r = unit_needs_mounts_for(UNIT(t), "/var/lib/systemd/timers", UNIT_REQUIRES); if (r < 0) return r; diff --git a/src/core/unit.c b/src/core/unit.c index 6ac359e..a2f2e36 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -400,32 +400,33 @@ static void unit_remove_transient(Unit *u) { } } -static void unit_free_requires_mounts_for(Unit *u) { +static void unit_free_needs_mounts_for(Unit *u, UnitDependency d) { char **j; + bool severity = (d != UNIT_REQUIRES); - STRV_FOREACH(j, u->requires_mounts_for) { + STRV_FOREACH(j, u->needs_mounts_for[severity]) { char s[strlen(*j) + 1]; PATH_FOREACH_PREFIX_MORE(s, *j) { char *y; Set *x; - x = hashmap_get2(u->manager->units_requiring_mounts_for, s, (void**) &y); + x = hashmap_get2(u->manager->units_need_mounts_for[severity], s, (void**) &y); if (!x) continue; set_remove(x, u); if (set_isempty(x)) { - hashmap_remove(u->manager->units_requiring_mounts_for, y); + hashmap_remove(u->manager->units_need_mounts_for[severity], y); free(y); set_free(x); } } } - strv_free(u->requires_mounts_for); - u->requires_mounts_for = NULL; + strv_free(u->needs_mounts_for[severity]); + u->needs_mounts_for[severity] = NULL; } static void unit_done(Unit *u) { @@ -463,7 +464,8 @@ void unit_free(Unit *u) { unit_done(u); - unit_free_requires_mounts_for(u); + unit_free_needs_mounts_for(u, UNIT_REQUIRES); + unit_free_needs_mounts_for(u, UNIT_WANTS); SET_FOREACH(t, u->names, i) hashmap_remove_value(u->manager->units, t, u); @@ -712,13 +714,13 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) { assert(c); if (c->working_directory) { - r = unit_require_mounts_for(u, c->working_directory); + r = unit_needs_mounts_for(u, c->working_directory, UNIT_REQUIRES); if (r < 0) return r; } if (c->root_directory) { - r = unit_require_mounts_for(u, c->root_directory); + r = unit_needs_mounts_for(u, c->root_directory, UNIT_REQUIRES); if (r < 0) return r; } @@ -727,11 +729,11 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) { return 0; if (c->private_tmp) { - r = unit_require_mounts_for(u, "/tmp"); + r = unit_needs_mounts_for(u, "/tmp", UNIT_REQUIRES); if (r < 0) return r; - r = unit_require_mounts_for(u, "/var/tmp"); + r = unit_needs_mounts_for(u, "/var/tmp", UNIT_REQUIRES); if (r < 0) return r; } @@ -875,11 +877,21 @@ 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)) { + if (!strv_isempty(u->needs_mounts_for[0])) { fprintf(f, "%s\tRequiresMountsFor:", prefix); - STRV_FOREACH(j, u->requires_mounts_for) + STRV_FOREACH(j, u->needs_mounts_for[0]) + fprintf(f, " %s", *j); + + fputs("\n", f); + } + + if (!strv_isempty(u->needs_mounts_for[1])) { + fprintf(f, + "%s\tWantsMountsFor:", prefix); + + STRV_FOREACH(j, u->needs_mounts_for[1]) fprintf(f, " %s", *j); fputs("\n", f); @@ -1036,37 +1048,41 @@ static int unit_add_slice_dependencies(Unit *u) { static int unit_add_mount_dependencies(Unit *u) { char **i; int r; + bool strong = false; assert(u); - STRV_FOREACH(i, u->requires_mounts_for) { - char prefix[strlen(*i) + 1]; - - PATH_FOREACH_PREFIX_MORE(prefix, *i) { - Unit *m; + do { + STRV_FOREACH(i, u->needs_mounts_for[!strong]) { + char prefix[strlen(*i) + 1]; - r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m); - if (r < 0) - return r; - if (r == 0) - continue; - if (m == u) - continue; + PATH_FOREACH_PREFIX_MORE(prefix, *i) { + Unit *m; - if (m->load_state != UNIT_LOADED) - continue; + r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m); + if (r < 0) + return r; + if (r == 0) + continue; + if (m == u) + continue; - r = unit_add_dependency(u, UNIT_AFTER, m, true); - if (r < 0) - return r; + if (m->load_state != UNIT_LOADED) + continue; - if (m->fragment_path) { - r = unit_add_dependency(u, UNIT_REQUIRES, m, true); + r = unit_add_dependency(u, UNIT_AFTER, m, true); if (r < 0) return r; + + if (m->fragment_path) { + r = unit_add_dependency(u, strong ? UNIT_REQUIRES : UNIT_WANTS, m, true); + if (r < 0) + return r; + } } } - } + strong = !strong; + } while (strong); return 0; } @@ -3213,14 +3229,15 @@ int unit_kill_context( return wait_for_exit; } -int unit_require_mounts_for(Unit *u, const char *path) { +int unit_needs_mounts_for(Unit *u, const char *path, UnitDependency d) { char prefix[strlen(path) + 1], *p; int r; + bool severity = (d != UNIT_REQUIRES); assert(u); assert(path); - /* Registers a unit for requiring a certain path and all its + /* Registers a unit for the need of a certain path and all its * prefixes. We keep a simple array of these paths in the * unit, since its usually short. However, we build a prefix * table for all possible prefixes so that new appearing mount @@ -3241,25 +3258,25 @@ int unit_require_mounts_for(Unit *u, const char *path) { return -EPERM; } - if (strv_contains(u->requires_mounts_for, p)) { + if (strv_contains(u->needs_mounts_for[severity], p)) { free(p); return 0; } - r = strv_consume(&u->requires_mounts_for, p); + r = strv_consume(&u->needs_mounts_for[severity], p); if (r < 0) return r; PATH_FOREACH_PREFIX_MORE(prefix, p) { Set *x; - x = hashmap_get(u->manager->units_requiring_mounts_for, prefix); + x = hashmap_get(u->manager->units_need_mounts_for[severity], prefix); if (!x) { char *q; - if (!u->manager->units_requiring_mounts_for) { - u->manager->units_requiring_mounts_for = hashmap_new(string_hash_func, string_compare_func); - if (!u->manager->units_requiring_mounts_for) + if (!u->manager->units_need_mounts_for[severity]) { + u->manager->units_need_mounts_for[severity] = hashmap_new(string_hash_func, string_compare_func); + if (!u->manager->units_need_mounts_for[severity]) return -ENOMEM; } @@ -3273,7 +3290,7 @@ int unit_require_mounts_for(Unit *u, const char *path) { return -ENOMEM; } - r = hashmap_put(u->manager->units_requiring_mounts_for, q, x); + r = hashmap_put(u->manager->units_need_mounts_for[severity], q, x); if (r < 0) { free(q); set_free(x); diff --git a/src/core/unit.h b/src/core/unit.h index 3e61067..2947109 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -142,7 +142,7 @@ struct Unit { Set *names; Set *dependencies[_UNIT_DEPENDENCY_MAX]; - char **requires_mounts_for; + char **needs_mounts_for[2]; /* [0] - required, [1] - wanted */ char *description; char **documentation; @@ -186,9 +186,6 @@ struct Unit { /* Per type list */ LIST_FIELDS(Unit, units_by_type); - /* All units which have requires_mounts_for set */ - LIST_FIELDS(Unit, has_requires_mounts_for); - /* Load queue */ LIST_FIELDS(Unit, load_queue); @@ -624,7 +621,7 @@ int unit_kill_context(Unit *u, KillContext *c, bool sigkill, pid_t main_pid, pid int unit_make_transient(Unit *u); -int unit_require_mounts_for(Unit *u, const char *path); +int unit_needs_mounts_for(Unit *u, const char *path, UnitDependency d); const char *unit_active_state_to_string(UnitActiveState i) _const_; UnitActiveState unit_active_state_from_string(const char *s) _pure_; diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c index f4eeb2a..ce7ae92 100644 --- a/src/cryptsetup/cryptsetup-generator.c +++ b/src/cryptsetup/cryptsetup-generator.c @@ -153,7 +153,8 @@ static int create_disk( fprintf(f, "After=%1$s\nRequires=%1$s\n", dd); } else - fprintf(f, "RequiresMountsFor=%s\n", password); + /* Do not use 'RequiresMountsFor=' here to allow fallback to password in case the key device is not available */ + fprintf(f, "WantsMountsFor=%s\n", password); } } -- 1.9.0 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel