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