Skip to content

Commit 7163e1c

Browse files
dsdpoettering
authored andcommitted
Create initrd-root-device.target synchronization point (systemd#3239)
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).
1 parent 42d35e1 commit 7163e1c

File tree

10 files changed

+71
-4
lines changed

10 files changed

+71
-4
lines changed

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,7 @@ dist_systemunit_DATA = \
467467
units/local-fs-pre.target \
468468
units/initrd.target \
469469
units/initrd-fs.target \
470+
units/initrd-root-device.target \
470471
units/initrd-root-fs.target \
471472
units/remote-fs.target \
472473
units/remote-fs-pre.target \

man/bootup.xml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@
179179
identical to the system manager bootup (see above) until it
180180
reaches <filename>basic.target</filename>. From there, systemd
181181
approaches the special target <filename>initrd.target</filename>.
182+
When the root device becomes available,
183+
<filename>initd-root-device.target</filename> is reached.
182184
If the root device can be mounted at
183185
<filename>/sysroot</filename>, the
184186
<filename>sysroot.mount</filename> unit becomes active and
@@ -204,7 +206,10 @@
204206
| emergency.service
205207
______________________/| |
206208
/ | v
207-
| sysroot.mount <emphasis>emergency.target</emphasis>
209+
| initrd-root-device.target <emphasis>emergency.target</emphasis>
210+
| |
211+
| v
212+
| sysroot.mount
208213
| |
209214
| v
210215
| initrd-root-fs.target

man/systemd.special.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
<filename>remote-fs.target</filename>,
8484
<filename>remote-fs-pre.target</filename>,
8585
<filename>rescue.target</filename>,
86+
<filename>initrd-root-device.target</filename>,
8687
<filename>initrd-root-fs.target</filename>,
8788
<filename>rpcbind.target</filename>,
8889
<filename>runlevel2.target</filename>,
@@ -464,6 +465,18 @@
464465
SysV.</para>
465466
</listitem>
466467
</varlistentry>
468+
<varlistentry>
469+
<term><filename>initrd-root-device.target</filename></term>
470+
<listitem>
471+
<para>A special initrd target unit that is reached when the root filesystem device is available, but before
472+
it has been mounted.
473+
<citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry>
474+
and
475+
<citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>3</manvolnum></citerefentry>
476+
automatically setup the appropiate dependencies to make this happen.
477+
</para>
478+
</listitem>
479+
</varlistentry>
467480
<varlistentry>
468481
<term><filename>initrd-root-fs.target</filename></term>
469482
<listitem>

src/basic/special.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#define SPECIAL_LOCAL_FS_TARGET "local-fs.target"
5353
#define SPECIAL_LOCAL_FS_PRE_TARGET "local-fs-pre.target"
5454
#define SPECIAL_INITRD_FS_TARGET "initrd-fs.target"
55+
#define SPECIAL_INITRD_ROOT_DEVICE_TARGET "initrd-root-device.target"
5556
#define SPECIAL_INITRD_ROOT_FS_TARGET "initrd-root-fs.target"
5657
#define SPECIAL_REMOTE_FS_TARGET "remote-fs.target" /* LSB's $remote_fs */
5758
#define SPECIAL_REMOTE_FS_PRE_TARGET "remote-fs-pre.target"

src/fstab-generator/fstab-generator.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,7 @@ static int parse_fstab(bool initrd) {
489489
static int add_sysroot_mount(void) {
490490
_cleanup_free_ char *what = NULL;
491491
const char *opts;
492+
int r;
492493

493494
if (isempty(arg_root_what)) {
494495
log_debug("Could not find a root= entry on the kernel command line.");
@@ -508,6 +509,13 @@ static int add_sysroot_mount(void) {
508509
opts = arg_root_options;
509510

510511
log_debug("Found entry what=%s where=/sysroot type=%s", what, strna(arg_root_fstype));
512+
513+
if (is_device_path(what)) {
514+
r = generator_write_initrd_root_device_deps(arg_dest, what);
515+
if (r < 0)
516+
return r;
517+
}
518+
511519
return add_mount(what,
512520
"/sysroot",
513521
arg_root_fstype,

src/gpt-auto-generator/gpt-auto-generator.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,12 @@ static int add_root_mount(void) {
956956
* wait for a root device to show up. A udev rule will create
957957
* the link for us under the right name. */
958958

959+
if (in_initrd()) {
960+
r = generator_write_initrd_root_device_deps(arg_dest, "/dev/gpt-auto-root");
961+
if (r < 0)
962+
return 0;
963+
}
964+
959965
return add_mount(
960966
"root",
961967
"/dev/gpt-auto-root",

src/shared/generator.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static int write_fsck_sysroot_service(const char *dir, const char *what) {
6565
"Description=File System Check on %2$s\n"
6666
"DefaultDependencies=no\n"
6767
"BindsTo=%3$s\n"
68-
"After=%3$s local-fs-pre.target\n"
68+
"After=initrd-root-device.target local-fs-pre.target\n"
6969
"Before=shutdown.target\n"
7070
"\n"
7171
"[Service]\n"
@@ -191,3 +191,17 @@ int generator_write_timeouts(
191191
"[Unit]\nJobTimeoutSec=%s",
192192
program_invocation_short_name, timeout);
193193
}
194+
195+
int generator_write_initrd_root_device_deps(const char *dir, const char *what) {
196+
_cleanup_free_ char *unit = NULL;
197+
int r;
198+
199+
r = unit_name_from_path(what, ".device", &unit);
200+
if (r < 0)
201+
return log_error_errno(r, "Failed to make unit name from path: %m");
202+
203+
return write_drop_in_format(dir, SPECIAL_INITRD_ROOT_DEVICE_TARGET, 50, "root-device",
204+
"# Automatically generated by %s\n\n"
205+
"[Unit]\nRequires=%s\nAfter=%s",
206+
program_invocation_short_name, unit, unit);
207+
}

src/shared/generator.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,7 @@ int generator_write_timeouts(
3434
const char *where,
3535
const char *opts,
3636
char **filtered);
37+
38+
int generator_write_initrd_root_device_deps(
39+
const char *dir,
40+
const char *what);

units/initrd-root-device.target

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# This file is part of systemd.
2+
#
3+
# systemd is free software; you can redistribute it and/or modify it
4+
# under the terms of the GNU Lesser General Public License as published by
5+
# the Free Software Foundation; either version 2.1 of the License, or
6+
# (at your option) any later version.
7+
8+
[Unit]
9+
Description=Initrd Root Device
10+
Documentation=man:systemd.special(7)
11+
ConditionPathExists=/etc/initrd-release
12+
OnFailure=emergency.target
13+
OnFailureJobMode=replace-irreversibly
14+
DefaultDependencies=no
15+
Conflicts=shutdown.target

units/initrd.target

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ OnFailure=emergency.target
1212
OnFailureJobMode=replace-irreversibly
1313
ConditionPathExists=/etc/initrd-release
1414
Requires=basic.target
15-
Wants=initrd-root-fs.target initrd-fs.target initrd-parse-etc.service
16-
After=initrd-root-fs.target initrd-fs.target basic.target rescue.service rescue.target
15+
Wants=initrd-root-fs.target initrd-root-device.target initrd-fs.target initrd-parse-etc.service
16+
After=initrd-root-fs.target initrd-root-device.target initrd-fs.target basic.target rescue.service rescue.target
1717
AllowIsolate=yes

0 commit comments

Comments
 (0)