[systemd-devel] [PATCH 1/2] add initrd-fs.target and root-fs.target

harald at redhat.com harald at redhat.com
Tue Mar 12 11:41:58 PDT 2013


From: Harald Hoyer <harald at redhat.com>

Instead of using local-fs*.target in the initrd, use root-fs.target for
sysroot.mount and initrd-fs.target for /sysroot/usr and friends.

Using local-fs.target would mean to carry over the activated
local-fs.target to the isolated initrd-switch-root.target and thus in
the real root. Having local-fs.target already active after
deserialization causes ordering problems with the real root services and
targets.

We better isolate to targets for initrd-switch-root.target, which are
only available in the initrd.
---
 Makefile.am                           |  2 +
 man/systemd.special.xml               | 30 +++++++++++++
 src/core/special.h                    |  2 +
 src/fstab-generator/fstab-generator.c | 79 ++++++++++++++++++++---------------
 units/initrd-cleanup.service.in       |  4 +-
 units/initrd-fs.target                | 13 ++++++
 units/initrd-parse-etc.service.in     |  6 +--
 units/initrd-switch-root.target       |  4 +-
 units/root-fs.target                  | 11 +++++
 9 files changed, 110 insertions(+), 41 deletions(-)
 create mode 100644 units/initrd-fs.target
 create mode 100644 units/root-fs.target

diff --git a/Makefile.am b/Makefile.am
index c8f7b8e..9a98296 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -347,6 +347,8 @@ dist_systemunit_DATA = \
 	units/kexec.target \
 	units/local-fs.target \
 	units/local-fs-pre.target \
+	units/initrd-fs.target \
+	units/root-fs.target \
 	units/remote-fs.target \
 	units/remote-fs-pre.target \
 	units/network.target \
diff --git a/man/systemd.special.xml b/man/systemd.special.xml
index 0d1df84..7b78099 100644
--- a/man/systemd.special.xml
+++ b/man/systemd.special.xml
@@ -64,6 +64,7 @@
                 <filename>halt.target</filename>,
                 <filename>hibernate.target</filename>,
                 <filename>hybrid-sleep.target</filename>,
+                <filename>initrd-fs.target</filename>,
                 <filename>kbrequest.target</filename>,
                 <filename>kexec.target</filename>,
                 <filename>local-fs.target</filename>,
@@ -78,6 +79,7 @@
                 <filename>remote-fs.target</filename>,
                 <filename>remote-fs-pre.target</filename>,
                 <filename>rescue.target</filename>,
+                <filename>root-fs.target</filename>,
                 <filename>rpcbind.target</filename>,
                 <filename>runlevel2.target</filename>,
                 <filename>runlevel3.target</filename>,
@@ -296,6 +298,22 @@
                                 </listitem>
                         </varlistentry>
                         <varlistentry>
+                                <term><filename>initrd-fs.target</filename></term>
+                                <listitem>
+                                        <para>systemd automatically
+                                        adds dependencies of type
+                                        Before to sysroot-usr.mount and
+                                        all mount points fround in
+                                        <filename>/etc/fstab</filename>
+                                        that have the
+                                        <option>auto</option> and
+                                        <option>x-initrd.mount</option>
+                                        mount options set.
+                                        See also <literal>systemd-fstab-generator</literal>.
+                                        </para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
                                 <term><filename>kbrequest.target</filename></term>
                                 <listitem>
                                         <para>systemd starts this
@@ -505,6 +523,17 @@
                                 </listitem>
                         </varlistentry>
                         <varlistentry>
+                                <term><filename>root-fs.target</filename></term>
+                                <listitem>
+                                        <para>systemd automatically
+                                        adds dependencies of type
+                                        Before to the sysroot.mount unit,
+                                        which is generated from the kernel command
+                                        line by the <literal>systemd-fstab-generator</literal>.
+                                        </para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
                                 <term><filename>rpcbind.target</filename></term>
                                 <listitem>
                                         <para>systemd automatically
@@ -760,6 +789,7 @@
                           <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
                           <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+                          <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                   </para>
         </refsect1>
 
diff --git a/src/core/special.h b/src/core/special.h
index 99c0e12..52e593b 100644
--- a/src/core/special.h
+++ b/src/core/special.h
@@ -48,6 +48,8 @@
 #define SPECIAL_SOCKETS_TARGET "sockets.target"
 #define SPECIAL_LOCAL_FS_TARGET "local-fs.target"
 #define SPECIAL_LOCAL_FS_PRE_TARGET "local-fs-pre.target"
+#define SPECIAL_INITRD_FS_TARGET "initrd-fs.target"
+#define SPECIAL_ROOT_FS_TARGET "root-fs.target"
 #define SPECIAL_REMOTE_FS_TARGET "remote-fs.target"       /* LSB's $remote_fs */
 #define SPECIAL_REMOTE_FS_PRE_TARGET "remote-fs-pre.target"
 #define SPECIAL_SWAP_TARGET "swap.target"
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 910bbc1..b4fb134 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -200,14 +200,13 @@ static bool mount_in_initrd(struct mntent *me) {
 }
 
 static int add_mount(const char *what, const char *where, const char *type, const char *opts,
-                     int passno, bool noauto, bool nofail, bool automount, bool isbind, bool isnetwork,
-                     const char *source) {
+                     int passno, bool noauto, bool nofail, bool automount, bool isbind,
+                     const char *pre, const char *post, const char *source) {
         char _cleanup_free_
                 *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL,
                 *automount_name = NULL, *automount_unit = NULL;
         FILE _cleanup_fclose_ *f = NULL;
         int r;
-        const char *post, *pre;
 
         assert(what);
         assert(where);
@@ -227,14 +226,6 @@ static int add_mount(const char *what, const char *where, const char *type, cons
             mount_point_ignore(where))
                 return 0;
 
-        if (isnetwork) {
-                post = SPECIAL_REMOTE_FS_TARGET;
-                pre = SPECIAL_REMOTE_FS_PRE_TARGET;
-        } else {
-                post = SPECIAL_LOCAL_FS_TARGET;
-                pre = SPECIAL_LOCAL_FS_PRE_TARGET;
-        }
-
         name = unit_name_from_path(where, ".mount");
         if (!name)
                 return log_oom();
@@ -259,17 +250,19 @@ static int add_mount(const char *what, const char *where, const char *type, cons
               "DefaultDependencies=no\n",
               source);
 
-        if (!path_equal(where, "/"))
+        if (!path_equal(where, "/")) {
+                if (pre)
+                        fprintf(f,
+                                "After=%s\n"
+                                "Wants=%s\n",
+                                pre,
+                                pre);
                 fprintf(f,
-                        "After=%s\n"
-                        "Wants=%s\n"
                         "Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
-                        "Before=" SPECIAL_UMOUNT_TARGET "\n",
-                        pre,
-                        pre);
-
+                        "Before=" SPECIAL_UMOUNT_TARGET "\n");
+        }
 
-        if (!noauto && !nofail && !automount)
+        if (post && !noauto && !nofail && !automount)
                 fprintf(f,
                         "Before=%s\n",
                         post);
@@ -299,14 +292,16 @@ static int add_mount(const char *what, const char *where, const char *type, cons
         }
 
         if (!noauto) {
-                lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL);
-                if (!lnk)
-                        return log_oom();
+                if (post) {
+                        lnk = strjoin(arg_dest, "/", post, nofail || automount ? ".wants/" : ".requires/", name, NULL);
+                        if (!lnk)
+                                return log_oom();
 
-                mkdir_parents_label(lnk, 0755);
-                if (symlink(unit, lnk) < 0) {
-                        log_error("Failed to create symlink %s: %m", lnk);
-                        return -errno;
+                        mkdir_parents_label(lnk, 0755);
+                        if (symlink(unit, lnk) < 0) {
+                                log_error("Failed to create symlink %s: %m", lnk);
+                                return -errno;
+                        }
                 }
 
                 if (!isbind &&
@@ -353,12 +348,17 @@ static int add_mount(const char *what, const char *where, const char *type, cons
                         "SourcePath=%s\n"
                         "DefaultDependencies=no\n"
                         "Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
-                        "Before=" SPECIAL_UMOUNT_TARGET " %s\n"
-                        "\n"
+                        "Before=" SPECIAL_UMOUNT_TARGET "\n",
+                        source);
+
+                if (post)
+                        fprintf(f,
+                                "Before= %s\n",
+                                post);
+
+                fprintf(f,
                         "[Automount]\n"
                         "Where=%s\n",
-                        source,
-                        post,
                         where);
 
                 fflush(f);
@@ -421,7 +421,8 @@ static int parse_fstab(const char *prefix, bool initrd) {
                 if (streq(me->mnt_type, "swap"))
                         k = add_swap(what, me);
                 else {
-                        bool noauto, nofail, automount, isbind, isnetwork;
+                        bool noauto, nofail, automount, isbind;
+                        const char *pre, *post;
 
                         noauto = !!hasmntopt(me, "noauto");
                         nofail = !!hasmntopt(me, "nofail");
@@ -429,11 +430,21 @@ static int parse_fstab(const char *prefix, bool initrd) {
                                   hasmntopt(me, "comment=systemd.automount") ||
                                   hasmntopt(me, "x-systemd.automount");
                         isbind = mount_is_bind(me);
-                        isnetwork = mount_is_network(me);
+
+                        if (initrd) {
+                                post = SPECIAL_INITRD_FS_TARGET;
+                                pre = NULL;
+                        } else if (mount_is_network(me)) {
+                                post = SPECIAL_REMOTE_FS_TARGET;
+                                pre = SPECIAL_REMOTE_FS_PRE_TARGET;
+                        } else {
+                                post = SPECIAL_LOCAL_FS_TARGET;
+                                pre = SPECIAL_LOCAL_FS_PRE_TARGET;
+                        }
 
                         k = add_mount(what, where, me->mnt_type, me->mnt_opts,
                                      me->mnt_passno, noauto, nofail, automount,
-                                     isbind, isnetwork, fstab_path);
+                                     isbind, pre, post, fstab_path);
                 }
 
                 if (k < 0)
@@ -514,7 +525,7 @@ static int parse_new_root_from_proc_cmdline(void) {
 
         log_debug("Found entry what=%s where=/sysroot type=%s", what, type);
         r = add_mount(what, "/sysroot", type, opts, 0, false, false, false,
-                      false, false, "/proc/cmdline");
+                      false, NULL, SPECIAL_ROOT_FS_TARGET, "/proc/cmdline");
 
         return (r < 0) ? r : 0;
 }
diff --git a/units/initrd-cleanup.service.in b/units/initrd-cleanup.service.in
index e926a1e..5bef090 100644
--- a/units/initrd-cleanup.service.in
+++ b/units/initrd-cleanup.service.in
@@ -10,8 +10,8 @@ Description=Cleaning Up and Shutting Down Daemons
 DefaultDependencies=no
 ConditionPathExists=/etc/initrd-release
 OnFailure=emergency.target
-Requires=local-fs.target swap.target
-After=local-fs.target swap.target
+Wants=root-fs.target initrd-fs.target
+After=root-fs.target initrd-fs.target
 
 [Service]
 Type=oneshot
diff --git a/units/initrd-fs.target b/units/initrd-fs.target
new file mode 100644
index 0000000..6ba1758
--- /dev/null
+++ b/units/initrd-fs.target
@@ -0,0 +1,13 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Initrd File Systems
+Documentation=man:systemd.special(7)
+OnFailure=emergency.target
+OnFailureIsolate=yes
+ConditionPathExists=/etc/initrd-release
diff --git a/units/initrd-parse-etc.service.in b/units/initrd-parse-etc.service.in
index 1a2711a..44fee7b 100644
--- a/units/initrd-parse-etc.service.in
+++ b/units/initrd-parse-etc.service.in
@@ -8,13 +8,13 @@
 [Unit]
 Description=Reload Configuration from the Real Root
 DefaultDependencies=no
-Requires=local-fs.target swap.target
-After=local-fs.target swap.target
+Requires=root-fs.target
+After=root-fs.target
 OnFailure=emergency.target
 ConditionPathExists=/etc/initrd-release
 
 [Service]
 Type=oneshot
 ExecStartPre=@rootbindir@/systemctl daemon-reload
-ExecStart=@rootbindir@/systemctl start local-fs.target
+ExecStart=@rootbindir@/systemctl start initrd-fs.target
 ExecStart=@rootbindir@/systemctl --no-block start initrd-cleanup.service
diff --git a/units/initrd-switch-root.target b/units/initrd-switch-root.target
index f706d29..cf646c4 100644
--- a/units/initrd-switch-root.target
+++ b/units/initrd-switch-root.target
@@ -12,5 +12,5 @@ DefaultDependencies=no
 Requires=initrd-switch-root.service
 Before=initrd-switch-root.service
 AllowIsolate=yes
-Wants=initrd-udevadm-cleanup-db.service local-fs.target swap.target systemd-journald.service
-After=initrd-udevadm-cleanup-db.service local-fs.target swap.target emergency.service emergency.target
+Wants=initrd-udevadm-cleanup-db.service root-fs.target initrd-fs.target systemd-journald.service
+After=initrd-udevadm-cleanup-db.service root-fs.target initrd-fs.target emergency.service emergency.target
diff --git a/units/root-fs.target b/units/root-fs.target
new file mode 100644
index 0000000..1351534
--- /dev/null
+++ b/units/root-fs.target
@@ -0,0 +1,11 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Initrd Root File System
+Documentation=man:systemd.special(7)
+ConditionPathExists=/etc/initrd-release
-- 
1.8.1



More information about the systemd-devel mailing list