X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Ffstab-generator%2Ffstab-generator.c;h=5521a864df478ee139b6a27c7fc5a89630ba2882;hb=96197df081a16bec192a6cfb8f19674ca58f4835;hp=b73dfa4899ee65d137915c8468cbc42cd83dd744;hpb=4e82fe5213bedcb70e25c0270e516d5f2706d8c8;p=elogind.git diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index b73dfa489..5521a864d 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -32,7 +32,6 @@ #include "mount-setup.h" #include "special.h" #include "mkdir.h" -#include "virt.h" #include "fileio.h" static const char *arg_dest = "/tmp"; @@ -64,7 +63,7 @@ static int mount_find_pri(struct mntent *me, int *ret) { } static int add_swap(const char *what, struct mntent *me) { - _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL; + _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL; _cleanup_fclose_ FILE *f = NULL; bool noauto; int r, pri = -1; @@ -147,6 +146,57 @@ static bool mount_in_initrd(struct mntent *me) { streq(me->mnt_dir, "/usr"); } +static int add_fsck(FILE *f, const char *what, const char *where, const char *type, int passno) { + assert(f); + + if (passno == 0) + return 0; + + if (!is_device_path(what)) { + log_warning("Checking was requested for \"%s\", but it is not a device.", what); + return 0; + } + + if (type && !streq(type, "auto")) { + int r; + const char *checker; + + checker = strappenda("/sbin/fsck.", type); + r = access(checker, X_OK); + if (r < 0) { + log_warning("Checking was requested for %s, but %s cannot be used: %m", what, checker); + + /* treat missing check as essentially OK */ + return errno == ENOENT ? 0 : -errno; + } + } + + if (streq(where, "/")) { + char *lnk; + + lnk = strappenda(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/systemd-fsck-root.service"); + mkdir_parents_label(lnk, 0755); + if (symlink(SYSTEM_DATA_UNIT_PATH "/systemd-fsck-root.service", lnk) < 0) { + log_error("Failed to create symlink %s: %m", lnk); + return -errno; + } + } else { + _cleanup_free_ char *fsck = NULL; + + fsck = unit_name_from_path_instance("systemd-fsck", what, ".service"); + if (!fsck) + return log_oom(); + + fprintf(f, + "RequiresOverridable=%s\n" + "After=%s\n", + fsck, + fsck); + } + + return 0; +} + static int add_mount( const char *what, const char *where, @@ -159,9 +209,10 @@ static int add_mount( const char *post, const char *source) { _cleanup_free_ char - *name = NULL, *unit = NULL, *lnk = NULL, *device = NULL, + *name = NULL, *unit = NULL, *lnk = NULL, *automount_name = NULL, *automount_unit = NULL; _cleanup_fclose_ FILE *f = NULL; + int r; assert(what); assert(where); @@ -209,17 +260,19 @@ static int add_mount( "Before=%s\n", post); + r = add_fsck(f, what, where, type, passno); + if (r < 0) + return r; + fprintf(f, "\n" "[Mount]\n" "What=%s\n" "Where=%s\n" - "Type=%s\n" - "FsckPassNo=%i\n", + "Type=%s\n", what, where, - type, - passno); + type); if (!isempty(opts) && !streq(opts, "defaults")) @@ -301,15 +354,12 @@ static int add_mount( } static int parse_fstab(const char *prefix, bool initrd) { - _cleanup_free_ char *fstab_path = NULL; - FILE *f; + char *fstab_path; + _cleanup_endmntent_ FILE *f; int r = 0; struct mntent *me; - fstab_path = strjoin(strempty(prefix), "/etc/fstab", NULL); - if (!fstab_path) - return log_oom(); - + fstab_path = strappenda(strempty(prefix), "/etc/fstab"); f = setmntent(fstab_path, "r"); if (!f) { if (errno == ENOENT) @@ -328,10 +378,8 @@ static int parse_fstab(const char *prefix, bool initrd) { what = fstab_node_to_udev_node(me->mnt_fsname); where = strjoin(strempty(prefix), me->mnt_dir, NULL); - if (!what || !where) { - r = log_oom(); - goto finish; - } + if (!what || !where) + return log_oom(); if (is_path(where)) path_kill_slashes(where); @@ -369,23 +417,21 @@ static int parse_fstab(const char *prefix, bool initrd) { r = k; } -finish: - endmntent(f); return r; } static int parse_new_root_from_proc_cmdline(void) { _cleanup_free_ char *what = NULL, *type = NULL, *opts = NULL, *line = NULL; + bool noauto, nofail; char *w, *state; - int r; size_t l; - bool noauto, nofail; + int r; - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { - log_error("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + r = proc_cmdline(&line); + if (r < 0) + log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + if (r <= 0) return 0; - } opts = strdup("ro"); type = strdup("auto"); @@ -449,56 +495,36 @@ static int parse_new_root_from_proc_cmdline(void) { } log_debug("Found entry what=%s where=/sysroot type=%s", what, type); - r = add_mount(what, "/sysroot", type, opts, 0, noauto, nofail, false, + r = add_mount(what, "/sysroot", type, opts, 1, noauto, nofail, false, SPECIAL_INITRD_ROOT_FS_TARGET, "/proc/cmdline"); return (r < 0) ? r : 0; } -static int parse_proc_cmdline(void) { - _cleanup_free_ char *line = NULL; - char *w, *state; +static int parse_proc_cmdline_word(const char *word) { int r; - size_t l; - - if (detect_container(NULL) > 0) - return 0; - - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { - log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); - return 0; - } - FOREACH_WORD_QUOTED(w, l, line, state) { - _cleanup_free_ char *word = NULL; + if (startswith(word, "fstab=")) { + r = parse_boolean(word + 6); + if (r < 0) + log_warning("Failed to parse fstab switch %s. Ignoring.", word + 6); + else + arg_enabled = r; - word = strndup(w, l); - if (!word) - return log_oom(); + } else if (startswith(word, "rd.fstab=")) { - if (startswith(word, "fstab=")) { - r = parse_boolean(word + 6); + if (in_initrd()) { + r = parse_boolean(word + 9); if (r < 0) - log_warning("Failed to parse fstab switch %s. Ignoring.", word + 6); + log_warning("Failed to parse fstab switch %s. Ignoring.", word + 9); else arg_enabled = r; + } - } else if (startswith(word, "rd.fstab=")) { - - if (in_initrd()) { - r = parse_boolean(word + 9); - if (r < 0) - log_warning("Failed to parse fstab switch %s. Ignoring.", word + 9); - else - arg_enabled = r; - } - - } else if (startswith(word, "fstab.") || - (in_initrd() && startswith(word, "rd.fstab."))) { + } else if (startswith(word, "fstab.") || + (in_initrd() && startswith(word, "rd.fstab."))) { - log_warning("Unknown kernel switch %s. Ignoring.", word); - } + log_warning("Unknown kernel switch %s. Ignoring.", word); } return 0; @@ -521,7 +547,7 @@ int main(int argc, char *argv[]) { umask(0022); - if (parse_proc_cmdline() < 0) + if (parse_proc_cmdline(parse_proc_cmdline_word) < 0) return EXIT_FAILURE; if (in_initrd())