]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
units: make templates for quotaon and systemd-quotacheck service
authorThomas Blume <tblume@suse.com>
Mon, 19 Sep 2022 14:57:48 +0000 (16:57 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Sat, 9 Mar 2024 19:32:09 +0000 (19:32 +0000)
12 files changed:
src/basic/special.h
src/core/mount.c
src/fstab-generator/fstab-generator.c
src/quotacheck/quotacheck.c
src/shared/generator.c
src/shared/generator.h
units/meson.build
units/quotaon-root.service.in [new file with mode: 0644]
units/quotaon@.service.in [moved from units/quotaon.service.in with 78% similarity]
units/systemd-journal-flush.service
units/systemd-quotacheck-root.service.in [new file with mode: 0644]
units/systemd-quotacheck@.service.in [moved from units/systemd-quotacheck.service.in with 81% similarity]

index 27d2c26e48e028a1f1febde2ce2f9121ed5c11e8..166737a9ca815455f289a59bf2601bbe6eabca54 100644 (file)
 #define SPECIAL_FSCK_SERVICE "systemd-fsck@.service"
 #define SPECIAL_FSCK_ROOT_SERVICE "systemd-fsck-root.service"
 #define SPECIAL_FSCK_USR_SERVICE "systemd-fsck-usr.service"
-#define SPECIAL_QUOTACHECK_SERVICE "systemd-quotacheck.service"
-#define SPECIAL_QUOTAON_SERVICE "quotaon.service"
+#define SPECIAL_QUOTACHECK_SERVICE "systemd-quotacheck@.service"
+#define SPECIAL_QUOTACHECK_ROOT_SERVICE "systemd-quotacheck-root.service"
+#define SPECIAL_QUOTAON_SERVICE "quotaon@.service"
+#define SPECIAL_QUOTAON_ROOT_SERVICE "quotaon-root.service"
 #define SPECIAL_REMOUNT_FS_SERVICE "systemd-remount-fs.service"
 #define SPECIAL_VOLATILE_ROOT_SERVICE "systemd-volatile-root.service"
 #define SPECIAL_UDEVD_SERVICE "systemd-udevd.service"
index 5090465f936f693b3a0974c8437cb0ca94ff04b4..7dbf5f48f9722bcdf13c107a3ec784ec455387a6 100644 (file)
@@ -171,19 +171,6 @@ static bool mount_propagate_stop(Mount *m) {
                                   * otherwise let's not bother. */
 }
 
-static bool mount_needs_quota(const MountParameters *p) {
-        assert(p);
-
-        if (p->fstype && !fstype_needs_quota(p->fstype))
-                return false;
-
-        if (mount_is_bind(p))
-                return false;
-
-        return fstab_test_option(p->options,
-                                 "usrquota\0" "grpquota\0" "quota\0" "usrjquota\0" "grpjquota\0");
-}
-
 static void mount_init(Unit *u) {
         Mount *m = MOUNT(u);
 
@@ -420,35 +407,6 @@ static int mount_add_device_dependencies(Mount *m) {
         return 0;
 }
 
-static int mount_add_quota_dependencies(Mount *m) {
-        MountParameters *p;
-        int r;
-
-        assert(m);
-
-        if (!MANAGER_IS_SYSTEM(UNIT(m)->manager))
-                return 0;
-
-        p = get_mount_parameters_fragment(m);
-        if (!p)
-                return 0;
-
-        if (!mount_needs_quota(p))
-                return 0;
-
-        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE,
-                                              /* add_reference= */ true, UNIT_DEPENDENCY_FILE);
-        if (r < 0)
-                return r;
-
-        r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE,
-                                              /* add_reference= */true, UNIT_DEPENDENCY_FILE);
-        if (r < 0)
-                return r;
-
-        return 0;
-}
-
 static bool mount_is_extrinsic(Unit *u) {
         MountParameters *p;
         Mount *m = MOUNT(u);
@@ -663,10 +621,6 @@ static int mount_add_non_exec_dependencies(Mount *m) {
         if (r < 0)
                 return r;
 
-        r = mount_add_quota_dependencies(m);
-        if (r < 0)
-                return r;
-
         r = mount_add_default_dependencies(m);
         if (r < 0)
                 return r;
index 4d65289befc52789dc4f70b784b2861ca0261ab2..e4c8c9674c044e26d00c127adb99ab4ee51afabe 100644 (file)
@@ -46,6 +46,7 @@ typedef enum MountPointFlags {
         MOUNT_GROWFS    = 1 << 4,
         MOUNT_RW_ONLY   = 1 << 5,
         MOUNT_PCRFS     = 1 << 6,
+        MOUNT_QUOTA     = 1 << 7,
 } MountPointFlags;
 
 typedef struct Mount {
@@ -717,6 +718,18 @@ static int add_mount(
                 }
         }
 
+        if (flags & MOUNT_QUOTA) {
+                r = generator_hook_up_quotacheck(dest, what, where, target_unit, fstype);
+                if (r < 0) {
+                        if (r != -EOPNOTSUPP)
+                                return r;
+                } else {
+                        r = generator_hook_up_quotaon(dest, where, target_unit);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
         if (FLAGS_SET(flags, MOUNT_AUTOMOUNT)) {
                 r = unit_name_from_path(where, ".automount", &automount_name);
                 if (r < 0)
@@ -858,6 +871,8 @@ static MountPointFlags fstab_options_to_flags(const char *options, bool is_swap)
                 flags |= MOUNT_GROWFS;
         if (fstab_test_option(options, "x-systemd.pcrfs\0"))
                 flags |= MOUNT_PCRFS;
+        if (fstab_test_option(options, "usrquota\0" "grpquota\0" "quota\0" "usrjquota\0" "grpjquota\0" "prjquota\0"))
+                flags |= MOUNT_QUOTA;
         if (fstab_test_yes_no_option(options, "noauto\0" "auto\0"))
                 flags |= MOUNT_NOAUTO;
         if (fstab_test_yes_no_option(options, "nofail\0" "fail\0"))
@@ -1210,7 +1225,7 @@ static int add_sysroot_mount(void) {
                          fstype,
                          opts,
                          is_device_path(what) ? 1 : 0, /* passno */
-                         flags,                        /* makefs off, pcrfs off, noauto off, nofail off, automount off */
+                         flags,                        /* makefs off, pcrfs off, quota off, noauto off, nofail off, automount off */
                          SPECIAL_INITRD_ROOT_FS_TARGET);
 }
 
index 27a914d737a44881b039b5d0fafb0fca9cf8f848..c77e0d6143a0622e4812c07b7616fb08ddd2cbd6 100644 (file)
@@ -56,12 +56,14 @@ static void test_files(void) {
 
 static int run(int argc, char *argv[]) {
         int r;
+        _cleanup_free_ char *fspath = NULL;
+        bool quota_check_all = false;
 
         log_setup();
 
-        if (argc > 1)
+        if (argc > 2)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
-                                       "This program takes no arguments.");
+                                       "This program expects one or no arguments.");
 
         umask(0022);
 
@@ -79,13 +81,22 @@ static int run(int argc, char *argv[]) {
                         return 0;
         }
 
+        if (argc == 2) {
+                fspath = strdup(argv[1]);
+                if (!fspath)
+                        return log_oom();
+        } else
+                quota_check_all = true;
+
         r = safe_fork("(quotacheck)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_WAIT|FORK_LOG, NULL);
         if (r < 0)
                 return r;
+
         if (r == 0) {
-                static const char * const cmdline[] = {
+                const char *cmdline[] = {
                         QUOTACHECK,
-                        "-anug",
+                        quota_check_all ? "-anug" : "-nug",
+                        fspath,
                         NULL
                 };
 
index b96715c59cc7c91fe7c37e5a02b66055d65a8001..e03ed4b29fce206175b9a592c5410977e1c0e520 100644 (file)
@@ -15,6 +15,7 @@
 #include "log.h"
 #include "macro.h"
 #include "mkdir-label.h"
+#include "mountpoint-util.h"
 #include "path-util.h"
 #include "process-util.h"
 #include "special.h"
@@ -708,6 +709,77 @@ int generator_hook_up_pcrfs(
         return generator_add_symlink_full(dir, where_unit, "wants", pcrfs_unit_path, instance);
 }
 
+int generator_hook_up_quotacheck(
+                const char *dir,
+                const char *what,
+                const char *where,
+                const char *target,
+                const char *fstype) {
+
+        _cleanup_free_ char *where_unit = NULL, *instance = NULL;
+        int r;
+
+        assert(dir);
+        assert(where);
+
+        if (isempty(fstype) || streq(fstype, "auto"))
+                return log_warning_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Couldn't determine filesystem type for %s, quota cannot be activated", what);
+        if (!fstype_needs_quota(fstype))
+                return log_warning_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Quota was requested for %s, but not supported, ignoring: %s", what, fstype);
+
+        /* quotacheck unit for system root */
+        if (path_equal(where, "/"))
+                return generator_add_symlink(dir, SPECIAL_LOCAL_FS_TARGET, "wants", SYSTEM_DATA_UNIT_DIR "/" SPECIAL_QUOTACHECK_ROOT_SERVICE);
+
+        r = unit_name_path_escape(where, &instance);
+        if (r < 0)
+                return log_error_errno(r, "Failed to escape path '%s': %m", where);
+
+        if (target) {
+                r = generator_add_ordering(dir, target, "After", SPECIAL_QUOTACHECK_SERVICE, instance);
+                if (r < 0)
+                        return r;
+        }
+
+        r = unit_name_from_path(where, ".mount", &where_unit);
+        if (r < 0)
+                return log_error_errno(r, "Failed to make unit name from path '%s': %m", where);
+
+        return generator_add_symlink_full(dir, where_unit, "wants", SYSTEM_DATA_UNIT_DIR "/" SPECIAL_QUOTACHECK_SERVICE, instance);
+}
+
+int generator_hook_up_quotaon(
+                const char *dir,
+                const char *where,
+                const char *target) {
+
+        _cleanup_free_ char *where_unit = NULL, *instance = NULL;
+        int r;
+
+        assert(dir);
+        assert(where);
+
+        /* quotaon unit for system root is not instantiated */
+        if (path_equal(where, "/"))
+                return generator_add_symlink(dir,  SPECIAL_LOCAL_FS_TARGET, "wants", SYSTEM_DATA_UNIT_DIR "/" SPECIAL_QUOTAON_ROOT_SERVICE);
+
+        r = unit_name_path_escape(where, &instance);
+        if (r < 0)
+                return log_error_errno(r, "Failed to escape path '%s': %m", where);
+
+        if (target) {
+                r = generator_add_ordering(dir, target, "After", SPECIAL_QUOTAON_SERVICE, instance);
+                if (r < 0)
+                        return r;
+        }
+
+        r = unit_name_from_path(where, ".mount", &where_unit);
+        if (r < 0)
+                return log_error_errno(r, "Failed to make unit name from path '%s': %m", where);
+
+        return generator_add_symlink_full(dir, where_unit, "wants", SYSTEM_DATA_UNIT_DIR "/" SPECIAL_QUOTAON_SERVICE, instance);
+}
+
 int generator_enable_remount_fs_service(const char *dir) {
         /* Pull in systemd-remount-fs.service */
         return generator_add_symlink(dir, SPECIAL_LOCAL_FS_TARGET, "wants",
index e5db1c17ce0d74134d47d863f1cc87accdfaf255..baf1dafca3fb791fc0758e9d88dda5e3177a39dc 100644 (file)
@@ -85,6 +85,16 @@ int generator_hook_up_pcrfs(
         const char *dir,
         const char *where,
         const char *target);
+int generator_hook_up_quotacheck(
+        const char *dir,
+        const char *what,
+        const char *where,
+        const char *target,
+        const char *fstype);
+int generator_hook_up_quotaon(
+        const char *dir,
+        const char *where,
+        const char *target);
 
 int generator_enable_remount_fs_service(const char *dir);
 
index 936ebf783745ea97d4ab6fe274131b1ef47d47a1..afe9ec7d1d9043977df8f5628f8f495c4b5e4027 100644 (file)
@@ -161,7 +161,11 @@ units = [
           'conditions' : ['ENABLE_BINFMT'],
         },
         {
-          'file' : 'quotaon.service.in',
+          'file' : 'quotaon@.service.in',
+          'conditions' : ['ENABLE_QUOTACHECK'],
+        },
+        {
+          'file' : 'quotaon-root.service.in',
           'conditions' : ['ENABLE_QUOTACHECK'],
         },
         {
@@ -552,7 +556,11 @@ units = [
           'conditions' : ['ENABLE_PSTORE'],
         },
         {
-          'file' : 'systemd-quotacheck.service.in',
+          'file' : 'systemd-quotacheck@.service.in',
+          'conditions' : ['ENABLE_QUOTACHECK'],
+        },
+        {
+          'file' : 'systemd-quotacheck-root.service.in',
           'conditions' : ['ENABLE_QUOTACHECK'],
         },
         {
diff --git a/units/quotaon-root.service.in b/units/quotaon-root.service.in
new file mode 100644 (file)
index 0000000..cd308f4
--- /dev/null
@@ -0,0 +1,24 @@
+#  SPDX-License-Identifier: LGPL-2.1-or-later
+#
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Enable Root File System Quotas
+Documentation=man:quotaon(8)
+
+ConditionPathExists=!/etc/initrd-release
+
+DefaultDependencies=no
+After=systemd-quotacheck-root.service
+Before=local-fs.target shutdown.target
+Conflicts=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart={{QUOTAON}} -ug /
similarity index 78%
rename from units/quotaon.service.in
rename to units/quotaon@.service.in
index 7fa7061eeaef01bdda4b2d4e1002da4f29bdd85b..136060a9a1738d9c18c96ea9b459c5dc5cadf1e8 100644 (file)
@@ -12,13 +12,15 @@ Description=Enable File System Quotas
 Documentation=man:quotaon(8)
 
 ConditionPathExists={{QUOTAON}}
+ConditionPathExists=!/etc/initrd-release
 
+After=%i.mount
+After=systemd-quotacheck@%i.service
 DefaultDependencies=no
-After=systemd-quotacheck.service
-Before=remote-fs.target
 Before=shutdown.target
+Conflicts=shutdown.target
 
 [Service]
 Type=oneshot
 RemainAfterExit=yes
-ExecStart={{QUOTAON}} -aug
+ExecStart={{QUOTAON}} -ug %f
index 8c01587cad81505c127616425f3e08c03db4a319..13c3985ed3c3521c20a531aa93c593e124aed332 100644 (file)
@@ -14,7 +14,7 @@ Documentation=man:systemd-journald.service(8) man:journald.conf(5)
 ConditionPathExists=!/etc/initrd-release
 
 DefaultDependencies=no
-After=systemd-remount-fs.service
+After=systemd-remount-fs.service systemd-quotacheck-root.service
 Before=systemd-tmpfiles-setup.service
 Wants=systemd-journald.service
 After=systemd-journald.service
diff --git a/units/systemd-quotacheck-root.service.in b/units/systemd-quotacheck-root.service.in
new file mode 100644 (file)
index 0000000..a182059
--- /dev/null
@@ -0,0 +1,25 @@
+#  SPDX-License-Identifier: LGPL-2.1-or-later
+#
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Root File System Quota Check
+Documentation=man:systemd-quotacheck.service(8)
+
+ConditionPathExists=!/etc/initrd-release
+
+DefaultDependencies=no
+After=systemd-remount-fs.service
+Before=local-fs.target shutdown.target
+Conflicts=shutdown.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart={{LIBEXECDIR}}/systemd-quotacheck /
+TimeoutSec=infinity
similarity index 81%
rename from units/systemd-quotacheck.service.in
rename to units/systemd-quotacheck@.service.in
index 0f94e382863c754ffbcd91862de518b888b37647..dddce2ee8320217a28397c5aca4ee80da31b3b41 100644 (file)
@@ -12,14 +12,15 @@ Description=File System Quota Check
 Documentation=man:systemd-quotacheck.service(8)
 
 ConditionPathExists={{QUOTACHECK}}
+ConditionPathExists=!/etc/initrd-release
 
 DefaultDependencies=no
-After=systemd-remount-fs.service
-Before=remote-fs.target
+After=%i.mount
 Before=shutdown.target
+Conflicts=shutdown.target
 
 [Service]
 Type=oneshot
 RemainAfterExit=yes
-ExecStart={{LIBEXECDIR}}/systemd-quotacheck
+ExecStart={{LIBEXECDIR}}/systemd-quotacheck %f
 TimeoutSec=infinity