X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Ffstab-generator%2Ffstab-generator.c;h=5480e54b4ea87073d7b13f853e20dbc4056c22a8;hb=e2f123b97b9af34f39cb18ce0c1c5ef6cb89117e;hp=9efccb983de752d14f1b310829dce33341524941;hpb=1dc2ced4646a78b3dee9e3ea44130f938d6425bc;p=elogind.git diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 9efccb983..5480e54b4 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"; @@ -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("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, @@ -162,6 +212,7 @@ static int add_mount( *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,7 +495,7 @@ 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; @@ -458,17 +504,14 @@ static int parse_new_root_from_proc_cmdline(void) { static int parse_proc_cmdline(void) { _cleanup_free_ char *line = NULL; char *w, *state; - int r; size_t l; + int r; - if (detect_container(NULL) > 0) - return 0; - - r = read_one_line_file("/proc/cmdline", &line); - if (r < 0) { + r = proc_cmdline(&line); + if (r < 0) log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r)); + if (r <= 0) return 0; - } FOREACH_WORD_QUOTED(w, l, line, state) { _cleanup_free_ char *word = NULL;