[systemd-devel] [PATCH 2/2] core/cryptsetup: Remove duplicated code.

Przemek Rudy prudy1 at o2.pl
Tue Apr 29 13:09:27 PDT 2014


---
 src/core/automount.c                  |   2 +-
 src/core/dbus-unit.c                  |   4 +-
 src/core/load-fragment-gperf.gperf.m4 |   4 +-
 src/core/load-fragment.c              |  55 +--------
 src/core/load-fragment.h              |   3 +-
 src/core/manager.c                    |  24 +---
 src/core/manager.h                    |  14 +--
 src/core/mount.c                      |  61 ++++------
 src/core/path.c                       |   2 +-
 src/core/socket.c                     |   2 +-
 src/core/swap.c                       |   2 +-
 src/core/timer.c                      |   2 +-
 src/core/unit.c                       | 223 +++++++---------------------------
 src/core/unit.h                       |  12 +-
 14 files changed, 95 insertions(+), 315 deletions(-)

diff --git a/src/core/automount.c b/src/core/automount.c
index 65e6d6f..d4359b9 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, true);
 }
 
 static int automount_add_default_dependencies(Automount *a) {
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index 31a35e9..18d21ff 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -515,8 +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("WantsMountsFor", "as", NULL, offsetof(Unit, wants_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 4e51866..7b9406b 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -138,8 +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.WantsMountsFor,             config_parse_unit_wants_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 24c1849..a1777a9 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,56 +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 == UNIT_REQUIRES);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to add required mount for, ignoring: %s", rvalue);
-                        continue;
-                }
-        }
-
-        return 0;
-}
-
-int config_parse_unit_wants_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) {
-
-        Unit *u = userdata;
-        char *state;
-        size_t l;
-        char *w;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-        assert(data);
-
-        FOREACH_WORD_QUOTED(w, l, rvalue, state) {
-                int r;
-                _cleanup_free_ char *n;
-
-                n = strndup(w, l);
-                if (!n)
-                        return log_oom();
-
-                if (!utf8_is_valid(n)) {
-                        log_invalid_utf8(unit, LOG_ERR, filename, line, EINVAL, rvalue);
-                        continue;
-                }
-
-                r = unit_want_mounts_for(u, n);
-                if (r < 0) {
-                        log_syntax(unit, LOG_ERR, filename, line, r,
-                                   "Failed to add wanted mount for, ignoring: %s", rvalue);
+                                   "Failed to add %s mount for, ignoring: %s", ltype == UNIT_REQUIRES ? "required" : "wanted", rvalue);
                         continue;
                 }
         }
@@ -3467,8 +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_wants_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 761d936..05aba1d 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -73,8 +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_wants_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 84ce11d..9e239d8 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -827,11 +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_want_mounts_for));
-        hashmap_free(m->units_want_mounts_for);
+        assert(hashmap_isempty(m->units_need_mounts_for[1]));
+        hashmap_free(m->units_need_mounts_for[1]);
 
         free(m);
 }
@@ -2840,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);
@@ -2849,19 +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);
-}
-
-Set *manager_get_units_want_mounts_for(Manager *m, const char *path) {
-        char p[strlen(path)+1];
-
-        assert(m);
-        assert(path);
-
-        strcpy(p, path);
-        path_kill_slashes(p);
-
-        return hashmap_get(m->units_want_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 ba5e688..e80fc26 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -266,13 +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;
-
-        /* This maps all possible path prefixes to the units want
-         * them. It's a hashmap with a path string as key and a Set as
-         * value where Unit objects are contained. */
-        Hashmap *units_want_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;
@@ -339,8 +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_want_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 64d6914..c1c4cb6 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, true);
                 if (r < 0)
                         return r;
         }
@@ -259,56 +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, true);
                 if (r < 0)
                         return r;
         }
 
-        /* Adds in links to other units that use (require) 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;
-                }
-        }
-
-        /* Adds in links to other units that use (want) this path or paths
-         * further down in the hierarchy */
-        s = manager_get_units_want_mounts_for(UNIT(m)->manager, m->where);
-        SET_FOREACH(other, s, i) {
-
-                if (other->load_state != UNIT_LOADED)
-                        continue;
 
-                if (other == UNIT(m))
-                        continue;
-
-                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 required */
-                        r = unit_add_dependency(other, UNIT_WANTS, 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..19fd04d 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, true);
                 if (r < 0)
                         return r;
         }
diff --git a/src/core/socket.c b/src/core/socket.c
index 536904f..84c5aa7 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, true);
                 if (r < 0)
                         return r;
         }
diff --git a/src/core/swap.c b/src/core/swap.c
index 10eed6d..2f73c62 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, true);
                 if (r < 0)
                         return r;
 
diff --git a/src/core/timer.c b/src/core/timer.c
index b0a9023..89bbe0a 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", true);
                 if (r < 0)
                         return r;
 
diff --git a/src/core/unit.c b/src/core/unit.c
index f7c03f7..b0069d3 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -400,60 +400,32 @@ 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, bool strong) {
         char **j;
 
-        STRV_FOREACH(j, u->requires_mounts_for) {
+        STRV_FOREACH(j, u->needs_mounts_for[!strong]) {
                 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[!strong], 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[!strong], y);
                                 free(y);
                                 set_free(x);
                         }
                 }
         }
 
-        strv_free(u->requires_mounts_for);
-        u->requires_mounts_for = NULL;
-}
-
-static void unit_free_wants_mounts_for(Unit *u) {
-        char **j;
-
-        STRV_FOREACH(j, u->wants_mounts_for) {
-                char s[strlen(*j) + 1];
-
-                PATH_FOREACH_PREFIX_MORE(s, *j) {
-                        char *y;
-                        Set *x;
-
-                        x = hashmap_get2(u->manager->units_want_mounts_for, s, (void**) &y);
-                        if (!x)
-                                continue;
-
-                        set_remove(x, u);
-
-                        if (set_isempty(x)) {
-                                hashmap_remove(u->manager->units_want_mounts_for, y);
-                                free(y);
-                                set_free(x);
-                        }
-                }
-        }
-
-        strv_free(u->wants_mounts_for);
-        u->wants_mounts_for = NULL;
+        strv_free(u->needs_mounts_for[!strong]);
+        u->needs_mounts_for[!strong] = NULL;
 }
 
 static void unit_done(Unit *u) {
@@ -491,8 +463,8 @@ void unit_free(Unit *u) {
 
         unit_done(u);
 
-        unit_free_requires_mounts_for(u);
-        unit_free_wants_mounts_for(u);
+        unit_free_needs_mounts_for(u, true);
+        unit_free_needs_mounts_for(u, false);
 
         SET_FOREACH(t, u->names, i)
                 hashmap_remove_value(u->manager->units, t, u);
@@ -741,13 +713,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, true);
                 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, true);
                 if (r < 0)
                         return r;
         }
@@ -756,11 +728,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", true);
                 if (r < 0)
                         return r;
 
-                r = unit_require_mounts_for(u, "/var/tmp");
+                r = unit_needs_mounts_for(u, "/var/tmp", true);
                 if (r < 0)
                         return r;
         }
@@ -904,21 +876,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->wants_mounts_for)) {
+        if (!strv_isempty(u->needs_mounts_for[1])) {
                 fprintf(f,
                         "%s\tWantsMountsFor:", prefix);
 
-                STRV_FOREACH(j, u->wants_mounts_for)
+                STRV_FOREACH(j, u->needs_mounts_for[1])
                         fprintf(f, " %s", *j);
 
                 fputs("\n", f);
@@ -1075,66 +1047,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;
-
-                        r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m);
-                        if (r < 0)
-                                return r;
-                        if (r == 0)
-                                continue;
-                        if (m == u)
-                                continue;
-
-                        if (m->load_state != UNIT_LOADED)
-                                continue;
+        do {
+                STRV_FOREACH(i, u->needs_mounts_for[!strong]) {
+                        char prefix[strlen(*i) + 1];
 
-                        r = unit_add_dependency(u, UNIT_AFTER, m, true);
-                        if (r < 0)
-                                return r;
+                        PATH_FOREACH_PREFIX_MORE(prefix, *i) {
+                                Unit *m;
 
-                        if (m->fragment_path) {
-                                r = unit_add_dependency(u, UNIT_REQUIRES, m, true);
+                                r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m);
                                 if (r < 0)
                                         return r;
-                        }
-                }
-        }
+                                if (r == 0)
+                                        continue;
+                                if (m == u)
+                                        continue;
 
-        STRV_FOREACH(i, u->wants_mounts_for) {
-                char prefix[strlen(*i) + 1];
+                                if (m->load_state != UNIT_LOADED)
+                                        continue;
 
-                PATH_FOREACH_PREFIX_MORE(prefix, *i) {
-                        Unit *m;
-
-                        r = manager_get_unit_by_path(u->manager, prefix, ".mount", &m);
-                        if (r < 0)
-                                return r;
-                        if (r == 0)
-                                continue;
-                        if (m == u)
-                                continue;
-
-                        if (m->load_state != UNIT_LOADED)
-                                continue;
-
-                        r = unit_add_dependency(u, UNIT_AFTER, m, true);
-                        if (r < 0)
-                                return r;
-
-                        if (m->fragment_path) {
-                                r = unit_add_dependency(u, UNIT_WANTS, 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;
 }
@@ -3281,90 +3228,14 @@ int unit_kill_context(
         return wait_for_exit;
 }
 
-int unit_require_mounts_for(Unit *u, const char *path) {
-        char prefix[strlen(path) + 1], *p;
-        int r;
-
-        assert(u);
-        assert(path);
-
-        /* Registers a unit for requiring 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
-         * units can easily determine which units to make themselves a
-         * dependency of. */
-
-        if (!path_is_absolute(path))
-                return -EINVAL;
-
-        p = strdup(path);
-        if (!p)
-                return -ENOMEM;
-
-        path_kill_slashes(p);
-
-        if (!path_is_safe(p)) {
-                free(p);
-                return -EPERM;
-        }
-
-        if (strv_contains(u->requires_mounts_for, p)) {
-                free(p);
-                return 0;
-        }
-
-        r = strv_consume(&u->requires_mounts_for, p);
-        if (r < 0)
-                return r;
-
-        PATH_FOREACH_PREFIX_MORE(prefix, p) {
-                Set *x;
-
-                x = hashmap_get(u->manager->units_requiring_mounts_for, 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)
-                                        return -ENOMEM;
-                        }
-
-                        q = strdup(prefix);
-                        if (!q)
-                                return -ENOMEM;
-
-                        x = set_new(NULL, NULL);
-                        if (!x) {
-                                free(q);
-                                return -ENOMEM;
-                        }
-
-                        r = hashmap_put(u->manager->units_requiring_mounts_for, q, x);
-                        if (r < 0) {
-                                free(q);
-                                set_free(x);
-                                return r;
-                        }
-                }
-
-                r = set_put(x, u);
-                if (r < 0)
-                        return r;
-        }
-
-        return 0;
-}
-
-int unit_want_mounts_for(Unit *u, const char *path) {
+int unit_needs_mounts_for(Unit *u, const char *path, bool strong) {
         char prefix[strlen(path) + 1], *p;
         int r;
 
         assert(u);
         assert(path);
 
-        /* Registers a unit for want 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
@@ -3385,25 +3256,25 @@ int unit_want_mounts_for(Unit *u, const char *path) {
                 return -EPERM;
         }
 
-        if (strv_contains(u->wants_mounts_for, p)) {
+        if (strv_contains(u->needs_mounts_for[!strong], p)) {
                 free(p);
                 return 0;
         }
 
-        r = strv_consume(&u->wants_mounts_for, p);
+        r = strv_consume(&u->needs_mounts_for[!strong], p);
         if (r < 0)
                 return r;
 
         PATH_FOREACH_PREFIX_MORE(prefix, p) {
                 Set *x;
 
-                x = hashmap_get(u->manager->units_want_mounts_for, prefix);
+                x = hashmap_get(u->manager->units_need_mounts_for[!strong], prefix);
                 if (!x) {
                         char *q;
 
-                        if (!u->manager->units_want_mounts_for) {
-                                u->manager->units_want_mounts_for = hashmap_new(string_hash_func, string_compare_func);
-                                if (!u->manager->units_want_mounts_for)
+                        if (!u->manager->units_need_mounts_for[!strong]) {
+                                u->manager->units_need_mounts_for[!strong] = hashmap_new(string_hash_func, string_compare_func);
+                                if (!u->manager->units_need_mounts_for[!strong])
                                         return -ENOMEM;
                         }
 
@@ -3417,7 +3288,7 @@ int unit_want_mounts_for(Unit *u, const char *path) {
                                 return -ENOMEM;
                         }
 
-                        r = hashmap_put(u->manager->units_want_mounts_for, q, x);
+                        r = hashmap_put(u->manager->units_need_mounts_for[!strong], q, x);
                         if (r < 0) {
                                 free(q);
                                 set_free(x);
diff --git a/src/core/unit.h b/src/core/unit.h
index 0db0b91..947833e 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -142,8 +142,7 @@ struct Unit {
         Set *names;
         Set *dependencies[_UNIT_DEPENDENCY_MAX];
 
-        char **requires_mounts_for;
-        char **wants_mounts_for;
+        char **needs_mounts_for[2]; /* [0] - required, [1] - wanted */
 
         char *description;
         char **documentation;
@@ -187,12 +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);
-
-        /* All units which have wantss_mounts_for set */
-        LIST_FIELDS(Unit, has_wants_mounts_for);
-
         /* Load queue */
         LIST_FIELDS(Unit, load_queue);
 
@@ -628,8 +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_want_mounts_for(Unit *u, const char *path);
+int unit_needs_mounts_for(Unit *u, const char *path, bool strong);
 
 const char *unit_active_state_to_string(UnitActiveState i) _const_;
 UnitActiveState unit_active_state_from_string(const char *s) _pure_;
-- 
1.9.0



More information about the systemd-devel mailing list