From d3445ec416d26fb4fc9fd2bac84d850eac4a98d9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 21 Apr 2025 06:05:10 +0900 Subject: [PATCH 01/11] fsck,quotacheck: drop support for traditional /forcefsck, /fastboot, and /forcequotacheck files Instead, please use the kernel command line options with the same name. I am not sure these files are System V complieant or not, but at least they are very traditional way to control fsck or quotacheck. However, the concept of the files are really broken, especially for fsck. As when we want to fsck the root filesystem, we need to access the filessystem, but it may be broken... Let's drop such traditional ways to control fsck and quotacheck. We already support kernel command line options to control the behaviors. Maybe, also it is better to provide ways to control them by credentials. --- src/fsck/fsck.c | 22 ++-------------------- src/quotacheck/quotacheck.c | 12 ------------ tmpfiles.d/legacy.conf.in | 7 ------- 3 files changed, 2 insertions(+), 39 deletions(-) diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index a41427ab4d..9e4f7c6646 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -33,7 +33,6 @@ static bool arg_skip = false; static bool arg_force = false; -static bool arg_show_progress = false; static const char *arg_repair = "-a"; static void start_target(const char *target, const char *mode) { @@ -105,23 +104,6 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat return 0; } -static void test_files(void) { - -#if HAVE_SYSV_COMPAT - if (access("/fastboot", F_OK) >= 0) { - log_error("Please pass 'fsck.mode=skip' on the kernel command line rather than creating /fastboot on the root file system."); - arg_skip = true; - } - - if (access("/forcefsck", F_OK) >= 0) { - log_error("Please pass 'fsck.mode=force' on the kernel command line rather than creating /forcefsck on the root file system."); - arg_force = true; - } -#endif - - arg_show_progress = access("/run/systemd/show-status", F_OK) >= 0; -} - static double percent(int pass, unsigned long cur, unsigned long max) { /* Values stolen from e2fsck */ @@ -249,7 +231,7 @@ static int run(int argc, char *argv[]) { if (r < 0) log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); - test_files(); + bool show_progress = access("/run/systemd/show-status", F_OK) >= 0; if (!arg_force && arg_skip) return 0; @@ -328,7 +310,7 @@ static int run(int argc, char *argv[]) { console = fopen("/dev/console", "we"); if (console && - arg_show_progress && + show_progress && pipe(progress_pipe) < 0) return log_error_errno(errno, "pipe(): %m"); diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c index 3451f63ef2..23a5f414c5 100644 --- a/src/quotacheck/quotacheck.c +++ b/src/quotacheck/quotacheck.c @@ -38,16 +38,6 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat return 0; } -static void test_files(void) { - -#if HAVE_SYSV_COMPAT - if (access("/forcequotacheck", F_OK) >= 0) { - log_error("Please pass 'quotacheck.mode=force' on the kernel command line rather than creating /forcequotacheck on the root file system. Proceeding anyway."); - arg_force = true; - } -#endif -} - static int run(int argc, char *argv[]) { int r; @@ -63,8 +53,6 @@ static int run(int argc, char *argv[]) { if (r < 0) log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); - test_files(); - if (!arg_force) { if (arg_skip) return 0; diff --git a/tmpfiles.d/legacy.conf.in b/tmpfiles.d/legacy.conf.in index b475500e58..cdef21fa9b 100644 --- a/tmpfiles.d/legacy.conf.in +++ b/tmpfiles.d/legacy.conf.in @@ -21,11 +21,4 @@ L$ /var/log/README - - - - ../..{{DOC_DIR}}/README.logs # /run/lock/subsys is used for serializing SysV service execution, and # hence without use on SysV-less systems. d /run/lock/subsys 0755 root root - - -# /forcefsck, /fastboot and /forcequotacheck are deprecated in favor of the -# kernel command line options 'fsck.mode=force', 'fsck.mode=skip' and -# 'quotacheck.mode=force' -r! /forcefsck -r! /fastboot -r! /forcequotacheck {% endif %} From a85428b1d325654dc7e1afbabf4b689bd31116f5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 13 Jul 2025 04:07:53 +0900 Subject: [PATCH 02/11] fsck: introduce string tables for fsck.mode= and fsck.repair= No functional change, just refactoring and preparation for later change. --- src/fsck/fsck.c | 83 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 29 deletions(-) diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index 9e4f7c6646..7f2b0f5d36 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -28,12 +28,52 @@ #include "socket-util.h" #include "special.h" #include "stdio-util.h" +#include "string-table.h" #include "string-util.h" #include "time-util.h" -static bool arg_skip = false; -static bool arg_force = false; -static const char *arg_repair = "-a"; +typedef enum FSCKMode { + FSCK_AUTO, + FSCK_FORCE, + FSCK_SKIP, + _FSCK_MODE_MAX, + _FSCK_MODE_INVALID = -EINVAL, +} FSCKMode; + +typedef enum FSCKRepair { + FSCK_REPAIR_NO, + FSCK_REPAIR_YES, + FSCK_REPAIR_PREEN, + _FSCK_REPAIR_MAX, + _FSCK_REPAIR_INVALID = -EINVAL, +} FSCKRepair; + +static FSCKMode arg_mode = FSCK_AUTO; +static FSCKRepair arg_repair = FSCK_REPAIR_PREEN; + +static const char * const fsck_mode_table[_FSCK_MODE_MAX] = { + [FSCK_AUTO] = "auto", + [FSCK_FORCE] = "force", + [FSCK_SKIP] = "skip", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(fsck_mode, FSCKMode); + +static const char * const fsck_repair_table[_FSCK_REPAIR_MAX] = { + [FSCK_REPAIR_NO] = "no", + [FSCK_REPAIR_YES] = "yes", + [FSCK_REPAIR_PREEN] = "preen", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(fsck_repair, FSCKRepair, FSCK_REPAIR_YES); + +static const char * const fsck_repair_option_table[_FSCK_REPAIR_MAX] = { + [FSCK_REPAIR_NO] = "-n", + [FSCK_REPAIR_YES] = "-y", + [FSCK_REPAIR_PREEN] = "-a", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(fsck_repair_option, FSCKRepair); static void start_target(const char *target, const char *mode) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; @@ -59,8 +99,6 @@ static void start_target(const char *target, const char *mode) { } static int parse_proc_cmdline_item(const char *key, const char *value, void *data) { - int r; - assert(key); if (streq(key, "fsck.mode")) { @@ -68,38 +106,25 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat if (proc_cmdline_value_missing(key, value)) return 0; - if (streq(value, "auto")) - arg_force = arg_skip = false; - else if (streq(value, "force")) - arg_force = true; - else if (streq(value, "skip")) - arg_skip = true; - else - log_warning("Invalid fsck.mode= parameter '%s'. Ignoring.", value); + arg_mode = fsck_mode_from_string(value); + if (arg_mode < 0) + log_warning_errno(arg_mode, "Invalid fsck.mode= parameter, ignoring: %s", value); } else if (streq(key, "fsck.repair")) { if (proc_cmdline_value_missing(key, value)) return 0; - if (streq(value, "preen")) - arg_repair = "-a"; - else { - r = parse_boolean(value); - if (r > 0) - arg_repair = "-y"; - else if (r == 0) - arg_repair = "-n"; - else - log_warning("Invalid fsck.repair= parameter '%s'. Ignoring.", value); - } + arg_repair = fsck_repair_from_string(value); + if (arg_repair < 0) + log_warning_errno(arg_repair, "Invalid fsck.repair= parameter, ignoring: %s", value); } else if (streq(key, "fastboot") && !value) - arg_skip = true; + arg_mode = FSCK_SKIP; else if (streq(key, "forcefsck") && !value) - arg_force = true; + arg_mode = FSCK_FORCE; return 0; } @@ -233,7 +258,7 @@ static int run(int argc, char *argv[]) { bool show_progress = access("/run/systemd/show-status", F_OK) >= 0; - if (!arg_force && arg_skip) + if (arg_mode == FSCK_SKIP) return 0; if (argc > 1) { @@ -341,7 +366,7 @@ static int run(int argc, char *argv[]) { dash_c[0] = 0; cmdline[i++] = "fsck"; - cmdline[i++] = arg_repair; + cmdline[i++] = fsck_repair_option_to_string(arg_repair); cmdline[i++] = "-T"; /* @@ -354,7 +379,7 @@ static int run(int argc, char *argv[]) { if (!root_directory) cmdline[i++] = "-M"; - if (arg_force) + if (arg_mode == FSCK_FORCE) cmdline[i++] = "-f"; if (!isempty(dash_c)) From 059afcadfd89c6c302f20c9ac1a1c44592b716df Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 13 Jul 2025 04:25:26 +0900 Subject: [PATCH 03/11] fsck: add fsck.mode and fsck.repair credentials support Maybe useful when kernel command line is hard to change, e.g. when UKI is used. --- man/systemd-fsck@.service.xml | 28 +++++++++++++++++++ man/systemd.system-credentials.xml | 14 ++++++++++ src/fsck/fsck.c | 28 +++++++++++++++++++ src/shared/generator.c | 3 +- .../systemd-fsck-root.service | 1 + .../systemd-fsck-root.service | 1 + .../systemd-fsck-root.service | 1 + .../systemd-fsck-root.service | 1 + .../systemd-fsck-root.service | 1 + .../systemd-fsck-root.service | 1 + .../systemd-fsck-root.service | 1 + .../systemd-fsck-usr.service | 1 + units/systemd-fsck-root.service.in | 1 + units/systemd-fsck@.service.in | 1 + 14 files changed, 82 insertions(+), 1 deletion(-) diff --git a/man/systemd-fsck@.service.xml b/man/systemd-fsck@.service.xml index b0e2ebafbd..3df215ba1f 100644 --- a/man/systemd-fsck@.service.xml +++ b/man/systemd-fsck@.service.xml @@ -110,6 +110,34 @@ + + Credentials + + systemd-fsck supports the service credentials logic as implemented by + ImportCredential=/LoadCredential=/SetCredential= + (see systemd.exec5 for + details). The following credentials are used when passed in: + + + + fsck.mode + fsck.repair + + + The contents of the credentials are parsed as same as the kernel command line options with + the same name. See above for more details. + + + + + + + Note that by default the systemd-fsck@.service, + systemd-fsck-root.service, and systemd-fsck-usr.service unit + files are set up to inherit both fsck.mode and fsck.repair + credentials from the service manager. + + See Also diff --git a/man/systemd.system-credentials.xml b/man/systemd.system-credentials.xml index d436cff5d4..0411061ca3 100644 --- a/man/systemd.system-credentials.xml +++ b/man/systemd.system-credentials.xml @@ -510,6 +510,20 @@ + + + fsck.* + + + Read by systemd-fsck@.service, + systemd-fsck-root.service, and systemd-fsck-usr.service. + See + systemd-fsck@.service8 + for more details. + + + + diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index 7f2b0f5d36..1d7f4ea3af 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -16,6 +16,7 @@ #include "bus-error.h" #include "bus-locator.h" #include "bus-util.h" +#include "creds-util.h" #include "device-util.h" #include "fd-util.h" #include "fs-util.h" @@ -129,6 +130,31 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat return 0; } +static void parse_credentials(void) { + _cleanup_free_ char *value = NULL; + int r; + + r = read_credential("fsck.mode", (void**) &value, /* ret_size = */ NULL); + if (r < 0) + log_debug_errno(r, "Failed to read credential 'fsck.mode', ignoring: %m"); + else { + arg_mode = fsck_mode_from_string(value); + if (arg_mode < 0) + log_warning_errno(arg_mode, "Invalid 'fsck.mode' credential, ignoring: %s", value); + } + + value = mfree(value); + + r = read_credential("fsck.repair", (void**) &value, /* ret_size = */ NULL); + if (r < 0) + log_debug_errno(r, "Failed to read credential 'fsck.repair', ignoring: %m"); + else { + arg_repair = fsck_repair_from_string(value); + if (arg_repair < 0) + log_warning_errno(arg_repair, "Invalid 'fsck.repair' credential, ignoring: %s", value); + } +} + static double percent(int pass, unsigned long cur, unsigned long max) { /* Values stolen from e2fsck */ @@ -256,6 +282,8 @@ static int run(int argc, char *argv[]) { if (r < 0) log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); + parse_credentials(); + bool show_progress = access("/run/systemd/show-status", F_OK) >= 0; if (arg_mode == FSCK_SKIP) diff --git a/src/shared/generator.c b/src/shared/generator.c index ea665a6c33..f978d43fe8 100644 --- a/src/shared/generator.c +++ b/src/shared/generator.c @@ -250,7 +250,8 @@ static int write_fsck_sysroot_service( "Type=oneshot\n" "RemainAfterExit=yes\n" "ExecStart=" SYSTEMD_FSCK_PATH " %6$s\n" - "TimeoutSec=infinity\n", + "TimeoutSec=infinity\n" + "ImportCredential=fsck.*\n", escaped, unit, device, diff --git a/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service index 147348899d..797ffa08db 100644 --- a/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service +++ b/test/test-fstab-generator/test-12-dev-sdx.expected/systemd-fsck-root.service @@ -15,3 +15,4 @@ Type=oneshot RemainAfterExit=yes ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx1 TimeoutSec=infinity +ImportCredential=fsck.* diff --git a/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service index 85c1936bce..ee146aa3b2 100644 --- a/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service +++ b/test/test-fstab-generator/test-13-label.expected/systemd-fsck-root.service @@ -15,3 +15,4 @@ Type=oneshot RemainAfterExit=yes ExecStart=/usr/lib/systemd/systemd-fsck /dev/disk/by-label/Root TimeoutSec=infinity +ImportCredential=fsck.* diff --git a/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service index 1c7eaea103..73e9134fb1 100644 --- a/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service +++ b/test/test-fstab-generator/test-14-uuid.expected/systemd-fsck-root.service @@ -15,3 +15,4 @@ Type=oneshot RemainAfterExit=yes ExecStart=/usr/lib/systemd/systemd-fsck /dev/disk/by-uuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7 TimeoutSec=infinity +ImportCredential=fsck.* diff --git a/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service index ab27bfd79c..2d5c9bfbfd 100644 --- a/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service +++ b/test/test-fstab-generator/test-15-partuuid.expected/systemd-fsck-root.service @@ -15,3 +15,4 @@ Type=oneshot RemainAfterExit=yes ExecStart=/usr/lib/systemd/systemd-fsck /dev/disk/by-partuuid/3f5ad593-4546-4a94-a374-bcfb68aa11f7 TimeoutSec=infinity +ImportCredential=fsck.* diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service index 147348899d..797ffa08db 100644 --- a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service +++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service @@ -15,3 +15,4 @@ Type=oneshot RemainAfterExit=yes ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx1 TimeoutSec=infinity +ImportCredential=fsck.* diff --git a/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service index 147348899d..797ffa08db 100644 --- a/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service +++ b/test/test-fstab-generator/test-18-options.fstab.expected/systemd-fsck-root.service @@ -15,3 +15,4 @@ Type=oneshot RemainAfterExit=yes ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx1 TimeoutSec=infinity +ImportCredential=fsck.* diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-root.service index 147348899d..797ffa08db 100644 --- a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-root.service +++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-root.service @@ -15,3 +15,4 @@ Type=oneshot RemainAfterExit=yes ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx1 TimeoutSec=infinity +ImportCredential=fsck.* diff --git a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-usr.service b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-usr.service index 512e7b1636..61c0af0490 100644 --- a/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-usr.service +++ b/test/test-fstab-generator/test-19-mounts-from-cmdline.expected/systemd-fsck-usr.service @@ -15,3 +15,4 @@ Type=oneshot RemainAfterExit=yes ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx5 TimeoutSec=infinity +ImportCredential=fsck.* diff --git a/units/systemd-fsck-root.service.in b/units/systemd-fsck-root.service.in index ebe8262a49..22e86acadd 100644 --- a/units/systemd-fsck-root.service.in +++ b/units/systemd-fsck-root.service.in @@ -22,3 +22,4 @@ Type=oneshot RemainAfterExit=yes ExecStart={{LIBEXECDIR}}/systemd-fsck TimeoutSec=infinity +ImportCredential=fsck.* diff --git a/units/systemd-fsck@.service.in b/units/systemd-fsck@.service.in index 8eb4821d41..d5caed6ae0 100644 --- a/units/systemd-fsck@.service.in +++ b/units/systemd-fsck@.service.in @@ -22,3 +22,4 @@ Type=oneshot RemainAfterExit=yes ExecStart={{LIBEXECDIR}}/systemd-fsck %f TimeoutSec=infinity +ImportCredential=fsck.* From fff4dcc6de215211ad16dfa279bb0fc4e52a9204 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 13 Jul 2025 05:26:47 +0900 Subject: [PATCH 04/11] man: fix reference to systemd-quotacheck@.service Also this makes the man page mentions systemd-quotacheck-root.service. --- man/kernel-command-line.xml | 4 ++-- man/rules/meson.build | 4 ++-- man/systemd-fsck@.service.xml | 2 +- ...ce.xml => systemd-quotacheck@.service.xml} | 20 ++++++++++--------- units/systemd-quotacheck-root.service.in | 2 +- units/systemd-quotacheck@.service.in | 2 +- 6 files changed, 18 insertions(+), 16 deletions(-) rename man/{systemd-quotacheck.service.xml => systemd-quotacheck@.service.xml} (73%) diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index 54213d31c6..0806b800b4 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -275,7 +275,7 @@ Parameter understood by the file quota checker service. For details, see - systemd-quotacheck.service8. + systemd-quotacheck@.service8. @@ -820,7 +820,7 @@ smbios-type-117 systemd-debug-generator8 systemd-fsck@.service8 - systemd-quotacheck.service8 + systemd-quotacheck@.service8 systemd-journald.service8 systemd-vconsole-setup.service8 systemd-udevd.service8 diff --git a/man/rules/meson.build b/man/rules/meson.build index 1fcf30e692..fdec807cb2 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -1086,9 +1086,9 @@ manpages = [ ''], ['systemd-pstore.service', '8', ['systemd-pstore'], 'ENABLE_PSTORE'], ['systemd-pty-forward', '1', [], ''], - ['systemd-quotacheck.service', + ['systemd-quotacheck@.service', '8', - ['systemd-quotacheck'], + ['systemd-quotacheck', 'systemd-quotacheck-root.service'], 'ENABLE_QUOTACHECK'], ['systemd-random-seed.service', '8', diff --git a/man/systemd-fsck@.service.xml b/man/systemd-fsck@.service.xml index 3df215ba1f..e6d34538fe 100644 --- a/man/systemd-fsck@.service.xml +++ b/man/systemd-fsck@.service.xml @@ -143,7 +143,7 @@ systemd1 fsck8 - systemd-quotacheck.service8 + systemd-quotacheck@.service8 fsck.btrfs8 fsck.cramfs8 fsck.ext48 diff --git a/man/systemd-quotacheck.service.xml b/man/systemd-quotacheck@.service.xml similarity index 73% rename from man/systemd-quotacheck.service.xml rename to man/systemd-quotacheck@.service.xml index 034d13a148..503df381e0 100644 --- a/man/systemd-quotacheck.service.xml +++ b/man/systemd-quotacheck@.service.xml @@ -3,37 +3,39 @@ - - systemd-quotacheck.service + systemd-quotacheck@.service systemd - systemd-quotacheck.service + systemd-quotacheck@.service 8 - systemd-quotacheck.service + systemd-quotacheck@.service + systemd-quotacheck-root.service systemd-quotacheck File system quota checker logic - systemd-quotacheck.service + systemd-quotacheck@.service + systemd-quotacheck-root.service /usr/lib/systemd/systemd-quotacheck Description - systemd-quotacheck.service is a service - responsible for file system quota checks. It is run once at boot - after all necessary file systems are mounted. It is pulled in only - if at least one file system has quotas enabled. + systemd-quotacheck@.service and + systemd-quotacheck-root.service are services responsible for file system quota + checks. They run once at boot after all necessary file systems are mounted. They are pulled in only if at + least one file system has quotas enabled. diff --git a/units/systemd-quotacheck-root.service.in b/units/systemd-quotacheck-root.service.in index a182059376..4792e5bdd5 100644 --- a/units/systemd-quotacheck-root.service.in +++ b/units/systemd-quotacheck-root.service.in @@ -9,7 +9,7 @@ [Unit] Description=Root File System Quota Check -Documentation=man:systemd-quotacheck.service(8) +Documentation=man:systemd-quotacheck@.service(8) ConditionPathExists=!/etc/initrd-release diff --git a/units/systemd-quotacheck@.service.in b/units/systemd-quotacheck@.service.in index f2b8db7abb..b38450ed09 100644 --- a/units/systemd-quotacheck@.service.in +++ b/units/systemd-quotacheck@.service.in @@ -9,7 +9,7 @@ [Unit] Description=File System Quota Check -Documentation=man:systemd-quotacheck.service(8) +Documentation=man:systemd-quotacheck@.service(8) ConditionPathExists={{QUOTACHECK}} ConditionPathExists=!/etc/initrd-release From 59a6ae4e163c924ceaff3e154f1c37932832b1e2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 13 Jul 2025 05:30:07 +0900 Subject: [PATCH 05/11] man: fix service names --- man/systemd.mount.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index c3d06d696a..035069437b 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -111,7 +111,7 @@ If traditional file system quota is enabled for a mount unit, automatic Wants= and Before= dependencies on - systemd-quotacheck.service and quotaon.service + systemd-quotacheck@.service and quotaon@.service are added. Additional implicit dependencies may be added as result of execution and From e5a017becf8ecda2af4f6ebe080b00744fe7855b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 13 Jul 2025 04:48:23 +0900 Subject: [PATCH 06/11] quotacheck: drop unnecessary use of global variable --- src/quotacheck/quotacheck.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c index 23a5f414c5..b98819f0ef 100644 --- a/src/quotacheck/quotacheck.c +++ b/src/quotacheck/quotacheck.c @@ -7,15 +7,11 @@ #include "main-func.h" #include "proc-cmdline.h" #include "process-util.h" -#include "static-destruct.h" #include "string-util.h" -static char *arg_path = NULL; static bool arg_skip = false; static bool arg_force = false; -STATIC_DESTRUCTOR_REGISTER(arg_path, freep); - static int parse_proc_cmdline_item(const char *key, const char *value, void *data) { if (streq(key, "quotacheck.mode")) { @@ -68,9 +64,10 @@ static int run(int argc, char *argv[]) { } } + _cleanup_free_ char *path = NULL; if (argc == 2) { - arg_path = strdup(argv[1]); - if (!arg_path) + path = strdup(argv[1]); + if (!path) return log_oom(); } @@ -80,8 +77,8 @@ static int run(int argc, char *argv[]) { if (r == 0) { const char *cmdline[] = { QUOTACHECK, - arg_path ? "-nug" : "-anug", /* Check all file systems if path isn't specified */ - arg_path, + path ? "-nug" : "-anug", /* Check all file systems if path isn't specified */ + path, NULL }; From d73691c64e05650d838aaeb7da94fd8bdfb60907 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 13 Jul 2025 04:46:22 +0900 Subject: [PATCH 07/11] quotacheck: introduce string table for quota check mode No functional change, just refactoring. --- src/quotacheck/quotacheck.c | 39 ++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c index b98819f0ef..49d63d77d0 100644 --- a/src/quotacheck/quotacheck.c +++ b/src/quotacheck/quotacheck.c @@ -7,10 +7,26 @@ #include "main-func.h" #include "proc-cmdline.h" #include "process-util.h" +#include "string-table.h" #include "string-util.h" -static bool arg_skip = false; -static bool arg_force = false; +typedef enum QuotaCheckMode { + QUOTA_CHECK_AUTO, + QUOTA_CHECK_FORCE, + QUOTA_CHECK_SKIP, + _QUOTA_CHECK_MODE_MAX, + _QUOTA_CHECK_MODE_INVALID = -EINVAL, +} QuotaCheckMode; + +static QuotaCheckMode arg_mode = QUOTA_CHECK_AUTO; + +static const char * const quota_check_mode_table[_QUOTA_CHECK_MODE_MAX] = { + [QUOTA_CHECK_AUTO] = "auto", + [QUOTA_CHECK_FORCE] = "force", + [QUOTA_CHECK_SKIP] = "skip", +}; + +DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(quota_check_mode, QuotaCheckMode); static int parse_proc_cmdline_item(const char *key, const char *value, void *data) { @@ -19,17 +35,12 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat if (proc_cmdline_value_missing(key, value)) return 0; - if (streq(value, "auto")) - arg_force = arg_skip = false; - else if (streq(value, "force")) - arg_force = true; - else if (streq(value, "skip")) - arg_skip = true; - else - log_warning("Invalid quotacheck.mode= value, ignoring: %s", value); + arg_mode = quota_check_mode_from_string(value); + if (arg_mode < 0) + log_warning_errno(arg_mode, "Invalid quotacheck.mode= value, ignoring: %s", value); } else if (streq(key, "forcequotacheck") && !value) - arg_force = true; + arg_mode = QUOTA_CHECK_FORCE; return 0; } @@ -49,10 +60,10 @@ static int run(int argc, char *argv[]) { if (r < 0) log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); - if (!arg_force) { - if (arg_skip) - return 0; + if (arg_mode == QUOTA_CHECK_SKIP) + return 0; + if (arg_mode == QUOTA_CHECK_AUTO) { /* This is created by systemd-fsck when fsck detected and corrected errors. In normal * operations quotacheck is not needed. */ if (access("/run/systemd/quotacheck", F_OK) < 0) { From dba4fe9a60e8876addcd6a597c9e1d5f529309ca Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 13 Jul 2025 04:52:36 +0900 Subject: [PATCH 08/11] quotacheck: add quotacheck.mode credential support --- man/systemd-quotacheck@.service.xml | 26 ++++++++++++++++++++++++ man/systemd.system-credentials.xml | 13 ++++++++++++ src/quotacheck/quotacheck.c | 17 ++++++++++++++++ units/systemd-quotacheck-root.service.in | 1 + units/systemd-quotacheck@.service.in | 1 + 5 files changed, 58 insertions(+) diff --git a/man/systemd-quotacheck@.service.xml b/man/systemd-quotacheck@.service.xml index 503df381e0..56397ff7bd 100644 --- a/man/systemd-quotacheck@.service.xml +++ b/man/systemd-quotacheck@.service.xml @@ -62,6 +62,32 @@ + + Credentials + + systemd-quotacheck supports the service credentials logic as implemented by + ImportCredential=/LoadCredential=/SetCredential= + (see systemd.exec5 for + details). The following credentials are used when passed in: + + + + quotacheck.mode + + + The contents of the credential is parsed as same as the kernel command line option with the + same name. See above for more details. + + + + + + + Note that by default the systemd-quotacheck@.service and + systemd-quotacheck-root.service unit files are set up to inherit + quotacheck.mode credential from the service manager. + + See Also diff --git a/man/systemd.system-credentials.xml b/man/systemd.system-credentials.xml index 0411061ca3..fd0d12320d 100644 --- a/man/systemd.system-credentials.xml +++ b/man/systemd.system-credentials.xml @@ -524,6 +524,19 @@ + + + quotacheck.* + + + Read by systemd-quotacheck@.service and + systemd-quotacheck-root.service. See + systemd-quotacheck8 + for more details. + + + + diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c index 49d63d77d0..f686621348 100644 --- a/src/quotacheck/quotacheck.c +++ b/src/quotacheck/quotacheck.c @@ -3,6 +3,7 @@ #include #include +#include "creds-util.h" #include "log.h" #include "main-func.h" #include "proc-cmdline.h" @@ -45,6 +46,20 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat return 0; } +static void parse_credentials(void) { + _cleanup_free_ char *value = NULL; + int r; + + r = read_credential("quotacheck.mode", (void**) &value, /* ret_size = */ NULL); + if (r < 0) + log_debug_errno(r, "Failed to read credential 'quotacheck.mode', ignoring: %m"); + else { + arg_mode = quota_check_mode_from_string(value); + if (arg_mode < 0) + log_warning_errno(arg_mode, "Invalid 'quotacheck.mode' credential, ignoring: %s", value); + } +} + static int run(int argc, char *argv[]) { int r; @@ -60,6 +75,8 @@ static int run(int argc, char *argv[]) { if (r < 0) log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); + parse_credentials(); + if (arg_mode == QUOTA_CHECK_SKIP) return 0; diff --git a/units/systemd-quotacheck-root.service.in b/units/systemd-quotacheck-root.service.in index 4792e5bdd5..eea656c562 100644 --- a/units/systemd-quotacheck-root.service.in +++ b/units/systemd-quotacheck-root.service.in @@ -23,3 +23,4 @@ Type=oneshot RemainAfterExit=yes ExecStart={{LIBEXECDIR}}/systemd-quotacheck / TimeoutSec=infinity +ImportCredential=quotacheck.* diff --git a/units/systemd-quotacheck@.service.in b/units/systemd-quotacheck@.service.in index b38450ed09..7569052d82 100644 --- a/units/systemd-quotacheck@.service.in +++ b/units/systemd-quotacheck@.service.in @@ -25,3 +25,4 @@ Type=oneshot RemainAfterExit=yes ExecStart={{LIBEXECDIR}}/systemd-quotacheck %f TimeoutSec=infinity +ImportCredential=quotacheck.* From 644b6041d45ffbee3ad0848d72a417bb4559e1ae Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 23 Apr 2025 10:48:11 +0900 Subject: [PATCH 09/11] NEWS: mention changes in systemd-fsck and systemd-quotacheck --- NEWS | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/NEWS b/NEWS index 5c72926d18..6ef5f81460 100644 --- a/NEWS +++ b/NEWS @@ -148,6 +148,16 @@ CHANGES WITH 258 in spe: - The concept of runlevels has been removed, so runlevel transitions are no longer recorded in the utmp/wtmp databases. + * Support for traditional /forcefsck and /fastboot files to control + exection mode of fsck on boot has been removed from systemd-fsck. To + control the mode, please use the fsck.mode= kernel command line option + or newly introduced fsck.mode credential. + + * Support for traditional /forcequotacheck file to control execution + mode of quotacheck on boot has been removed from systemd-quotacheck. + To control the mode, please use the quotacheck.mode= kerenl command + line option of newly introduced quotacheck.mode credential. + Announcements of Future Feature Removals: * Support for System V service scripts is deprecated and will be @@ -1400,6 +1410,12 @@ CHANGES WITH 258 in spe: once boot-up is complete will tell you how to connect to the system via SSH, if that's available. + * systemd-fsck gained fsck.mode and fsck.repair credentials support to + control the execution mode of fsck. + + * systemd-quotacheck gained quotacheck.mode credential support to + control the execution mode of quotacheck. + — , CHANGES WITH 257: From d48387623b7918eb4d2da6544997b994e5ca1b31 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 16 Jul 2025 04:55:32 +0900 Subject: [PATCH 10/11] mkosi: patch filelists by opensuse --- .../build/mkosi.conf.d/opensuse/mkosi.build.chroot | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mkosi/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.build.chroot b/mkosi/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.build.chroot index 8ec7500d7b..76a8e08ee1 100755 --- a/mkosi/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.build.chroot +++ b/mkosi/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.build.chroot @@ -22,7 +22,11 @@ TS="${SOURCE_DATE_EPOCH:-$(date +%s)}" # TODO: remove patches for removal of cgroups-agent, renaming pubring file, and removal of sysv files # when the upstream spec is updated while read -r filelist; do - sed -E 's/\.gz$//; /systemd-cgroups-agent/d; s/import-pubring.gpg/import-pubring.pgp/; /(initctl|runlevel|telinit)/ d' "$filelist" >"/tmp/$(basename "$filelist")" + sed -E \ + -e 's/\.gz$//; /systemd-cgroups-agent/d; s/import-pubring.gpg/import-pubring.pgp/' \ + -e '/(initctl|runlevel|telinit)/ d' \ + -e 's/systemd-quotacheck.service.8/systemd-quotacheck@.service.8/' \ + "$filelist" >"/tmp/$(basename "$filelist")" mount --bind "/tmp/$(basename "$filelist")" "$filelist" done < <(find "pkg/$PKG_SUBDIR${GIT_SUBDIR:+/$GIT_SUBDIR}" -name "files.*") From 48bc6f47ea6378cbf118acc58386a57068d0877a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 16 Jul 2025 05:50:01 +0900 Subject: [PATCH 11/11] mkosi: update debian commit reference to 61144ff7a6747bd3cc6340fbac38a8e15e9a239b * 61144ff7a6 Install new quota manpages for upstream build * a50c51d8c8 systemd-boot: fix initramfs post-update hook for uncompressed kernels --- mkosi/mkosi.conf.d/debian-ubuntu/mkosi.conf.d/pkgenv.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkosi/mkosi.conf.d/debian-ubuntu/mkosi.conf.d/pkgenv.conf b/mkosi/mkosi.conf.d/debian-ubuntu/mkosi.conf.d/pkgenv.conf index 62486e424a..ab330aa654 100644 --- a/mkosi/mkosi.conf.d/debian-ubuntu/mkosi.conf.d/pkgenv.conf +++ b/mkosi/mkosi.conf.d/debian-ubuntu/mkosi.conf.d/pkgenv.conf @@ -5,5 +5,5 @@ Environment= GIT_URL=https://salsa.debian.org/systemd-team/systemd.git GIT_SUBDIR=debian GIT_BRANCH=debian/master - GIT_COMMIT=a8ad8e30e70c0b82ecb8fe016f2dde3a084236f0 + GIT_COMMIT=61144ff7a6747bd3cc6340fbac38a8e15e9a239b PKG_SUBDIR=debian