Zbigniew Jędrzejewski-Szmek 930e1b
From ea46250058d413de21a38d29290eb90f453af72d Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 930e1b
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Zbigniew Jędrzejewski-Szmek 930e1b
Date: Tue, 12 Nov 2013 00:53:59 -0500
Zbigniew Jędrzejewski-Szmek 930e1b
Subject: [PATCH] fsck,fstab-generator: be lenient about missing fsck.<type>
Zbigniew Jędrzejewski-Szmek 930e1b
Zbigniew Jędrzejewski-Szmek 930e1b
If fstab contains 1 for passno, treat this as an error, but only warn
Zbigniew Jędrzejewski-Szmek 930e1b
briefly. If fstab doesn't contain this information, don't complain at
Zbigniew Jędrzejewski-Szmek 930e1b
all.
Zbigniew Jędrzejewski-Szmek 930e1b
Zbigniew Jędrzejewski-Szmek 930e1b
Patch is complicated a bit by the fact that we might have the fstype specified
Zbigniew Jędrzejewski-Szmek 930e1b
in fstab or on /proc/cmdline, in which case we can check if we have the appropriate
Zbigniew Jędrzejewski-Szmek 930e1b
fsck tool, or not specified, or specified as auto, in which case we have to look
Zbigniew Jędrzejewski-Szmek 930e1b
and check the type of the filesystem ourselves. It cannot be done before the
Zbigniew Jędrzejewski-Szmek 930e1b
device appears, so it is too early in the generator phase, and it must be done
Zbigniew Jędrzejewski-Szmek 930e1b
directly in fsck service.
Zbigniew Jędrzejewski-Szmek 930e1b
Zbigniew Jędrzejewski-Szmek 930e1b
Conflicts:
Zbigniew Jędrzejewski-Szmek 930e1b
	src/fstab-generator/fstab-generator.c
Zbigniew Jędrzejewski-Szmek 930e1b
---
Zbigniew Jędrzejewski-Szmek 930e1b
 src/fsck/fsck.c                       | 40 +++++++++++++++++++++------
Zbigniew Jędrzejewski-Szmek 930e1b
 src/fstab-generator/fstab-generator.c | 51 +++++++++++++++++++++++++++++++++++
Zbigniew Jędrzejewski-Szmek 930e1b
 2 files changed, 83 insertions(+), 8 deletions(-)
Zbigniew Jędrzejewski-Szmek 930e1b
Zbigniew Jędrzejewski-Szmek 930e1b
diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c
Zbigniew Jędrzejewski-Szmek 930e1b
index 9b4e555..1189fe7 100644
Zbigniew Jędrzejewski-Szmek 930e1b
--- a/src/fsck/fsck.c
Zbigniew Jędrzejewski-Szmek 930e1b
+++ b/src/fsck/fsck.c
Zbigniew Jędrzejewski-Szmek 930e1b
@@ -244,10 +244,11 @@ int main(int argc, char *argv[]) {
Zbigniew Jędrzejewski-Szmek 930e1b
         siginfo_t status;
Zbigniew Jędrzejewski-Szmek 930e1b
         _cleanup_udev_unref_ struct udev *udev = NULL;
Zbigniew Jędrzejewski-Szmek 930e1b
         _cleanup_udev_device_unref_ struct udev_device *udev_device = NULL;
Zbigniew Jędrzejewski-Szmek 930e1b
-        const char *device;
Zbigniew Jędrzejewski-Szmek 930e1b
+        const char *device, *type;
Zbigniew Jędrzejewski-Szmek 930e1b
         bool root_directory;
Zbigniew Jędrzejewski-Szmek 930e1b
         int progress_pipe[2] = { -1, -1 };
Zbigniew Jędrzejewski-Szmek 930e1b
         char dash_c[2+10+1];
Zbigniew Jędrzejewski-Szmek 930e1b
+        struct stat st;
Zbigniew Jędrzejewski-Szmek 930e1b
 
Zbigniew Jędrzejewski-Szmek 930e1b
         if (argc > 2) {
Zbigniew Jędrzejewski-Szmek 930e1b
                 log_error("This program expects one or no arguments.");
Zbigniew Jędrzejewski-Szmek 930e1b
@@ -266,11 +267,27 @@ int main(int argc, char *argv[]) {
Zbigniew Jędrzejewski-Szmek 930e1b
         if (!arg_force && arg_skip)
Zbigniew Jędrzejewski-Szmek 930e1b
                 return 0;
Zbigniew Jędrzejewski-Szmek 930e1b
 
Zbigniew Jędrzejewski-Szmek 930e1b
+        udev = udev_new();
Zbigniew Jędrzejewski-Szmek 930e1b
+        if (!udev) {
Zbigniew Jędrzejewski-Szmek 930e1b
+                log_oom();
Zbigniew Jędrzejewski-Szmek 930e1b
+                return EXIT_FAILURE;
Zbigniew Jędrzejewski-Szmek 930e1b
+        }
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
         if (argc > 1) {
Zbigniew Jędrzejewski-Szmek 930e1b
                 device = argv[1];
Zbigniew Jędrzejewski-Szmek 930e1b
                 root_directory = false;
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
+                if (stat(device, &st) < 0) {
Zbigniew Jędrzejewski-Szmek 930e1b
+                        log_error("Failed to stat '%s': %m", device);
Zbigniew Jędrzejewski-Szmek 930e1b
+                        return EXIT_FAILURE;
Zbigniew Jędrzejewski-Szmek 930e1b
+                }
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
+                udev_device = udev_device_new_from_devnum(udev, 'b', st.st_rdev);
Zbigniew Jędrzejewski-Szmek 930e1b
+                if (!udev_device) {
Zbigniew Jędrzejewski-Szmek 930e1b
+                        log_error("Failed to detect device %s", device);
Zbigniew Jędrzejewski-Szmek 930e1b
+                        return EXIT_FAILURE;
Zbigniew Jędrzejewski-Szmek 930e1b
+                }
Zbigniew Jędrzejewski-Szmek 930e1b
         } else {
Zbigniew Jędrzejewski-Szmek 930e1b
-                struct stat st;
Zbigniew Jędrzejewski-Szmek 930e1b
                 struct timespec times[2];
Zbigniew Jędrzejewski-Szmek 930e1b
 
Zbigniew Jędrzejewski-Szmek 930e1b
                 /* Find root device */
Zbigniew Jędrzejewski-Szmek 930e1b
@@ -292,12 +309,6 @@ int main(int argc, char *argv[]) {
Zbigniew Jędrzejewski-Szmek 930e1b
                         return EXIT_SUCCESS;
Zbigniew Jędrzejewski-Szmek 930e1b
                 }
Zbigniew Jędrzejewski-Szmek 930e1b
 
Zbigniew Jędrzejewski-Szmek 930e1b
-                udev = udev_new();
Zbigniew Jędrzejewski-Szmek 930e1b
-                if (!udev) {
Zbigniew Jędrzejewski-Szmek 930e1b
-                        log_oom();
Zbigniew Jędrzejewski-Szmek 930e1b
-                        return EXIT_FAILURE;
Zbigniew Jędrzejewski-Szmek 930e1b
-                }
Zbigniew Jędrzejewski-Szmek 930e1b
-
Zbigniew Jędrzejewski-Szmek 930e1b
                 udev_device = udev_device_new_from_devnum(udev, 'b', st.st_dev);
Zbigniew Jędrzejewski-Szmek 930e1b
                 if (!udev_device) {
Zbigniew Jędrzejewski-Szmek 930e1b
                         log_error("Failed to detect root device.");
Zbigniew Jędrzejewski-Szmek 930e1b
@@ -313,6 +324,19 @@ int main(int argc, char *argv[]) {
Zbigniew Jędrzejewski-Szmek 930e1b
                 root_directory = true;
Zbigniew Jędrzejewski-Szmek 930e1b
         }
Zbigniew Jędrzejewski-Szmek 930e1b
 
Zbigniew Jędrzejewski-Szmek 930e1b
+        type = udev_device_get_property_value(udev_device, "ID_FS_TYPE");
Zbigniew Jędrzejewski-Szmek 930e1b
+        if (type) {
Zbigniew Jędrzejewski-Szmek 930e1b
+                const char *checker = strappenda("/sbin/fsck.", type);
Zbigniew Jędrzejewski-Szmek 930e1b
+                r = access(checker, X_OK);
Zbigniew Jędrzejewski-Szmek 930e1b
+                if (r < 0) {
Zbigniew Jędrzejewski-Szmek 930e1b
+                        if (errno == ENOENT) {
Zbigniew Jędrzejewski-Szmek 930e1b
+                                log_info("%s doesn't exist, not checking file system.", checker);
Zbigniew Jędrzejewski-Szmek 930e1b
+                                return EXIT_SUCCESS;
Zbigniew Jędrzejewski-Szmek 930e1b
+                        } else
Zbigniew Jędrzejewski-Szmek 930e1b
+                                log_warning("%s cannot be used: %m", checker);
Zbigniew Jędrzejewski-Szmek 930e1b
+                }
Zbigniew Jędrzejewski-Szmek 930e1b
+        }
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
         if (arg_show_progress)
Zbigniew Jędrzejewski-Szmek 930e1b
                 if (pipe(progress_pipe) < 0) {
Zbigniew Jędrzejewski-Szmek 930e1b
                         log_error("pipe(): %m");
Zbigniew Jędrzejewski-Szmek 930e1b
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
Zbigniew Jędrzejewski-Szmek 930e1b
index 9efccb9..795a24c 100644
Zbigniew Jędrzejewski-Szmek 930e1b
--- a/src/fstab-generator/fstab-generator.c
Zbigniew Jędrzejewski-Szmek 930e1b
+++ b/src/fstab-generator/fstab-generator.c
Zbigniew Jędrzejewski-Szmek 930e1b
@@ -147,6 +147,52 @@ static bool mount_in_initrd(struct mntent *me) {
Zbigniew Jędrzejewski-Szmek 930e1b
                 streq(me->mnt_dir, "/usr");
Zbigniew Jędrzejewski-Szmek 930e1b
 }
Zbigniew Jędrzejewski-Szmek 930e1b
 
Zbigniew Jędrzejewski-Szmek 930e1b
+static int add_fsck(FILE *f, const char *what, const char *where, const char *type, int passno) {
Zbigniew Jędrzejewski-Szmek 930e1b
+        assert(f);
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
+        if (passno == 0)
Zbigniew Jędrzejewski-Szmek 930e1b
+                return 0;
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
+        if (type && !streq(type, "auto")) {
Zbigniew Jędrzejewski-Szmek 930e1b
+                int r;
Zbigniew Jędrzejewski-Szmek 930e1b
+                const char *checker;
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
+                checker = strappenda("/sbin/fsck.", type);
Zbigniew Jędrzejewski-Szmek 930e1b
+                r = access(checker, X_OK);
Zbigniew Jędrzejewski-Szmek 930e1b
+                if (r < 0) {
Zbigniew Jędrzejewski-Szmek 930e1b
+                        log_warning("Checking was requested for %s, but %s cannot be used: %m", what, checker);
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
+                        /* treat missing check as essentially OK */
Zbigniew Jędrzejewski-Szmek 930e1b
+                        return errno == ENOENT ? 0 : -errno;
Zbigniew Jędrzejewski-Szmek 930e1b
+                }
Zbigniew Jędrzejewski-Szmek 930e1b
+        }
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
+        if (streq(where, "/")) {
Zbigniew Jędrzejewski-Szmek 930e1b
+                char *lnk;
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
+                lnk = strappenda(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/systemd-fsck-root.service");
Zbigniew Jędrzejewski-Szmek 930e1b
+                mkdir_parents_label(lnk, 0755);
Zbigniew Jędrzejewski-Szmek 930e1b
+                if (symlink("systemd-fsck-root.service", lnk) < 0) {
Zbigniew Jędrzejewski-Szmek 930e1b
+                        log_error("Failed to create symlink %s: %m", lnk);
Zbigniew Jędrzejewski-Szmek 930e1b
+                        return -errno;
Zbigniew Jędrzejewski-Szmek 930e1b
+                }
Zbigniew Jędrzejewski-Szmek 930e1b
+        } else {
Zbigniew Jędrzejewski-Szmek 930e1b
+                _cleanup_free_ char *fsck = NULL;
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
+                fsck = unit_name_from_path_instance("systemd-fsck", what, ".service");
Zbigniew Jędrzejewski-Szmek 930e1b
+                if (!fsck)
Zbigniew Jędrzejewski-Szmek 930e1b
+                        return log_oom();
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
+                fprintf(f,
Zbigniew Jędrzejewski-Szmek 930e1b
+                        "Requires=%s\n"
Zbigniew Jędrzejewski-Szmek 930e1b
+                        "After=%s\n",
Zbigniew Jędrzejewski-Szmek 930e1b
+                        fsck,
Zbigniew Jędrzejewski-Szmek 930e1b
+                        fsck);
Zbigniew Jędrzejewski-Szmek 930e1b
+        }
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
+        return 0;
Zbigniew Jędrzejewski-Szmek 930e1b
+}
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
 static int add_mount(
Zbigniew Jędrzejewski-Szmek 930e1b
                 const char *what,
Zbigniew Jędrzejewski-Szmek 930e1b
                 const char *where,
Zbigniew Jędrzejewski-Szmek 930e1b
@@ -162,6 +208,7 @@ static int add_mount(
Zbigniew Jędrzejewski-Szmek 930e1b
                 *name = NULL, *unit = NULL, *lnk = NULL,
Zbigniew Jędrzejewski-Szmek 930e1b
                 *automount_name = NULL, *automount_unit = NULL;
Zbigniew Jędrzejewski-Szmek 930e1b
         _cleanup_fclose_ FILE *f = NULL;
Zbigniew Jędrzejewski-Szmek 930e1b
+        int r;
Zbigniew Jędrzejewski-Szmek 930e1b
 
Zbigniew Jędrzejewski-Szmek 930e1b
         assert(what);
Zbigniew Jędrzejewski-Szmek 930e1b
         assert(where);
Zbigniew Jędrzejewski-Szmek 930e1b
@@ -209,6 +256,10 @@ static int add_mount(
Zbigniew Jędrzejewski-Szmek 930e1b
                         "Before=%s\n",
Zbigniew Jędrzejewski-Szmek 930e1b
                         post);
Zbigniew Jędrzejewski-Szmek 930e1b
 
Zbigniew Jędrzejewski-Szmek 930e1b
+        r = add_fsck(f, what, where, type, passno);
Zbigniew Jędrzejewski-Szmek 930e1b
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek 930e1b
+                return r;
Zbigniew Jędrzejewski-Szmek 930e1b
+
Zbigniew Jędrzejewski-Szmek 930e1b
         fprintf(f,
Zbigniew Jędrzejewski-Szmek 930e1b
                 "\n"
Zbigniew Jędrzejewski-Szmek 930e1b
                 "[Mount]\n"