mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
fstab-generator: support creating bind mounts via root= kernel cmdline switches
This is useful for bind mounting a freshly downloaded and unpacked tar disk images to /sysroot to mount into. Specifically, with a kernel command line like this one: rd.systemd.pull=verify=no,machine,tar:root:http://_gateway:8081/image.tar root=bind:/run/machines/root ip=any The first parameter downloads the root image, the second one then binds it to /sysroot so that we can boot into it.
This commit is contained in:
@@ -99,6 +99,10 @@
|
||||
separate, immutable <filename>/usr/</filename> file system. Also see
|
||||
<varname>systemd.volatile=</varname> below.</para>
|
||||
|
||||
<para>Use <literal>bind:…</literal> to bind mount another directory as operating system root
|
||||
filesystems (added in v258). Expects an absolute path name referencing an existing directory within the initrd's file
|
||||
hierarchy to boot into.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v217"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -242,6 +242,16 @@
|
||||
<literal>http://example.com/image.efi</literal> this would result in a root disk being downloaded from
|
||||
<literal>http://example.com/image.raw.xz</literal>.</para>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title>Boot into disk image (tar), with URL derived from UEFI HTTP network booting</title>
|
||||
|
||||
<programlisting>systemd.pull=tar,machine,verify=no,bootorigin:root:image.tar.xz root=bind:/run/machines/root</programlisting>
|
||||
|
||||
<para>This is similar to the previous example, but instead of a raw (i.e. block device based) disk
|
||||
image the system boots into a tarball that is downloaded from the originating UEFI network
|
||||
server.</para>
|
||||
</example>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
||||
@@ -494,7 +494,8 @@ static int add_mount(
|
||||
const char *opts,
|
||||
int passno,
|
||||
MountPointFlags flags,
|
||||
const char *target_unit) {
|
||||
const char *target_unit,
|
||||
const char *extra_after) {
|
||||
|
||||
_cleanup_free_ char *name = NULL, *automount_name = NULL, *filtered = NULL, *where_escaped = NULL,
|
||||
*opts_root_filtered = NULL;
|
||||
@@ -596,6 +597,9 @@ static int add_mount(
|
||||
if (target_unit && !FLAGS_SET(flags, MOUNT_NOFAIL))
|
||||
fprintf(f, "Before=%s\n", target_unit);
|
||||
|
||||
if (extra_after)
|
||||
fprintf(f, "After=%s\n", extra_after);
|
||||
|
||||
if (passno != 0) {
|
||||
r = generator_write_fsck_deps(f, dest, what, where, fstype);
|
||||
if (r < 0)
|
||||
@@ -814,15 +818,16 @@ static bool sysfs_check(void) {
|
||||
|
||||
static int add_sysusr_sysroot_usr_bind_mount(const char *source) {
|
||||
return add_mount(source,
|
||||
arg_dest,
|
||||
"/sysusr/usr",
|
||||
"/sysroot/usr",
|
||||
NULL,
|
||||
NULL,
|
||||
"bind",
|
||||
0,
|
||||
0,
|
||||
SPECIAL_INITRD_FS_TARGET);
|
||||
arg_dest,
|
||||
"/sysusr/usr",
|
||||
"/sysroot/usr",
|
||||
/* original_where= */ NULL,
|
||||
/* fstype= */ NULL,
|
||||
"bind",
|
||||
/* passno= */ 0,
|
||||
/* flags= */ 0,
|
||||
SPECIAL_INITRD_FS_TARGET,
|
||||
/* extra_after= */ NULL);
|
||||
}
|
||||
|
||||
static MountPointFlags fstab_options_to_flags(const char *options, bool is_swap) {
|
||||
@@ -1000,7 +1005,8 @@ static int parse_fstab_one(
|
||||
options,
|
||||
passno,
|
||||
flags,
|
||||
target_unit);
|
||||
target_unit,
|
||||
/* extra_after= */ NULL);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@@ -1105,8 +1111,8 @@ static int sysroot_is_nfsroot(void) {
|
||||
|
||||
static int add_sysroot_mount(void) {
|
||||
_cleanup_free_ char *what = NULL;
|
||||
const char *opts, *fstype;
|
||||
bool default_rw, makefs;
|
||||
const char *extra_opts = NULL, *fstype = NULL;
|
||||
bool default_rw = true, makefs = false;
|
||||
MountPointFlags flags;
|
||||
int r;
|
||||
|
||||
@@ -1149,7 +1155,20 @@ static int add_sysroot_mount(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (streq(arg_root_what, "tmpfs")) {
|
||||
const char *bind = startswith(arg_root_what, "bind:");
|
||||
if (bind) {
|
||||
if (!path_is_valid(bind) || !path_is_absolute(bind)) {
|
||||
log_debug("Invalid root=bind: source path, ignoring: %s", bind);
|
||||
return 0;
|
||||
}
|
||||
|
||||
what = strdup(bind);
|
||||
if (!what)
|
||||
return log_oom();
|
||||
|
||||
extra_opts = "bind";
|
||||
|
||||
} else if (streq(arg_root_what, "tmpfs")) {
|
||||
/* If root=tmpfs is specified, then take this as shortcut for a writable tmpfs mount as root */
|
||||
|
||||
what = strdup("rootfs"); /* just a pretty name, to show up in /proc/self/mountinfo */
|
||||
@@ -1157,8 +1176,6 @@ static int add_sysroot_mount(void) {
|
||||
return log_oom();
|
||||
|
||||
fstype = arg_root_fstype ?: "tmpfs"; /* tmpfs, unless overridden */
|
||||
|
||||
default_rw = true; /* writable, unless overridden */;
|
||||
} else {
|
||||
|
||||
what = fstab_node_to_udev_node(arg_root_what);
|
||||
@@ -1166,40 +1183,44 @@ static int add_sysroot_mount(void) {
|
||||
return log_oom();
|
||||
|
||||
fstype = arg_root_fstype; /* if not specified explicitly, don't default to anything here */
|
||||
|
||||
default_rw = false; /* read-only, unless overridden */
|
||||
}
|
||||
|
||||
if (!arg_root_options)
|
||||
opts = arg_root_rw > 0 || (arg_root_rw < 0 && default_rw) ? "rw" : "ro";
|
||||
else if (arg_root_rw >= 0 ||
|
||||
!fstab_test_option(arg_root_options, "ro\0" "rw\0"))
|
||||
opts = strjoina(arg_root_options, ",", arg_root_rw > 0 ? "rw" : "ro");
|
||||
else
|
||||
opts = arg_root_options;
|
||||
_cleanup_free_ char *combined_options = NULL;
|
||||
if (strdup_to(&combined_options, arg_root_options) < 0)
|
||||
return log_oom();
|
||||
|
||||
log_debug("Found entry what=%s where=/sysroot type=%s opts=%s", what, strna(arg_root_fstype), strempty(opts));
|
||||
if (arg_root_rw >= 0 || !fstab_test_option(combined_options, "ro\0" "rw\0"))
|
||||
if (!strextend_with_separator(&combined_options, ",", arg_root_rw > 0 || (arg_root_rw < 0 && default_rw) ? "rw" : "ro"))
|
||||
return log_oom();
|
||||
|
||||
makefs = fstab_test_option(opts, "x-systemd.makefs\0");
|
||||
if (extra_opts)
|
||||
if (!strextend_with_separator(&combined_options, ",", extra_opts))
|
||||
return log_oom();
|
||||
|
||||
log_debug("Found entry what=%s where=/sysroot type=%s opts=%s", what, strna(arg_root_fstype), strempty(combined_options));
|
||||
|
||||
makefs = fstab_test_option(combined_options, "x-systemd.makefs\0");
|
||||
flags = makefs * MOUNT_MAKEFS;
|
||||
|
||||
return add_mount("/proc/cmdline",
|
||||
arg_dest,
|
||||
what,
|
||||
"/sysroot",
|
||||
NULL,
|
||||
/* original_where= */ NULL,
|
||||
fstype,
|
||||
opts,
|
||||
is_device_path(what) ? 1 : 0, /* passno */
|
||||
flags, /* makefs off, pcrfs off, quota off, noauto off, nofail off, automount off */
|
||||
SPECIAL_INITRD_ROOT_FS_TARGET);
|
||||
combined_options,
|
||||
/* passno= */ is_device_path(what) ? 1 : 0,
|
||||
flags,
|
||||
SPECIAL_INITRD_ROOT_FS_TARGET,
|
||||
"imports.target");
|
||||
}
|
||||
|
||||
static int add_sysroot_usr_mount(void) {
|
||||
_cleanup_free_ char *what = NULL;
|
||||
const char *opts;
|
||||
bool makefs;
|
||||
const char *extra_opts = NULL;
|
||||
MountPointFlags flags;
|
||||
bool makefs;
|
||||
int r;
|
||||
|
||||
/* Returns 0 if we didn't do anything, > 0 if we either generated a unit for the /usr/ mount, or we
|
||||
@@ -1250,16 +1271,35 @@ static int add_sysroot_usr_mount(void) {
|
||||
return 1; /* As above, report that NFS code will create the unit */
|
||||
}
|
||||
|
||||
what = fstab_node_to_udev_node(arg_usr_what);
|
||||
if (!what)
|
||||
const char *bind = startswith(arg_usr_what, "bind:");
|
||||
if (bind) {
|
||||
if (!path_is_valid(bind) || !path_is_absolute(bind)) {
|
||||
log_debug("Invalid mount.usr=bind: source path, ignoring: %s", bind);
|
||||
return 0;
|
||||
}
|
||||
|
||||
what = strdup(bind);
|
||||
if (!what)
|
||||
return log_oom();
|
||||
|
||||
extra_opts = "bind";
|
||||
} else {
|
||||
what = fstab_node_to_udev_node(arg_usr_what);
|
||||
if (!what)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
_cleanup_free_ char *combined_options = NULL;
|
||||
if (strdup_to(&combined_options, arg_usr_options) < 0)
|
||||
return log_oom();
|
||||
|
||||
if (!arg_usr_options)
|
||||
opts = arg_root_rw > 0 ? "rw" : "ro";
|
||||
else if (!fstab_test_option(arg_usr_options, "ro\0" "rw\0"))
|
||||
opts = strjoina(arg_usr_options, ",", arg_root_rw > 0 ? "rw" : "ro");
|
||||
else
|
||||
opts = arg_usr_options;
|
||||
if (!fstab_test_option(combined_options, "ro\0" "rw\0"))
|
||||
if (!strextend_with_separator(&combined_options, ",", arg_root_rw > 0 ? "rw" : "ro"))
|
||||
return log_oom();
|
||||
|
||||
if (extra_opts)
|
||||
if (!strextend_with_separator(&combined_options, ",", extra_opts))
|
||||
return log_oom();
|
||||
|
||||
/* When mounting /usr from the initrd, we add an extra level of indirection: we first mount the /usr/
|
||||
* partition to /sysusr/usr/, and then afterwards bind mount that to /sysroot/usr/. We do this so
|
||||
@@ -1268,21 +1308,22 @@ static int add_sysroot_usr_mount(void) {
|
||||
* this should order itself after initrd-usr-fs.target and before initrd-fs.target; and it should
|
||||
* look into both /sysusr/ and /sysroot/ for the configuration data to apply. */
|
||||
|
||||
log_debug("Found entry what=%s where=/sysusr/usr type=%s opts=%s", what, strna(arg_usr_fstype), strempty(opts));
|
||||
log_debug("Found entry what=%s where=/sysusr/usr type=%s opts=%s", what, strna(arg_usr_fstype), strempty(combined_options));
|
||||
|
||||
makefs = fstab_test_option(opts, "x-systemd.makefs\0");
|
||||
makefs = fstab_test_option(combined_options, "x-systemd.makefs\0");
|
||||
flags = makefs * MOUNT_MAKEFS;
|
||||
|
||||
r = add_mount("/proc/cmdline",
|
||||
arg_dest,
|
||||
what,
|
||||
"/sysusr/usr",
|
||||
NULL,
|
||||
/* original_where= */ NULL,
|
||||
arg_usr_fstype,
|
||||
opts,
|
||||
is_device_path(what) ? 1 : 0, /* passno */
|
||||
combined_options,
|
||||
/* passno= */ is_device_path(what) ? 1 : 0,
|
||||
flags,
|
||||
SPECIAL_INITRD_USR_FS_TARGET);
|
||||
SPECIAL_INITRD_USR_FS_TARGET,
|
||||
"imports.target");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1336,12 +1377,13 @@ static int add_volatile_var(void) {
|
||||
arg_dest_late,
|
||||
"tmpfs",
|
||||
"/var",
|
||||
NULL,
|
||||
/* original_where= */ NULL,
|
||||
"tmpfs",
|
||||
"mode=0755" TMPFS_LIMITS_VAR,
|
||||
0,
|
||||
0,
|
||||
SPECIAL_LOCAL_FS_TARGET);
|
||||
/* passno= */ 0,
|
||||
/* flags= */ 0,
|
||||
SPECIAL_LOCAL_FS_TARGET,
|
||||
/* extra_after= */ NULL);
|
||||
}
|
||||
|
||||
static int add_mounts_from_cmdline(void) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
|
||||
SourcePath=/proc/cmdline
|
||||
Before=initrd-root-fs.target
|
||||
After=imports.target
|
||||
Requires=systemd-fsck-root.service
|
||||
After=systemd-fsck-root.service
|
||||
After=blockdev@dev-sdx1.target
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
|
||||
SourcePath=/proc/cmdline
|
||||
Before=initrd-root-fs.target
|
||||
After=imports.target
|
||||
Requires=systemd-fsck-root.service
|
||||
After=systemd-fsck-root.service
|
||||
After=blockdev@dev-disk-by\x2dlabel-Root.target
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
|
||||
SourcePath=/proc/cmdline
|
||||
Before=initrd-root-fs.target
|
||||
After=imports.target
|
||||
Requires=systemd-fsck-root.service
|
||||
After=systemd-fsck-root.service
|
||||
After=blockdev@dev-disk-by\x2duuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.target
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
|
||||
SourcePath=/proc/cmdline
|
||||
Before=initrd-root-fs.target
|
||||
After=imports.target
|
||||
Requires=systemd-fsck-root.service
|
||||
After=systemd-fsck-root.service
|
||||
After=blockdev@dev-disk-by\x2dpartuuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.target
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
|
||||
SourcePath=/proc/cmdline
|
||||
Before=initrd-root-fs.target
|
||||
After=imports.target
|
||||
|
||||
[Mount]
|
||||
What=rootfs
|
||||
|
||||
Reference in New Issue
Block a user