1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 17:35:35 +03:00

Merge pull request #27563 from yuwata/fstab-generator

fstab-generator: support defining mount units through kernel command line
This commit is contained in:
Lennart Poettering 2023-05-26 02:52:19 -07:00 committed by GitHub
commit 0706718c07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
89 changed files with 922 additions and 176 deletions

View File

@ -239,6 +239,33 @@
any swap devices configured in <filename>/etc/fstab</filename>.
Defaults to enabled.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>systemd.mount-extra=<replaceable>WHAT</replaceable>:<replaceable>WHERE</replaceable>[:<replaceable>FSTYPE</replaceable>[:<replaceable>OPTIONS</replaceable>]]</varname></term>
<listitem>
<para>Specifies the mount unit. Takes at least two and at most four fields separated with a colon
(<literal>:</literal>). Each field is handled as the corresponding fstab field. This option can be
specified multiple times.</para>
<para>Example:
<programlisting>
systemd.mount-extra=/dev/sda1:/mount-point:ext4:rw,noatime</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>systemd.swap-extra=<replaceable>WHAT</replaceable>[:<replaceable>OPTIONS</replaceable>]</varname></term>
<listitem>
<para>Specifies the swap unit. Takes the block device to be used as a swap device, and optionally
takes mount options followed by a colon (<literal>:</literal>).</para>
<para>Example:
<programlisting>
systemd.swap=/dev/sda2:x-systemd.makefs</programlisting>
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -22,6 +22,7 @@
#include "mount-setup.h"
#include "mount-util.h"
#include "mountpoint-util.h"
#include "nulstr-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "proc-cmdline.h"
@ -45,6 +46,15 @@ typedef enum MountPointFlags {
MOUNT_PCRFS = 1 << 6,
} MountPointFlags;
typedef struct Mount {
char *what;
char *where;
char *fstype;
char *options;
} Mount;
static void mount_array_free(Mount *mounts, size_t n);
static bool arg_sysroot_check = false;
static const char *arg_dest = NULL;
static const char *arg_dest_late = NULL;
@ -61,6 +71,8 @@ static char *arg_usr_options = NULL;
static char *arg_usr_hash = NULL;
static VolatileMode arg_volatile_mode = _VOLATILE_MODE_INVALID;
static bool arg_verity = true;
static Mount *arg_mounts = NULL;
static size_t arg_n_mounts = 0;
STATIC_DESTRUCTOR_REGISTER(arg_root_what, freep);
STATIC_DESTRUCTOR_REGISTER(arg_root_fstype, freep);
@ -70,6 +82,101 @@ STATIC_DESTRUCTOR_REGISTER(arg_usr_what, freep);
STATIC_DESTRUCTOR_REGISTER(arg_usr_fstype, freep);
STATIC_DESTRUCTOR_REGISTER(arg_usr_options, freep);
STATIC_DESTRUCTOR_REGISTER(arg_usr_hash, freep);
STATIC_ARRAY_DESTRUCTOR_REGISTER(arg_mounts, arg_n_mounts, mount_array_free);
static void mount_done(Mount *m) {
assert(m);
free(m->what);
free(m->where);
free(m->fstype);
free(m->options);
}
static void mount_array_free(Mount *mounts, size_t n) {
FOREACH_ARRAY(m, mounts, n)
mount_done(m);
free(mounts);
}
static int mount_array_add_internal(char *in_what, char *in_where, const char *in_fstype, const char *in_options) {
_cleanup_free_ char *what = NULL, *where = NULL, *fstype = NULL, *options = NULL;
int r;
/* This takes what and where. */
what = ASSERT_PTR(in_what);
where = in_where;
fstype = strdup(isempty(in_fstype) ? "auto" : in_fstype);
if (!fstype)
return -ENOMEM;
if (streq(fstype, "swap"))
where = mfree(where);
if (!isempty(in_options)) {
_cleanup_strv_free_ char **options_strv = NULL;
r = strv_split_full(&options_strv, in_options, ",", 0);
if (r < 0)
return r;
r = strv_make_nulstr(options_strv, &options, NULL);
} else
r = strv_make_nulstr(STRV_MAKE("defaults"), &options, NULL);
if (r < 0)
return r;
if (!GREEDY_REALLOC(arg_mounts, arg_n_mounts + 1))
return -ENOMEM;
arg_mounts[arg_n_mounts++] = (Mount) {
.what = TAKE_PTR(what),
.where = TAKE_PTR(where),
.fstype = TAKE_PTR(fstype),
.options = TAKE_PTR(options),
};
return 0;
}
static int mount_array_add(const char *str) {
_cleanup_free_ char *what = NULL, *where = NULL, *fstype = NULL, *options = NULL;
int r;
assert(str);
r = extract_many_words(&str, ":", EXTRACT_CUNESCAPE | EXTRACT_DONT_COALESCE_SEPARATORS,
&what, &where, &fstype, &options, NULL);
if (r < 0)
return r;
if (r < 2)
return -EINVAL;
if (!isempty(str))
return -EINVAL;
return mount_array_add_internal(TAKE_PTR(what), TAKE_PTR(where), fstype, options);
}
static int mount_array_add_swap(const char *str) {
_cleanup_free_ char *what = NULL, *options = NULL;
int r;
assert(str);
r = extract_many_words(&str, ":", EXTRACT_CUNESCAPE | EXTRACT_DONT_COALESCE_SEPARATORS,
&what, &options, NULL);
if (r < 0)
return r;
if (r < 1)
return -EINVAL;
if (!isempty(str))
return -EINVAL;
return mount_array_add_internal(TAKE_PTR(what), NULL, "swap", options);
}
static int write_options(FILE *f, const char *options) {
_cleanup_free_ char *o = NULL;
@ -102,7 +209,7 @@ static int write_what(FILE *f, const char *what) {
static int add_swap(
const char *source,
const char *what,
struct mntent *me,
const char *options,
MountPointFlags flags) {
_cleanup_free_ char *name = NULL;
@ -110,20 +217,14 @@ static int add_swap(
int r;
assert(what);
assert(me);
if (!arg_swap_enabled) {
log_info("Swap unit generation disabled on kernel command line, ignoring fstab swap entry for %s.", what);
return 0;
}
if (access("/proc/swaps", F_OK) < 0) {
log_info("Swap not supported, ignoring fstab swap entry for %s.", what);
log_info("Swap not supported, ignoring swap entry for %s.", what);
return 0;
}
if (detect_container() > 0) {
log_info("Running in a container, ignoring fstab swap entry for %s.", what);
log_info("Running in a container, ignoring swap entry for %s.", what);
return 0;
}
@ -132,6 +233,11 @@ static int add_swap(
return true;
}
log_debug("Found swap entry what=%s makefs=%s growfs=%s pcrfs=%s noauto=%s nofail=%s",
what,
yes_no(flags & MOUNT_MAKEFS), yes_no(flags & MOUNT_GROWFS), yes_no(flags & MOUNT_PCRFS),
yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL));
r = unit_name_from_path(what, ".swap", &name);
if (r < 0)
return log_error_errno(r, "Failed to generate unit name: %m");
@ -158,7 +264,7 @@ static int add_swap(
if (r < 0)
return r;
r = write_options(f, me->mnt_opts);
r = write_options(f, options);
if (r < 0)
return r;
@ -167,7 +273,7 @@ static int add_swap(
return log_error_errno(r, "Failed to write unit file %s: %m", name);
/* use what as where, to have a nicer error message */
r = generator_write_timeouts(arg_dest, what, what, me->mnt_opts, NULL);
r = generator_write_timeouts(arg_dest, what, what, options, NULL);
if (r < 0)
return r;
@ -193,18 +299,14 @@ static int add_swap(
return true;
}
static bool mount_is_network(struct mntent *me) {
assert(me);
return fstab_test_option(me->mnt_opts, "_netdev\0") ||
fstype_is_network(me->mnt_type);
static bool mount_is_network(const char *fstype, const char *options) {
return fstab_test_option(options, "_netdev\0") ||
(fstype && fstype_is_network(fstype));
}
static bool mount_in_initrd(struct mntent *me) {
assert(me);
return fstab_test_option(me->mnt_opts, "x-initrd.mount\0") ||
path_equal(me->mnt_dir, "/usr");
static bool mount_in_initrd(const char *where, const char *options) {
return fstab_test_option(options, "x-initrd.mount\0") ||
(where && path_equal(where, "/usr"));
}
static int write_timeout(
@ -643,6 +745,20 @@ static const char* sysroot_fstab_path(void) {
return getenv("SYSTEMD_SYSROOT_FSTAB") ?: "/sysroot/etc/fstab";
}
static bool sysfs_check(void) {
static int cached = -1;
int r;
if (cached < 0) {
r = getenv_bool_secure("SYSTEMD_SYSFS_CHECK");
if (r < 0 && r != -ENXIO)
log_debug_errno(r, "Failed to parse $SYSTEMD_SYSFS_CHECK, ignoring: %m");
cached = r != 0;
}
return cached;
}
static int add_sysusr_sysroot_usr_bind_mount(const char *source) {
return add_mount(source,
arg_dest,
@ -656,11 +772,164 @@ static int add_sysusr_sysroot_usr_bind_mount(const char *source) {
SPECIAL_INITRD_FS_TARGET);
}
static MountPointFlags fstab_options_to_flags(const char *options, bool is_swap) {
MountPointFlags flags = 0;
if (fstab_test_option(options, "x-systemd.makefs\0"))
flags |= MOUNT_MAKEFS;
if (fstab_test_option(options, "x-systemd.growfs\0"))
flags |= MOUNT_GROWFS;
if (fstab_test_option(options, "x-systemd.pcrfs\0"))
flags |= MOUNT_PCRFS;
if (fstab_test_yes_no_option(options, "noauto\0" "auto\0"))
flags |= MOUNT_NOAUTO;
if (fstab_test_yes_no_option(options, "nofail\0" "fail\0"))
flags |= MOUNT_NOFAIL;
if (!is_swap) {
if (fstab_test_option(options, "x-systemd.rw-only\0"))
flags |= MOUNT_RW_ONLY;
if (fstab_test_option(options,
"comment=systemd.automount\0"
"x-systemd.automount\0"))
flags |= MOUNT_AUTOMOUNT;
}
return flags;
}
static int parse_fstab_one(
const char *source,
const char *what_original,
const char *where_original,
const char *fstype,
const char *options,
int passno,
bool initrd,
bool use_swap_enabled) {
_cleanup_free_ char *what = NULL, *where = NULL;
MountPointFlags flags;
bool is_swap;
int r;
assert(what_original);
assert(fstype);
assert(options);
if (initrd && !mount_in_initrd(where_original, options))
return 0;
is_swap = streq_ptr(fstype, "swap");
if (is_swap && use_swap_enabled && !arg_swap_enabled) {
log_info("Swap unit generation disabled on kernel command line, ignoring swap entry for %s.", what);
return 0;
}
what = fstab_node_to_udev_node(what_original);
if (!what)
return log_oom();
if (path_is_read_only_fs("/sys") > 0 &&
(streq(what, "sysfs") ||
(sysfs_check() && is_device_path(what)))) {
log_info("/sys/ is read-only (running in a container?), ignoring mount for %s.", what);
return 0;
}
flags = fstab_options_to_flags(options, is_swap);
if (is_swap)
return add_swap(source, what, options, flags);
assert(where_original); /* 'where' is not necessary for swap entry. */
if (!is_path(where_original)) {
log_warning("Mount point %s is not a valid path, ignoring.", where);
return 0;
}
/* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for
* mount units, but causes problems since it historically worked to have symlinks in e.g.
* /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case
* where a symlink refers to another mount target; this works assuming the sub-mountpoint
* target is the final directory.
*
* FIXME: when chase() learns to chase non-existent paths, use this here and
* drop the prefixing with /sysroot on error below.
*/
r = chase(where_original, initrd ? "/sysroot" : NULL, CHASE_PREFIX_ROOT | CHASE_NONEXISTENT, &where, NULL);
if (r < 0) {
/* If we can't canonicalize, continue as if it wasn't a symlink */
log_debug_errno(r, "Failed to read symlink target for %s, using as-is: %m", where_original);
if (initrd)
where = path_join("/sysroot", where_original);
else
where = strdup(where_original);
if (!where)
return log_oom();
path_simplify(where);
}
if (streq(where, where_original)) /* If it was fully canonicalized, suppress the change */
where = mfree(where);
else
log_debug("Canonicalized what=%s where=%s to %s", what, where_original, where);
log_debug("Found entry what=%s where=%s type=%s makefs=%s growfs=%s pcrfs=%s noauto=%s nofail=%s",
what, where, strna(fstype),
yes_no(flags & MOUNT_MAKEFS), yes_no(flags & MOUNT_GROWFS), yes_no(flags & MOUNT_PCRFS),
yes_no(flags & MOUNT_NOAUTO), yes_no(flags & MOUNT_NOFAIL));
bool is_sysroot = in_initrd() && path_equal(where ?: where_original, "/sysroot");
/* See comment from add_sysroot_usr_mount() about the need for extra indirection in case /usr needs
* to be mounted in order for the root fs to be synthesized based on configuration included in /usr/,
* e.g. systemd-repart. */
bool is_sysroot_usr = in_initrd() && path_equal(where ?: where_original, "/sysroot/usr");
const char *target_unit =
initrd ? SPECIAL_INITRD_FS_TARGET :
is_sysroot ? SPECIAL_INITRD_ROOT_FS_TARGET :
is_sysroot_usr ? SPECIAL_INITRD_USR_FS_TARGET :
mount_is_network(fstype, options) ? SPECIAL_REMOTE_FS_TARGET :
SPECIAL_LOCAL_FS_TARGET;
if (is_sysroot && is_device_path(what)) {
r = generator_write_initrd_root_device_deps(arg_dest, what);
if (r < 0)
return r;
}
r = add_mount(source,
arg_dest,
what,
is_sysroot_usr ? "/sysusr/usr" : where ?: where_original,
!is_sysroot_usr && where ? where_original : NULL,
fstype,
options,
passno,
flags,
target_unit);
if (r <= 0)
return r;
if (is_sysroot_usr) {
log_debug("Synthesizing fstab entry what=/sysusr/usr where=/sysroot/usr opts=bind");
r = add_sysusr_sysroot_usr_bind_mount(source);
if (r < 0)
return r;
}
return true;
}
static int parse_fstab(bool initrd) {
_cleanup_endmntent_ FILE *f = NULL;
const char *fstab;
struct mntent *me;
int r = 0, sysfs_check = -1;
int r, ret = 0;
if (initrd)
fstab = sysroot_fstab_path();
@ -680,147 +949,16 @@ static int parse_fstab(bool initrd) {
}
while ((me = getmntent(f))) {
_cleanup_free_ char *where = NULL, *what = NULL, *canonical_where = NULL;
bool makefs, growfs, pcrfs, noauto, nofail;
MountPointFlags flags;
int k;
if (initrd && !mount_in_initrd(me))
continue;
what = fstab_node_to_udev_node(me->mnt_fsname);
if (!what)
return log_oom();
if (path_is_read_only_fs("/sys") > 0) {
if (streq(what, "sysfs")) {
log_info("/sys/ is read-only (running in a container?), ignoring fstab entry for %s.", me->mnt_dir);
continue;
}
if (sysfs_check < 0) {
k = getenv_bool_secure("SYSTEMD_SYSFS_CHECK");
if (k < 0 && k != -ENXIO)
log_debug_errno(k, "Failed to parse $SYSTEMD_SYSFS_CHECK, ignoring: %m");
sysfs_check = k != 0;
}
if (sysfs_check && is_device_path(what)) {
log_info("/sys/ is read-only (running in a container?), ignoring fstab device entry for %s.", what);
continue;
}
}
where = strdup(me->mnt_dir);
if (!where)
return log_oom();
if (is_path(where)) {
path_simplify(where);
/* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for
* mount units, but causes problems since it historically worked to have symlinks in e.g.
* /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case
* where a symlink refers to another mount target; this works assuming the sub-mountpoint
* target is the final directory.
*
* FIXME: when chase() learns to chase non-existent paths, use this here and
* drop the prefixing with /sysroot on error below.
*/
k = chase(where, initrd ? "/sysroot" : NULL, CHASE_PREFIX_ROOT | CHASE_NONEXISTENT,
&canonical_where, NULL);
if (k < 0) {
/* If we can't canonicalize, continue as if it wasn't a symlink */
log_debug_errno(k, "Failed to read symlink target for %s, using as-is: %m", where);
if (initrd) {
canonical_where = path_join("/sysroot", where);
if (!canonical_where)
return log_oom();
}
} else if (streq(canonical_where, where)) /* If it was fully canonicalized, suppress the change */
canonical_where = mfree(canonical_where);
else
log_debug("Canonicalized what=%s where=%s to %s", what, where, canonical_where);
}
makefs = fstab_test_option(me->mnt_opts, "x-systemd.makefs\0");
growfs = fstab_test_option(me->mnt_opts, "x-systemd.growfs\0");
pcrfs = fstab_test_option(me->mnt_opts, "x-systemd.pcrfs\0");
noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0");
nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0");
log_debug("Found entry what=%s where=%s type=%s makefs=%s growfs=%s pcrfs=%s noauto=%s nofail=%s",
what, where, me->mnt_type,
yes_no(makefs), yes_no(growfs), yes_no(pcrfs),
yes_no(noauto), yes_no(nofail));
flags = makefs * MOUNT_MAKEFS |
growfs * MOUNT_GROWFS |
pcrfs * MOUNT_PCRFS |
noauto * MOUNT_NOAUTO |
nofail * MOUNT_NOFAIL;
if (streq(me->mnt_type, "swap"))
k = add_swap(fstab, what, me, flags);
else {
bool rw_only, automount, is_sysroot, is_sysroot_usr;
rw_only = fstab_test_option(me->mnt_opts, "x-systemd.rw-only\0");
automount = fstab_test_option(me->mnt_opts,
"comment=systemd.automount\0"
"x-systemd.automount\0");
flags |= rw_only * MOUNT_RW_ONLY |
automount * MOUNT_AUTOMOUNT;
is_sysroot = in_initrd() && path_equal(where, "/sysroot");
/* See comment from add_sysroot_usr_mount about the need for extra indirection
* in case /usr needs to be mounted in order for the root fs to be synthesized
* based on configuration included in /usr/, e.g. systemd-repart. */
is_sysroot_usr = in_initrd() && path_equal(where, "/sysroot/usr");
const char *target_unit =
initrd ? SPECIAL_INITRD_FS_TARGET :
is_sysroot ? SPECIAL_INITRD_ROOT_FS_TARGET :
is_sysroot_usr ? SPECIAL_INITRD_USR_FS_TARGET :
mount_is_network(me) ? SPECIAL_REMOTE_FS_TARGET :
SPECIAL_LOCAL_FS_TARGET;
if (is_sysroot && is_device_path(what)) {
r = generator_write_initrd_root_device_deps(arg_dest, what);
if (r < 0)
return r;
}
k = add_mount(fstab,
arg_dest,
what,
is_sysroot_usr ? "/sysusr/usr" : canonical_where ?: where,
!is_sysroot_usr && canonical_where ? where : NULL,
me->mnt_type,
me->mnt_opts,
me->mnt_passno,
flags,
target_unit);
if (is_sysroot_usr && k >= 0) {
log_debug("Synthesizing fstab entry what=/sysusr/usr where=/sysroot/usr opts=bind");
r = add_sysusr_sysroot_usr_bind_mount(fstab);
if (r != 0)
k = r;
}
}
if (arg_sysroot_check && k > 0)
r = parse_fstab_one(fstab,
me->mnt_fsname, me->mnt_dir, me->mnt_type, me->mnt_opts, me->mnt_passno,
initrd, /* use_swap_enabled = */ true);
if (r < 0 && ret >= 0)
ret = r;
if (arg_sysroot_check && r > 0)
return true; /* We found a mount or swap that would be started… */
if (r >= 0 && k < 0)
r = k;
}
return r;
return ret;
}
static int sysroot_is_nfsroot(void) {
@ -1121,6 +1259,28 @@ static int add_volatile_var(void) {
SPECIAL_LOCAL_FS_TARGET);
}
static int add_mounts_from_cmdline(void) {
int r, ret = 0;
/* Handle each entries found in cmdline as a fstab entry. */
FOREACH_ARRAY(m, arg_mounts, arg_n_mounts) {
r = parse_fstab_one(
"/proc/cmdline",
m->what,
m->where,
m->fstype,
m->options,
/* passno = */ 0,
/* initrd = */ false,
/* use_swap_enabled = */ false);
if (r < 0 && ret >= 0)
ret = r;
}
return ret;
}
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
int r;
@ -1225,6 +1385,24 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
log_warning("Failed to parse systemd.verity= kernel command line switch %s. Ignoring.", value);
else
arg_verity = r;
} else if (streq(key, "systemd.mount-extra")) {
if (proc_cmdline_value_missing(key, value))
return 0;
r = mount_array_add(value);
if (r < 0)
log_warning("Failed to parse systemd.mount-extra= option, ignoring: %s", value);
} else if (streq(key, "systemd.swap-extra")) {
if (proc_cmdline_value_missing(key, value))
return 0;
r = mount_array_add_swap(value);
if (r < 0)
log_warning("Failed to parse systemd.swap-extra= option, ignoring: %s", value);
}
return 0;
@ -1268,7 +1446,7 @@ static int determine_usr(void) {
* with /sysroot/etc/fstab available, and then we can write additional units based
* on that file. */
static int run_generator(void) {
int r, r2 = 0, r3 = 0;
int r, ret = 0;
r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
if (r < 0)
@ -1289,26 +1467,43 @@ static int run_generator(void) {
/* Always honour root= and usr= in the kernel command line if we are in an initrd */
if (in_initrd()) {
r = add_sysroot_mount();
if (r < 0 && ret >= 0)
ret = r;
r2 = add_sysroot_usr_mount_or_fallback();
r = add_sysroot_usr_mount_or_fallback();
if (r < 0 && ret >= 0)
ret = r;
r3 = add_volatile_root();
} else
r = add_volatile_root();
if (r < 0 && ret >= 0)
ret = r;
} else {
r = add_volatile_var();
if (r < 0 && ret >= 0)
ret = r;
}
/* Honour /etc/fstab only when that's enabled */
if (arg_fstab_enabled) {
/* Parse the local /etc/fstab, possibly from the initrd */
r2 = parse_fstab(false);
r = parse_fstab(false);
if (r < 0 && ret >= 0)
ret = r;
/* If running in the initrd also parse the /etc/fstab from the host */
if (in_initrd())
r3 = parse_fstab(true);
r = parse_fstab(true);
else
r3 = generator_enable_remount_fs_service(arg_dest);
r = generator_enable_remount_fs_service(arg_dest);
if (r < 0 && ret >= 0)
ret = r;
}
return r < 0 ? r : r2 < 0 ? r2 : r3;
r = add_mounts_from_cmdline();
if (r < 0 && ret >= 0)
ret = r;
return ret;
}
static int run(int argc, char **argv) {

View File

@ -1,6 +1,8 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -e
shopt -s nullglob
shopt -s globstar
if [[ -n "$1" ]]; then
generator=$1
@ -25,23 +27,89 @@ for f in "$src"/test-*.input; do
# shellcheck disable=SC2064
trap "rm -rf '$out'" EXIT INT QUIT PIPE
# shellcheck disable=SC2046
if [[ "$f" == *.fstab.input ]]; then
exp="${f%.input}.expected"
if [[ "${f##*/}" =~ swap ]] && systemd-detect-virt --container >/dev/null; then
exp="${exp}.container"
fi
if [[ "${f##*/}" =~ \.fstab\.input ]]; then
SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=yes root=fstab" SYSTEMD_FSTAB="$f" SYSTEMD_SYSROOT_FSTAB="/dev/null" $generator "$out" "$out" "$out"
else
SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$f")" $generator "$out" "$out" "$out"
SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$f")" $generator "$out" "$out" "$out"
fi
if [[ -f "$out"/systemd-fsck-root.service ]]; then
# For split-usr system
sed -i -e 's:ExecStart=/lib/systemd/systemd-fsck:ExecStart=/usr/lib/systemd/systemd-fsck:' "$out"/systemd-fsck-root.service
# The option x-systemd.growfs creates symlink to system's systemd-growfs@.service in .mount.wants directory.
# The system that the test is currently running on may not have or may have outdated unit file.
# Let's replace the symlink with an empty file.
for i in "$out"/*/systemd-growfs@*.service; do
[[ -L "$i" ]] || continue
rm "$i"
touch "$i"
done
# For split-usr system
for i in "$out"/systemd-*.service; do
sed -i -e 's:ExecStart=/lib/systemd/:ExecStart=/usr/lib/systemd/:' "$i"
done
if [[ "${f##*/}" =~ \.fstab\.input ]]; then
for i in "$out"/*.{automount,mount,swap}; do
sed -i -e 's:SourcePath=.*$:SourcePath=/etc/fstab:' "$i"
done
fi
# We store empty files rather than symlinks, so that they don't get pruned when packaged up, so compare
# .deb packager seems to dislike files named with backslash. So, as a workaround, we store files
# without backslash in .expected.
for i in "$out"/**/*\\*.{mount,swap}; do
k="${i//\\/}"
if [[ "$i" != "$k" ]]; then
if [[ -f "$i" ]]; then
mv "$i" "$k"
elif [[ -L "$i" ]]; then
dest=$(readlink "$i")
rm "$i"
ln -s "${dest//\\/}" "$k"
fi
fi
done
# We store empty files rather than dead symlinks, so that they don't get pruned when packaged up, so compare
# the list of filenames rather than their content
if ! diff -u <(find "$out" -printf '%P\n' | sort) <(find "${f%.input}.expected" -printf '%P\n' | sort); then
if ! diff -u <(find "$out" -printf '%P\n' | sort) <(find "$exp" -printf '%P\n' | sort); then
echo "**** Unexpected output for $f"
exit 1
fi
# Check the main units.
if ! diff -u "$out" "$exp"; then
echo "**** Unexpected output for $f"
exit 1
fi
# Also check drop-ins.
for i in "$out"/*; do
[[ -d "$i" ]] || continue
dir="${i##*/}"
for j in "$i"/*; do
fname="${j##*/}"
expf="$exp/$dir/$fname"
if [[ -L "$j" && ! -e "$j" ]]; then
# For dead symlink, we store an empty file.
if [[ ! -e "$expf" || -n "$(cat "$expf")" ]]; then
echo "**** Unexpected symlink $j created by $f"
exit 1
fi
continue
fi
if ! diff -u "$j" "$expf"; then
echo "**** Unexpected output in $j for $f"
exit 1
fi
done
done
) || exit 1
done

View File

@ -3,6 +3,7 @@
[Unit]
Description=File System Check on /dev/sdx1
Documentation=man:systemd-fsck-root.service(8)
DefaultDependencies=no
BindsTo=dev-sdx1.device
Conflicts=shutdown.target

View File

@ -3,6 +3,7 @@
[Unit]
Description=File System Check on /dev/disk/by-label/Root
Documentation=man:systemd-fsck-root.service(8)
DefaultDependencies=no
BindsTo=dev-disk-by\x2dlabel-Root.device
Conflicts=shutdown.target

View File

@ -3,6 +3,7 @@
[Unit]
Description=File System Check on /dev/disk/by-uuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7
Documentation=man:systemd-fsck-root.service(8)
DefaultDependencies=no
BindsTo=dev-disk-by\x2duuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.device
Conflicts=shutdown.target

View File

@ -3,6 +3,7 @@
[Unit]
Description=File System Check on /dev/disk/by-partuuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7
Documentation=man:systemd-fsck-root.service(8)
DefaultDependencies=no
BindsTo=dev-disk-by\x2dpartuuid-3f5ad593\x2d4546\x2d4a94\x2da374\x2dbcfb68aa11f7.device
Conflicts=shutdown.target

View File

@ -3,6 +3,7 @@
[Unit]
Description=File System Check on /dev/sdx1
Documentation=man:systemd-fsck-root.service(8)
DefaultDependencies=no
BindsTo=dev-sdx1.device
Conflicts=shutdown.target

View File

@ -0,0 +1 @@
../mnt-requiredby.mount

View File

@ -0,0 +1 @@
../mnt-wantedby.mount

View File

@ -0,0 +1,5 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Requires=dev-sdx1.device
After=dev-sdx1.device

View File

@ -0,0 +1,4 @@
# Automatically generated by systemd-fstab-generator
[Unit]
After=systemd-growfs@mnt-growfs.service

View File

@ -0,0 +1 @@
../mnt-automount2.automount

View File

@ -0,0 +1,13 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
After=foo.service
Before=local-fs.target
After=blockdev@dev-sdx3.target
[Mount]
What=/dev/sdx3
Where=/mnt/after
Options=x-systemd.after=foo.service

View File

@ -0,0 +1,9 @@
# Automatically generated by systemd-fstab-generator
[Unit]
SourcePath=/etc/fstab
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
[Automount]
Where=/mnt/automount1
TimeoutIdleSec=30min

View File

@ -0,0 +1,12 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
Before=local-fs.target
After=blockdev@dev-sdx9.target
[Mount]
What=/dev/sdx9
Where=/mnt/automount1
Options=x-systemd.automount,x-systemd.idle-timeout=30m

View File

@ -0,0 +1,8 @@
# Automatically generated by systemd-fstab-generator
[Unit]
SourcePath=/etc/fstab
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
[Automount]
Where=/mnt/automount2

View File

@ -0,0 +1,11 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
After=blockdev@dev-sdx10.target
[Mount]
What=/dev/sdx10
Where=/mnt/automount2
Options=x-systemd.automount,nofail

View File

@ -0,0 +1,13 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
Before=foo.service
Before=local-fs.target
After=blockdev@dev-sdx4.target
[Mount]
What=/dev/sdx4
Where=/mnt/before
Options=x-systemd.before=foo.service

View File

@ -0,0 +1,12 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
Before=local-fs.target
After=blockdev@dev-sdx13.target
[Mount]
What=/dev/sdx13
Where=/mnt/growfs
Options=x-systemd.growfs

View File

@ -0,0 +1,13 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
Before=local-fs.target
After=blockdev@dev-sdx12.target
[Mount]
What=/dev/sdx12
Where=/mnt/mkfs
Type=ext4
Options=x-systemd.makefs

View File

@ -0,0 +1 @@
../systemd-makefs@dev-sdx12.service

View File

@ -0,0 +1,12 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
Before=local-fs.target
After=blockdev@dev-sdx15.target
[Mount]
What=/dev/sdx15
Where=/mnt/noauto
Options=noauto

View File

@ -0,0 +1,11 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
After=blockdev@dev-sdx16.target
[Mount]
What=/dev/sdx16
Where=/mnt/nofail
Options=nofail

View File

@ -0,0 +1,12 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
Before=local-fs.target
After=blockdev@dev-sdx14.target
[Mount]
What=/dev/sdx14
Where=/mnt/pcrfs
Options=x-systemd.pcrfs

View File

@ -0,0 +1,13 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
RequiresMountsFor=/hoge
Before=local-fs.target
After=blockdev@dev-sdx6.target
[Mount]
What=/dev/sdx6
Where=/mnt/reqmounts
Options=x-systemd.requires-mounts-for=/hoge

View File

@ -0,0 +1,12 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
Before=local-fs.target
After=blockdev@dev-sdx8.target
[Mount]
What=/dev/sdx8
Where=/mnt/requiredby
Options=x-systemd.required-by=foo.service

View File

@ -0,0 +1,14 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
After=foo.service
Requires=foo.service
Before=local-fs.target
After=blockdev@dev-sdx5.target
[Mount]
What=/dev/sdx5
Where=/mnt/requires
Options=x-systemd.requires=foo.service

View File

@ -0,0 +1,13 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
Before=local-fs.target
After=blockdev@dev-sdx11.target
[Mount]
What=/dev/sdx11
Where=/mnt/rwonly
Options=x-systemd.rw-only
ReadWriteOnly=yes

View File

@ -0,0 +1,13 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
Before=local-fs.target
After=blockdev@dev-sdx2.target
[Mount]
What=/dev/sdx2
Where=/mnt/timeout
TimeoutSec=10min
Options=x-systemd.mount-timeout=10m

View File

@ -0,0 +1,12 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
Before=local-fs.target
After=blockdev@dev-sdx7.target
[Mount]
What=/dev/sdx7
Where=/mnt/wantedby
Options=x-systemd.wanted-by=foo.service

View File

@ -0,0 +1,13 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/etc/fstab
Before=initrd-root-fs.target
Requires=systemd-fsck-root.service
After=systemd-fsck-root.service
After=blockdev@dev-sdx1.target
[Mount]
What=/dev/sdx1
Where=/sysroot

View File

@ -0,0 +1,17 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Description=File System Check on /dev/sdx1
Documentation=man:systemd-fsck-root.service(8)
DefaultDependencies=no
BindsTo=dev-sdx1.device
Conflicts=shutdown.target
After=initrd-root-device.target local-fs-pre.target dev-sdx1.device
Before=shutdown.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx1
TimeoutSec=0

View File

@ -0,0 +1,18 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Description=Make File System on %f
Documentation=man:systemd-makefs@.service(8)
DefaultDependencies=no
BindsTo=%i.device
After=%i.device
Before=systemd-fsck@%i.service mnt-mkfs.mount
Conflicts=shutdown.target
Before=shutdown.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/lib/systemd/systemd-makefs ext4 /dev/sdx12
TimeoutSec=0

View File

@ -0,0 +1,16 @@
/dev/sdx1 /sysroot auto defaults 0 1
/dev/sdx2 /mnt/timeout auto x-systemd.mount-timeout=10m 0 0
/dev/sdx3 /mnt/after auto x-systemd.after=foo.service 0 0
/dev/sdx4 /mnt/before auto x-systemd.before=foo.service 0 0
/dev/sdx5 /mnt/requires auto x-systemd.requires=foo.service 0 0
/dev/sdx6 /mnt/reqmounts auto x-systemd.requires-mounts-for=/hoge 0 0
/dev/sdx7 /mnt/wantedby auto x-systemd.wanted-by=foo.service 0 0
/dev/sdx8 /mnt/requiredby auto x-systemd.required-by=foo.service 0 0
/dev/sdx9 /mnt/automount1 auto x-systemd.automount,x-systemd.idle-timeout=30m 0 0
/dev/sdx10 /mnt/automount2 auto x-systemd.automount,nofail 0 0
/dev/sdx11 /mnt/rwonly auto x-systemd.rw-only 0 0
/dev/sdx12 /mnt/mkfs ext4 x-systemd.makefs 0 0
/dev/sdx13 /mnt/growfs auto x-systemd.growfs 0 0
/dev/sdx14 /mnt/pcrfs auto x-systemd.pcrfs 0 0
/dev/sdx15 /mnt/noauto auto noauto 0 0
/dev/sdx16 /mnt/nofail auto nofail 0 0

View File

@ -0,0 +1,11 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
Before=local-fs.target
After=blockdev@dev-sdx3.target
[Mount]
What=/dev/sdx3
Where=/hoge/without_fstype

View File

@ -0,0 +1,11 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
Before=local-fs.target
After=blockdev@dev-sdx2.target
[Mount]
What=/dev/sdx2
Where=/hoge/without_options

View File

@ -0,0 +1,12 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
Before=remote-fs.target
[Mount]
What=//foo￾bar
Where=/hoge/with space
Type=cifs
Options=rw

View File

@ -0,0 +1,5 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Requires=dev-sdx1.device
After=dev-sdx1.device

View File

@ -0,0 +1,11 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
Before=initrd-root-fs.target
After=blockdev@dev-sdx1.target
[Mount]
What=/dev/sdx1
Where=/sysroot

View File

@ -0,0 +1,5 @@
systemd.mount-extra=/dev/sdx1:/sysroot:auto:defaults
systemd.mount-extra=/dev/sdx2:/hoge/without_options:auto
systemd.mount-extra=/dev/sdx3:/hoge/without_fstype
systemd.mount-extra=/dev/sdx4
systemd.mount-extra=//foo\ufffebar:/hoge/with\x20space:cifs:rw,seclabel

View File

@ -0,0 +1,9 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
After=blockdev@dev-sdy1.target
[Swap]
What=/dev/sdy1

View File

@ -0,0 +1,10 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
After=blockdev@dev-sdy2.target
[Swap]
What=/dev/sdy2
Options=x-systemd.makefs

View File

@ -0,0 +1 @@
../systemd-mkswap@dev-sdy2.service

View File

@ -0,0 +1,10 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
After=blockdev@dev-sdy3.target
[Swap]
What=/dev/sdy3
Options=x-systemd.makefs

View File

@ -0,0 +1 @@
../systemd-mkswap@dev-sdy3.service

View File

@ -0,0 +1,9 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Documentation=man:fstab(5) man:systemd-fstab-generator(8)
SourcePath=/proc/cmdline
After=blockdev@dev-sdy4.target
[Swap]
What=/dev/sdy4

Some files were not shown because too many files have changed in this diff Show More