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