summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Blume <tblume@suse.com>2022-09-19 16:57:48 +0200
committerLuca Boccassi <luca.boccassi@gmail.com>2024-03-09 20:32:09 +0100
commitfc5c6eccb4bdd5fa22c2f1118fc57a230409470a (patch)
tree69a9f3c38c332cd133d66359fae672e9ec47115a
parentcore/exec-invoke: Fix missing arguments for PR_SET_MEMORY_MERGE call (diff)
downloadsystemd-fc5c6eccb4bdd5fa22c2f1118fc57a230409470a.tar.xz
systemd-fc5c6eccb4bdd5fa22c2f1118fc57a230409470a.zip
units: make templates for quotaon and systemd-quotacheck service
-rw-r--r--src/basic/special.h6
-rw-r--r--src/core/mount.c46
-rw-r--r--src/fstab-generator/fstab-generator.c17
-rw-r--r--src/quotacheck/quotacheck.c19
-rw-r--r--src/shared/generator.c72
-rw-r--r--src/shared/generator.h10
-rw-r--r--units/meson.build12
-rw-r--r--units/quotaon-root.service.in24
-rw-r--r--units/quotaon@.service.in (renamed from units/quotaon.service.in)8
-rw-r--r--units/systemd-journal-flush.service2
-rw-r--r--units/systemd-quotacheck-root.service.in25
-rw-r--r--units/systemd-quotacheck@.service.in (renamed from units/systemd-quotacheck.service.in)7
12 files changed, 186 insertions, 62 deletions
diff --git a/src/basic/special.h b/src/basic/special.h
index 27d2c26e48..166737a9ca 100644
--- a/src/basic/special.h
+++ b/src/basic/special.h
@@ -84,8 +84,10 @@
#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"
diff --git a/src/core/mount.c b/src/core/mount.c
index 5090465f93..7dbf5f48f9 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -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;
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 4d65289bef..e4c8c9674c 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -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);
}
diff --git a/src/quotacheck/quotacheck.c b/src/quotacheck/quotacheck.c
index 27a914d737..c77e0d6143 100644
--- a/src/quotacheck/quotacheck.c
+++ b/src/quotacheck/quotacheck.c
@@ -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
};
diff --git a/src/shared/generator.c b/src/shared/generator.c
index b96715c59c..e03ed4b29f 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -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",
diff --git a/src/shared/generator.h b/src/shared/generator.h
index e5db1c17ce..baf1dafca3 100644
--- a/src/shared/generator.h
+++ b/src/shared/generator.h
@@ -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);
diff --git a/units/meson.build b/units/meson.build
index 936ebf7837..afe9ec7d1d 100644
--- a/units/meson.build
+++ b/units/meson.build
@@ -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
index 0000000000..cd308f43d9
--- /dev/null
+++ b/units/quotaon-root.service.in
@@ -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 /
diff --git a/units/quotaon.service.in b/units/quotaon@.service.in
index 7fa7061eea..136060a9a1 100644
--- a/units/quotaon.service.in
+++ b/units/quotaon@.service.in
@@ -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
diff --git a/units/systemd-journal-flush.service b/units/systemd-journal-flush.service
index 8c01587cad..13c3985ed3 100644
--- a/units/systemd-journal-flush.service
+++ b/units/systemd-journal-flush.service
@@ -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
index 0000000000..a182059376
--- /dev/null
+++ b/units/systemd-quotacheck-root.service.in
@@ -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
diff --git a/units/systemd-quotacheck.service.in b/units/systemd-quotacheck@.service.in
index 0f94e38286..dddce2ee83 100644
--- a/units/systemd-quotacheck.service.in
+++ b/units/systemd-quotacheck@.service.in
@@ -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