diff --git a/man/systemd-fstab-generator.xml b/man/systemd-fstab-generator.xml
index fa85dc3c3f..e21115f173 100644
--- a/man/systemd-fstab-generator.xml
+++ b/man/systemd-fstab-generator.xml
@@ -239,6 +239,33 @@
any swap devices configured in /etc/fstab.
Defaults to enabled.
+
+
+ systemd.mount-extra=WHAT:WHERE[:FSTYPE[:OPTIONS]]
+
+
+ Specifies the mount unit. Takes at least two and at most four fields separated with a colon
+ (:). Each field is handled as the corresponding fstab field. This option can be
+ specified multiple times.
+ Example:
+
+systemd.mount-extra=/dev/sda1:/mount-point:ext4:rw,noatime
+
+
+
+
+
+ systemd.swap-extra=WHAT[:OPTIONS]
+
+
+ Specifies the swap unit. Takes the block device to be used as a swap device, and optionally
+ takes mount options followed by a colon (:).
+ Example:
+
+systemd.swap=/dev/sda2:x-systemd.makefs
+
+
+
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 0a5e9cf692..6337bc235f 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -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) {
diff --git a/test/test-fstab-generator.sh b/test/test-fstab-generator.sh
index c86914a107..68c9d0631e 100755
--- a/test/test-fstab-generator.sh
+++ b/test/test-fstab-generator.sh
@@ -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
diff --git a/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-root-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-usr-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-12-dev-sdx.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service
index 7f914fdd14..95d943b87a 100644
--- a/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service
@@ -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
diff --git a/test/test-fstab-generator/test-13-label.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-13-label.expected/initrd-root-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-13-label.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-13-label.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-13-label.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-13-label.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-13-label.expected/initrd-usr-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-13-label.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-13-label.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-13-label.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service
index a1327396ca..d6c59ff608 100644
--- a/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service
@@ -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
diff --git a/test/test-fstab-generator/test-14-uuid.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-14-uuid.expected/initrd-root-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-14-uuid.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-14-uuid.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-14-uuid.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-14-uuid.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-14-uuid.expected/initrd-usr-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-14-uuid.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-14-uuid.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-14-uuid.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service
index 5945560287..cd9583c4dd 100644
--- a/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service
@@ -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
diff --git a/test/test-fstab-generator/test-15-partuuid.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-15-partuuid.expected/initrd-root-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-15-partuuid.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-15-partuuid.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-15-partuuid.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-15-partuuid.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-15-partuuid.expected/initrd-usr-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-15-partuuid.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-15-partuuid.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-15-partuuid.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service
index aa1d455ecd..650ed8070a 100644
--- a/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service
@@ -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
diff --git a/test/test-fstab-generator/test-16-tmpfs.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-16-tmpfs.expected/initrd-root-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-16-tmpfs.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-16-tmpfs.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-16-tmpfs.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-16-tmpfs.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-16-tmpfs.expected/initrd-usr-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-16-tmpfs.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-16-tmpfs.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-16-tmpfs.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount
new file mode 120000
index 0000000000..8bcbb16eae
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount
@@ -0,0 +1 @@
+../sysroot-usr.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount
new file mode 120000
index 0000000000..8fb2e18647
--- /dev/null
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount
@@ -0,0 +1 @@
+../sysusr-usr.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service
index 7f914fdd14..95d943b87a 100644
--- a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service
+++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.requires/mnt-requiredby.mount b/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.requires/mnt-requiredby.mount
new file mode 120000
index 0000000000..6b012b09ef
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.requires/mnt-requiredby.mount
@@ -0,0 +1 @@
+../mnt-requiredby.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.wants/mnt-wantedby.mount b/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.wants/mnt-wantedby.mount
new file mode 120000
index 0000000000..cdf21276b6
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/foo.service.wants/mnt-wantedby.mount
@@ -0,0 +1 @@
+../mnt-wantedby.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-device.target.d/50-root-device.conf b/test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-device.target.d/50-root-device.conf
new file mode 100644
index 0000000000..47c4232223
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-device.target.d/50-root-device.conf
@@ -0,0 +1,5 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Requires=dev-sdx1.device
+After=dev-sdx1.device
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-18-options.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.d/50-order-systemd-growfs@mnt-growfs.service.conf b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.d/50-order-systemd-growfs@mnt-growfs.service.conf
new file mode 100644
index 0000000000..ac770bcb51
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.d/50-order-systemd-growfs@mnt-growfs.service.conf
@@ -0,0 +1,4 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+After=systemd-growfs@mnt-growfs.service
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-after.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-after.mount
new file mode 120000
index 0000000000..68364ef19c
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-after.mount
@@ -0,0 +1 @@
+../mnt-after.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-automount1.automount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-automount1.automount
new file mode 120000
index 0000000000..3638a8c90e
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-automount1.automount
@@ -0,0 +1 @@
+../mnt-automount1.automount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-before.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-before.mount
new file mode 120000
index 0000000000..3a50a40d5f
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-before.mount
@@ -0,0 +1 @@
+../mnt-before.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-growfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-growfs.mount
new file mode 120000
index 0000000000..cb05081e45
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-growfs.mount
@@ -0,0 +1 @@
+../mnt-growfs.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-mkfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-mkfs.mount
new file mode 120000
index 0000000000..51f897e419
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-mkfs.mount
@@ -0,0 +1 @@
+../mnt-mkfs.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-pcrfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-pcrfs.mount
new file mode 120000
index 0000000000..276dfc0731
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-pcrfs.mount
@@ -0,0 +1 @@
+../mnt-pcrfs.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-reqmounts.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-reqmounts.mount
new file mode 120000
index 0000000000..7efce8da9a
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-reqmounts.mount
@@ -0,0 +1 @@
+../mnt-reqmounts.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-requires.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-requires.mount
new file mode 120000
index 0000000000..34a6aad26f
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-requires.mount
@@ -0,0 +1 @@
+../mnt-requires.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-rwonly.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-rwonly.mount
new file mode 120000
index 0000000000..d03abd2353
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-rwonly.mount
@@ -0,0 +1 @@
+../mnt-rwonly.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-timeout.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-timeout.mount
new file mode 120000
index 0000000000..b0ec730825
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.requires/mnt-timeout.mount
@@ -0,0 +1 @@
+../mnt-timeout.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-automount2.automount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-automount2.automount
new file mode 120000
index 0000000000..a30481ec1f
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-automount2.automount
@@ -0,0 +1 @@
+../mnt-automount2.automount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-nofail.mount b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-nofail.mount
new file mode 120000
index 0000000000..b82bbad730
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/local-fs.target.wants/mnt-nofail.mount
@@ -0,0 +1 @@
+../mnt-nofail.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-after.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-after.mount
new file mode 100644
index 0000000000..2aebb686a7
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-after.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.automount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.automount
new file mode 100644
index 0000000000..e376689b67
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.automount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.mount
new file mode 100644
index 0000000000..1413292c79
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount1.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.automount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.automount
new file mode 100644
index 0000000000..e05d3976ef
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.automount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.mount
new file mode 100644
index 0000000000..1eba08c9f7
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-automount2.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-before.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-before.mount
new file mode 100644
index 0000000000..eea084b7b6
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-before.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-growfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-growfs.mount
new file mode 100644
index 0000000000..bbe958c076
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-growfs.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-growfs.mount.wants/systemd-growfs@mnt-growfs.service b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-growfs.mount.wants/systemd-growfs@mnt-growfs.service
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount
new file mode 100644
index 0000000000..be4c8fa17f
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount.requires/systemd-makefs@dev-sdx12.service b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount.requires/systemd-makefs@dev-sdx12.service
new file mode 120000
index 0000000000..fe80548a68
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-mkfs.mount.requires/systemd-makefs@dev-sdx12.service
@@ -0,0 +1 @@
+../systemd-makefs@dev-sdx12.service
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-noauto.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-noauto.mount
new file mode 100644
index 0000000000..4d52a6e698
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-noauto.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-nofail.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-nofail.mount
new file mode 100644
index 0000000000..3c20b652b0
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-nofail.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-pcrfs.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-pcrfs.mount
new file mode 100644
index 0000000000..2c070e695a
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-pcrfs.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-reqmounts.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-reqmounts.mount
new file mode 100644
index 0000000000..c21ccd27ba
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-reqmounts.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requiredby.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requiredby.mount
new file mode 100644
index 0000000000..5edc4ddf22
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requiredby.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requires.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requires.mount
new file mode 100644
index 0000000000..8386616593
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-requires.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-rwonly.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-rwonly.mount
new file mode 100644
index 0000000000..8649734386
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-rwonly.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-timeout.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-timeout.mount
new file mode 100644
index 0000000000..09d772a52b
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-timeout.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby.mount b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby.mount
new file mode 100644
index 0000000000..e12df820d4
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/mnt-wantedby.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/sysroot.mount b/test/test-fstab-generator/test-18-options.fstab.expected/sysroot.mount
new file mode 100644
index 0000000000..0e8a701be9
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/sysroot.mount
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service
new file mode 100644
index 0000000000..95d943b87a
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/systemd-makefs@dev-sdx12.service b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-makefs@dev-sdx12.service
new file mode 100644
index 0000000000..303c1ee680
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-makefs@dev-sdx12.service
@@ -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
diff --git a/test/test-fstab-generator/test-18-options.fstab.input b/test/test-fstab-generator/test-18-options.fstab.input
new file mode 100644
index 0000000000..98ef0b9fba
--- /dev/null
+++ b/test/test-fstab-generator/test-18-options.fstab.input
@@ -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
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_fstype.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_fstype.mount
new file mode 100644
index 0000000000..4d7d975cc0
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_fstype.mount
@@ -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
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_options.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_options.mount
new file mode 100644
index 0000000000..4f16d2e40b
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-without_options.mount
@@ -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
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-withx20space.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-withx20space.mount
new file mode 100644
index 0000000000..e9ffb4bbd9
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/hoge-withx20space.mount
@@ -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=//foobar
+Where=/hoge/with space
+Type=cifs
+Options=rw
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-device.target.d/50-root-device.conf b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-device.target.d/50-root-device.conf
new file mode 100644
index 0000000000..47c4232223
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-device.target.d/50-root-device.conf
@@ -0,0 +1,5 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Requires=dev-sdx1.device
+After=dev-sdx1.device
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-root-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 120000
index 0000000000..0c969cdbd4
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/initrd-usr-fs.target.requires/sysroot.mount
@@ -0,0 +1 @@
+../sysroot.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_fstype.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_fstype.mount
new file mode 120000
index 0000000000..d46cee354e
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_fstype.mount
@@ -0,0 +1 @@
+../hoge-without_fstype.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_options.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_options.mount
new file mode 120000
index 0000000000..9c790fb248
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/local-fs.target.requires/hoge-without_options.mount
@@ -0,0 +1 @@
+../hoge-without_options.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/remote-fs.target.requires/hoge-withx20space.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/remote-fs.target.requires/hoge-withx20space.mount
new file mode 120000
index 0000000000..2404d7619f
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/remote-fs.target.requires/hoge-withx20space.mount
@@ -0,0 +1 @@
+../hoge-withx20space.mount
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot.mount b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot.mount
new file mode 100644
index 0000000000..c8547fa539
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/sysroot.mount
@@ -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
diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.input b/test/test-fstab-generator/test-19-mounts-from-cmdline.input
new file mode 100644
index 0000000000..4312d01e52
--- /dev/null
+++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.input
@@ -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
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected.container/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-20-swap-from-cmdline.expected.container/initrd-usr-fs.target.requires/sysroot.mount
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy1.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy1.swap
new file mode 100644
index 0000000000..f515bc149e
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy1.swap
@@ -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
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap
new file mode 100644
index 0000000000..104260a60d
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap
@@ -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
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap.requires/systemd-mkswap@dev-sdy2.service b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap.requires/systemd-mkswap@dev-sdy2.service
new file mode 120000
index 0000000000..5248a5f8b7
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy2.swap.requires/systemd-mkswap@dev-sdy2.service
@@ -0,0 +1 @@
+../systemd-mkswap@dev-sdy2.service
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap
new file mode 100644
index 0000000000..3b6563d216
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap
@@ -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
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap.requires/systemd-mkswap@dev-sdy3.service b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap.requires/systemd-mkswap@dev-sdy3.service
new file mode 120000
index 0000000000..e41d758141
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy3.swap.requires/systemd-mkswap@dev-sdy3.service
@@ -0,0 +1 @@
+../systemd-mkswap@dev-sdy3.service
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy4.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy4.swap
new file mode 100644
index 0000000000..37d90f7b64
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/dev-sdy4.swap
@@ -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
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/initrd-usr-fs.target.requires/sysroot.mount
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy1.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy1.swap
new file mode 120000
index 0000000000..a899ff84c0
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy1.swap
@@ -0,0 +1 @@
+../dev-sdy1.swap
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy2.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy2.swap
new file mode 120000
index 0000000000..14df9d6acc
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy2.swap
@@ -0,0 +1 @@
+../dev-sdy2.swap
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy3.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy3.swap
new file mode 120000
index 0000000000..19663fe046
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy3.swap
@@ -0,0 +1 @@
+../dev-sdy3.swap
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy4.swap b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy4.swap
new file mode 120000
index 0000000000..9bfd9d8316
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/swap.target.requires/dev-sdy4.swap
@@ -0,0 +1 @@
+../dev-sdy4.swap
\ No newline at end of file
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy2.service b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy2.service
new file mode 100644
index 0000000000..0911f03f62
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy2.service
@@ -0,0 +1,18 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Description=Make Swap on %f
+Documentation=man:systemd-mkswap@.service(8)
+
+DefaultDependencies=no
+BindsTo=%i.device
+After=%i.device
+Before=dev-sdy2.swap
+Conflicts=shutdown.target
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/lib/systemd/systemd-makefs swap /dev/sdy2
+TimeoutSec=0
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy3.service b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy3.service
new file mode 100644
index 0000000000..6201fec86b
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.expected/systemd-mkswap@dev-sdy3.service
@@ -0,0 +1,18 @@
+# Automatically generated by systemd-fstab-generator
+
+[Unit]
+Description=Make Swap on %f
+Documentation=man:systemd-mkswap@.service(8)
+
+DefaultDependencies=no
+BindsTo=%i.device
+After=%i.device
+Before=dev-sdy3.swap
+Conflicts=shutdown.target
+Before=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/lib/systemd/systemd-makefs swap /dev/sdy3
+TimeoutSec=0
diff --git a/test/test-fstab-generator/test-20-swap-from-cmdline.input b/test/test-fstab-generator/test-20-swap-from-cmdline.input
new file mode 100644
index 0000000000..953c09ff10
--- /dev/null
+++ b/test/test-fstab-generator/test-20-swap-from-cmdline.input
@@ -0,0 +1,4 @@
+systemd.mount-extra=/dev/sdy1:none:swap
+systemd.mount-extra=/dev/sdy2:none:swap:x-systemd.makefs
+systemd.swap-extra=/dev/sdy3:x-systemd.makefs,nofail
+systemd.swap-extra=/dev/sdy4