]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Create initrd-root-device.target synchronization point (#3239)
authorDaniel Drake <drake@endlessm.com>
Thu, 12 May 2016 16:42:39 +0000 (10:42 -0600)
committerLennart Poettering <lennart@poettering.net>
Thu, 12 May 2016 16:42:39 +0000 (18:42 +0200)
Add a synchronization point so that custom initramfs units can run
after the root device becomes available, before it is fsck'd and
mounted.

This is useful for custom initramfs units that may modify the
root disk partition table, where the root device is not known in
advance (it's dynamically selected by the generators).

Makefile.am
man/bootup.xml
man/systemd.special.xml
src/basic/special.h
src/fstab-generator/fstab-generator.c
src/gpt-auto-generator/gpt-auto-generator.c
src/shared/generator.c
src/shared/generator.h
units/initrd-root-device.target [new file with mode: 0644]
units/initrd.target

index aea91e9c948296a928896e89ce95474793eece13..c126f65ad2b16438960e5e2e0efc2a9225807f57 100644 (file)
@@ -467,6 +467,7 @@ dist_systemunit_DATA = \
        units/local-fs-pre.target \
        units/initrd.target \
        units/initrd-fs.target \
+       units/initrd-root-device.target \
        units/initrd-root-fs.target \
        units/remote-fs.target \
        units/remote-fs-pre.target \
index b92057af294dac764b7ec9e6aaf50a5908e689f4..986996398cc4049fe832b7a6eb3da2a67a3d07c4 100644 (file)
     identical to the system manager bootup (see above) until it
     reaches <filename>basic.target</filename>. From there, systemd
     approaches the special target <filename>initrd.target</filename>.
+    When the root device becomes available,
+    <filename>initd-root-device.target</filename> is reached.
     If the root device can be mounted at
     <filename>/sysroot</filename>, the
     <filename>sysroot.mount</filename> unit becomes active and
                                                |                                 emergency.service
                         ______________________/|                                         |
                        /                       |                                         v
-                       |                  sysroot.mount                          <emphasis>emergency.target</emphasis>
+                       |            initrd-root-device.target                    <emphasis>emergency.target</emphasis>
+                       |                       |
+                       |                       v
+                       |                  sysroot.mount
                        |                       |
                        |                       v
                        |             initrd-root-fs.target
index 14998b9647dd089f6f1b11fd38d4834ddfbba69d..26974ed73fc370a1c22f1b01debd9497c003df2f 100644 (file)
@@ -83,6 +83,7 @@
     <filename>remote-fs.target</filename>,
     <filename>remote-fs-pre.target</filename>,
     <filename>rescue.target</filename>,
+    <filename>initrd-root-device.target</filename>,
     <filename>initrd-root-fs.target</filename>,
     <filename>rpcbind.target</filename>,
     <filename>runlevel2.target</filename>,
           SysV.</para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term><filename>initrd-root-device.target</filename></term>
+        <listitem>
+          <para>A special initrd target unit that is reached when the root filesystem device is available, but before
+          it has been mounted.
+          <citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+          and
+          <citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+          automatically setup the appropiate dependencies to make this happen.
+          </para>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term><filename>initrd-root-fs.target</filename></term>
         <listitem>
index 2fd03d9f7579757be215b3b7038c95339851a7d0..084d3dfa23c8e4ac55db365d815f1453d74a4d28 100644 (file)
@@ -52,6 +52,7 @@
 #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_INITRD_ROOT_DEVICE_TARGET "initrd-root-device.target"
 #define SPECIAL_INITRD_ROOT_FS_TARGET "initrd-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"
index 343e3b18179d391d42e4a55d12276774d54f7f6b..108522873e8730114bbb2dd3a23329d642058b72 100644 (file)
@@ -489,6 +489,7 @@ static int parse_fstab(bool initrd) {
 static int add_sysroot_mount(void) {
         _cleanup_free_ char *what = NULL;
         const char *opts;
+        int r;
 
         if (isempty(arg_root_what)) {
                 log_debug("Could not find a root= entry on the kernel command line.");
@@ -508,6 +509,13 @@ static int add_sysroot_mount(void) {
                 opts = arg_root_options;
 
         log_debug("Found entry what=%s where=/sysroot type=%s", what, strna(arg_root_fstype));
+
+        if (is_device_path(what)) {
+                r = generator_write_initrd_root_device_deps(arg_dest, what);
+                if (r < 0)
+                        return r;
+        }
+
         return add_mount(what,
                          "/sysroot",
                          arg_root_fstype,
index af96adec0689b960ad9a5090c57452cb1617f847..a4938a7c3a63ab0fee6e7e55dd57b61dc498b656 100644 (file)
@@ -956,6 +956,12 @@ static int add_root_mount(void) {
          * wait for a root device to show up. A udev rule will create
          * the link for us under the right name. */
 
+        if (in_initrd()) {
+                r = generator_write_initrd_root_device_deps(arg_dest, "/dev/gpt-auto-root");
+                if (r < 0)
+                        return 0;
+        }
+
         return add_mount(
                         "root",
                         "/dev/gpt-auto-root",
index cd3c35cd5509593b62ae23b4eeb9908ab05949c3..70afc6a285b26a5379f09ea44c3fc5e4f87e294d 100644 (file)
@@ -65,7 +65,7 @@ static int write_fsck_sysroot_service(const char *dir, const char *what) {
                 "Description=File System Check on %2$s\n"
                 "DefaultDependencies=no\n"
                 "BindsTo=%3$s\n"
-                "After=%3$s local-fs-pre.target\n"
+                "After=initrd-root-device.target local-fs-pre.target\n"
                 "Before=shutdown.target\n"
                 "\n"
                 "[Service]\n"
@@ -191,3 +191,17 @@ int generator_write_timeouts(
                                     "[Unit]\nJobTimeoutSec=%s",
                                     program_invocation_short_name, timeout);
 }
+
+int generator_write_initrd_root_device_deps(const char *dir, const char *what) {
+        _cleanup_free_ char *unit = NULL;
+        int r;
+
+        r = unit_name_from_path(what, ".device", &unit);
+        if (r < 0)
+                return log_error_errno(r, "Failed to make unit name from path: %m");
+
+        return write_drop_in_format(dir, SPECIAL_INITRD_ROOT_DEVICE_TARGET, 50, "root-device",
+                                    "# Automatically generated by %s\n\n"
+                                    "[Unit]\nRequires=%s\nAfter=%s",
+                                    program_invocation_short_name, unit, unit);
+}
index a734e139700bb643b387f65d8d905b835876b2f1..a6017c1b76a1970d78903a79d4ce5190eb9d8786 100644 (file)
@@ -34,3 +34,7 @@ int generator_write_timeouts(
         const char *where,
         const char *opts,
         char **filtered);
+
+int generator_write_initrd_root_device_deps(
+        const char *dir,
+        const char *what);
diff --git a/units/initrd-root-device.target b/units/initrd-root-device.target
new file mode 100644 (file)
index 0000000..9d44d2d
--- /dev/null
@@ -0,0 +1,15 @@
+#  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 Device
+Documentation=man:systemd.special(7)
+ConditionPathExists=/etc/initrd-release
+OnFailure=emergency.target
+OnFailureJobMode=replace-irreversibly
+DefaultDependencies=no
+Conflicts=shutdown.target
index eae7c703c166632b5724d97fe310c4464e17b1bf..8be7e2b3994a2e8f0e0cafb85afa156ba6c4f7ba 100644 (file)
@@ -12,6 +12,6 @@ OnFailure=emergency.target
 OnFailureJobMode=replace-irreversibly
 ConditionPathExists=/etc/initrd-release
 Requires=basic.target
-Wants=initrd-root-fs.target initrd-fs.target initrd-parse-etc.service
-After=initrd-root-fs.target initrd-fs.target basic.target rescue.service rescue.target
+Wants=initrd-root-fs.target initrd-root-device.target initrd-fs.target initrd-parse-etc.service
+After=initrd-root-fs.target initrd-root-device.target initrd-fs.target basic.target rescue.service rescue.target
 AllowIsolate=yes