[systemd-devel] [PATCH] core/cryptsetup: Add WantsMountFor option to enable fallback to password request for crypt mounts.

Przemek Rudy prudy1 at o2.pl
Sun May 18 11:36:45 PDT 2014


Combined into one ptach.

I see it is not clear how this patch is related to the cryptsetup password timeout. Note the cryptsetup timeout is done by the cryptsetup service. Thus it will occur only if the cryptsetup is reached and the key is not valid. But that is true only for the key file on accessible path. When the key is on removable device and the device is not inserted the cryptsetup will not even be started. And no any cryptsetup timeout has a chance to show itself. This is because of a strong rule 'RequiresMountsFor'. If the device is not present, the requirement fails preventing cryptsetup service from being started. The cryptsetup does not really 'require' the device with key on it, it only 'wants' this device, so it can start at all with the fallback to password request. This patch is changing the 'requires' into 'wants' allowing cryptsetup service startup. It is already covered by ancient bug in bugzilla redhat #905683.

---
 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                       | 99 ++++++++++++++++++++---------------
 src/core/unit.h                       |  7 +--
 src/cryptsetup/cryptsetup-generator.c |  3 +-
 15 files changed, 109 insertions(+), 85 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 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..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,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 == UNIT_REQUIRES);
                 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..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,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, true);
                 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..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 6ac359e..b0069d3 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -400,32 +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;
+        strv_free(u->needs_mounts_for[!strong]);
+        u->needs_mounts_for[!strong] = NULL;
 }
 
 static void unit_done(Unit *u) {
@@ -463,7 +463,8 @@ void unit_free(Unit *u) {
 
         unit_done(u);
 
-        unit_free_requires_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);
@@ -712,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;
         }
@@ -727,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;
         }
@@ -875,11 +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->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 +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;
+        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 +3228,14 @@ 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, bool strong) {
         char prefix[strlen(path) + 1], *p;
         int r;
 
         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 +3256,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[!strong], p)) {
                 free(p);
                 return 0;
         }
 
-        r = strv_consume(&u->requires_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_requiring_mounts_for, prefix);
+                x = hashmap_get(u->manager->units_need_mounts_for[!strong], 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[!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;
                         }
 
@@ -3273,7 +3288,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[!strong], q, x);
                         if (r < 0) {
                                 free(q);
                                 set_free(x);
diff --git a/src/core/unit.h b/src/core/unit.h
index 3e61067..947833e 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, bool strong);
 
 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



More information about the systemd-devel mailing list