diff mbox series

[1/1] dosfstools: Use standard fsck exit codes

Message ID 20250627122158.18544-2-mark.jonas@de.bosch.com
State New
Headers show
Series Adjust dosfstools fsck exit codes | expand

Commit Message

Jonas Mark (BT-FS/ENG1-Mue) June 27, 2025, 12:21 p.m. UTC
From: Ricardo Simoes <ricardo.simoes@pt.bosch.com>

This commit brings in `dosfstools` patches to make `fsck.vfat` exit
codes adhere to the standard exit codes defined by `fsck`. See [1].

These will fix the interaction of `fsck.vfat` with other tools like
`systemd-fsck` which expect the exit codes to be in line with the
standard [2].

However, as of today the dosfstools maintainer(s) are invisible for over
a year [3]. Thus, if upstream ever becomes active again, these patches
should be reassessed.

[1] https://github.com/dosfstools/dosfstools/issues/89

[2] https://man7.org/linux/man-pages/man8/systemd-fsck@.service.8.html

[3] https://github.com/dosfstools/dosfstools/issues/210

Signed-off-by: Ricardo Simoes <ricardo.simoes@pt.bosch.com>
Signed-off-by: Mark Jonas <mark.jonas@de.bosch.com>
---
 ...ck.fat-Adhere-to-the-fsck-exit-codes.patch | 214 ++++++++++++++++++
 ...ges-Document-fsck.fat-new-exit-codes.patch |  46 ++++
 .../dosfstools/dosfstools_4.2.bb              |   7 +-
 3 files changed, 264 insertions(+), 3 deletions(-)
 create mode 100644 meta/recipes-devtools/dosfstools/dosfstools/0001-fsck.fat-Adhere-to-the-fsck-exit-codes.patch
 create mode 100644 meta/recipes-devtools/dosfstools/dosfstools/0002-manpages-Document-fsck.fat-new-exit-codes.patch
diff mbox series

Patch

diff --git a/meta/recipes-devtools/dosfstools/dosfstools/0001-fsck.fat-Adhere-to-the-fsck-exit-codes.patch b/meta/recipes-devtools/dosfstools/dosfstools/0001-fsck.fat-Adhere-to-the-fsck-exit-codes.patch
new file mode 100644
index 0000000000..3d2ce48723
--- /dev/null
+++ b/meta/recipes-devtools/dosfstools/dosfstools/0001-fsck.fat-Adhere-to-the-fsck-exit-codes.patch
@@ -0,0 +1,214 @@ 
+From 9d165145b9f9c20a56e111360fbc2003c2b28cba Mon Sep 17 00:00:00 2001
+From: Ricardo Simoes <ricardo.simoes@pt.bosch.com>
+Date: Thu, 26 Jun 2025 08:14:29 +0100
+Subject: [PATCH] fsck.fat: Adhere to the fsck exit codes
+
+fsck.fat is used as a filesystem-specific checker for the `fsck`. This
+also causes `fsck` to return the same exit-codes given by `fsck.fat`.
+
+In most cases this is already the case. One exception to that comes when
+checking a read-only filesystem. In that case `fsck.fat` will return 6,
+which for `fsck` means "Fiesystem errors left uncorrected" and "System
+should reboot". When a more proper response would be to return 8,
+"Operational Error".
+
+This commit solves that problem by introducing a new header file which
+standardizes the exit codes used by `fsck.fat`.
+
+Signed-off-by: Ricardo Ungerer <ungerer.ricardo@gmail.com>
+
+Upstream-Status: Inactive-Upstream [lastcommit: 2023, lastrelease: 2021]
+Upstream-Status: Submitted [https://github.com/dosfstools/dosfstools/pull/217]
+---
+ src/Makefile.am  |  4 ++--
+ src/common.c     |  8 ++++----
+ src/exit_codes.h | 15 +++++++++++++++
+ src/fsck.fat.c   | 23 ++++++++++++-----------
+ src/io.c         |  3 ++-
+ 5 files changed, 35 insertions(+), 18 deletions(-)
+ create mode 100644 src/exit_codes.h
+
+diff --git a/src/Makefile.am b/src/Makefile.am
+index a389046..48f00dd 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -23,7 +23,7 @@ EXTRA_DIST = blkdev/README
+
+ charconv_common_sources = charconv.c charconv.h
+ charconv_common_ldadd = $(LIBICONV)
+-fscklabel_common_sources = boot.c boot.h common.c common.h \
++fscklabel_common_sources = boot.c boot.h common.c common.h exit_codes.h \
+ 			   fat.c fat.h io.c io.h msdos_fs.h \
+ 			   $(charconv_common_sources) \
+ 			   fsck.fat.h endian_compat.h
+@@ -38,7 +38,7 @@ devinfo_common_sources = device_info.c device_info.h \
+ 			 blkdev/blkdev.c blkdev/blkdev.h \
+ 			 blkdev/linux_version.c blkdev/linux_version.h
+ mkfs_fat_SOURCES  = mkfs.fat.c msdos_fs.h common.c common.h endian_compat.h \
+-		    $(charconv_common_sources) $(devinfo_common_sources)
++		    exit_codes.h $(charconv_common_sources) $(devinfo_common_sources)
+ mkfs_fat_CPPFLAGS = -I$(srcdir)/blkdev
+ mkfs_fat_CFLAGS   = $(AM_CFLAGS)
+ mkfs_fat_LDADD    = $(charconv_common_ldadd)
+diff --git a/src/common.c b/src/common.c
+index 4f1afcb..089d4b3 100644
+--- a/src/common.c
++++ b/src/common.c
+@@ -38,7 +38,7 @@
+
+ #include "common.h"
+ #include "charconv.h"
+-
++#include "exit_codes.h"
+
+ int interactive;
+ int write_immed;
+@@ -62,7 +62,7 @@ void die(const char *msg, ...)
+     vfprintf(stderr, msg, args);
+     va_end(args);
+     fprintf(stderr, "\n");
+-    exit(1);
++    exit(OPERATIONAL_ERROR);
+ }
+
+ void pdie(const char *msg, ...)
+@@ -205,7 +205,7 @@ int get_choice(int noninteractive_result, const char *noninteractive_msg,
+ 	} while (choice == '\n');  /* filter out enter presses */
+
+ 	if (choice == EOF)
+-	    exit(1);
++	    exit(USAGE_OR_SYNTAX_ERROR);
+
+ 	printf("%c\n", choice);
+
+@@ -235,7 +235,7 @@ int get_choice(int noninteractive_result, const char *noninteractive_msg,
+ 	    inhibit_quit_choice = 0;
+
+ 	    if (quit_choice == 1)
+-		exit(0);
++		exit(NO_ERRORS);
+ 	}
+     }
+
+diff --git a/src/exit_codes.h b/src/exit_codes.h
+new file mode 100644
+index 0000000..f67d22e
+--- /dev/null
++++ b/src/exit_codes.h
+@@ -0,0 +1,15 @@
++#ifndef _EXIT_CODES_H
++#define _EXIT_CODES_H
++
++/* Codes as defined by fsck.
++   For more information, see fsck manpage. */
++#define NO_ERRORS                   0
++#define FS_ERRORS_CORRECTED         1
++#define SYSTEM_SHOULD_BE_REBOOTED   2
++#define FS_ERRORS_LEFT_UNCORRECTED  4
++#define OPERATIONAL_ERROR           8
++#define USAGE_OR_SYNTAX_ERROR       16
++#define CHECKING_CANCELED_BY_USER   32
++#define SHARED_LIB_ERROR            128
++
++#endif
+diff --git a/src/fsck.fat.c b/src/fsck.fat.c
+index 8b02b57..42e3ab4 100644
+--- a/src/fsck.fat.c
++++ b/src/fsck.fat.c
+@@ -46,6 +46,7 @@
+ #include "file.h"
+ #include "check.h"
+ #include "charconv.h"
++#include "exit_codes.h"
+
+ int rw = 0, list = 0, test = 0, verbose = 0;
+ long fat_table = 0;
+@@ -147,10 +148,10 @@ int main(int argc, char **argv)
+ 	    codepage = strtol(optarg, &tmp, 10);
+ 	    if (!*optarg || isspace(*optarg) || *tmp || errno || codepage < 0 || codepage > INT_MAX) {
+ 		fprintf(stderr, "Invalid codepage : %s\n", optarg);
+-		usage(argv[0], 2);
++		usage(argv[0], USAGE_OR_SYNTAX_ERROR);
+ 	    }
+ 	    if (!set_dos_codepage(codepage))
+-		usage(argv[0], 2);
++		usage(argv[0], USAGE_OR_SYNTAX_ERROR);
+ 	    break;
+ 	case 'd':
+ 	    file_add(optarg, fdt_drop);
+@@ -163,7 +164,7 @@ int main(int argc, char **argv)
+ 	    fat_table = strtol(optarg, &tmp, 10);
+ 	    if (!*optarg || isspace(*optarg) || *tmp || errno || fat_table < 0 || fat_table > 255) {
+ 		fprintf(stderr, "Invalid FAT table : %s\n", optarg);
+-		usage(argv[0], 2);
++		usage(argv[0], USAGE_OR_SYNTAX_ERROR);
+ 	    }
+ 	    break;
+ 	case 'l':
+@@ -202,31 +203,31 @@ int main(int argc, char **argv)
+ 		    atari_format = 1;
+ 	    } else {
+ 		    fprintf(stderr, "Unknown variant: %s\n", optarg);
+-		    usage(argv[0], 2);
++		    usage(argv[0], USAGE_OR_SYNTAX_ERROR);
+ 	    }
+ 	    break;
+ 	case 'w':
+ 	    write_immed = 1;
+ 	    break;
+ 	case OPT_HELP:
+-	    usage(argv[0], 0);
++	    usage(argv[0], EXIT_SUCCESS);
+ 	    break;
+ 	case '?':
+-	    usage(argv[0], 2);
++	    usage(argv[0], USAGE_OR_SYNTAX_ERROR);
+ 	    break;
+ 	default:
+ 	    fprintf(stderr,
+ 		    "Internal error: getopt_long() returned unexpected value %d\n", c);
+-	    exit(3);
++	    exit(OPERATIONAL_ERROR);
+ 	}
+     if (!set_dos_codepage(-1))	/* set default codepage if none was given in command line */
+-        exit(2);
++        exit(OPERATIONAL_ERROR);
+     if ((test || write_immed) && !rw) {
+ 	fprintf(stderr, "-t and -w can not be used in read only mode\n");
+-	exit(2);
++	exit(USAGE_OR_SYNTAX_ERROR);
+     }
+     if (optind != argc - 1)
+-	usage(argv[0], 2);
++	usage(argv[0], USAGE_OR_SYNTAX_ERROR);
+
+     printf("fsck.fat " VERSION " (" VERSION_DATE ")\n");
+     fs_open(argv[optind], rw);
+@@ -285,5 +286,5 @@ exit:
+ 	       n_files, (unsigned long)fs.data_clusters - free_clusters,
+ 	       (unsigned long)fs.data_clusters);
+
+-    return fs_close(rw) ? 1 : 0;
++    return fs_close(rw) ? FS_ERRORS_CORRECTED : NO_ERRORS;
+ }
+diff --git a/src/io.c b/src/io.c
+index 8c0c3b2..8bd1ae5 100644
+--- a/src/io.c
++++ b/src/io.c
+@@ -44,6 +44,7 @@
+ #include "fsck.fat.h"
+ #include "common.h"
+ #include "io.h"
++#include "exit_codes.h"
+
+ typedef struct _change {
+     void *data;
+@@ -60,7 +61,7 @@ void fs_open(const char *path, int rw)
+ {
+     if ((fd = open(path, rw ? O_RDWR : O_RDONLY)) < 0) {
+ 	perror("open");
+-	exit(6);
++	exit(OPERATIONAL_ERROR);
+     }
+     changes = last = NULL;
+     did_change = 0;
diff --git a/meta/recipes-devtools/dosfstools/dosfstools/0002-manpages-Document-fsck.fat-new-exit-codes.patch b/meta/recipes-devtools/dosfstools/dosfstools/0002-manpages-Document-fsck.fat-new-exit-codes.patch
new file mode 100644
index 0000000000..29bba7b093
--- /dev/null
+++ b/meta/recipes-devtools/dosfstools/dosfstools/0002-manpages-Document-fsck.fat-new-exit-codes.patch
@@ -0,0 +1,46 @@ 
+From 8d703216d2ea3247092a08adb0c37b38eb77ccc7 Mon Sep 17 00:00:00 2001
+From: Ricardo Ungerer <ungerer.ricardo@gmail.com>
+Date: Wed, 21 May 2025 07:18:15 +0100
+Subject: [PATCH 2/3] manpages: Document fsck.fat new exit codes
+
+Signed-off-by: Ricardo Ungerer <ungerer.ricardo@gmail.com>
+
+Upstream-Status: Inactive-Upstream [lastcommit: 2023, lastrelease: 2021]
+Upstream-Status: Submitted [https://github.com/dosfstools/dosfstools/pull/217]
+---
+ manpages/fsck.fat.8.in | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/manpages/fsck.fat.8.in b/manpages/fsck.fat.8.in
+index 824a83d..557aa4c 100644
+--- a/manpages/fsck.fat.8.in
++++ b/manpages/fsck.fat.8.in
+@@ -222,13 +222,21 @@ Display help message describing usage and options then exit.
+ .\" ----------------------------------------------------------------------------
+ .SH "EXIT STATUS"
+ .IP "0" 4
+-No recoverable errors have been detected.
++No errors
+ .IP "1" 4
+-Recoverable errors have been detected or \fBfsck.fat\fP has discovered an
+-internal inconsistency.
++Filesystem errors corrected
+ .IP "2" 4
+-Usage error.
+-\fBfsck.fat\fP did not access the filesystem.
++System should be rebooted
++.IP "4" 4
++Filesystem errors left uncorrected
++.IP "8" 4
++Operational error
++.IP "16" 4
++Usage or syntax error
++.IP "32" 4
++Checking canceled by user request
++.IP "128" 4
++Shared-library error
+ .\" ----------------------------------------------------------------------------
+ .SH FILES
+ .IP "\fIfsck0000.rec\fP, \fIfsck0001.rec\fP, ..." 4
+--
+2.25.1
diff --git a/meta/recipes-devtools/dosfstools/dosfstools_4.2.bb b/meta/recipes-devtools/dosfstools/dosfstools_4.2.bb
index 175fa265ef..86fb68f664 100644
--- a/meta/recipes-devtools/dosfstools/dosfstools_4.2.bb
+++ b/meta/recipes-devtools/dosfstools/dosfstools_4.2.bb
@@ -10,11 +10,12 @@  LICENSE = "GPL-3.0-only"
 LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504"
 
 SRC_URI = "${GITHUB_BASE_URI}/download/v${PV}/${BP}.tar.gz \
-          "
+           file://source-date-epoch.patch \
+           file://0001-fsck.fat-Adhere-to-the-fsck-exit-codes.patch \
+           file://0002-manpages-Document-fsck.fat-new-exit-codes.patch \
+           "
 SRC_URI[sha256sum] = "64926eebf90092dca21b14259a5301b7b98e7b1943e8a201c7d726084809b527"
 
-SRC_URI += "file://source-date-epoch.patch"
-
 inherit autotools gettext pkgconfig update-alternatives github-releases
 
 EXTRA_OECONF = "--enable-compat-symlinks --without-iconv"