More legacy kernel support removal; follow-ups for XAT_FDROOT (#40384)
This commit is contained in:
@@ -50,9 +50,10 @@ REQUIREMENTS:
|
||||
≥ 5.6 for getrandom() GRND_INSECURE
|
||||
≥ 5.7 for CLONE_INTO_CGROUP, cgroup2fs memory_recursiveprot option,
|
||||
BPF links and the BPF LSM hook
|
||||
≥ 5.8 for LOOP_CONFIGURE and STATX_ATTR_MOUNT_ROOT
|
||||
≥ 5.8 for LOOP_CONFIGURE, STATX_ATTR_MOUNT_ROOT, and procfs
|
||||
per-instance hidepid=/subset= options
|
||||
≥ 5.9 for close_range()
|
||||
≥ 5.10 for STATX_MNT_ID
|
||||
≥ 5.10 for STATX_MNT_ID and MS_NOSYMFOLLOW mount option
|
||||
|
||||
⛔ Kernel versions below 5.10 ("minimum baseline") are not supported at all,
|
||||
and are missing required functionality as listed above.
|
||||
@@ -124,7 +125,8 @@ REQUIREMENTS:
|
||||
CONFIG_SECCOMP
|
||||
CONFIG_SECCOMP_FILTER (required for seccomp support)
|
||||
CONFIG_KCMP (for the kcmp() syscall, used to be under
|
||||
CONFIG_CHECKPOINT_RESTORE before ~5.12)
|
||||
CONFIG_CHECKPOINT_RESTORE before ~5.12;
|
||||
not needed after 6.10)
|
||||
CONFIG_NET_SCHED
|
||||
CONFIG_NET_SCH_FQ_CODEL
|
||||
|
||||
@@ -192,25 +194,12 @@ REQUIREMENTS:
|
||||
This is shipped by default, see modprobe.d/systemd.conf.
|
||||
|
||||
Required for systemd-nspawn:
|
||||
CONFIG_DEVPTS_MULTIPLE_INSTANCES or Linux kernel >= 4.7
|
||||
CONFIG_DEVPTS_MULTIPLE_INSTANCES (removed and unneeded since 4.7)
|
||||
|
||||
Required for systemd-oomd:
|
||||
CONFIG_PSI
|
||||
CONFIG_MEMCG
|
||||
|
||||
Note that kernel auditing is broken when used with systemd's container
|
||||
code. When using systemd in conjunction with containers, please make
|
||||
sure to either turn off auditing at runtime using the kernel command
|
||||
line option "audit=0", or turn it off at kernel compile time using:
|
||||
CONFIG_AUDIT=n
|
||||
|
||||
If systemd is compiled with libseccomp support on architectures which do
|
||||
not use socketcall() and where seccomp is supported (this effectively
|
||||
means x86-64 and ARM, but excludes 32-bit x86!), then nspawn will now
|
||||
install a work-around seccomp filter that makes containers boot even
|
||||
with audit being enabled. This works correctly only on kernels 3.14 and
|
||||
newer though. TL;DR: turn audit off, still.
|
||||
|
||||
glibc >= 2.31
|
||||
libxcrypt >= 4.4.0 (optional)
|
||||
libmount >= 2.30 (from util-linux)
|
||||
|
||||
@@ -107,8 +107,6 @@ Deprecations and removals:
|
||||
* drop support for LOOP_CONFIGURE-less loopback block devices, once kernel
|
||||
baseline is 5.8.
|
||||
|
||||
* Once baseline is 5.10, remove support or MS_NOSYMFOLLOW-less kernels
|
||||
|
||||
* Remove /dev/mem ACPI FPDT parsing when /sys/firmware/acpi/fpdt is ubiquitous.
|
||||
That requires distros to enable CONFIG_ACPI_FPDT, and have kernels v5.12 for
|
||||
x86 and v6.2 for arm.
|
||||
@@ -122,10 +120,6 @@ Deprecations and removals:
|
||||
https://github.com/util-linux/util-linux/commit/508fb0e7ac103b68531a59db2a4473897853ab52
|
||||
has hit the prominent distributions, revert --issue-file= hack in units/*getty*service.in
|
||||
|
||||
* Once kernel baseline is 5.7, obsolete DefaultMemoryMin/Low= and DefaultStartupMemoryLow=
|
||||
since we can systematically enable memory_recursiveprot on cgroupfs and have those
|
||||
enforced by the kernel
|
||||
|
||||
Features:
|
||||
|
||||
* systemd-sysupdate: add support a "best before" in manifests (ie. SHA256SUMS)
|
||||
|
||||
@@ -2969,12 +2969,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b MemoryAccounting = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultMemoryLow = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultStartupMemoryLow = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultMemoryMin = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryMin = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryLow = ...;
|
||||
@@ -3642,12 +3636,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<!--property MemoryAccounting is not documented!-->
|
||||
|
||||
<!--property DefaultMemoryLow is not documented!-->
|
||||
|
||||
<!--property DefaultStartupMemoryLow is not documented!-->
|
||||
|
||||
<!--property DefaultMemoryMin is not documented!-->
|
||||
|
||||
<!--property MemoryMin is not documented!-->
|
||||
|
||||
<!--property MemoryLow is not documented!-->
|
||||
@@ -4336,12 +4324,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryAccounting"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryLow"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultStartupMemoryLow"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryMin"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryMin"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryLow"/>
|
||||
@@ -5238,12 +5220,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b MemoryAccounting = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultMemoryLow = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultStartupMemoryLow = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultMemoryMin = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryMin = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryLow = ...;
|
||||
@@ -5929,12 +5905,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
||||
|
||||
<!--property MemoryAccounting is not documented!-->
|
||||
|
||||
<!--property DefaultMemoryLow is not documented!-->
|
||||
|
||||
<!--property DefaultStartupMemoryLow is not documented!-->
|
||||
|
||||
<!--property DefaultMemoryMin is not documented!-->
|
||||
|
||||
<!--property MemoryMin is not documented!-->
|
||||
|
||||
<!--property MemoryLow is not documented!-->
|
||||
@@ -6599,12 +6569,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryAccounting"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryLow"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultStartupMemoryLow"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryMin"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryMin"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryLow"/>
|
||||
@@ -7325,12 +7289,6 @@ node /org/freedesktop/systemd1/unit/home_2emount {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b MemoryAccounting = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultMemoryLow = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultStartupMemoryLow = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultMemoryMin = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryMin = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryLow = ...;
|
||||
@@ -7940,12 +7898,6 @@ node /org/freedesktop/systemd1/unit/home_2emount {
|
||||
|
||||
<!--property MemoryAccounting is not documented!-->
|
||||
|
||||
<!--property DefaultMemoryLow is not documented!-->
|
||||
|
||||
<!--property DefaultStartupMemoryLow is not documented!-->
|
||||
|
||||
<!--property DefaultMemoryMin is not documented!-->
|
||||
|
||||
<!--property MemoryMin is not documented!-->
|
||||
|
||||
<!--property MemoryLow is not documented!-->
|
||||
@@ -8518,12 +8470,6 @@ node /org/freedesktop/systemd1/unit/home_2emount {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryAccounting"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryLow"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultStartupMemoryLow"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryMin"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryMin"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryLow"/>
|
||||
@@ -9377,12 +9323,6 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b MemoryAccounting = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultMemoryLow = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultStartupMemoryLow = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultMemoryMin = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryMin = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryLow = ...;
|
||||
@@ -9974,12 +9914,6 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
|
||||
|
||||
<!--property MemoryAccounting is not documented!-->
|
||||
|
||||
<!--property DefaultMemoryLow is not documented!-->
|
||||
|
||||
<!--property DefaultStartupMemoryLow is not documented!-->
|
||||
|
||||
<!--property DefaultMemoryMin is not documented!-->
|
||||
|
||||
<!--property MemoryMin is not documented!-->
|
||||
|
||||
<!--property MemoryLow is not documented!-->
|
||||
@@ -10534,12 +10468,6 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryAccounting"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryLow"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultStartupMemoryLow"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryMin"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryMin"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryLow"/>
|
||||
@@ -11246,12 +11174,6 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b MemoryAccounting = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultMemoryLow = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultStartupMemoryLow = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultMemoryMin = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryMin = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryLow = ...;
|
||||
@@ -11427,12 +11349,6 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
|
||||
|
||||
<!--property MemoryAccounting is not documented!-->
|
||||
|
||||
<!--property DefaultMemoryLow is not documented!-->
|
||||
|
||||
<!--property DefaultStartupMemoryLow is not documented!-->
|
||||
|
||||
<!--property DefaultMemoryMin is not documented!-->
|
||||
|
||||
<!--property MemoryMin is not documented!-->
|
||||
|
||||
<!--property MemoryLow is not documented!-->
|
||||
@@ -11619,12 +11535,6 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryAccounting"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryLow"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultStartupMemoryLow"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryMin"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryMin"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryLow"/>
|
||||
@@ -11836,12 +11746,6 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b MemoryAccounting = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultMemoryLow = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultStartupMemoryLow = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultMemoryMin = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryMin = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryLow = ...;
|
||||
@@ -12031,12 +11935,6 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
|
||||
|
||||
<!--property MemoryAccounting is not documented!-->
|
||||
|
||||
<!--property DefaultMemoryLow is not documented!-->
|
||||
|
||||
<!--property DefaultStartupMemoryLow is not documented!-->
|
||||
|
||||
<!--property DefaultMemoryMin is not documented!-->
|
||||
|
||||
<!--property MemoryMin is not documented!-->
|
||||
|
||||
<!--property MemoryLow is not documented!-->
|
||||
@@ -12247,12 +12145,6 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryAccounting"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryLow"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultStartupMemoryLow"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryMin"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryMin"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryLow"/>
|
||||
|
||||
@@ -326,7 +326,7 @@ CPUWeight=20 DisableControllers=cpu / \
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>MemoryMin=<replaceable>bytes</replaceable></varname>, <varname>MemoryLow=<replaceable>bytes</replaceable></varname></term>
|
||||
<term><varname>StartupMemoryLow=<replaceable>bytes</replaceable></varname>, <varname>DefaultStartupMemoryLow=<replaceable>bytes</replaceable></varname></term>
|
||||
<term><varname>StartupMemoryLow=<replaceable>bytes</replaceable></varname></term>
|
||||
|
||||
<listitem>
|
||||
<para>These settings control the <option>memory</option> controller in the unified hierarchy.</para>
|
||||
@@ -353,16 +353,6 @@ CPUWeight=20 DisableControllers=cpu / \
|
||||
For details about this control group attribute, see <ulink
|
||||
url="https://docs.kernel.org/admin-guide/cgroup-v2.html#memory-interface-files">Memory Interface Files</ulink>.</para>
|
||||
|
||||
<para>Units may have their children use a default <literal>memory.min</literal> or
|
||||
<literal>memory.low</literal> value by specifying <varname>DefaultMemoryMin=</varname> or
|
||||
<varname>DefaultMemoryLow=</varname>, which has the same semantics as
|
||||
<varname>MemoryMin=</varname> and <varname>MemoryLow=</varname>, or <varname>DefaultStartupMemoryLow=</varname>
|
||||
which has the same semantics as <varname>StartupMemoryLow=</varname>.
|
||||
This setting does not affect <literal>memory.min</literal> or <literal>memory.low</literal>
|
||||
in the unit itself.
|
||||
Using it to set a default child allocation is only useful on kernels older than 5.7,
|
||||
which do not support the <literal>memory_recursiveprot</literal> cgroup2 mount option.</para>
|
||||
|
||||
<para>While <varname>StartupMemoryLow=</varname> applies to the startup and shutdown phases of the system,
|
||||
<varname>MemoryMin=</varname> applies to normal runtime of the system, and if the former is not set also to
|
||||
the startup and shutdown phases. Using <varname>StartupMemoryLow=</varname> allows prioritizing specific services at
|
||||
|
||||
@@ -18,9 +18,6 @@ TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
|
||||
# The openSUSE filelists hardcode the manpage compression extension. This causes rpmbuild errors since we
|
||||
# disable manpage compression as the files cannot be found. Fix the issue by removing the compression
|
||||
# extension.
|
||||
#
|
||||
# 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 \
|
||||
-e 's/\.gz$//' \
|
||||
|
||||
+27
-57
@@ -321,22 +321,7 @@ int futimens_opath(int fd, const struct timespec ts[2]) {
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
if (utimensat(fd, "", ts, AT_EMPTY_PATH) >= 0)
|
||||
return 0;
|
||||
if (errno != EINVAL)
|
||||
return -errno;
|
||||
|
||||
/* Support for AT_EMPTY_PATH is added rather late (kernel 5.8), so fall back to going through /proc/
|
||||
* if unavailable. */
|
||||
|
||||
if (utimensat(AT_FDCWD, FORMAT_PROC_FD_PATH(fd), ts, /* flags= */ 0) < 0) {
|
||||
if (errno != ENOENT)
|
||||
return -errno;
|
||||
|
||||
return proc_fd_enoent_errno();
|
||||
}
|
||||
|
||||
return 0;
|
||||
return RET_NERRNO(utimensat(fd, "", ts, AT_EMPTY_PATH));
|
||||
}
|
||||
|
||||
int stat_warn_permissions(const char *path, const struct stat *st) {
|
||||
@@ -375,6 +360,19 @@ int access_nofollow(const char *path, int mode) {
|
||||
return RET_NERRNO(faccessat(AT_FDCWD, path, mode, AT_SYMLINK_NOFOLLOW));
|
||||
}
|
||||
|
||||
int access_fd(int fd, int mode) {
|
||||
/* Like access() but operates on an already open fd */
|
||||
|
||||
if (fd == AT_FDCWD)
|
||||
return RET_NERRNO(access(".", mode));
|
||||
if (fd == XAT_FDROOT)
|
||||
return RET_NERRNO(access("/", mode));
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
return RET_NERRNO(faccessat(fd, "", mode, AT_EMPTY_PATH));
|
||||
}
|
||||
|
||||
int touch_fd(int fd, usec_t stamp) {
|
||||
assert(fd >= 0);
|
||||
|
||||
@@ -712,34 +710,6 @@ char* unlink_and_free(char *p) {
|
||||
return mfree(p);
|
||||
}
|
||||
|
||||
int access_fd(int fd, int mode) {
|
||||
/* Like access() but operates on an already open fd */
|
||||
|
||||
if (fd == AT_FDCWD)
|
||||
return RET_NERRNO(access(".", mode));
|
||||
if (fd == XAT_FDROOT)
|
||||
return RET_NERRNO(access("/", mode));
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
if (faccessat(fd, "", mode, AT_EMPTY_PATH) >= 0)
|
||||
return 0;
|
||||
if (errno != EINVAL)
|
||||
return -errno;
|
||||
|
||||
/* Support for AT_EMPTY_PATH is added rather late (kernel 5.8), so fall back to going through /proc/
|
||||
* if unavailable. */
|
||||
|
||||
if (access(FORMAT_PROC_FD_PATH(fd), mode) < 0) {
|
||||
if (errno != ENOENT)
|
||||
return -errno;
|
||||
|
||||
return proc_fd_enoent_errno();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int unlinkat_deallocate(int fd, const char *name, UnlinkDeallocateFlags flags) {
|
||||
_cleanup_close_ int truncate_fd = -EBADF;
|
||||
struct stat st;
|
||||
@@ -1188,19 +1158,6 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_
|
||||
* • The dir fd can be passed as XAT_FDROOT, in which case any relative paths will be taken relative to the root fs.
|
||||
*/
|
||||
|
||||
_cleanup_close_ int _dir_fd = -EBADF;
|
||||
if (dir_fd == XAT_FDROOT) {
|
||||
if (path_is_absolute(path))
|
||||
dir_fd = AT_FDCWD;
|
||||
else {
|
||||
_dir_fd = open("/", O_CLOEXEC|O_DIRECTORY|O_RDONLY);
|
||||
if (_dir_fd < 0)
|
||||
return -errno;
|
||||
|
||||
dir_fd = _dir_fd;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == MODE_INVALID)
|
||||
mode = (open_flags & O_DIRECTORY) ? 0755 : 0644;
|
||||
|
||||
@@ -1216,6 +1173,19 @@ int xopenat_full(int dir_fd, const char *path, int open_flags, XOpenFlags xopen_
|
||||
return fd_reopen(dir_fd, open_flags & ~O_NOFOLLOW);
|
||||
}
|
||||
|
||||
_cleanup_close_ int _dir_fd = -EBADF;
|
||||
if (dir_fd == XAT_FDROOT) {
|
||||
if (path_is_absolute(path))
|
||||
dir_fd = AT_FDCWD;
|
||||
else {
|
||||
_dir_fd = open("/", O_CLOEXEC|O_DIRECTORY|O_PATH);
|
||||
if (_dir_fd < 0)
|
||||
return -errno;
|
||||
|
||||
dir_fd = _dir_fd;
|
||||
}
|
||||
}
|
||||
|
||||
bool call_label_ops_post = false;
|
||||
|
||||
if (FLAGS_SET(open_flags, O_CREAT) && FLAGS_SET(xopen_flags, XO_LABEL)) {
|
||||
|
||||
+1
-2
@@ -42,6 +42,7 @@ int fd_warn_permissions(const char *path, int fd);
|
||||
int stat_warn_permissions(const char *path, const struct stat *st);
|
||||
|
||||
int access_nofollow(const char *path, int mode);
|
||||
int access_fd(int fd, int mode);
|
||||
|
||||
int touch_fd(int fd, usec_t stamp);
|
||||
int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode);
|
||||
@@ -86,8 +87,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(char*, rmdir_and_free);
|
||||
char* unlink_and_free(char *p);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(char*, unlink_and_free);
|
||||
|
||||
int access_fd(int fd, int mode);
|
||||
|
||||
typedef enum UnlinkDeallocateFlags {
|
||||
UNLINK_REMOVEDIR = 1 << 0,
|
||||
UNLINK_ERASE = 1 << 1,
|
||||
|
||||
@@ -529,66 +529,6 @@ bool mount_new_api_supported(void) {
|
||||
return (cache = true);
|
||||
}
|
||||
|
||||
unsigned long ms_nosymfollow_supported(void) {
|
||||
_cleanup_close_ int fsfd = -EBADF, mntfd = -EBADF;
|
||||
static int cache = -1;
|
||||
|
||||
/* Returns MS_NOSYMFOLLOW if it is supported, zero otherwise. */
|
||||
|
||||
if (cache >= 0)
|
||||
return cache ? MS_NOSYMFOLLOW : 0;
|
||||
|
||||
if (!mount_new_api_supported())
|
||||
goto not_supported;
|
||||
|
||||
/* Checks if MS_NOSYMFOLLOW is supported (which was added in 5.10). We use the new mount API's
|
||||
* mount_setattr() call for that, which was added in 5.12, which is close enough. */
|
||||
|
||||
fsfd = fsopen("tmpfs", FSOPEN_CLOEXEC);
|
||||
if (fsfd < 0) {
|
||||
if (ERRNO_IS_NOT_SUPPORTED(errno))
|
||||
goto not_supported;
|
||||
|
||||
log_debug_errno(errno, "Failed to open superblock context for tmpfs: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fsconfig(fsfd, FSCONFIG_CMD_CREATE, NULL, NULL, 0) < 0) {
|
||||
if (ERRNO_IS_NOT_SUPPORTED(errno))
|
||||
goto not_supported;
|
||||
|
||||
log_debug_errno(errno, "Failed to create tmpfs superblock: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mntfd = fsmount(fsfd, FSMOUNT_CLOEXEC, 0);
|
||||
if (mntfd < 0) {
|
||||
if (ERRNO_IS_NOT_SUPPORTED(errno))
|
||||
goto not_supported;
|
||||
|
||||
log_debug_errno(errno, "Failed to turn superblock fd into mount fd: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mount_setattr(mntfd, "", AT_EMPTY_PATH|AT_RECURSIVE,
|
||||
&(struct mount_attr) {
|
||||
.attr_set = MOUNT_ATTR_NOSYMFOLLOW,
|
||||
}, sizeof(struct mount_attr)) < 0) {
|
||||
if (ERRNO_IS_NOT_SUPPORTED(errno))
|
||||
goto not_supported;
|
||||
|
||||
log_debug_errno(errno, "Failed to set MOUNT_ATTR_NOSYMFOLLOW mount attribute: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cache = true;
|
||||
return MS_NOSYMFOLLOW;
|
||||
|
||||
not_supported:
|
||||
cache = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mount_option_supported(const char *fstype, const char *key, const char *value) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
int r;
|
||||
|
||||
@@ -75,7 +75,6 @@ int mount_propagation_flag_from_string(const char *name, unsigned long *ret);
|
||||
bool mount_propagation_flag_is_valid(unsigned long flag);
|
||||
|
||||
bool mount_new_api_supported(void);
|
||||
unsigned long ms_nosymfollow_supported(void);
|
||||
|
||||
int mount_option_supported(const char *fstype, const char *key, const char *value);
|
||||
|
||||
|
||||
@@ -36,8 +36,7 @@ int readdir_all(int dir_fd, RecurseDirFlags flags, DirectoryEntries **ret) {
|
||||
|
||||
assert(dir_fd >= 0);
|
||||
|
||||
/* Returns an array with pointers to "struct dirent" directory entries, optionally sorted. Free the
|
||||
* array with readdir_all_freep().
|
||||
/* Returns an array with pointers to "struct dirent" directory entries, optionally sorted.
|
||||
*
|
||||
* Start with space for up to 8 directory entries. We expect at least 2 ("." + ".."), hence hopefully
|
||||
* 8 will cover most cases comprehensively. (Note that most likely a lot more entries will actually
|
||||
|
||||
+16
-16
@@ -257,6 +257,22 @@ static int xfstatfs(int fd, struct statfs *ret) {
|
||||
return RET_NERRNO(fstatfs(fd, ret));
|
||||
}
|
||||
|
||||
int xstatfsat(int dir_fd, const char *path, struct statfs *ret) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
|
||||
assert(dir_fd >= 0 || IN_SET(dir_fd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(ret);
|
||||
|
||||
if (!isempty(path)) {
|
||||
fd = xopenat(dir_fd, path, O_PATH|O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
dir_fd = fd;
|
||||
}
|
||||
|
||||
return xfstatfs(dir_fd, ret);
|
||||
}
|
||||
|
||||
int fd_is_read_only_fs(int fd) {
|
||||
int r;
|
||||
|
||||
@@ -522,22 +538,6 @@ bool statx_mount_same(const struct statx *a, const struct statx *b) {
|
||||
return a->stx_mnt_id == b->stx_mnt_id;
|
||||
}
|
||||
|
||||
int xstatfsat(int dir_fd, const char *path, struct statfs *ret) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
|
||||
assert(dir_fd >= 0 || IN_SET(dir_fd, AT_FDCWD, XAT_FDROOT));
|
||||
assert(ret);
|
||||
|
||||
if (!isempty(path)) {
|
||||
fd = xopenat(dir_fd, path, O_PATH|O_CLOEXEC|O_NOCTTY);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
dir_fd = fd;
|
||||
}
|
||||
|
||||
return RET_NERRNO(xfstatfs(dir_fd, ret));
|
||||
}
|
||||
|
||||
usec_t statx_timestamp_load(const struct statx_timestamp *ts) {
|
||||
return timespec_load(&(const struct timespec) { .tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec });
|
||||
}
|
||||
|
||||
+21
-83
@@ -330,13 +330,13 @@ static int unit_compare_memory_limit(Unit *u, const char *property_name, uint64_
|
||||
bool startup = u->manager && IN_SET(manager_state(u->manager), MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING);
|
||||
|
||||
if (streq(property_name, "MemoryLow")) {
|
||||
unit_value = unit_get_ancestor_memory_low(u);
|
||||
unit_value = c->memory_low;
|
||||
file = "memory.low";
|
||||
} else if (startup && streq(property_name, "StartupMemoryLow")) {
|
||||
unit_value = unit_get_ancestor_startup_memory_low(u);
|
||||
unit_value = c->startup_memory_low;
|
||||
file = "memory.low";
|
||||
} else if (streq(property_name, "MemoryMin")) {
|
||||
unit_value = unit_get_ancestor_memory_min(u);
|
||||
unit_value = c->memory_min;
|
||||
file = "memory.min";
|
||||
} else if (streq(property_name, "MemoryHigh")) {
|
||||
unit_value = c->memory_high;
|
||||
@@ -504,8 +504,6 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||||
"%sStartupAllowedMemoryNodes: %s\n"
|
||||
"%sIOWeight: %" PRIu64 "\n"
|
||||
"%sStartupIOWeight: %" PRIu64 "\n"
|
||||
"%sDefaultMemoryMin: %" PRIu64 "\n"
|
||||
"%sDefaultMemoryLow: %" PRIu64 "\n"
|
||||
"%sMemoryMin: %" PRIu64 "%s\n"
|
||||
"%sMemoryLow: %" PRIu64 "%s\n"
|
||||
"%sStartupMemoryLow: %" PRIu64 "%s\n"
|
||||
@@ -542,8 +540,6 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||||
prefix, strempty(startup_cpuset_mems),
|
||||
prefix, c->io_weight,
|
||||
prefix, c->startup_io_weight,
|
||||
prefix, c->default_memory_min,
|
||||
prefix, c->default_memory_low,
|
||||
prefix, c->memory_min, format_cgroup_memory_limit_comparison(u, "MemoryMin", cda, sizeof(cda)),
|
||||
prefix, c->memory_low, format_cgroup_memory_limit_comparison(u, "MemoryLow", cdb, sizeof(cdb)),
|
||||
prefix, c->startup_memory_low, format_cgroup_memory_limit_comparison(u, "StartupMemoryLow", cdc, sizeof(cdc)),
|
||||
@@ -764,36 +760,6 @@ int cgroup_context_add_bpf_foreign_program(CGroupContext *c, uint32_t attach_typ
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP(entry) \
|
||||
uint64_t unit_get_ancestor_##entry(Unit *u) { \
|
||||
CGroupContext *c; \
|
||||
\
|
||||
/* 1. Is entry set in this unit? If so, use that. \
|
||||
* 2. Is the default for this entry set in any \
|
||||
* ancestor? If so, use that. \
|
||||
* 3. Otherwise, return CGROUP_LIMIT_MIN. */ \
|
||||
\
|
||||
assert(u); \
|
||||
\
|
||||
c = unit_get_cgroup_context(u); \
|
||||
if (c && c->entry##_set) \
|
||||
return c->entry; \
|
||||
\
|
||||
while ((u = UNIT_GET_SLICE(u))) { \
|
||||
c = unit_get_cgroup_context(u); \
|
||||
if (c && c->default_##entry##_set) \
|
||||
return c->default_##entry; \
|
||||
} \
|
||||
\
|
||||
/* We've reached the root, but nobody had default for \
|
||||
* this entry set, so set it to the kernel default. */ \
|
||||
return CGROUP_LIMIT_MIN; \
|
||||
}
|
||||
|
||||
UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP(memory_low);
|
||||
UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP(startup_memory_low);
|
||||
UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP(memory_min);
|
||||
|
||||
static void unit_set_xattr_graceful(Unit *u, const char *name, const void *data, size_t size) {
|
||||
int r;
|
||||
|
||||
@@ -944,39 +910,12 @@ static void cgroup_delegate_xattr_apply(Unit *u) {
|
||||
}
|
||||
|
||||
static void cgroup_survive_xattr_apply(Unit *u) {
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
|
||||
CGroupRuntime *crt = unit_get_cgroup_runtime(u);
|
||||
if (!crt)
|
||||
return;
|
||||
|
||||
if (u->survive_final_kill_signal) {
|
||||
r = cg_set_xattr(
|
||||
crt->cgroup_path,
|
||||
"user.survive_final_kill_signal",
|
||||
"1",
|
||||
1,
|
||||
/* flags= */ 0);
|
||||
/* user xattr support was added in kernel v5.7 */
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
|
||||
r = cg_set_xattr(
|
||||
crt->cgroup_path,
|
||||
"trusted.survive_final_kill_signal",
|
||||
"1",
|
||||
1,
|
||||
/* flags= */ 0);
|
||||
if (r < 0)
|
||||
log_unit_debug_errno(u,
|
||||
r,
|
||||
"Failed to set 'survive_final_kill_signal' xattr on control "
|
||||
"group %s, ignoring: %m",
|
||||
empty_to_root(crt->cgroup_path));
|
||||
} else {
|
||||
if (u->survive_final_kill_signal)
|
||||
unit_set_xattr_graceful(u, "user.survive_final_kill_signal", "1", 1);
|
||||
else
|
||||
unit_remove_xattr_graceful(u, "user.survive_final_kill_signal");
|
||||
unit_remove_xattr_graceful(u, "trusted.survive_final_kill_signal");
|
||||
}
|
||||
}
|
||||
|
||||
static void cgroup_xattr_apply(Unit *u) {
|
||||
@@ -1177,8 +1116,9 @@ static void cgroup_apply_cpuset(Unit *u, const CPUSet *cpus, const char *name) {
|
||||
}
|
||||
|
||||
static bool cgroup_context_has_io_config(CGroupContext *c) {
|
||||
return c->io_accounting ||
|
||||
c->io_weight != CGROUP_WEIGHT_INVALID ||
|
||||
assert(c);
|
||||
|
||||
return c->io_weight != CGROUP_WEIGHT_INVALID ||
|
||||
c->startup_io_weight != CGROUP_WEIGHT_INVALID ||
|
||||
c->io_device_weights ||
|
||||
c->io_device_latencies ||
|
||||
@@ -1289,15 +1229,11 @@ static void cgroup_apply_io_device_limit(Unit *u, const char *dev_path, uint64_t
|
||||
(void) set_attribute_and_warn(u, "io.max", buf);
|
||||
}
|
||||
|
||||
static bool unit_has_memory_config(Unit *u) {
|
||||
CGroupContext *c;
|
||||
static bool cgroup_context_has_memory_config(CGroupContext *c) {
|
||||
assert(c);
|
||||
|
||||
assert(u);
|
||||
|
||||
assert_se(c = unit_get_cgroup_context(u));
|
||||
|
||||
return unit_get_ancestor_memory_min(u) > 0 ||
|
||||
unit_get_ancestor_memory_low(u) > 0 || unit_get_ancestor_startup_memory_low(u) > 0 ||
|
||||
return c->memory_min > 0 ||
|
||||
c->memory_low > 0 || c->startup_memory_low_set ||
|
||||
c->memory_high != CGROUP_LIMIT_MAX || c->startup_memory_high_set ||
|
||||
c->memory_max != CGROUP_LIMIT_MAX || c->startup_memory_max_set ||
|
||||
c->memory_swap_max != CGROUP_LIMIT_MAX || c->startup_memory_swap_max_set ||
|
||||
@@ -1543,19 +1479,20 @@ static void cgroup_context_apply(
|
||||
|
||||
/* 'memory' attributes do not exist on the root cgroup. */
|
||||
if ((apply_mask & CGROUP_MASK_MEMORY) && !is_local_root) {
|
||||
uint64_t max = CGROUP_LIMIT_MAX, swap_max = CGROUP_LIMIT_MAX, zswap_max = CGROUP_LIMIT_MAX, high = CGROUP_LIMIT_MAX;
|
||||
uint64_t low = CGROUP_LIMIT_MIN, max = CGROUP_LIMIT_MAX, swap_max = CGROUP_LIMIT_MAX, zswap_max = CGROUP_LIMIT_MAX, high = CGROUP_LIMIT_MAX;
|
||||
|
||||
if (unit_has_memory_config(u)) {
|
||||
if (cgroup_context_has_memory_config(c)) {
|
||||
bool startup = IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING);
|
||||
|
||||
low = startup && c->startup_memory_low_set ? c->startup_memory_low : c->memory_low;
|
||||
high = startup && c->startup_memory_high_set ? c->startup_memory_high : c->memory_high;
|
||||
max = startup && c->startup_memory_max_set ? c->startup_memory_max : c->memory_max;
|
||||
swap_max = startup && c->startup_memory_swap_max_set ? c->startup_memory_swap_max : c->memory_swap_max;
|
||||
zswap_max = startup && c->startup_memory_zswap_max_set ? c->startup_memory_zswap_max : c->memory_zswap_max;
|
||||
}
|
||||
|
||||
cgroup_apply_memory_limit(u, "memory.min", unit_get_ancestor_memory_min(u));
|
||||
cgroup_apply_memory_limit(u, "memory.low", unit_get_ancestor_memory_low(u));
|
||||
cgroup_apply_memory_limit(u, "memory.min", c->memory_min);
|
||||
cgroup_apply_memory_limit(u, "memory.low", low);
|
||||
cgroup_apply_memory_limit(u, "memory.high", high);
|
||||
cgroup_apply_memory_limit(u, "memory.max", max);
|
||||
cgroup_apply_memory_limit(u, "memory.swap.max", swap_max);
|
||||
@@ -1718,11 +1655,12 @@ static CGroupMask unit_get_cgroup_mask(Unit *u) {
|
||||
if (cgroup_context_has_allowed_cpus(c) || cgroup_context_has_allowed_mems(c))
|
||||
mask |= CGROUP_MASK_CPUSET;
|
||||
|
||||
if (cgroup_context_has_io_config(c))
|
||||
if (c->io_accounting ||
|
||||
cgroup_context_has_io_config(c))
|
||||
mask |= CGROUP_MASK_IO;
|
||||
|
||||
if (c->memory_accounting ||
|
||||
unit_has_memory_config(u))
|
||||
cgroup_context_has_memory_config(c))
|
||||
mask |= CGROUP_MASK_MEMORY;
|
||||
|
||||
if (cgroup_context_has_device_policy(c))
|
||||
|
||||
@@ -137,9 +137,6 @@ typedef struct CGroupContext {
|
||||
LIST_HEAD(CGroupIODeviceLimit, io_device_limits);
|
||||
LIST_HEAD(CGroupIODeviceLatency, io_device_latencies);
|
||||
|
||||
uint64_t default_memory_min;
|
||||
uint64_t default_memory_low;
|
||||
uint64_t default_startup_memory_low;
|
||||
uint64_t memory_min;
|
||||
uint64_t memory_low;
|
||||
uint64_t startup_memory_low;
|
||||
@@ -152,11 +149,6 @@ typedef struct CGroupContext {
|
||||
uint64_t memory_zswap_max;
|
||||
uint64_t startup_memory_zswap_max;
|
||||
|
||||
bool default_memory_min_set:1;
|
||||
bool default_memory_low_set:1;
|
||||
bool default_startup_memory_low_set:1;
|
||||
bool memory_min_set:1;
|
||||
bool memory_low_set:1;
|
||||
bool startup_memory_low_set:1;
|
||||
bool startup_memory_high_set:1;
|
||||
bool startup_memory_max_set:1;
|
||||
@@ -416,10 +408,6 @@ Unit* manager_get_unit_by_pidref_cgroup(Manager *m, const PidRef *pid);
|
||||
Unit* manager_get_unit_by_pidref_watching(Manager *m, const PidRef *pid);
|
||||
Unit* manager_get_unit_by_pidref(Manager *m, PidRef *pid);
|
||||
|
||||
uint64_t unit_get_ancestor_memory_min(Unit *u);
|
||||
uint64_t unit_get_ancestor_memory_low(Unit *u);
|
||||
uint64_t unit_get_ancestor_startup_memory_low(Unit *u);
|
||||
|
||||
int unit_search_main_pid(Unit *u, PidRef *ret);
|
||||
|
||||
int unit_get_memory_available(Unit *u, uint64_t *ret);
|
||||
|
||||
+20
-64
@@ -395,9 +395,6 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
|
||||
SD_BUS_PROPERTY("IOWriteIOPSMax", "a(st)", property_get_io_device_limits, 0, 0),
|
||||
SD_BUS_PROPERTY("IODeviceLatencyTargetUSec", "a(st)", property_get_io_device_latency, 0, 0),
|
||||
SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, memory_accounting), 0),
|
||||
SD_BUS_PROPERTY("DefaultMemoryLow", "t", NULL, offsetof(CGroupContext, default_memory_low), 0),
|
||||
SD_BUS_PROPERTY("DefaultStartupMemoryLow", "t", NULL, offsetof(CGroupContext, default_startup_memory_low), 0),
|
||||
SD_BUS_PROPERTY("DefaultMemoryMin", "t", NULL, offsetof(CGroupContext, default_memory_min), 0),
|
||||
SD_BUS_PROPERTY("MemoryMin", "t", NULL, offsetof(CGroupContext, memory_min), 0),
|
||||
SD_BUS_PROPERTY("MemoryLow", "t", NULL, offsetof(CGroupContext, memory_low), 0),
|
||||
SD_BUS_PROPERTY("StartupMemoryLow", "t", NULL, offsetof(CGroupContext, startup_memory_low), 0),
|
||||
@@ -447,6 +444,10 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
|
||||
SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_ast, 0, SD_BUS_VTABLE_DEPRECATED|SD_BUS_VTABLE_HIDDEN),
|
||||
/* since kernel v4.15 CPU accounting requires no controller, i.e. is available everywhere */
|
||||
SD_BUS_PROPERTY("CPUAccounting", "b", bus_property_get_bool_true, 0, SD_BUS_VTABLE_DEPRECATED|SD_BUS_VTABLE_HIDDEN),
|
||||
/* since kernel v5.7 kernel would take care of these when cgroup is mounted with memory_recursiveprot */
|
||||
SD_BUS_PROPERTY("DefaultMemoryMin", "t", bus_property_get_uint64_0, 0, SD_BUS_VTABLE_DEPRECATED|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("DefaultMemoryLow", "t", bus_property_get_uint64_0, 0, SD_BUS_VTABLE_DEPRECATED|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("DefaultStartupMemoryLow", "t", bus_property_get_uint64_0, 0, SD_BUS_VTABLE_DEPRECATED|SD_BUS_VTABLE_HIDDEN),
|
||||
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
@@ -1053,19 +1054,11 @@ int bus_cgroup_set_property(
|
||||
if (streq(name, "MemoryAccounting"))
|
||||
return bus_cgroup_set_boolean(u, name, &c->memory_accounting, CGROUP_MASK_MEMORY, message, flags, reterr_error);
|
||||
|
||||
if (streq(name, "MemoryMin")) {
|
||||
r = bus_cgroup_set_memory_protection(u, name, &c->memory_min, message, flags, reterr_error);
|
||||
if (r > 0)
|
||||
c->memory_min_set = true;
|
||||
return r;
|
||||
}
|
||||
if (streq(name, "MemoryMin"))
|
||||
return bus_cgroup_set_memory_protection(u, name, &c->memory_min, message, flags, reterr_error);
|
||||
|
||||
if (streq(name, "MemoryLow")) {
|
||||
r = bus_cgroup_set_memory_protection(u, name, &c->memory_low, message, flags, reterr_error);
|
||||
if (r > 0)
|
||||
c->memory_low_set = true;
|
||||
return r;
|
||||
}
|
||||
if (streq(name, "MemoryLow"))
|
||||
return bus_cgroup_set_memory_protection(u, name, &c->memory_low, message, flags, reterr_error);
|
||||
|
||||
if (streq(name, "StartupMemoryLow")) {
|
||||
r = bus_cgroup_set_memory_protection(u, name, &c->startup_memory_low, message, flags, reterr_error);
|
||||
@@ -1074,27 +1067,6 @@ int bus_cgroup_set_property(
|
||||
return r;
|
||||
}
|
||||
|
||||
if (streq(name, "DefaultMemoryMin")) {
|
||||
r = bus_cgroup_set_memory_protection(u, name, &c->default_memory_min, message, flags, reterr_error);
|
||||
if (r > 0)
|
||||
c->default_memory_min_set = true;
|
||||
return r;
|
||||
}
|
||||
|
||||
if (streq(name, "DefaultMemoryLow")) {
|
||||
r = bus_cgroup_set_memory_protection(u, name, &c->default_memory_low, message, flags, reterr_error);
|
||||
if (r > 0)
|
||||
c->default_memory_low_set = true;
|
||||
return r;
|
||||
}
|
||||
|
||||
if (streq(name, "DefaultStartupMemoryLow")) {
|
||||
r = bus_cgroup_set_memory_protection(u, name, &c->default_startup_memory_low, message, flags, reterr_error);
|
||||
if (r > 0)
|
||||
c->default_startup_memory_low_set = true;
|
||||
return r;
|
||||
}
|
||||
|
||||
if (streq(name, "MemoryHigh"))
|
||||
return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, reterr_error);
|
||||
|
||||
@@ -1135,33 +1107,11 @@ int bus_cgroup_set_property(
|
||||
return r;
|
||||
}
|
||||
|
||||
if (streq(name, "MemoryMinScale")) {
|
||||
r = bus_cgroup_set_memory_protection_scale(u, name, &c->memory_min, message, flags, reterr_error);
|
||||
if (r > 0)
|
||||
c->memory_min_set = true;
|
||||
return r;
|
||||
}
|
||||
if (streq(name, "MemoryMinScale"))
|
||||
return bus_cgroup_set_memory_protection_scale(u, name, &c->memory_min, message, flags, reterr_error);
|
||||
|
||||
if (streq(name, "MemoryLowScale")) {
|
||||
r = bus_cgroup_set_memory_protection_scale(u, name, &c->memory_low, message, flags, reterr_error);
|
||||
if (r > 0)
|
||||
c->memory_low_set = true;
|
||||
return r;
|
||||
}
|
||||
|
||||
if (streq(name, "DefaultMemoryMinScale")) {
|
||||
r = bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_min, message, flags, reterr_error);
|
||||
if (r > 0)
|
||||
c->default_memory_min_set = true;
|
||||
return r;
|
||||
}
|
||||
|
||||
if (streq(name, "DefaultMemoryLowScale")) {
|
||||
r = bus_cgroup_set_memory_protection_scale(u, name, &c->default_memory_low, message, flags, reterr_error);
|
||||
if (r > 0)
|
||||
c->default_memory_low_set = true;
|
||||
return r;
|
||||
}
|
||||
if (streq(name, "MemoryLowScale"))
|
||||
return bus_cgroup_set_memory_protection_scale(u, name, &c->memory_low, message, flags, reterr_error);
|
||||
|
||||
if (streq(name, "MemoryHighScale"))
|
||||
return bus_cgroup_set_memory_scale(u, name, &c->memory_high, message, flags, reterr_error);
|
||||
@@ -2041,8 +1991,8 @@ int bus_cgroup_set_property(
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* deprecated CGroup v1 properties */
|
||||
if (STR_IN_SET(name,
|
||||
/* deprecated CGroup v1 properties */
|
||||
"MemoryLimit",
|
||||
"MemoryLimitScale",
|
||||
"CPUShares",
|
||||
@@ -2053,7 +2003,13 @@ int bus_cgroup_set_property(
|
||||
"BlockIODeviceWeight",
|
||||
"BlockIOReadBandwidth",
|
||||
"BlockIOWriteBandwidth",
|
||||
"CPUAccounting")) { /* see comment in bus_cgroup_vtable */
|
||||
/* see comments in bus_cgroup_vtable */
|
||||
"CPUAccounting",
|
||||
"DefaultMemoryMin",
|
||||
"DefaultMemoryMinScale",
|
||||
"DefaultMemoryLow",
|
||||
"DefaultMemoryLowScale",
|
||||
"DefaultStartupMemoryLow")) {
|
||||
|
||||
r = sd_bus_message_skip(message, NULL);
|
||||
if (r < 0)
|
||||
|
||||
@@ -132,18 +132,6 @@ static int exec_cgroup_context_serialize(const CGroupContext *c, FILE *f) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (c->default_memory_min > 0) {
|
||||
r = serialize_item_format(f, "exec-cgroup-context-default-memory-min", "%" PRIu64, c->default_memory_min);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (c->default_memory_low > 0) {
|
||||
r = serialize_item_format(f, "exec-cgroup-context-default-memory-low", "%" PRIu64, c->default_memory_low);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (c->memory_min > 0) {
|
||||
r = serialize_item_format(f, "exec-cgroup-context-memory-min", "%" PRIu64, c->memory_min);
|
||||
if (r < 0)
|
||||
@@ -226,26 +214,6 @@ static int exec_cgroup_context_serialize(const CGroupContext *c, FILE *f) {
|
||||
return r;
|
||||
}
|
||||
|
||||
r = serialize_bool_elide(f, "exec-cgroup-context-default-memory-min-set", c->default_memory_min_set);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = serialize_bool_elide(f, "exec-cgroup-context-default-memory-low-set", c->default_memory_low_set);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = serialize_bool_elide(f, "exec-cgroup-context-default-startup-memory-low-set", c->default_startup_memory_low_set);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = serialize_bool_elide(f, "exec-cgroup-context-memory-min-set", c->memory_min_set);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = serialize_bool_elide(f, "exec-cgroup-context-memory-low-set", c->memory_low_set);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-low-set", c->startup_memory_low_set);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -532,14 +500,6 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) {
|
||||
r = safe_atou64(val, &c->startup_io_weight);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-default-memory-min="))) {
|
||||
r = safe_atou64(val, &c->default_memory_min);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-default-memory-low="))) {
|
||||
r = safe_atou64(val, &c->default_memory_low);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-memory-min="))) {
|
||||
r = safe_atou64(val, &c->memory_min);
|
||||
if (r < 0)
|
||||
@@ -597,31 +557,6 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) {
|
||||
r = safe_atou64(val, &c->tasks_max.scale);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-default-memory-min-set="))) {
|
||||
r = parse_boolean(val);
|
||||
if (r < 0)
|
||||
return r;
|
||||
c->default_memory_min_set = r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-default-memory-low-set="))) {
|
||||
r = parse_boolean(val);
|
||||
if (r < 0)
|
||||
return r;
|
||||
c->default_memory_low_set = r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-default-startup-memory-low-set="))) {
|
||||
r = parse_boolean(val);
|
||||
if (r < 0)
|
||||
return r;
|
||||
c->default_startup_memory_low_set = r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-memory-min-set="))) {
|
||||
r = parse_boolean(val);
|
||||
if (r < 0)
|
||||
return r;
|
||||
c->memory_min_set = r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-memory-low-set="))) {
|
||||
r = parse_boolean(val);
|
||||
if (r < 0)
|
||||
return r;
|
||||
c->memory_low_set = r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-startup-memory-low-set="))) {
|
||||
r = parse_boolean(val);
|
||||
if (r < 0)
|
||||
|
||||
@@ -223,11 +223,11 @@
|
||||
{{type}}.CPUQuotaPeriodSec, config_parse_sec_def_infinity, 0, offsetof({{type}}, cgroup_context.cpu_quota_period_usec)
|
||||
{{type}}.MemoryAccounting, config_parse_bool, 0, offsetof({{type}}, cgroup_context.memory_accounting)
|
||||
{{type}}.MemoryMin, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context)
|
||||
{{type}}.DefaultMemoryMin, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context)
|
||||
{{type}}.DefaultMemoryLow, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context)
|
||||
{{type}}.DefaultStartupMemoryLow, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context)
|
||||
{{type}}.MemoryLow, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context)
|
||||
{{type}}.StartupMemoryLow, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context)
|
||||
{{type}}.DefaultMemoryMin, config_parse_warn_compat, DISABLED_LEGACY, 0
|
||||
{{type}}.DefaultMemoryLow, config_parse_warn_compat, DISABLED_LEGACY, 0
|
||||
{{type}}.DefaultStartupMemoryLow, config_parse_warn_compat, DISABLED_LEGACY, 0
|
||||
{{type}}.MemoryHigh, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context)
|
||||
{{type}}.StartupMemoryHigh, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context)
|
||||
{{type}}.MemoryMax, config_parse_memory_limit, 0, offsetof({{type}}, cgroup_context)
|
||||
|
||||
@@ -3790,9 +3790,7 @@ int config_parse_memory_limit(
|
||||
uint64_t bytes = CGROUP_LIMIT_MAX;
|
||||
int r;
|
||||
|
||||
if (isempty(rvalue) && STR_IN_SET(lvalue, "DefaultMemoryLow",
|
||||
"DefaultMemoryMin",
|
||||
"MemoryLow",
|
||||
if (isempty(rvalue) && STR_IN_SET(lvalue, "MemoryLow",
|
||||
"StartupMemoryLow",
|
||||
"MemoryMin"))
|
||||
bytes = CGROUP_LIMIT_MIN;
|
||||
@@ -3816,31 +3814,17 @@ int config_parse_memory_limit(
|
||||
"StartupMemoryZSwapMax",
|
||||
"MemoryLow",
|
||||
"StartupMemoryLow",
|
||||
"MemoryMin",
|
||||
"DefaultMemoryLow",
|
||||
"DefaultstartupMemoryLow",
|
||||
"DefaultMemoryMin"))) {
|
||||
"MemoryMin"))) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0, "Memory limit '%s' out of range, ignoring.", rvalue);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (streq(lvalue, "DefaultMemoryLow")) {
|
||||
c->default_memory_low = bytes;
|
||||
c->default_memory_low_set = true;
|
||||
} else if (streq(lvalue, "DefaultStartupMemoryLow")) {
|
||||
c->default_startup_memory_low = bytes;
|
||||
c->default_startup_memory_low_set = true;
|
||||
} else if (streq(lvalue, "DefaultMemoryMin")) {
|
||||
c->default_memory_min = bytes;
|
||||
c->default_memory_min_set = true;
|
||||
} else if (streq(lvalue, "MemoryMin")) {
|
||||
if (streq(lvalue, "MemoryMin"))
|
||||
c->memory_min = bytes;
|
||||
c->memory_min_set = true;
|
||||
} else if (streq(lvalue, "MemoryLow")) {
|
||||
else if (streq(lvalue, "MemoryLow"))
|
||||
c->memory_low = bytes;
|
||||
c->memory_low_set = true;
|
||||
} else if (streq(lvalue, "StartupMemoryLow")) {
|
||||
else if (streq(lvalue, "StartupMemoryLow")) {
|
||||
c->startup_memory_low = bytes;
|
||||
c->startup_memory_low_set = true;
|
||||
} else if (streq(lvalue, "MemoryHigh"))
|
||||
|
||||
+9
-24
@@ -1515,6 +1515,7 @@ static int mount_private_cgroup2fs(const MountEntry *m, const NamespaceParameter
|
||||
|
||||
static int mount_procfs(const MountEntry *m, const NamespaceParameters *p) {
|
||||
_cleanup_free_ char *opts = NULL;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(p);
|
||||
@@ -1522,32 +1523,16 @@ static int mount_procfs(const MountEntry *m, const NamespaceParameters *p) {
|
||||
if (p->protect_proc != PROTECT_PROC_DEFAULT ||
|
||||
p->proc_subset != PROC_SUBSET_ALL) {
|
||||
|
||||
/* Starting with kernel 5.8 procfs' hidepid= logic is truly per-instance (previously it
|
||||
* pretended to be per-instance but actually was per-namespace), hence let's make use of it
|
||||
* if requested. To make sure this logic succeeds only on kernels where hidepid= is
|
||||
* per-instance, we'll exclusively use the textual value for hidepid=, since support was
|
||||
* added in the same commit: if it's supported it is thus also per-instance. */
|
||||
opts = strjoin("hidepid=",
|
||||
p->protect_proc == PROTECT_PROC_DEFAULT ? "off" : protect_proc_to_string(p->protect_proc));
|
||||
if (!opts)
|
||||
return -ENOMEM;
|
||||
|
||||
const char *hpv = p->protect_proc == PROTECT_PROC_DEFAULT ?
|
||||
"off" :
|
||||
protect_proc_to_string(p->protect_proc);
|
||||
|
||||
/* hidepid= support was added in 5.8, so we can use fsconfig()/fsopen() (which were added in
|
||||
* 5.2) to check if hidepid= is supported. This avoids a noisy dmesg log by the kernel when
|
||||
* trying to use hidepid= on systems where it isn't supported. The same applies for subset=.
|
||||
* fsopen()/fsconfig() was also backported on some distros which allows us to detect
|
||||
* hidepid=/subset= support in even more scenarios. */
|
||||
|
||||
if (mount_option_supported("proc", "hidepid", hpv) > 0) {
|
||||
opts = strjoin("hidepid=", hpv);
|
||||
if (!opts)
|
||||
return -ENOMEM;
|
||||
if (p->proc_subset != PROC_SUBSET_ALL) {
|
||||
r = strextendf_with_separator(&opts, ",", "subset=%s", proc_subset_to_string(p->proc_subset));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (p->proc_subset == PROC_SUBSET_PID &&
|
||||
mount_option_supported("proc", "subset", "pid") > 0)
|
||||
if (!strextend_with_separator(&opts, ",", "subset=pid"))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Mount a new instance, so that we get the one that matches our user namespace, if we are running in
|
||||
|
||||
@@ -259,12 +259,9 @@ int unit_cgroup_context_build_json(sd_json_variant **ret, const char *name, void
|
||||
|
||||
/* Memory Accounting and Control */
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("MemoryAccounting", c->memory_accounting),
|
||||
JSON_BUILD_PAIR_CONDITION_UNSIGNED(c->memory_min_set, "MemoryMin", c->memory_min),
|
||||
JSON_BUILD_PAIR_CONDITION_UNSIGNED(c->default_memory_min_set, "DefaultMemoryMin", c->default_memory_min),
|
||||
JSON_BUILD_PAIR_CONDITION_UNSIGNED(c->memory_low_set, "MemoryLow", c->memory_low),
|
||||
JSON_BUILD_PAIR_CONDITION_UNSIGNED(c->default_memory_low_set, "DefaultMemoryLow", c->default_memory_low),
|
||||
JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("MemoryMin", c->memory_min, CGROUP_LIMIT_MIN),
|
||||
JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("MemoryLow", c->memory_low, CGROUP_LIMIT_MIN),
|
||||
JSON_BUILD_PAIR_CONDITION_UNSIGNED(c->startup_memory_low_set, "StartupMemoryLow", c->startup_memory_low),
|
||||
JSON_BUILD_PAIR_CONDITION_UNSIGNED(c->default_startup_memory_low_set, "DefaultStartupMemoryLow", c->default_startup_memory_low),
|
||||
JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("MemoryHigh", c->memory_high, CGROUP_LIMIT_MAX),
|
||||
JSON_BUILD_PAIR_CONDITION_UNSIGNED(c->startup_memory_high_set, "StartupMemoryHigh", c->startup_memory_high),
|
||||
JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("MemoryMax", c->memory_max, CGROUP_LIMIT_MAX),
|
||||
|
||||
@@ -117,8 +117,7 @@ int rtnl_resolve_ifname_full(
|
||||
r = sd_netlink_call(*rtnl, message, 0, &reply);
|
||||
if (r >= 0)
|
||||
return parse_newlink_message(reply, ret_name, ret_altnames);
|
||||
/* The kernels older than 76c9ac0ee878f6693d398d3a95ccaf85e1f597a6 (v5.5) return -EINVAL. */
|
||||
if (!IN_SET(r, -ENODEV, -EINVAL))
|
||||
if (r != -ENODEV)
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
+5
-13
@@ -2767,16 +2767,8 @@ static int reset_audit_loginuid(void) {
|
||||
return 0;
|
||||
|
||||
r = write_string_file("/proc/self/loginuid", "4294967295", WRITE_STRING_FILE_DISABLE_BUFFER);
|
||||
if (r < 0) {
|
||||
log_error_errno(r,
|
||||
"Failed to reset audit login UID. This probably means that your kernel is too\n"
|
||||
"old and you have audit enabled. Note that the auditing subsystem is known to\n"
|
||||
"be incompatible with containers on old kernels. Please make sure to upgrade\n"
|
||||
"your kernel or to off auditing with 'audit=0' on the kernel command line before\n"
|
||||
"using systemd-nspawn. Sleeping for 5s... (%m)");
|
||||
|
||||
sleep(5);
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to reset audit login UID: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3775,7 +3767,7 @@ static int setup_unix_export_dir_outside(char **ret) {
|
||||
"tmpfs",
|
||||
q,
|
||||
"tmpfs",
|
||||
MS_NODEV|MS_NOEXEC|MS_NOSUID|ms_nosymfollow_supported(),
|
||||
MS_NODEV|MS_NOEXEC|MS_NOSUID|MS_NOSYMFOLLOW,
|
||||
"size=4M,nr_inodes=64,mode=0755");
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -3789,7 +3781,7 @@ static int setup_unix_export_dir_outside(char **ret) {
|
||||
/* what= */ NULL,
|
||||
w,
|
||||
/* fstype= */ NULL,
|
||||
MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NODEV|MS_NOEXEC|MS_NOSUID|ms_nosymfollow_supported(),
|
||||
MS_BIND|MS_REMOUNT|MS_RDONLY|MS_NODEV|MS_NOEXEC|MS_NOSUID|MS_NOSYMFOLLOW,
|
||||
/* options= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -3834,7 +3826,7 @@ static int setup_unix_export_host_inside(const char *directory, const char *unix
|
||||
/* what= */ NULL,
|
||||
p,
|
||||
/* fstype= */ NULL,
|
||||
MS_BIND|MS_REMOUNT|MS_NODEV|MS_NOEXEC|MS_NOSUID|ms_nosymfollow_supported(),
|
||||
MS_BIND|MS_REMOUNT|MS_NODEV|MS_NOEXEC|MS_NOSUID|MS_NOSYMFOLLOW,
|
||||
/* options= */ NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
BUS_DEFINE_PROPERTY_GET_GLOBAL(bus_property_get_bool_false, "b", 0);
|
||||
BUS_DEFINE_PROPERTY_GET_GLOBAL(bus_property_get_bool_true, "b", 1);
|
||||
BUS_DEFINE_PROPERTY_GET_GLOBAL(bus_property_get_uint64_0, "t", UINT64_C(0));
|
||||
BUS_DEFINE_PROPERTY_GET_GLOBAL(bus_property_get_uint64_max, "t", UINT64_MAX);
|
||||
|
||||
int bus_property_get_bool(
|
||||
|
||||
@@ -107,4 +107,5 @@ int bus_property_get_pidfdid(sd_bus *bus, const char *path, const char *interfac
|
||||
/* For deprecated properties. */
|
||||
int bus_property_get_bool_false(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *reterr_error);
|
||||
int bus_property_get_bool_true(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *reterr_error);
|
||||
int bus_property_get_uint64_0(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *reterr_error);
|
||||
int bus_property_get_uint64_max(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *reterr_error);
|
||||
|
||||
@@ -342,8 +342,6 @@ static int bus_append_parse_resource_limit(sd_bus_message *m, const char *field,
|
||||
if (isempty(eq) || streq(eq, "infinity")) {
|
||||
uint64_t x = streq(eq, "infinity") ? CGROUP_LIMIT_MAX :
|
||||
STR_IN_SET(field,
|
||||
"DefaultMemoryLow",
|
||||
"DefaultMemoryMin",
|
||||
"MemoryLow",
|
||||
"MemoryMin") ? CGROUP_LIMIT_MIN : CGROUP_LIMIT_MAX;
|
||||
|
||||
@@ -2348,8 +2346,6 @@ static const BusProperty cgroup_properties[] = {
|
||||
{ "DisableControllers", bus_append_strv },
|
||||
{ "Delegate", bus_append_parse_delegate },
|
||||
{ "MemoryMin", bus_append_parse_resource_limit },
|
||||
{ "DefaultMemoryLow", bus_append_parse_resource_limit },
|
||||
{ "DefaultMemoryMin", bus_append_parse_resource_limit },
|
||||
{ "MemoryLow", bus_append_parse_resource_limit },
|
||||
{ "MemoryHigh", bus_append_parse_resource_limit },
|
||||
{ "MemoryMax", bus_append_parse_resource_limit },
|
||||
@@ -2386,6 +2382,8 @@ static const BusProperty cgroup_properties[] = {
|
||||
{ "BlockIOReadBandwidth", warn_deprecated },
|
||||
{ "BlockIOWriteBandwidth", warn_deprecated },
|
||||
{ "CPUAccounting", warn_deprecated },
|
||||
{ "DefaultMemoryMin", warn_deprecated },
|
||||
{ "DefaultMemoryLow", warn_deprecated },
|
||||
|
||||
{ NULL, bus_try_append_parse_cgroup_io_limit, cgroup_io_limits_list },
|
||||
{}
|
||||
|
||||
@@ -2383,7 +2383,7 @@ int partition_pick_mount_options(
|
||||
|
||||
case PARTITION_ESP:
|
||||
case PARTITION_XBOOTLDR:
|
||||
flags |= MS_NOSUID|MS_NOEXEC|ms_nosymfollow_supported();
|
||||
flags |= MS_NOSUID|MS_NOEXEC|MS_NOSYMFOLLOW;
|
||||
|
||||
/* The ESP might contain a pre-boot random seed. Let's make this unaccessible to regular
|
||||
* userspace. ESP/XBOOTLDR is almost certainly VFAT, hence if we don't know assume it is. */
|
||||
|
||||
@@ -1060,7 +1060,6 @@ static int fw_nftables_add_local_dnat_internal(
|
||||
|
||||
sd_netlink_message *messages[3] = {};
|
||||
_unused_ _cleanup_(netlink_message_unref_manyp) sd_netlink_message **unref = messages;
|
||||
static bool ipv6_supported = true;
|
||||
uint32_t data[5], key[2], dlen;
|
||||
size_t msgcnt = 0;
|
||||
int r;
|
||||
@@ -1069,9 +1068,6 @@ static int fw_nftables_add_local_dnat_internal(
|
||||
assert(add || !previous_remote);
|
||||
assert(IN_SET(af, AF_INET, AF_INET6));
|
||||
|
||||
if (!ipv6_supported && af == AF_INET6)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!IN_SET(protocol, IPPROTO_TCP, IPPROTO_UDP))
|
||||
return -EPROTONOSUPPORT;
|
||||
|
||||
@@ -1125,14 +1121,6 @@ static int fw_nftables_add_local_dnat_internal(
|
||||
|
||||
assert(msgcnt < ELEMENTSOF(messages));
|
||||
r = sd_nfnl_call_batch(nfnl, messages, msgcnt, NFNL_DEFAULT_TIMEOUT_USECS);
|
||||
if (r == -EOVERFLOW && af == AF_INET6) {
|
||||
/* The current implementation of DNAT in systemd requires kernel's
|
||||
* fdb9c405e35bdc6e305b9b4e20ebc141ed14fc81 (v5.8), and the older kernel returns
|
||||
* -EOVERFLOW. Let's treat the error as -EOPNOTSUPP. */
|
||||
log_debug_errno(r, "The current implementation of IPv6 DNAT in systemd requires kernel 5.8 or newer, ignoring: %m");
|
||||
ipv6_supported = false;
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -64,9 +64,6 @@ static bool is_in_survivor_cgroup(const PidRef *pid) {
|
||||
}
|
||||
|
||||
r = cg_get_xattr_bool(cgroup_path, "user.survive_final_kill_signal");
|
||||
/* user xattr support was added to kernel v5.7, try with the trusted namespace as a fallback */
|
||||
if (ERRNO_IS_NEG_XATTR_ABSENT(r))
|
||||
r = cg_get_xattr_bool(cgroup_path, "trusted.survive_final_kill_signal");
|
||||
if (r < 0 && !ERRNO_IS_NEG_XATTR_ABSENT(r))
|
||||
log_debug_errno(r,
|
||||
"Failed to get survive_final_kill_signal xattr of %s, ignoring: %m",
|
||||
|
||||
@@ -1951,7 +1951,7 @@ int trigger_automount_at(int dir_fd, const char *path) {
|
||||
|
||||
unsigned long credentials_fs_mount_flags(bool ro) {
|
||||
/* A tight set of mount flags for credentials mounts */
|
||||
return MS_NODEV|MS_NOEXEC|MS_NOSUID|ms_nosymfollow_supported()|(ro ? MS_RDONLY : 0);
|
||||
return MS_NODEV|MS_NOEXEC|MS_NOSUID|MS_NOSYMFOLLOW|(ro ? MS_RDONLY : 0);
|
||||
}
|
||||
|
||||
int fsmount_credentials_fs(int *ret_fsfd) {
|
||||
|
||||
@@ -166,7 +166,7 @@ int make_mount_point_inode_from_path(const char *source, const char *dest, mode_
|
||||
|
||||
int trigger_automount_at(int dir_fd, const char *path);
|
||||
|
||||
unsigned long credentials_fs_mount_flags(bool ro);
|
||||
unsigned long credentials_fs_mount_flags(bool ro) _const_;
|
||||
int fsmount_credentials_fs(int *ret_fsfd);
|
||||
int mount_credentials_fs(const char *path);
|
||||
|
||||
|
||||
@@ -111,15 +111,9 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#MemoryMin=bytes,%20MemoryLow=bytes"),
|
||||
SD_VARLINK_DEFINE_FIELD(MemoryMin, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#MemoryMin=bytes,%20MemoryLow=bytes"),
|
||||
SD_VARLINK_DEFINE_FIELD(DefaultMemoryMin, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#MemoryMin=bytes,%20MemoryLow=bytes"),
|
||||
SD_VARLINK_DEFINE_FIELD(MemoryLow, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#MemoryMin=bytes,%20MemoryLow=bytes"),
|
||||
SD_VARLINK_DEFINE_FIELD(DefaultMemoryLow, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#MemorySwapMax=bytes"),
|
||||
SD_VARLINK_DEFINE_FIELD(StartupMemoryLow, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#MemoryMin=bytes,%20MemoryLow=bytes"),
|
||||
SD_VARLINK_DEFINE_FIELD(DefaultStartupMemoryLow, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#MemoryHigh=bytes"),
|
||||
SD_VARLINK_DEFINE_FIELD(MemoryHigh, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#MemoryHigh=bytes"),
|
||||
|
||||
@@ -302,10 +302,6 @@ typedef struct UnitStatusInfo {
|
||||
uint64_t io_read_bytes;
|
||||
uint64_t io_write_bytes;
|
||||
|
||||
uint64_t default_memory_min;
|
||||
uint64_t default_memory_low;
|
||||
uint64_t default_startup_memory_low;
|
||||
|
||||
/* Exec Quotas */
|
||||
QuotaInfo exec_directories_quota[_EXEC_DIRECTORY_TYPE_MAX];
|
||||
|
||||
@@ -2248,9 +2244,6 @@ static int show_one(
|
||||
{ "MemorySwapPeak", "t", NULL, offsetof(UnitStatusInfo, memory_swap_peak) },
|
||||
{ "MemoryZSwapCurrent", "t", NULL, offsetof(UnitStatusInfo, memory_zswap_current) },
|
||||
{ "MemoryAvailable", "t", NULL, offsetof(UnitStatusInfo, memory_available) },
|
||||
{ "DefaultMemoryMin", "t", NULL, offsetof(UnitStatusInfo, default_memory_min) },
|
||||
{ "DefaultMemoryLow", "t", NULL, offsetof(UnitStatusInfo, default_memory_low) },
|
||||
{ "DefaultStartupMemoryLow", "t", NULL, offsetof(UnitStatusInfo, default_startup_memory_low) },
|
||||
{ "MemoryMin", "t", NULL, offsetof(UnitStatusInfo, memory_min) },
|
||||
{ "MemoryLow", "t", NULL, offsetof(UnitStatusInfo, memory_low) },
|
||||
{ "StartupMemoryLow", "t", NULL, offsetof(UnitStatusInfo, startup_memory_low) },
|
||||
|
||||
@@ -540,9 +540,6 @@ executables += [
|
||||
'sources' : files('test-cgroup-mask.c'),
|
||||
'dependencies' : common_test_dependencies,
|
||||
},
|
||||
core_test_template + {
|
||||
'sources' : files('test-cgroup-unit-default.c'),
|
||||
},
|
||||
core_test_template + {
|
||||
'sources' : files('test-chown-rec.c'),
|
||||
},
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "cgroup.h"
|
||||
#include "manager.h"
|
||||
#include "rm-rf.h"
|
||||
#include "tests.h"
|
||||
#include "unit.h"
|
||||
|
||||
TEST_RET(default_memory_low, .sd_booted = true) {
|
||||
_cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
|
||||
_cleanup_(manager_freep) Manager *m = NULL;
|
||||
Unit *root, *dml,
|
||||
*dml_passthrough, *dml_passthrough_empty, *dml_passthrough_set_dml, *dml_passthrough_set_ml,
|
||||
*dml_override, *dml_override_empty,
|
||||
*dml_discard, *dml_discard_empty, *dml_discard_set_ml;
|
||||
uint64_t dml_tree_default;
|
||||
int r;
|
||||
|
||||
r = enter_cgroup_subroot(NULL);
|
||||
if (r == -ENOMEDIUM)
|
||||
return log_tests_skipped("cgroupfs not available");
|
||||
|
||||
_cleanup_free_ char *unit_dir = NULL;
|
||||
ASSERT_OK(get_testdata_dir("test-cgroup-unit-default", &unit_dir));
|
||||
ASSERT_OK(setenv_unit_path(unit_dir));
|
||||
assert_se(runtime_dir = setup_fake_runtime_dir());
|
||||
r = manager_new(RUNTIME_SCOPE_USER, MANAGER_TEST_RUN_BASIC, &m);
|
||||
if (IN_SET(r, -EPERM, -EACCES)) {
|
||||
log_error_errno(r, "manager_new: %m");
|
||||
return log_tests_skipped("cannot create manager");
|
||||
}
|
||||
|
||||
ASSERT_OK(r);
|
||||
ASSERT_OK(manager_startup(m, NULL, NULL, NULL));
|
||||
|
||||
/* dml.slice has DefaultMemoryLow=50. Beyond that, individual subhierarchies look like this:
|
||||
*
|
||||
* 1. dml-passthrough.slice sets MemoryLow=100. This should not affect its children, as only
|
||||
* DefaultMemoryLow is propagated, not MemoryLow. As such, all leaf services should end up with
|
||||
* memory.low as 50, inherited from dml.slice, *except* for dml-passthrough-set-ml.service, which
|
||||
* should have the value of 0, as it has MemoryLow explicitly set.
|
||||
*
|
||||
* ┌───────────┐
|
||||
* │ dml.slice │
|
||||
* └─────┬─────┘
|
||||
* MemoryLow=100
|
||||
* ┌───────────┴───────────┐
|
||||
* │ dml-passthrough.slice │
|
||||
* └───────────┬───────────┘
|
||||
* ┌───────────────────────────────────┼───────────────────────────────────┐
|
||||
* no new settings DefaultMemoryLow=15 MemoryLow=0
|
||||
* ┌───────────────┴───────────────┐ ┌────────────────┴────────────────┐ ┌───────────────┴────────────────┐
|
||||
* │ dml-passthrough-empty.service │ │ dml-passthrough-set-dml.service │ │ dml-passthrough-set-ml.service │
|
||||
* └───────────────────────────────┘ └─────────────────────────────────┘ └────────────────────────────────┘
|
||||
*
|
||||
* 2. dml-override.slice sets DefaultMemoryLow=10. As such, dml-override-empty.service should also
|
||||
* end up with a memory.low of 10. dml-override.slice should still have a memory.low of 50.
|
||||
*
|
||||
* ┌───────────┐
|
||||
* │ dml.slice │
|
||||
* └─────┬─────┘
|
||||
* DefaultMemoryLow=10
|
||||
* ┌─────────┴──────────┐
|
||||
* │ dml-override.slice │
|
||||
* └─────────┬──────────┘
|
||||
* no new settings
|
||||
* ┌─────────────┴──────────────┐
|
||||
* │ dml-override-empty.service │
|
||||
* └────────────────────────────┘
|
||||
*
|
||||
* 3. dml-discard.slice sets DefaultMemoryLow= with no rvalue. As such,
|
||||
* dml-discard-empty.service should end up with a value of 0.
|
||||
* dml-discard-set-ml.service sets MemoryLow=15, and as such should have that override the
|
||||
* reset DefaultMemoryLow value. dml-discard.slice should still have an eventual memory.low of 50.
|
||||
*
|
||||
* ┌───────────┐
|
||||
* │ dml.slice │
|
||||
* └─────┬─────┘
|
||||
* DefaultMemoryLow=
|
||||
* ┌─────────┴─────────┐
|
||||
* │ dml-discard.slice │
|
||||
* └─────────┬─────────┘
|
||||
* ┌──────────────┴───────────────┐
|
||||
* no new settings MemoryLow=15
|
||||
* ┌─────────────┴─────────────┐ ┌─────────────┴──────────────┐
|
||||
* │ dml-discard-empty.service │ │ dml-discard-set-ml.service │
|
||||
* └───────────────────────────┘ └────────────────────────────┘
|
||||
*/
|
||||
ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml.slice", NULL, &dml));
|
||||
|
||||
ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-passthrough.slice", NULL, &dml_passthrough));
|
||||
assert_se(UNIT_GET_SLICE(dml_passthrough) == dml);
|
||||
ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-passthrough-empty.service", NULL, &dml_passthrough_empty));
|
||||
assert_se(UNIT_GET_SLICE(dml_passthrough_empty) == dml_passthrough);
|
||||
ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-passthrough-set-dml.service", NULL, &dml_passthrough_set_dml));
|
||||
assert_se(UNIT_GET_SLICE(dml_passthrough_set_dml) == dml_passthrough);
|
||||
ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-passthrough-set-ml.service", NULL, &dml_passthrough_set_ml));
|
||||
assert_se(UNIT_GET_SLICE(dml_passthrough_set_ml) == dml_passthrough);
|
||||
|
||||
ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-override.slice", NULL, &dml_override));
|
||||
assert_se(UNIT_GET_SLICE(dml_override) == dml);
|
||||
ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-override-empty.service", NULL, &dml_override_empty));
|
||||
assert_se(UNIT_GET_SLICE(dml_override_empty) == dml_override);
|
||||
|
||||
ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-discard.slice", NULL, &dml_discard));
|
||||
assert_se(UNIT_GET_SLICE(dml_discard) == dml);
|
||||
ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-discard-empty.service", NULL, &dml_discard_empty));
|
||||
assert_se(UNIT_GET_SLICE(dml_discard_empty) == dml_discard);
|
||||
ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-discard-set-ml.service", NULL, &dml_discard_set_ml));
|
||||
assert_se(UNIT_GET_SLICE(dml_discard_set_ml) == dml_discard);
|
||||
|
||||
assert_se(root = UNIT_GET_SLICE(dml));
|
||||
assert_se(!UNIT_GET_SLICE(root));
|
||||
|
||||
assert_se(unit_get_ancestor_memory_low(root) == CGROUP_LIMIT_MIN);
|
||||
|
||||
assert_se(unit_get_ancestor_memory_low(dml) == CGROUP_LIMIT_MIN);
|
||||
dml_tree_default = unit_get_cgroup_context(dml)->default_memory_low;
|
||||
assert_se(dml_tree_default == 50);
|
||||
|
||||
assert_se(unit_get_ancestor_memory_low(dml_passthrough) == 100);
|
||||
assert_se(unit_get_ancestor_memory_low(dml_passthrough_empty) == dml_tree_default);
|
||||
assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_dml) == 50);
|
||||
assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_ml) == 0);
|
||||
|
||||
assert_se(unit_get_ancestor_memory_low(dml_override) == dml_tree_default);
|
||||
assert_se(unit_get_ancestor_memory_low(dml_override_empty) == 10);
|
||||
|
||||
assert_se(unit_get_ancestor_memory_low(dml_discard) == dml_tree_default);
|
||||
assert_se(unit_get_ancestor_memory_low(dml_discard_empty) == CGROUP_LIMIT_MIN);
|
||||
assert_se(unit_get_ancestor_memory_low(dml_discard_set_ml) == 15);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_DEBUG);
|
||||
@@ -359,10 +359,6 @@ TEST(is_mount_point_at) {
|
||||
ASSERT_OK(is_mount_point_at(fd, "regular", 0));
|
||||
}
|
||||
|
||||
TEST(ms_nosymfollow_supported) {
|
||||
log_info("MS_NOSYMFOLLOW supported: %s", yes_no(ms_nosymfollow_supported()));
|
||||
}
|
||||
|
||||
TEST(mount_option_supported) {
|
||||
int r;
|
||||
|
||||
|
||||
@@ -332,7 +332,6 @@ if install_tests
|
||||
'journal-data',
|
||||
'knot-data',
|
||||
'test-cgroup-mask',
|
||||
'test-cgroup-unit-default',
|
||||
'test-engine',
|
||||
'test-execute',
|
||||
'test-fstab-generator',
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Unit]
|
||||
Description=DML discard empty service
|
||||
|
||||
[Service]
|
||||
Slice=dml-discard.slice
|
||||
Type=oneshot
|
||||
ExecStart=true
|
||||
@@ -1,9 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Unit]
|
||||
Description=DML discard set ml service
|
||||
|
||||
[Service]
|
||||
Slice=dml-discard.slice
|
||||
Type=oneshot
|
||||
ExecStart=true
|
||||
MemoryLow=15
|
||||
@@ -1,6 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Unit]
|
||||
Description=DML discard slice
|
||||
|
||||
[Slice]
|
||||
DefaultMemoryLow=
|
||||
@@ -1,8 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Unit]
|
||||
Description=DML override empty service
|
||||
|
||||
[Service]
|
||||
Slice=dml-override.slice
|
||||
Type=oneshot
|
||||
ExecStart=true
|
||||
@@ -1,6 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Unit]
|
||||
Description=DML override slice
|
||||
|
||||
[Slice]
|
||||
DefaultMemoryLow=10
|
||||
@@ -1,8 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Unit]
|
||||
Description=DML passthrough empty service
|
||||
|
||||
[Service]
|
||||
Slice=dml-passthrough.slice
|
||||
Type=oneshot
|
||||
ExecStart=true
|
||||
@@ -1,9 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Unit]
|
||||
Description=DML passthrough set DML service
|
||||
|
||||
[Service]
|
||||
Slice=dml-passthrough.slice
|
||||
Type=oneshot
|
||||
ExecStart=true
|
||||
DefaultMemoryLow=15
|
||||
@@ -1,9 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Unit]
|
||||
Description=DML passthrough set ML service
|
||||
|
||||
[Service]
|
||||
Slice=dml-passthrough.slice
|
||||
Type=oneshot
|
||||
ExecStart=true
|
||||
MemoryLow=0
|
||||
@@ -1,6 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Unit]
|
||||
Description=DML passthrough slice
|
||||
|
||||
[Slice]
|
||||
MemoryLow=100
|
||||
@@ -1,6 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Unit]
|
||||
Description=DML slice
|
||||
|
||||
[Slice]
|
||||
DefaultMemoryLow=50
|
||||
Reference in New Issue
Block a user