[systemd-commits] 5 commits - Makefile.am TODO man/systemd.service.xml man/systemd.unit.xml src/core units/systemd-random-seed-load.service.in units/systemd-random-seed-save.service.in

Lennart Poettering lennart at kemper.freedesktop.org
Mon Apr 30 01:56:57 PDT 2012


 Makefile.am                               |    1 
 TODO                                      |    5 +-
 man/systemd.service.xml                   |   13 +++++-
 man/systemd.unit.xml                      |   12 +++++
 src/core/dbus-unit.c                      |    1 
 src/core/dbus-unit.h                      |    1 
 src/core/load-fragment-gperf.gperf.m4     |    1 
 src/core/load-fragment.c                  |   30 ++++++++++++++
 src/core/load-fragment.h                  |    1 
 src/core/manager.h                        |    3 +
 src/core/mount.c                          |   19 +++++++++
 src/core/unit.c                           |   62 ++++++++++++++++++++++++++++++
 src/core/unit.h                           |    8 +++
 units/systemd-random-seed-load.service.in |    4 -
 units/systemd-random-seed-save.service.in |    1 
 15 files changed, 157 insertions(+), 5 deletions(-)

New commits:
commit 86fff248642cc9c0daef6da4e6e0a443bcb271d2
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Apr 30 10:56:46 2012 +0200

    units: make sure /var is writable before initializing random seed

diff --git a/units/systemd-random-seed-load.service.in b/units/systemd-random-seed-load.service.in
index 82f49c7..a5e2bbb 100644
--- a/units/systemd-random-seed-load.service.in
+++ b/units/systemd-random-seed-load.service.in
@@ -9,7 +9,7 @@
 Description=Load Random Seed
 DefaultDependencies=no
 Conflicts=shutdown.target
-After=systemd-readahead-collect.service systemd-readahead-replay.service
+After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
 Before=sysinit.target shutdown.target
 RequiresMountsFor=@RANDOM_SEED@
 

commit c3276d27912b2d07ca5d3b1d879c7cc1ea694e78
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Apr 30 10:49:39 2012 +0200

    TODO

diff --git a/TODO b/TODO
index 8a1d60d..493f644 100644
--- a/TODO
+++ b/TODO
@@ -101,8 +101,6 @@ Features:
 
 * journalctl: show multiline log messages sanely, expand tabs, and show all valid utf8 messages
 
-* introduce NeedsMounts= or so to create .mount dependencies automatically for a specific path
-
 * add DeleteSocketsOnStop=yes|no option to socket units
 
 * journal: store euid in journal if it differs from uid

commit 7c8fa05c4d5d01748ff2a04edb882afb3119b7d7
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sun Apr 29 14:26:07 2012 +0200

    unit: add new dependency type RequiresMountsFor=
    
    RequiresMountsFor= is a shortcut for adding requires and after
    dependencies to all mount units neeed for the specified paths.
    
    This solves a couple of issues regarding dep loop cycles for encrypted
    swap.

diff --git a/Makefile.am b/Makefile.am
index 41fd773..e1501ae 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2889,6 +2889,7 @@ SED_PROCESS = \
 		-e 's, at PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
 		-e 's, at PACKAGE_NAME\@,$(PACKAGE_NAME),g' \
 		-e 's, at PACKAGE_URL\@,$(PACKAGE_URL),g' \
+		-e 's, at RANDOM_SEED\@,$(localstatedir)/lib/random-seed,g' \
 		-e 's, at prefix\@,$(prefix),g' \
 		-e 's, at exec_prefix\@,$(exec_prefix),g' \
 		-e 's, at libdir\@,$(libdir),g' \
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 12416fa..c81c7a3 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -526,6 +526,18 @@
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>RequiresMountsFor=</varname></term>
+
+                                <listitem><para>Takes a space
+                                separated list of paths. Automatically
+                                adds dependencies of type
+                                <varname>Requires=</varname> and
+                                <varname>After=</varname> for all
+                                mount units required to access the
+                                specified path.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>OnFailureIsolate=</varname></term>
 
                                 <listitem><para>Takes a boolean
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index 0484d75..b8d6616 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -810,6 +810,7 @@ const BusProperty bus_unit_properties[] = {
         { "TriggeredBy",          bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]),            true },
         { "PropagateReloadTo",    bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_TO]),     true },
         { "PropagateReloadFrom",  bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_PROPAGATE_RELOAD_FROM]),   true },
+        { "RequiresMountsFor",    bus_property_append_strv,          "as", offsetof(Unit, requires_mounts_for),                        true },
         { "Description",          bus_unit_append_description,        "s", 0 },
         { "LoadState",            bus_unit_append_load_state,         "s", offsetof(Unit, load_state)                         },
         { "ActiveState",          bus_unit_append_active_state,       "s", 0 },
diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h
index e6d549c..d22802d 100644
--- a/src/core/dbus-unit.h
+++ b/src/core/dbus-unit.h
@@ -85,6 +85,7 @@
         "  <property name=\"TriggeredBy\" type=\"as\" access=\"read\"/>\n"    \
         "  <property name=\"PropagateReloadTo\" type=\"as\" access=\"read\"/>\n" \
         "  <property name=\"PropagateReloadFrom\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"RequiresMountsFor\" type=\"as\" access=\"read\"/>\n" \
         "  <property name=\"Description\" type=\"s\" access=\"read\"/>\n" \
         "  <property name=\"LoadState\" type=\"s\" access=\"read\"/>\n" \
         "  <property name=\"ActiveState\" type=\"s\" access=\"read\"/>\n" \
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index c65db30..d929273 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -104,6 +104,7 @@ Unit.After,                      config_parse_unit_deps,             UNIT_AFTER,
 Unit.OnFailure,                  config_parse_unit_deps,             UNIT_ON_FAILURE,               0
 Unit.PropagateReloadTo,          config_parse_unit_deps,             UNIT_PROPAGATE_RELOAD_TO,      0
 Unit.PropagateReloadFrom,        config_parse_unit_deps,             UNIT_PROPAGATE_RELOAD_FROM,    0
+Unit.RequiresMountsFor,          config_parse_unit_requires_mounts_for, 0,                          offsetof(Unit, requires_mounts_for)
 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 1665be8..d24919f 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -2032,6 +2032,35 @@ int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const
         return 0;
 }
 
+int config_parse_unit_requires_mounts_for(
+                const char *filename,
+                unsigned line,
+                const char *section,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Unit *u = userdata;
+        int r;
+        bool empty_before;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        empty_before = !u->requires_mounts_for;
+
+        r = config_parse_path_strv(filename, line, section, lvalue, ltype, rvalue, data, userdata);
+
+        /* Make it easy to find units with requires_mounts set */
+        if (empty_before && u->requires_mounts_for)
+                LIST_PREPEND(Unit, has_requires_mounts_for, u->manager->has_requires_mounts_for, u);
+
+        return r;
+}
 
 #define FOLLOW_MAX 8
 
@@ -2394,6 +2423,7 @@ void unit_dump_config_items(FILE *f) {
                 { config_parse_socket_bindtodevice,   "NETWORKINTERFACE" },
                 { config_parse_usec,                  "SECONDS" },
                 { config_parse_path_strv,             "PATH [...]" },
+                { config_parse_unit_requires_mounts_for, "PATH [...]" },
                 { config_parse_exec_mount_flags,      "MOUNTFLAG [...]" },
                 { config_parse_unit_string_printf,    "STRING" },
                 { config_parse_timer,                 "TIMER" },
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
index 03e13a9..ccc4364 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -83,6 +83,7 @@ int config_parse_unit_memory_limit(const char *filename, unsigned line, const ch
 int config_parse_unit_device_allow(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_unit_blkio_weight(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 int config_parse_unit_blkio_bandwidth(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_unit_requires_mounts_for(const char *filename, unsigned line, const char *section, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
 
 /* gperf prototypes */
 const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length);
diff --git a/src/core/manager.h b/src/core/manager.h
index 154c1fa..6d1f5d8 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -104,6 +104,9 @@ struct Manager {
          * type we maintain a per type linked list */
         LIST_HEAD(Unit, units_by_type[_UNIT_TYPE_MAX]);
 
+        /* To optimize iteration of units that have requires_mounts_for set */
+        LIST_HEAD(Unit, has_requires_mounts_for);
+
         /* Units that need to be loaded */
         LIST_HEAD(Unit, load_queue); /* this is actually more a stack than a queue, but uh. */
 
diff --git a/src/core/mount.c b/src/core/mount.c
index 3357b7d..5f50d95 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -263,6 +263,21 @@ static int mount_add_socket_links(Mount *m) {
         return 0;
 }
 
+static int mount_add_requires_mounts_links(Mount *m) {
+        Unit *other;
+        int r;
+
+        assert(m);
+
+        LIST_FOREACH(has_requires_mounts_for, other, UNIT(m)->manager->has_requires_mounts_for) {
+                r = unit_add_one_mount_link(other, m);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
 static char* mount_test_option(const char *haystack, const char *needle) {
         struct mntent me;
 
@@ -614,6 +629,10 @@ static int mount_load(Unit *u) {
                 if ((r = mount_add_path_links(m)) < 0)
                         return r;
 
+                r = mount_add_requires_mounts_links(m);
+                if (r < 0)
+                        return r;
+
                 if ((r = mount_add_automount_links(m)) < 0)
                         return r;
 
diff --git a/src/core/unit.c b/src/core/unit.c
index 491ba3f..fea75e8 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -370,6 +370,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);
 
@@ -691,6 +696,18 @@ 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)) {
+                char **j;
+
+                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 +886,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) {
 
@@ -2685,6 +2708,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",
diff --git a/src/core/unit.h b/src/core/unit.h
index c2bae0a..3392089 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -153,6 +153,8 @@ struct Unit {
         Set *names;
         Set *dependencies[_UNIT_DEPENDENCY_MAX];
 
+        char **requires_mounts_for;
+
         char *description;
 
         char *fragment_path; /* if loaded from a config file this is the primary path to it */
@@ -186,6 +188,9 @@ 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);
 
@@ -554,6 +559,9 @@ void unit_ref_unset(UnitRef *ref);
 
 #define UNIT_DEREF(ref) ((ref).unit)
 
+int unit_add_one_mount_link(Unit *u, Mount *m);
+int unit_add_mount_links(Unit *u);
+
 const char *unit_load_state_to_string(UnitLoadState i);
 UnitLoadState unit_load_state_from_string(const char *s);
 
diff --git a/units/systemd-random-seed-load.service.in b/units/systemd-random-seed-load.service.in
index 6360436..82f49c7 100644
--- a/units/systemd-random-seed-load.service.in
+++ b/units/systemd-random-seed-load.service.in
@@ -8,10 +8,10 @@
 [Unit]
 Description=Load Random Seed
 DefaultDependencies=no
-Wants=local-fs.target
 Conflicts=shutdown.target
-After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service
 Before=sysinit.target shutdown.target
+RequiresMountsFor=@RANDOM_SEED@
 
 [Service]
 Type=oneshot
diff --git a/units/systemd-random-seed-save.service.in b/units/systemd-random-seed-save.service.in
index 219731b..0ebd07d 100644
--- a/units/systemd-random-seed-save.service.in
+++ b/units/systemd-random-seed-save.service.in
@@ -11,6 +11,7 @@ DefaultDependencies=no
 After=systemd-random-seed-load.service
 Before=shutdown.target
 Conflicts=systemd-random-seed-load.service
+RequiresMountsFor=@RANDOM_SEED@
 
 [Service]
 Type=oneshot

commit a8ad0f89286b878cbe1f330f72abd2d22813f8ea
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 26 20:32:26 2012 +0200

    service: document new Type=idle

diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 258b059..0baeb75 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -121,7 +121,8 @@
                                 <option>forking</option>,
                                 <option>oneshot</option>,
                                 <option>dbus</option>,
-                                <option>notify</option>.</para>
+                                <option>notify</option> or
+                                <option>idle</option>.</para>
 
                                 <para>If set to
                                 <option>simple</option> (the default
@@ -201,6 +202,16 @@
                                 <varname>NotifyAccess=</varname> is
                                 not set, it will be implicitly set to
                                 <option>main</option>.</para>
+
+                                <para>Behaviour of
+                                <option>idle</option> is very similar
+                                to <option>idle</option>, however
+                                actual execution of a the service
+                                binary is delayed until all jobs are
+                                dispatched. This may be used to avoid
+                                interleaving of output of shell
+                                services with the status output on the
+                                console.</para>
                                 </listitem>
                         </varlistentry>
 

commit 896c3c783c5e7f51bea215d84ad9869f9334c783
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Apr 26 20:32:07 2012 +0200

    update TODO

diff --git a/TODO b/TODO
index a379ce6..8a1d60d 100644
--- a/TODO
+++ b/TODO
@@ -28,6 +28,9 @@ Features:
 
 * ExecOnFailure=/usr/bin/foo
 
+* logind: add "mode" flag to poweroff/suspend inhibit logic so that we can
+  support both "inhibit" and "delay" mode.
+
 * fedora: make sshd and pam_loginuid work in nspawn containers
 
 * fix utmp for console logins in containers



More information about the systemd-commits mailing list