fstab-generator: initrd - mount selected entries from /sysroot/etc/fstab

We only mount "/usr" and entries marked with "x-initrd.mount".

This (together with the right unit files) is needed in the initramfs in order to
natively support mounting /usr (and friends) from the initramfs.

The way it is meant to work is:
 * wait for sysroot.mount to be mounted
 * do a daemon-reload to generate sysroot-usr.mount (++) from /sysroot/etc/fstab
 * wait for sysroot-usr.mount to be mounted
 * switch-root

Cc: Harald Hoyer <harald.hoyer@gmail.com>
Cc: Dave Reisner <d@falconindy.com>
This commit is contained in:
Tom Gundersen 2013-02-22 11:52:36 +01:00
parent fea9740ae4
commit 3d22d1ab57
1 changed files with 28 additions and 11 deletions

View File

@ -191,6 +191,14 @@ static bool mount_is_network(struct mntent *me) {
fstype_is_network(me->mnt_type);
}
static bool mount_in_initrd(struct mntent *me) {
assert(me);
return
hasmntopt(me, "x-initrd.mount") ||
streq(me->mnt_dir, "/usr");
}
static int add_mount(const char *what, const char *where, const char *type, const char *opts,
int passno, bool noauto, bool nofail, bool automount, bool isbind, bool isnetwork,
const char *source) {
@ -342,13 +350,14 @@ static int add_mount(const char *what, const char *where, const char *type, cons
fprintf(f,
"# Automatically generated by systemd-fstab-generator\n\n"
"[Unit]\n"
"SourcePath=/etc/fstab\n"
"SourcePath=%s\n"
"DefaultDependencies=no\n"
"Conflicts=" SPECIAL_UMOUNT_TARGET "\n"
"Before=" SPECIAL_UMOUNT_TARGET " %s\n"
"\n"
"[Automount]\n"
"Where=%s\n",
source,
post,
where);
@ -373,18 +382,20 @@ static int add_mount(const char *what, const char *where, const char *type, cons
return 0;
}
static int parse_fstab(void) {
static int parse_fstab(const char *prefix, bool initrd) {
FILE *f;
_cleanup_free_ char *fstab_path = NULL;
int r = 0;
struct mntent *me;
errno = 0;
f = setmntent("/etc/fstab", "r");
fstab_path = strjoin(prefix, "/etc/fstab", NULL);
f = setmntent(fstab_path, "r");
if (!f) {
if (errno == ENOENT)
return 0;
log_error("Failed to open /etc/fstab: %m");
log_error("Failed to open %s/etc/fstab: %m", prefix);
return -errno;
}
@ -392,8 +403,11 @@ static int parse_fstab(void) {
char _cleanup_free_ *where = NULL, *what = NULL;
int k;
if (initrd && !mount_in_initrd(me))
continue;
what = fstab_node_to_udev_node(me->mnt_fsname);
where = strdup(me->mnt_dir);
where = strjoin(prefix, me->mnt_dir, NULL);
if (!what || !where) {
r = log_oom();
goto finish;
@ -419,7 +433,7 @@ static int parse_fstab(void) {
k = add_mount(what, where, me->mnt_type, me->mnt_opts,
me->mnt_passno, noauto, nofail, automount,
isbind, isnetwork, "/etc/fstab");
isbind, isnetwork, fstab_path);
}
if (k < 0)
@ -552,7 +566,7 @@ static int parse_proc_cmdline(void) {
}
int main(int argc, char *argv[]) {
int r, k = 0;
int r = 0, k, l = 0;
if (argc > 1 && argc != 4) {
log_error("This program takes three or no arguments.");
@ -572,12 +586,15 @@ int main(int argc, char *argv[]) {
return EXIT_FAILURE;
if (in_initrd())
k = parse_new_root_from_proc_cmdline();
r = parse_new_root_from_proc_cmdline();
if (!arg_enabled)
return EXIT_SUCCESS;
return (r < 0) ? EXIT_FAILURE : EXIT_SUCCESS;
r = parse_fstab();
k = parse_fstab("", false);
return (r < 0) || (k < 0) ? EXIT_FAILURE : EXIT_SUCCESS;
if (in_initrd())
l = parse_fstab("/sysroot", true);
return (r < 0) || (k < 0) || (l < 0) ? EXIT_FAILURE : EXIT_SUCCESS;
}