core: Add support for CPU pressure notifications
Works the same way as memory pressure notifications. Code is refactored to work on enum arrays to reduce duplication.
This commit is contained in:
committed by
Daan De Meyer
parent
b3bb4fefde
commit
316d17fcbd
@@ -552,6 +552,10 @@ node /org/freedesktop/systemd1 {
|
||||
readonly t DefaultMemoryPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s DefaultMemoryPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultCPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s DefaultCPUPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly t TimerSlackNSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
@@ -793,6 +797,10 @@ node /org/freedesktop/systemd1 {
|
||||
|
||||
<!--property DefaultMemoryPressureWatch is not documented!-->
|
||||
|
||||
<!--property DefaultCPUPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property DefaultCPUPressureWatch is not documented!-->
|
||||
|
||||
<!--property TimerSlackNSec is not documented!-->
|
||||
|
||||
<!--property DefaultOOMPolicy is not documented!-->
|
||||
@@ -1243,6 +1251,10 @@ node /org/freedesktop/systemd1 {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultCPUPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultCPUPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="TimerSlackNSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultOOMPolicy"/>
|
||||
@@ -3066,6 +3078,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s CPUPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t CPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiss) NFTSet = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b CoredumpReceive = ...;
|
||||
@@ -3735,6 +3751,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<!--property MemoryPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property CPUPressureWatch is not documented!-->
|
||||
|
||||
<!--property CPUPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property NFTSet is not documented!-->
|
||||
|
||||
<!--property CoredumpReceive is not documented!-->
|
||||
@@ -4427,6 +4447,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFTSet"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CoredumpReceive"/>
|
||||
@@ -5326,6 +5350,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s CPUPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t CPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiss) NFTSet = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b CoredumpReceive = ...;
|
||||
@@ -6011,6 +6039,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
||||
|
||||
<!--property MemoryPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property CPUPressureWatch is not documented!-->
|
||||
|
||||
<!--property CPUPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property NFTSet is not documented!-->
|
||||
|
||||
<!--property CoredumpReceive is not documented!-->
|
||||
@@ -6677,6 +6709,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFTSet"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CoredumpReceive"/>
|
||||
@@ -7399,6 +7435,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s CPUPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t CPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiss) NFTSet = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b CoredumpReceive = ...;
|
||||
@@ -8008,6 +8048,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
|
||||
|
||||
<!--property MemoryPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property CPUPressureWatch is not documented!-->
|
||||
|
||||
<!--property CPUPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property NFTSet is not documented!-->
|
||||
|
||||
<!--property CoredumpReceive is not documented!-->
|
||||
@@ -8582,6 +8626,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFTSet"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CoredumpReceive"/>
|
||||
@@ -9437,6 +9485,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s CPUPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t CPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiss) NFTSet = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b CoredumpReceive = ...;
|
||||
@@ -10028,6 +10080,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
|
||||
|
||||
<!--property MemoryPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property CPUPressureWatch is not documented!-->
|
||||
|
||||
<!--property CPUPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property NFTSet is not documented!-->
|
||||
|
||||
<!--property CoredumpReceive is not documented!-->
|
||||
@@ -10584,6 +10640,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFTSet"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CoredumpReceive"/>
|
||||
@@ -11292,6 +11352,10 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s CPUPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t CPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiss) NFTSet = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b CoredumpReceive = ...;
|
||||
@@ -11465,6 +11529,10 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
|
||||
|
||||
<!--property MemoryPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property CPUPressureWatch is not documented!-->
|
||||
|
||||
<!--property CPUPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property NFTSet is not documented!-->
|
||||
|
||||
<!--property CoredumpReceive is not documented!-->
|
||||
@@ -11653,6 +11721,10 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFTSet"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CoredumpReceive"/>
|
||||
@@ -11864,6 +11936,10 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t MemoryPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s CPUPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t CPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiss) NFTSet = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b CoredumpReceive = ...;
|
||||
@@ -12051,6 +12127,10 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
|
||||
|
||||
<!--property MemoryPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property CPUPressureWatch is not documented!-->
|
||||
|
||||
<!--property CPUPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property NFTSet is not documented!-->
|
||||
|
||||
<!--property CoredumpReceive is not documented!-->
|
||||
@@ -12263,6 +12343,10 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="MemoryPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFTSet"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CoredumpReceive"/>
|
||||
@@ -12475,7 +12559,9 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
||||
<function>RemoveSubgroupFromUnit()</function>, and
|
||||
<function>KillUnitSubgroup()</function> were added in version 258.</para>
|
||||
<para><varname>TransactionsWithOrderingCycle</varname> was added in version 259.</para>
|
||||
<para><varname>DefaultMemoryZSwapWriteback</varname> was added in version 261.</para>
|
||||
<para><varname>DefaultMemoryZSwapWriteback</varname>,
|
||||
<varname>DefaultCPUPressureThresholdUSec</varname> and
|
||||
<varname>DefaultCPUPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Unit Objects</title>
|
||||
@@ -12567,6 +12653,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
||||
<varname>ExecReloadPostEx</varname> were added in version 259.</para>
|
||||
<para><varname>BindNetworkInterface</varname>, <varname>MemoryTHP</varname>,
|
||||
<varname>RefreshOnReload</varname>, and <varname>RootMStack</varname> were added in version 260.</para>
|
||||
<para><varname>CPUPressureThresholdUSec</varname> and
|
||||
<varname>CPUPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Socket Unit Objects</title>
|
||||
@@ -12637,6 +12725,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
||||
<varname>ManagedOOMKills</varname> were added in 259.</para>
|
||||
<para><varname>BindNetworkInterface</varname> <varname>MemoryTHP</varname>, and
|
||||
<varname>RootMStack</varname> were added in version 260.</para>
|
||||
<para><varname>CPUPressureThresholdUSec</varname> and
|
||||
<varname>CPUPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Mount Unit Objects</title>
|
||||
@@ -12702,6 +12792,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
||||
<varname>ManagedOOMKills</varname> were added in 259.</para>
|
||||
<para><varname>BindNetworkInterface</varname> <varname>MemoryTHP</varname>, and
|
||||
<varname>RootMStack</varname> were added in version 260.</para>
|
||||
<para><varname>CPUPressureThresholdUSec</varname> and
|
||||
<varname>CPUPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Swap Unit Objects</title>
|
||||
@@ -12765,6 +12857,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
||||
<varname>ManagedOOMKills</varname> were added in 259.</para>
|
||||
<para><varname>BindNetworkInterface</varname>, <varname>MemoryTHP</varname>, and
|
||||
<varname>RootMStack</varname> were added in version 260.</para>
|
||||
<para><varname>CPUPressureThresholdUSec</varname> and
|
||||
<varname>CPUPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Slice Unit Objects</title>
|
||||
@@ -12798,6 +12892,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
||||
<para><varname>OOMKills</varname>, and
|
||||
<varname>ManagedOOMKills</varname> were added in 259.</para>
|
||||
<para><varname>BindNetworkInterface</varname> was added in version 260.</para>
|
||||
<para><varname>CPUPressureThresholdUSec</varname> and
|
||||
<varname>CPUPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Scope Unit Objects</title>
|
||||
@@ -12829,6 +12925,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
||||
<para><varname>OOMKills</varname>, and
|
||||
<varname>ManagedOOMKills</varname> were added in 259.</para>
|
||||
<para><varname>BindNetworkInterface</varname> was added in version 260.</para>
|
||||
<para><varname>CPUPressureThresholdUSec</varname> and
|
||||
<varname>CPUPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Job Objects</title>
|
||||
|
||||
@@ -326,6 +326,20 @@
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>DefaultCPUPressureWatch=</varname></term>
|
||||
<term><varname>DefaultCPUPressureThresholdSec=</varname></term>
|
||||
|
||||
<listitem><para>Configures the default settings for the per-unit
|
||||
<varname>CPUPressureWatch=</varname> and <varname>CPUPressureThresholdSec=</varname>
|
||||
settings. See
|
||||
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for details. Defaults to <literal>auto</literal> and <literal>200ms</literal>, respectively. This
|
||||
also sets the CPU pressure monitoring threshold for the service manager itself.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@@ -4705,6 +4705,18 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
|
||||
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$CPU_PRESSURE_WATCH</varname></term>
|
||||
<term><varname>$CPU_PRESSURE_WRITE</varname></term>
|
||||
|
||||
<listitem><para>If CPU pressure monitoring is enabled for this service unit, the path to watch
|
||||
and the data to write into it. See <ulink url="https://systemd.io/PRESSURE">Resource Pressure
|
||||
Handling</ulink> for details about these variables and the service protocol data they
|
||||
convey.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$FDSTORE</varname></term>
|
||||
|
||||
|
||||
@@ -1657,6 +1657,55 @@ DeviceAllow=/dev/loop-control
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>CPUPressureWatch=</varname></term>
|
||||
|
||||
<listitem><para>Controls CPU pressure monitoring for invoked processes. Takes a boolean or one of
|
||||
<literal>auto</literal> and <literal>skip</literal>. If <literal>no</literal>, tells the service not
|
||||
to watch for CPU pressure events, by setting the <varname>$CPU_PRESSURE_WATCH</varname>
|
||||
environment variable to the literal string <filename>/dev/null</filename>. If <literal>yes</literal>,
|
||||
tells the service to watch for CPU pressure events. This ensures the
|
||||
<filename>cpu.pressure</filename> cgroup attribute file is accessible for
|
||||
reading and writing by the service's user. It then sets the <varname>$CPU_PRESSURE_WATCH</varname>
|
||||
environment variable for processes invoked by the unit to the file system path to this file. The
|
||||
threshold information configured with <varname>CPUPressureThresholdSec=</varname> is encoded in
|
||||
the <varname>$CPU_PRESSURE_WRITE</varname> environment variable. If the <literal>auto</literal>
|
||||
value is set the protocol is enabled if CPU resource controls are configured for the unit (e.g. because
|
||||
<varname>CPUWeight=</varname> or <varname>CPUQuota=</varname> is set), and
|
||||
disabled otherwise. If set to <literal>skip</literal> the logic is neither enabled, nor disabled and
|
||||
the two environment variables are not set.</para>
|
||||
|
||||
<para>Note that services are free to use the two environment variables, but it is unproblematic if
|
||||
they ignore them. CPU pressure handling must be implemented individually in each service, and
|
||||
usually means different things for different software.</para>
|
||||
|
||||
<para>Services implemented using
|
||||
<citerefentry><refentrytitle>sd-event</refentrytitle><manvolnum>3</manvolnum></citerefentry> may use
|
||||
<citerefentry><refentrytitle>sd_event_add_cpu_pressure</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||
to watch for and handle CPU pressure events.</para>
|
||||
|
||||
<para>If not explicitly set, defaults to the <varname>DefaultCPUPressureWatch=</varname> setting in
|
||||
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>CPUPressureThresholdSec=</varname></term>
|
||||
|
||||
<listitem><para>Sets the CPU pressure threshold time for CPU pressure monitor as configured via
|
||||
<varname>CPUPressureWatch=</varname>. Specifies the maximum CPU stall time before a CPU
|
||||
pressure event is signalled to the service, per 2s window. If not specified, defaults to the
|
||||
<varname>DefaultCPUPressureThresholdSec=</varname> setting in
|
||||
<citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
(which in turn defaults to 200ms). The specified value expects a time unit such as
|
||||
<literal>ms</literal> or <literal>μs</literal>, see
|
||||
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
|
||||
details on the permitted syntax.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</refsect2><refsect2><title>Coredump Control</title>
|
||||
|
||||
@@ -43,6 +43,11 @@ typedef struct PressureResourceInfo {
|
||||
|
||||
extern const PressureResourceInfo pressure_resource_info[_PRESSURE_RESOURCE_MAX];
|
||||
|
||||
static inline const PressureResourceInfo* pressure_resource_get_info(PressureResource resource) {
|
||||
assert(resource >= 0 && resource < _PRESSURE_RESOURCE_MAX);
|
||||
return &pressure_resource_info[resource];
|
||||
}
|
||||
|
||||
DECLARE_STRING_TABLE_LOOKUP(pressure_resource, PressureResource);
|
||||
|
||||
/* Default parameters for pressure watch logic in sd-event and PID 1 */
|
||||
|
||||
+19
-10
@@ -185,8 +185,10 @@ void cgroup_context_init(CGroupContext *c) {
|
||||
* moom_mem_pressure_duration_usec is set to infinity. */
|
||||
.moom_mem_pressure_duration_usec = USEC_INFINITY,
|
||||
|
||||
.memory_pressure_watch = _CGROUP_PRESSURE_WATCH_INVALID,
|
||||
.memory_pressure_threshold_usec = USEC_INFINITY,
|
||||
.pressure = {
|
||||
[PRESSURE_MEMORY] = { .watch = _CGROUP_PRESSURE_WATCH_INVALID, .threshold_usec = USEC_INFINITY },
|
||||
[PRESSURE_CPU] = { .watch = _CGROUP_PRESSURE_WATCH_INVALID, .threshold_usec = USEC_INFINITY },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -528,6 +530,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||||
"%sManagedOOMMemoryPressureLimit: " PERMYRIAD_AS_PERCENT_FORMAT_STR "\n"
|
||||
"%sManagedOOMPreference: %s\n"
|
||||
"%sMemoryPressureWatch: %s\n"
|
||||
"%sCPUPressureWatch: %s\n"
|
||||
"%sCoredumpReceive: %s\n",
|
||||
prefix, yes_no(c->io_accounting),
|
||||
prefix, yes_no(c->memory_accounting),
|
||||
@@ -563,7 +566,8 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||||
prefix, managed_oom_mode_to_string(c->moom_mem_pressure),
|
||||
prefix, PERMYRIAD_AS_PERCENT_FORMAT_VAL(UINT32_SCALE_TO_PERMYRIAD(c->moom_mem_pressure_limit)),
|
||||
prefix, managed_oom_preference_to_string(c->moom_preference),
|
||||
prefix, cgroup_pressure_watch_to_string(c->memory_pressure_watch),
|
||||
prefix, cgroup_pressure_watch_to_string(c->pressure[PRESSURE_MEMORY].watch),
|
||||
prefix, cgroup_pressure_watch_to_string(c->pressure[PRESSURE_CPU].watch),
|
||||
prefix, yes_no(c->coredump_receive));
|
||||
|
||||
if (c->delegate_subgroup)
|
||||
@@ -574,9 +578,13 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||||
fprintf(f, "%sBindNetworkInterface: %s\n",
|
||||
prefix, c->bind_network_interface);
|
||||
|
||||
if (c->memory_pressure_threshold_usec != USEC_INFINITY)
|
||||
if (c->pressure[PRESSURE_MEMORY].threshold_usec != USEC_INFINITY)
|
||||
fprintf(f, "%sMemoryPressureThresholdSec: %s\n",
|
||||
prefix, FORMAT_TIMESPAN(c->memory_pressure_threshold_usec, 1));
|
||||
prefix, FORMAT_TIMESPAN(c->pressure[PRESSURE_MEMORY].threshold_usec, 1));
|
||||
|
||||
if (c->pressure[PRESSURE_CPU].threshold_usec != USEC_INFINITY)
|
||||
fprintf(f, "%sCPUPressureThresholdSec: %s\n",
|
||||
prefix, FORMAT_TIMESPAN(c->pressure[PRESSURE_CPU].threshold_usec, 1));
|
||||
|
||||
if (c->moom_mem_pressure_duration_usec != USEC_INFINITY)
|
||||
fprintf(f, "%sManagedOOMMemoryPressureDurationSec: %s\n",
|
||||
@@ -2107,12 +2115,13 @@ static int unit_update_cgroup(
|
||||
cgroup_context_apply(u, target_mask, state);
|
||||
cgroup_xattr_apply(u);
|
||||
|
||||
/* For most units we expect that memory monitoring is set up before the unit is started and we won't
|
||||
* touch it after. For PID 1 this is different though, because we couldn't possibly do that given
|
||||
* that PID 1 runs before init.scope is even set up. Hence, whenever init.scope is realized, let's
|
||||
* try to open the memory pressure interface anew. */
|
||||
/* For most units we expect that pressure monitoring is set up before the unit is started and we
|
||||
* won't touch it after. For PID 1 this is different though, because we couldn't possibly do that
|
||||
* given that PID 1 runs before init.scope is even set up. Hence, whenever init.scope is realized,
|
||||
* let's try to open the pressure interfaces anew. */
|
||||
if (unit_has_name(u, SPECIAL_INIT_SCOPE))
|
||||
(void) manager_setup_memory_pressure_event_source(u->manager);
|
||||
for (PressureResource t = 0; t < _PRESSURE_RESOURCE_MAX; t++)
|
||||
(void) manager_setup_pressure_event_source(u->manager, t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+32
-11
@@ -6,6 +6,7 @@
|
||||
#include "cpu-set-util.h"
|
||||
#include "firewall-util.h"
|
||||
#include "list.h"
|
||||
#include "psi-util.h"
|
||||
|
||||
typedef struct CGroupTasksMax {
|
||||
/* If scale == 0, just use value; otherwise, value / scale.
|
||||
@@ -95,14 +96,19 @@ typedef struct CGroupSocketBindItem {
|
||||
} CGroupSocketBindItem;
|
||||
|
||||
typedef enum CGroupPressureWatch {
|
||||
CGROUP_PRESSURE_WATCH_NO, /* → tells the service payload explicitly not to watch for memory pressure */
|
||||
CGROUP_PRESSURE_WATCH_NO, /* → tells the service payload explicitly not to watch for pressure */
|
||||
CGROUP_PRESSURE_WATCH_YES,
|
||||
CGROUP_PRESSURE_WATCH_AUTO, /* → on if memory account is on anyway for the unit, otherwise off */
|
||||
CGROUP_PRESSURE_WATCH_SKIP, /* → doesn't set up memory pressure watch, but also doesn't explicitly tell payload to avoid it */
|
||||
CGROUP_PRESSURE_WATCH_AUTO, /* → on if relevant accounting is on anyway for the unit, otherwise off */
|
||||
CGROUP_PRESSURE_WATCH_SKIP, /* → doesn't set up pressure watch, but also doesn't explicitly tell payload to avoid it */
|
||||
_CGROUP_PRESSURE_WATCH_MAX,
|
||||
_CGROUP_PRESSURE_WATCH_INVALID = -EINVAL,
|
||||
} CGroupPressureWatch;
|
||||
|
||||
typedef struct CGroupPressure {
|
||||
CGroupPressureWatch watch;
|
||||
usec_t threshold_usec;
|
||||
} CGroupPressure;
|
||||
|
||||
/* The user-supplied cgroup-related configuration options. This remains mostly immutable while the service
|
||||
* manager is running (except for an occasional SetProperties() configuration change), outside of reload
|
||||
* cycles. */
|
||||
@@ -189,11 +195,8 @@ typedef struct CGroupContext {
|
||||
usec_t moom_mem_pressure_duration_usec;
|
||||
ManagedOOMPreference moom_preference;
|
||||
|
||||
/* Memory pressure logic */
|
||||
CGroupPressureWatch memory_pressure_watch;
|
||||
usec_t memory_pressure_threshold_usec;
|
||||
/* NB: For now we don't make the period configurable, not the type, nor do we allow multiple
|
||||
* triggers, nor triggers for non-memory pressure. We might add that later. */
|
||||
/* Pressure logic */
|
||||
CGroupPressure pressure[_PRESSURE_RESOURCE_MAX];
|
||||
|
||||
NFTSetContext nft_set_context;
|
||||
|
||||
@@ -353,11 +356,29 @@ void cgroup_context_free_io_device_latency(CGroupContext *c, CGroupIODeviceLaten
|
||||
void cgroup_context_remove_bpf_foreign_program(CGroupContext *c, CGroupBPFForeignProgram *p);
|
||||
void cgroup_context_remove_socket_bind(CGroupSocketBindItem **head);
|
||||
|
||||
static inline bool cgroup_context_want_memory_pressure(const CGroupContext *c) {
|
||||
static inline bool cgroup_context_want_pressure(const CGroupContext *c, PressureResource t) {
|
||||
assert(c);
|
||||
assert(t >= 0 && t < _PRESSURE_RESOURCE_MAX);
|
||||
|
||||
return c->memory_pressure_watch == CGROUP_PRESSURE_WATCH_YES ||
|
||||
(c->memory_pressure_watch == CGROUP_PRESSURE_WATCH_AUTO && c->memory_accounting);
|
||||
if (c->pressure[t].watch == CGROUP_PRESSURE_WATCH_YES)
|
||||
return true;
|
||||
|
||||
if (c->pressure[t].watch != CGROUP_PRESSURE_WATCH_AUTO)
|
||||
return false;
|
||||
|
||||
switch (t) {
|
||||
|
||||
case PRESSURE_MEMORY:
|
||||
return c->memory_accounting;
|
||||
|
||||
case PRESSURE_CPU:
|
||||
return c->cpu_weight != CGROUP_WEIGHT_INVALID ||
|
||||
c->startup_cpu_weight != CGROUP_WEIGHT_INVALID ||
|
||||
c->cpu_quota_per_sec_usec != USEC_INFINITY;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool cgroup_context_has_device_policy(const CGroupContext *c) {
|
||||
|
||||
+15
-9
@@ -427,8 +427,10 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
|
||||
SD_BUS_PROPERTY("SocketBindDeny", "a(iiqq)", property_get_socket_bind, offsetof(CGroupContext, socket_bind_deny), 0),
|
||||
SD_BUS_PROPERTY("RestrictNetworkInterfaces", "(bas)", property_get_restrict_network_interfaces, 0, 0),
|
||||
SD_BUS_PROPERTY("BindNetworkInterface", "s", NULL, offsetof(CGroupContext, bind_network_interface), 0),
|
||||
SD_BUS_PROPERTY("MemoryPressureWatch", "s", bus_property_get_cgroup_pressure_watch, offsetof(CGroupContext, memory_pressure_watch), 0),
|
||||
SD_BUS_PROPERTY("MemoryPressureThresholdUSec", "t", bus_property_get_usec, offsetof(CGroupContext, memory_pressure_threshold_usec), 0),
|
||||
SD_BUS_PROPERTY("MemoryPressureWatch", "s", bus_property_get_cgroup_pressure_watch, offsetof(CGroupContext, pressure[PRESSURE_MEMORY].watch), 0),
|
||||
SD_BUS_PROPERTY("MemoryPressureThresholdUSec", "t", bus_property_get_usec, offsetof(CGroupContext, pressure[PRESSURE_MEMORY].threshold_usec), 0),
|
||||
SD_BUS_PROPERTY("CPUPressureWatch", "s", bus_property_get_cgroup_pressure_watch, offsetof(CGroupContext, pressure[PRESSURE_CPU].watch), 0),
|
||||
SD_BUS_PROPERTY("CPUPressureThresholdUSec", "t", bus_property_get_usec, offsetof(CGroupContext, pressure[PRESSURE_CPU].threshold_usec), 0),
|
||||
SD_BUS_PROPERTY("NFTSet", "a(iiss)", property_get_cgroup_nft_set, 0, 0),
|
||||
SD_BUS_PROPERTY("CoredumpReceive", "b", bus_property_get_bool, offsetof(CGroupContext, coredump_receive), 0),
|
||||
|
||||
@@ -712,10 +714,12 @@ static int bus_cgroup_set_transient_property(
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "MemoryPressureWatch")) {
|
||||
} else if (STR_IN_SET(name, "MemoryPressureWatch", "CPUPressureWatch")) {
|
||||
CGroupPressureWatch p;
|
||||
const char *t;
|
||||
|
||||
PressureResource pt = streq(name, "MemoryPressureWatch") ? PRESSURE_MEMORY : PRESSURE_CPU;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -729,26 +733,28 @@ static int bus_cgroup_set_transient_property(
|
||||
}
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->memory_pressure_watch = p;
|
||||
unit_write_settingf(u, flags, name, "MemoryPressureWatch=%s", strempty(cgroup_pressure_watch_to_string(p)));
|
||||
c->pressure[pt].watch = p;
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, strempty(cgroup_pressure_watch_to_string(p)));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "MemoryPressureThresholdUSec")) {
|
||||
} else if (STR_IN_SET(name, "MemoryPressureThresholdUSec", "CPUPressureThresholdUSec")) {
|
||||
uint64_t t;
|
||||
|
||||
PressureResource pt = streq(name, "MemoryPressureThresholdUSec") ? PRESSURE_MEMORY : PRESSURE_CPU;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->memory_pressure_threshold_usec = t;
|
||||
c->pressure[pt].threshold_usec = t;
|
||||
|
||||
if (t == UINT64_MAX)
|
||||
unit_write_setting(u, flags, name, "MemoryPressureThresholdUSec=");
|
||||
unit_write_settingf(u, flags, name, "%s=", name);
|
||||
else
|
||||
unit_write_settingf(u, flags, name, "MemoryPressureThresholdUSec=%" PRIu64, t);
|
||||
unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, t);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -2980,8 +2980,10 @@ const sd_bus_vtable bus_manager_vtable[] = {
|
||||
SD_BUS_PROPERTY("DefaultLimitRTTIME", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("DefaultLimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(Manager, defaults.rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("DefaultTasksMax", "t", bus_property_get_tasks_max, offsetof(Manager, defaults.tasks_max), 0),
|
||||
SD_BUS_PROPERTY("DefaultMemoryPressureThresholdUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.memory_pressure_threshold_usec), 0),
|
||||
SD_BUS_PROPERTY("DefaultMemoryPressureWatch", "s", bus_property_get_cgroup_pressure_watch, offsetof(Manager, defaults.memory_pressure_watch), 0),
|
||||
SD_BUS_PROPERTY("DefaultMemoryPressureThresholdUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.pressure[PRESSURE_MEMORY].threshold_usec), 0),
|
||||
SD_BUS_PROPERTY("DefaultMemoryPressureWatch", "s", bus_property_get_cgroup_pressure_watch, offsetof(Manager, defaults.pressure[PRESSURE_MEMORY].watch), 0),
|
||||
SD_BUS_PROPERTY("DefaultCPUPressureThresholdUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.pressure[PRESSURE_CPU].threshold_usec), 0),
|
||||
SD_BUS_PROPERTY("DefaultCPUPressureWatch", "s", bus_property_get_cgroup_pressure_watch, offsetof(Manager, defaults.pressure[PRESSURE_CPU].watch), 0),
|
||||
SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("DefaultOOMPolicy", "s", bus_property_get_oom_policy, offsetof(Manager, defaults.oom_policy), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("DefaultOOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
|
||||
+83
-45
@@ -2034,7 +2034,7 @@ static int build_environment(
|
||||
const char *shell,
|
||||
dev_t journal_stream_dev,
|
||||
ino_t journal_stream_ino,
|
||||
const char *memory_pressure_path,
|
||||
char *const *pressure_path,
|
||||
bool needs_sandboxing,
|
||||
char ***ret) {
|
||||
|
||||
@@ -2215,25 +2215,38 @@ static int build_environment(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (memory_pressure_path) {
|
||||
r = strv_extend_joined_with_size(&e, &n, "MEMORY_PRESSURE_WATCH=", memory_pressure_path);
|
||||
for (PressureResource t = 0; t < _PRESSURE_RESOURCE_MAX; t++) {
|
||||
if (!pressure_path[t])
|
||||
continue;
|
||||
|
||||
const PressureResourceInfo *info = pressure_resource_get_info(t);
|
||||
|
||||
_cleanup_free_ char *env_watch = strjoin(info->env_watch, "=");
|
||||
if (!env_watch)
|
||||
return -ENOMEM;
|
||||
|
||||
r = strv_extend_joined_with_size(&e, &n, env_watch, pressure_path[t]);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!path_equal(memory_pressure_path, "/dev/null")) {
|
||||
if (!path_equal(pressure_path[t], "/dev/null")) {
|
||||
_cleanup_free_ char *b = NULL, *x = NULL;
|
||||
|
||||
if (asprintf(&b, "%s " USEC_FMT " " USEC_FMT,
|
||||
PRESSURE_DEFAULT_TYPE,
|
||||
cgroup_context->memory_pressure_threshold_usec == USEC_INFINITY ? PRESSURE_DEFAULT_THRESHOLD_USEC :
|
||||
CLAMP(cgroup_context->memory_pressure_threshold_usec, 1U, PRESSURE_DEFAULT_WINDOW_USEC),
|
||||
cgroup_context->pressure[t].threshold_usec == USEC_INFINITY ? PRESSURE_DEFAULT_THRESHOLD_USEC :
|
||||
CLAMP(cgroup_context->pressure[t].threshold_usec, 1U, PRESSURE_DEFAULT_WINDOW_USEC),
|
||||
PRESSURE_DEFAULT_WINDOW_USEC) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
if (base64mem(b, strlen(b) + 1, &x) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = strv_extend_joined_with_size(&e, &n, "MEMORY_PRESSURE_WRITE=", x);
|
||||
_cleanup_free_ char *env_write = strjoin(info->env_write, "=");
|
||||
if (!env_write)
|
||||
return -ENOMEM;
|
||||
|
||||
r = strv_extend_joined_with_size(&e, &n, env_write, x);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@@ -3855,7 +3868,7 @@ static int apply_mount_namespace(
|
||||
const ExecParameters *params,
|
||||
const ExecRuntime *runtime,
|
||||
const PinnedResource *rootfs,
|
||||
const char *memory_pressure_path,
|
||||
char *const *pressure_path,
|
||||
bool needs_sandboxing,
|
||||
uid_t exec_directory_uid,
|
||||
gid_t exec_directory_gid,
|
||||
@@ -3887,16 +3900,28 @@ static int apply_mount_namespace(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* We need to make the pressure path writable even if /sys/fs/cgroups is made read-only, as the
|
||||
* service will need to write to it in order to start the notifications. */
|
||||
if (exec_is_cgroup_mount_read_only(context) && memory_pressure_path && !streq(memory_pressure_path, "/dev/null")) {
|
||||
/* We need to make the pressure paths writable even if /sys/fs/cgroups is made read-only, as the
|
||||
* service will need to write to them in order to start the notifications. */
|
||||
bool need_pressure_rw = false;
|
||||
for (PressureResource t = 0; t < _PRESSURE_RESOURCE_MAX; t++)
|
||||
if (pressure_path[t] && !streq(pressure_path[t], "/dev/null")) {
|
||||
need_pressure_rw = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (exec_is_cgroup_mount_read_only(context) && need_pressure_rw) {
|
||||
read_write_paths_cleanup = strv_copy(context->read_write_paths);
|
||||
if (!read_write_paths_cleanup)
|
||||
return -ENOMEM;
|
||||
|
||||
r = strv_extend(&read_write_paths_cleanup, memory_pressure_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
for (PressureResource t = 0; t < _PRESSURE_RESOURCE_MAX; t++) {
|
||||
if (!pressure_path[t] || streq(pressure_path[t], "/dev/null"))
|
||||
continue;
|
||||
|
||||
r = strv_extend(&read_write_paths_cleanup, pressure_path[t]);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
read_write_paths = read_write_paths_cleanup;
|
||||
} else
|
||||
@@ -4689,7 +4714,7 @@ static int setup_delegated_namespaces(
|
||||
const ExecRuntime *runtime,
|
||||
const PinnedResource *rootfs,
|
||||
bool delegate,
|
||||
const char *memory_pressure_path,
|
||||
char *const *pressure_path,
|
||||
uid_t uid,
|
||||
gid_t gid,
|
||||
const ExecCommand *command,
|
||||
@@ -4820,7 +4845,7 @@ static int setup_delegated_namespaces(
|
||||
params,
|
||||
runtime,
|
||||
rootfs,
|
||||
memory_pressure_path,
|
||||
pressure_path,
|
||||
needs_sandboxing,
|
||||
uid,
|
||||
gid,
|
||||
@@ -5146,6 +5171,10 @@ static int setup_term_environment(const ExecContext *context, char ***env) {
|
||||
return strv_env_replace_strdup(env, "TERM=" FALLBACK_TERM);
|
||||
}
|
||||
|
||||
static inline void free_pressure_paths(char *(*p)[_PRESSURE_RESOURCE_MAX]) {
|
||||
free_many_charp(*p, _PRESSURE_RESOURCE_MAX);
|
||||
}
|
||||
|
||||
int exec_invoke(
|
||||
const ExecCommand *command,
|
||||
const ExecContext *context,
|
||||
@@ -5157,7 +5186,8 @@ int exec_invoke(
|
||||
_cleanup_strv_free_ char **our_env = NULL, **pass_env = NULL, **joined_exec_search_path = NULL, **accum_env = NULL;
|
||||
int r;
|
||||
const char *username = NULL, *groupname = NULL;
|
||||
_cleanup_free_ char *home_buffer = NULL, *memory_pressure_path = NULL, *own_user = NULL;
|
||||
_cleanup_free_ char *home_buffer = NULL, *own_user = NULL;
|
||||
_cleanup_(free_pressure_paths) char *pressure_path[_PRESSURE_RESOURCE_MAX] = {};
|
||||
const char *pwent_home = NULL, *shell = NULL;
|
||||
dev_t journal_stream_dev = 0;
|
||||
ino_t journal_stream_ino = 0;
|
||||
@@ -5753,36 +5783,44 @@ int exec_invoke(
|
||||
}
|
||||
|
||||
if (is_pressure_supported() > 0) {
|
||||
if (cgroup_context_want_memory_pressure(cgroup_context)) {
|
||||
r = cg_get_path(params->cgroup_path, "memory.pressure", &memory_pressure_path);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return log_oom();
|
||||
}
|
||||
for (PressureResource t = 0; t < _PRESSURE_RESOURCE_MAX; t++) {
|
||||
if (cgroup_context_want_pressure(cgroup_context, t)) {
|
||||
_cleanup_free_ char *pressure_file = strjoin(pressure_resource_to_string(t), ".pressure");
|
||||
if (!pressure_file) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
r = chmod_and_chown(memory_pressure_path, 0644, uid, gid);
|
||||
if (r < 0) {
|
||||
log_full_errno(r == -ENOENT || ERRNO_IS_PRIVILEGE(r) ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"Failed to adjust ownership of '%s', ignoring: %m", memory_pressure_path);
|
||||
memory_pressure_path = mfree(memory_pressure_path);
|
||||
}
|
||||
/* First we use the current cgroup path to chmod and chown the memory pressure path, then pass the path relative
|
||||
* to the cgroup namespace to environment variables and mounts. If chown/chmod fails, we should not pass memory
|
||||
* pressure path environment variable or read-write mount to the unit. This is why we check if
|
||||
* memory_pressure_path != NULL in the conditional below. */
|
||||
if (memory_pressure_path && needs_sandboxing && exec_needs_cgroup_namespace(context)) {
|
||||
memory_pressure_path = mfree(memory_pressure_path);
|
||||
r = cg_get_path("/", "memory.pressure", &memory_pressure_path);
|
||||
r = cg_get_path(params->cgroup_path, pressure_file, &pressure_path[t]);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return log_oom();
|
||||
}
|
||||
}
|
||||
} else if (cgroup_context->memory_pressure_watch == CGROUP_PRESSURE_WATCH_NO) {
|
||||
memory_pressure_path = strdup("/dev/null"); /* /dev/null is explicit indicator for turning of memory pressure watch */
|
||||
if (!memory_pressure_path) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return log_oom();
|
||||
|
||||
r = chmod_and_chown(pressure_path[t], 0644, uid, gid);
|
||||
if (r < 0) {
|
||||
log_full_errno(r == -ENOENT || ERRNO_IS_PRIVILEGE(r) ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"Failed to adjust ownership of '%s', ignoring: %m", pressure_path[t]);
|
||||
pressure_path[t] = mfree(pressure_path[t]);
|
||||
}
|
||||
/* First we use the current cgroup path to chmod and chown the pressure path, then pass the
|
||||
* path relative to the cgroup namespace to environment variables and mounts. If chown/chmod
|
||||
* fails, we should not pass pressure path environment variable or read-write mount to the
|
||||
* unit. This is why we check if pressure_path[t] != NULL in the conditional below. */
|
||||
if (pressure_path[t] && needs_sandboxing && exec_needs_cgroup_namespace(context)) {
|
||||
pressure_path[t] = mfree(pressure_path[t]);
|
||||
r = cg_get_path("/", pressure_file, &pressure_path[t]);
|
||||
if (r < 0) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return log_oom();
|
||||
}
|
||||
}
|
||||
} else if (cgroup_context->pressure[t].watch == CGROUP_PRESSURE_WATCH_NO) {
|
||||
pressure_path[t] = strdup("/dev/null"); /* /dev/null is explicit indicator for turning off pressure watch */
|
||||
if (!pressure_path[t]) {
|
||||
*exit_status = EXIT_MEMORY;
|
||||
return log_oom();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5829,7 +5867,7 @@ int exec_invoke(
|
||||
shell,
|
||||
journal_stream_dev,
|
||||
journal_stream_ino,
|
||||
memory_pressure_path,
|
||||
pressure_path,
|
||||
needs_sandboxing,
|
||||
&our_env);
|
||||
if (r < 0) {
|
||||
@@ -6047,7 +6085,7 @@ int exec_invoke(
|
||||
runtime,
|
||||
&rootfs,
|
||||
/* delegate= */ false,
|
||||
memory_pressure_path,
|
||||
pressure_path,
|
||||
uid,
|
||||
gid,
|
||||
command,
|
||||
@@ -6144,7 +6182,7 @@ int exec_invoke(
|
||||
runtime,
|
||||
&rootfs,
|
||||
/* delegate= */ true,
|
||||
memory_pressure_path,
|
||||
pressure_path,
|
||||
uid,
|
||||
gid,
|
||||
command,
|
||||
|
||||
@@ -279,7 +279,11 @@ static int exec_cgroup_context_serialize(const CGroupContext *c, FILE *f) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = serialize_item(f, "exec-cgroup-context-memory-pressure-watch", cgroup_pressure_watch_to_string(c->memory_pressure_watch));
|
||||
r = serialize_item(f, "exec-cgroup-context-memory-pressure-watch", cgroup_pressure_watch_to_string(c->pressure[PRESSURE_MEMORY].watch));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = serialize_item(f, "exec-cgroup-context-cpu-pressure-watch", cgroup_pressure_watch_to_string(c->pressure[PRESSURE_CPU].watch));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -287,8 +291,14 @@ static int exec_cgroup_context_serialize(const CGroupContext *c, FILE *f) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (c->memory_pressure_threshold_usec != USEC_INFINITY) {
|
||||
r = serialize_usec(f, "exec-cgroup-context-memory-pressure-threshold-usec", c->memory_pressure_threshold_usec);
|
||||
if (c->pressure[PRESSURE_MEMORY].threshold_usec != USEC_INFINITY) {
|
||||
r = serialize_usec(f, "exec-cgroup-context-memory-pressure-threshold-usec", c->pressure[PRESSURE_MEMORY].threshold_usec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (c->pressure[PRESSURE_CPU].threshold_usec != USEC_INFINITY) {
|
||||
r = serialize_usec(f, "exec-cgroup-context-cpu-pressure-threshold-usec", c->pressure[PRESSURE_CPU].threshold_usec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@@ -621,15 +631,23 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-watch="))) {
|
||||
c->memory_pressure_watch = cgroup_pressure_watch_from_string(val);
|
||||
if (c->memory_pressure_watch < 0)
|
||||
c->pressure[PRESSURE_MEMORY].watch = cgroup_pressure_watch_from_string(val);
|
||||
if (c->pressure[PRESSURE_MEMORY].watch < 0)
|
||||
return -EINVAL;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-cpu-pressure-watch="))) {
|
||||
c->pressure[PRESSURE_CPU].watch = cgroup_pressure_watch_from_string(val);
|
||||
if (c->pressure[PRESSURE_CPU].watch < 0)
|
||||
return -EINVAL;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-delegate-subgroup="))) {
|
||||
r = free_and_strdup(&c->delegate_subgroup, val);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-threshold-usec="))) {
|
||||
r = deserialize_usec(val, &c->memory_pressure_threshold_usec);
|
||||
r = deserialize_usec(val, &c->pressure[PRESSURE_MEMORY].threshold_usec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-cpu-pressure-threshold-usec="))) {
|
||||
r = deserialize_usec(val, &c->pressure[PRESSURE_CPU].threshold_usec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-device-allow="))) {
|
||||
|
||||
@@ -276,8 +276,10 @@
|
||||
{{type}}.SocketBindAllow, config_parse_cgroup_socket_bind, 0, offsetof({{type}}, cgroup_context.socket_bind_allow)
|
||||
{{type}}.SocketBindDeny, config_parse_cgroup_socket_bind, 0, offsetof({{type}}, cgroup_context.socket_bind_deny)
|
||||
{{type}}.RestrictNetworkInterfaces, config_parse_restrict_network_interfaces, 0, offsetof({{type}}, cgroup_context)
|
||||
{{type}}.MemoryPressureThresholdSec, config_parse_sec, 0, offsetof({{type}}, cgroup_context.memory_pressure_threshold_usec)
|
||||
{{type}}.MemoryPressureWatch, config_parse_memory_pressure_watch, 0, offsetof({{type}}, cgroup_context.memory_pressure_watch)
|
||||
{{type}}.MemoryPressureThresholdSec, config_parse_sec, 0, offsetof({{type}}, cgroup_context.pressure[PRESSURE_MEMORY].threshold_usec)
|
||||
{{type}}.MemoryPressureWatch, config_parse_pressure_watch, 0, offsetof({{type}}, cgroup_context.pressure[PRESSURE_MEMORY].watch)
|
||||
{{type}}.CPUPressureThresholdSec, config_parse_sec, 0, offsetof({{type}}, cgroup_context.pressure[PRESSURE_CPU].threshold_usec)
|
||||
{{type}}.CPUPressureWatch, config_parse_pressure_watch, 0, offsetof({{type}}, cgroup_context.pressure[PRESSURE_CPU].watch)
|
||||
{{type}}.NFTSet, config_parse_cgroup_nft_set, NFT_SET_PARSE_CGROUP, offsetof({{type}}, cgroup_context)
|
||||
{{type}}.CoredumpReceive, config_parse_bool, 0, offsetof({{type}}, cgroup_context.coredump_receive)
|
||||
{{type}}.BindNetworkInterface, config_parse_bind_network_interface, 0, offsetof({{type}}, cgroup_context)
|
||||
|
||||
@@ -154,7 +154,7 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_service_timeout_failure_mode, service_time
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_socket_bind, socket_address_bind_ipv6_only_or_bool, SocketAddressBindIPv6Only);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_oom_policy, oom_policy, OOMPolicy);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_managed_oom_preference, managed_oom_preference, ManagedOOMPreference);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_memory_pressure_watch, cgroup_pressure_watch, CGroupPressureWatch);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_pressure_watch, cgroup_pressure_watch, CGroupPressureWatch);
|
||||
DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_ip_tos, ip_tos, int, -1);
|
||||
DEFINE_CONFIG_PARSE_PTR(config_parse_cg_weight, cg_weight_parse, uint64_t);
|
||||
DEFINE_CONFIG_PARSE_PTR(config_parse_cg_cpu_weight, cg_cpu_weight_parse, uint64_t);
|
||||
|
||||
@@ -164,7 +164,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_watchdog_sec);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_tty_size);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_log_filter_patterns);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_open_file);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_memory_pressure_watch);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_pressure_watch);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_cgroup_nft_set);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_mount_node);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_concurrency_max);
|
||||
|
||||
+80
-78
@@ -747,89 +747,91 @@ static int config_parse_crash_reboot(
|
||||
|
||||
static int parse_config_file(void) {
|
||||
const ConfigTableItem items[] = {
|
||||
{ "Manager", "LogLevel", config_parse_level2, 0, NULL },
|
||||
{ "Manager", "LogTarget", config_parse_target, 0, NULL },
|
||||
{ "Manager", "LogColor", config_parse_color, 0, NULL },
|
||||
{ "Manager", "LogLocation", config_parse_location, 0, NULL },
|
||||
{ "Manager", "LogTime", config_parse_time, 0, NULL },
|
||||
{ "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core },
|
||||
{ "Manager", "CrashChVT", /* legacy */ config_parse_crash_chvt, 0, &arg_crash_chvt },
|
||||
{ "Manager", "CrashChangeVT", config_parse_crash_chvt, 0, &arg_crash_chvt },
|
||||
{ "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
|
||||
{ "Manager", "CrashReboot", config_parse_crash_reboot, 0, &arg_crash_action },
|
||||
{ "Manager", "CrashAction", config_parse_crash_action, 0, &arg_crash_action },
|
||||
{ "Manager", "ShowStatus", config_parse_show_status, 0, &arg_show_status },
|
||||
{ "Manager", "StatusUnitFormat", config_parse_status_unit_format, 0, &arg_status_unit_format },
|
||||
{ "Manager", "CPUAffinity", config_parse_cpu_set, 0, &arg_cpu_affinity },
|
||||
{ "Manager", "NUMAPolicy", config_parse_numa_policy, 0, &arg_numa_policy.type },
|
||||
{ "Manager", "NUMAMask", config_parse_numa_mask, 0, &arg_numa_policy.nodes },
|
||||
{ "Manager", "JoinControllers", config_parse_warn_compat, DISABLED_LEGACY, NULL },
|
||||
{ "Manager", "RuntimeWatchdogSec", config_parse_watchdog_sec, 0, &arg_runtime_watchdog },
|
||||
{ "Manager", "RuntimeWatchdogPreSec", config_parse_watchdog_sec, 0, &arg_pretimeout_watchdog },
|
||||
{ "Manager", "RebootWatchdogSec", config_parse_watchdog_sec, 0, &arg_reboot_watchdog },
|
||||
{ "Manager", "ShutdownWatchdogSec", config_parse_watchdog_sec, 0, &arg_reboot_watchdog }, /* obsolete alias */
|
||||
{ "Manager", "KExecWatchdogSec", config_parse_watchdog_sec, 0, &arg_kexec_watchdog },
|
||||
{ "Manager", "WatchdogDevice", config_parse_path, 0, &arg_watchdog_device },
|
||||
{ "Manager", "RuntimeWatchdogPreGovernor", config_parse_string, CONFIG_PARSE_STRING_SAFE, &arg_watchdog_pretimeout_governor },
|
||||
{ "Manager", "CapabilityBoundingSet", config_parse_capability_set, 0, &arg_capability_bounding_set },
|
||||
{ "Manager", "NoNewPrivileges", config_parse_bool, 0, &arg_no_new_privs },
|
||||
{ "Manager", "ProtectSystem", config_parse_protect_system_pid1, 0, &arg_protect_system },
|
||||
{ "Manager", "LogLevel", config_parse_level2, 0, NULL },
|
||||
{ "Manager", "LogTarget", config_parse_target, 0, NULL },
|
||||
{ "Manager", "LogColor", config_parse_color, 0, NULL },
|
||||
{ "Manager", "LogLocation", config_parse_location, 0, NULL },
|
||||
{ "Manager", "LogTime", config_parse_time, 0, NULL },
|
||||
{ "Manager", "DumpCore", config_parse_bool, 0, &arg_dump_core },
|
||||
{ "Manager", "CrashChVT", /* legacy */ config_parse_crash_chvt, 0, &arg_crash_chvt },
|
||||
{ "Manager", "CrashChangeVT", config_parse_crash_chvt, 0, &arg_crash_chvt },
|
||||
{ "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
|
||||
{ "Manager", "CrashReboot", config_parse_crash_reboot, 0, &arg_crash_action },
|
||||
{ "Manager", "CrashAction", config_parse_crash_action, 0, &arg_crash_action },
|
||||
{ "Manager", "ShowStatus", config_parse_show_status, 0, &arg_show_status },
|
||||
{ "Manager", "StatusUnitFormat", config_parse_status_unit_format, 0, &arg_status_unit_format },
|
||||
{ "Manager", "CPUAffinity", config_parse_cpu_set, 0, &arg_cpu_affinity },
|
||||
{ "Manager", "NUMAPolicy", config_parse_numa_policy, 0, &arg_numa_policy.type },
|
||||
{ "Manager", "NUMAMask", config_parse_numa_mask, 0, &arg_numa_policy.nodes },
|
||||
{ "Manager", "JoinControllers", config_parse_warn_compat, DISABLED_LEGACY, NULL },
|
||||
{ "Manager", "RuntimeWatchdogSec", config_parse_watchdog_sec, 0, &arg_runtime_watchdog },
|
||||
{ "Manager", "RuntimeWatchdogPreSec", config_parse_watchdog_sec, 0, &arg_pretimeout_watchdog },
|
||||
{ "Manager", "RebootWatchdogSec", config_parse_watchdog_sec, 0, &arg_reboot_watchdog },
|
||||
{ "Manager", "ShutdownWatchdogSec", config_parse_watchdog_sec, 0, &arg_reboot_watchdog }, /* obsolete alias */
|
||||
{ "Manager", "KExecWatchdogSec", config_parse_watchdog_sec, 0, &arg_kexec_watchdog },
|
||||
{ "Manager", "WatchdogDevice", config_parse_path, 0, &arg_watchdog_device },
|
||||
{ "Manager", "RuntimeWatchdogPreGovernor", config_parse_string, CONFIG_PARSE_STRING_SAFE, &arg_watchdog_pretimeout_governor },
|
||||
{ "Manager", "CapabilityBoundingSet", config_parse_capability_set, 0, &arg_capability_bounding_set },
|
||||
{ "Manager", "NoNewPrivileges", config_parse_bool, 0, &arg_no_new_privs },
|
||||
{ "Manager", "ProtectSystem", config_parse_protect_system_pid1, 0, &arg_protect_system },
|
||||
#if HAVE_SECCOMP
|
||||
{ "Manager", "SystemCallArchitectures", config_parse_syscall_archs, 0, &arg_syscall_archs },
|
||||
{ "Manager", "SystemCallArchitectures", config_parse_syscall_archs, 0, &arg_syscall_archs },
|
||||
#else
|
||||
{ "Manager", "SystemCallArchitectures", config_parse_warn_compat, DISABLED_CONFIGURATION, NULL },
|
||||
{ "Manager", "SystemCallArchitectures", config_parse_warn_compat, DISABLED_CONFIGURATION, NULL },
|
||||
#endif
|
||||
{ "Manager", "TimerSlackNSec", config_parse_nsec, 0, &arg_timer_slack_nsec },
|
||||
{ "Manager", "DefaultTimerAccuracySec", config_parse_sec, 0, &arg_defaults.timer_accuracy_usec },
|
||||
{ "Manager", "DefaultStandardOutput", config_parse_output_restricted, 0, &arg_defaults.std_output },
|
||||
{ "Manager", "DefaultStandardError", config_parse_output_restricted, 0, &arg_defaults.std_error },
|
||||
{ "Manager", "DefaultTimeoutStartSec", config_parse_sec, 0, &arg_defaults.timeout_start_usec },
|
||||
{ "Manager", "DefaultTimeoutStopSec", config_parse_sec, 0, &arg_defaults.timeout_stop_usec },
|
||||
{ "Manager", "DefaultTimeoutAbortSec", config_parse_default_timeout_abort, 0, NULL },
|
||||
{ "Manager", "DefaultDeviceTimeoutSec", config_parse_sec, 0, &arg_defaults.device_timeout_usec },
|
||||
{ "Manager", "DefaultRestartSec", config_parse_sec, 0, &arg_defaults.restart_usec },
|
||||
{ "Manager", "DefaultStartLimitInterval", config_parse_sec, 0, &arg_defaults.start_limit.interval }, /* obsolete alias */
|
||||
{ "Manager", "DefaultStartLimitIntervalSec", config_parse_sec, 0, &arg_defaults.start_limit.interval },
|
||||
{ "Manager", "DefaultStartLimitBurst", config_parse_unsigned, 0, &arg_defaults.start_limit.burst },
|
||||
{ "Manager", "DefaultRestrictSUIDSGID", config_parse_bool, 0, &arg_defaults.restrict_suid_sgid },
|
||||
{ "Manager", "DefaultEnvironment", config_parse_environ, arg_runtime_scope, &arg_default_environment },
|
||||
{ "Manager", "ManagerEnvironment", config_parse_environ, arg_runtime_scope, &arg_manager_environment },
|
||||
{ "Manager", "DefaultLimitCPU", config_parse_rlimit, RLIMIT_CPU, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitFSIZE", config_parse_rlimit, RLIMIT_FSIZE, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitDATA", config_parse_rlimit, RLIMIT_DATA, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitSTACK", config_parse_rlimit, RLIMIT_STACK, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitCORE", config_parse_rlimit, RLIMIT_CORE, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitRSS", config_parse_rlimit, RLIMIT_RSS, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitNOFILE", config_parse_rlimit, RLIMIT_NOFILE, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitAS", config_parse_rlimit, RLIMIT_AS, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitNPROC", config_parse_rlimit, RLIMIT_NPROC, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitMEMLOCK", config_parse_rlimit, RLIMIT_MEMLOCK, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitLOCKS", config_parse_rlimit, RLIMIT_LOCKS, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitSIGPENDING", config_parse_rlimit, RLIMIT_SIGPENDING, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitMSGQUEUE", config_parse_rlimit, RLIMIT_MSGQUEUE, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitNICE", config_parse_rlimit, RLIMIT_NICE, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitRTPRIO", config_parse_rlimit, RLIMIT_RTPRIO, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitRTTIME", config_parse_rlimit, RLIMIT_RTTIME, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultCPUAccounting", config_parse_warn_compat, DISABLED_LEGACY, NULL },
|
||||
{ "Manager", "DefaultIOAccounting", config_parse_bool, 0, &arg_defaults.io_accounting },
|
||||
{ "Manager", "DefaultIPAccounting", config_parse_bool, 0, &arg_defaults.ip_accounting },
|
||||
{ "Manager", "DefaultBlockIOAccounting", config_parse_warn_compat, DISABLED_LEGACY, NULL },
|
||||
{ "Manager", "DefaultMemoryAccounting", config_parse_bool, 0, &arg_defaults.memory_accounting },
|
||||
{ "Manager", "DefaultTasksAccounting", config_parse_bool, 0, &arg_defaults.tasks_accounting },
|
||||
{ "Manager", "DefaultTasksMax", config_parse_tasks_max, 0, &arg_defaults.tasks_max },
|
||||
{ "Manager", "DefaultMemoryPressureThresholdSec", config_parse_sec, 0, &arg_defaults.memory_pressure_threshold_usec },
|
||||
{ "Manager", "DefaultMemoryPressureWatch", config_parse_memory_pressure_watch, 0, &arg_defaults.memory_pressure_watch },
|
||||
{ "Manager", "CtrlAltDelBurstAction", config_parse_emergency_action, arg_runtime_scope, &arg_cad_burst_action },
|
||||
{ "Manager", "DefaultOOMPolicy", config_parse_oom_policy, 0, &arg_defaults.oom_policy },
|
||||
{ "Manager", "DefaultOOMScoreAdjust", config_parse_oom_score_adjust, 0, NULL },
|
||||
{ "Manager", "ReloadLimitIntervalSec", config_parse_sec, 0, &arg_reload_limit_interval_sec },
|
||||
{ "Manager", "ReloadLimitBurst", config_parse_unsigned, 0, &arg_reload_limit_burst },
|
||||
{ "Manager", "DefaultMemoryZSwapWriteback", config_parse_bool, 0, &arg_defaults.memory_zswap_writeback },
|
||||
{ "Manager", "MinimumUptimeSec", config_parse_sec, 0, &arg_minimum_uptime_usec },
|
||||
{ "Manager", "TimerSlackNSec", config_parse_nsec, 0, &arg_timer_slack_nsec },
|
||||
{ "Manager", "DefaultTimerAccuracySec", config_parse_sec, 0, &arg_defaults.timer_accuracy_usec },
|
||||
{ "Manager", "DefaultStandardOutput", config_parse_output_restricted, 0, &arg_defaults.std_output },
|
||||
{ "Manager", "DefaultStandardError", config_parse_output_restricted, 0, &arg_defaults.std_error },
|
||||
{ "Manager", "DefaultTimeoutStartSec", config_parse_sec, 0, &arg_defaults.timeout_start_usec },
|
||||
{ "Manager", "DefaultTimeoutStopSec", config_parse_sec, 0, &arg_defaults.timeout_stop_usec },
|
||||
{ "Manager", "DefaultTimeoutAbortSec", config_parse_default_timeout_abort, 0, NULL },
|
||||
{ "Manager", "DefaultDeviceTimeoutSec", config_parse_sec, 0, &arg_defaults.device_timeout_usec },
|
||||
{ "Manager", "DefaultRestartSec", config_parse_sec, 0, &arg_defaults.restart_usec },
|
||||
{ "Manager", "DefaultStartLimitInterval", config_parse_sec, 0, &arg_defaults.start_limit.interval }, /* obsolete alias */
|
||||
{ "Manager", "DefaultStartLimitIntervalSec", config_parse_sec, 0, &arg_defaults.start_limit.interval },
|
||||
{ "Manager", "DefaultStartLimitBurst", config_parse_unsigned, 0, &arg_defaults.start_limit.burst },
|
||||
{ "Manager", "DefaultRestrictSUIDSGID", config_parse_bool, 0, &arg_defaults.restrict_suid_sgid },
|
||||
{ "Manager", "DefaultEnvironment", config_parse_environ, arg_runtime_scope, &arg_default_environment },
|
||||
{ "Manager", "ManagerEnvironment", config_parse_environ, arg_runtime_scope, &arg_manager_environment },
|
||||
{ "Manager", "DefaultLimitCPU", config_parse_rlimit, RLIMIT_CPU, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitFSIZE", config_parse_rlimit, RLIMIT_FSIZE, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitDATA", config_parse_rlimit, RLIMIT_DATA, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitSTACK", config_parse_rlimit, RLIMIT_STACK, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitCORE", config_parse_rlimit, RLIMIT_CORE, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitRSS", config_parse_rlimit, RLIMIT_RSS, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitNOFILE", config_parse_rlimit, RLIMIT_NOFILE, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitAS", config_parse_rlimit, RLIMIT_AS, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitNPROC", config_parse_rlimit, RLIMIT_NPROC, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitMEMLOCK", config_parse_rlimit, RLIMIT_MEMLOCK, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitLOCKS", config_parse_rlimit, RLIMIT_LOCKS, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitSIGPENDING", config_parse_rlimit, RLIMIT_SIGPENDING, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitMSGQUEUE", config_parse_rlimit, RLIMIT_MSGQUEUE, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitNICE", config_parse_rlimit, RLIMIT_NICE, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitRTPRIO", config_parse_rlimit, RLIMIT_RTPRIO, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultLimitRTTIME", config_parse_rlimit, RLIMIT_RTTIME, arg_defaults.rlimit },
|
||||
{ "Manager", "DefaultCPUAccounting", config_parse_warn_compat, DISABLED_LEGACY, NULL },
|
||||
{ "Manager", "DefaultIOAccounting", config_parse_bool, 0, &arg_defaults.io_accounting },
|
||||
{ "Manager", "DefaultIPAccounting", config_parse_bool, 0, &arg_defaults.ip_accounting },
|
||||
{ "Manager", "DefaultBlockIOAccounting", config_parse_warn_compat, DISABLED_LEGACY, NULL },
|
||||
{ "Manager", "DefaultMemoryAccounting", config_parse_bool, 0, &arg_defaults.memory_accounting },
|
||||
{ "Manager", "DefaultTasksAccounting", config_parse_bool, 0, &arg_defaults.tasks_accounting },
|
||||
{ "Manager", "DefaultTasksMax", config_parse_tasks_max, 0, &arg_defaults.tasks_max },
|
||||
{ "Manager", "DefaultMemoryPressureThresholdSec", config_parse_sec, 0, &arg_defaults.pressure[PRESSURE_MEMORY].threshold_usec },
|
||||
{ "Manager", "DefaultMemoryPressureWatch", config_parse_pressure_watch, 0, &arg_defaults.pressure[PRESSURE_MEMORY].watch },
|
||||
{ "Manager", "DefaultCPUPressureThresholdSec", config_parse_sec, 0, &arg_defaults.pressure[PRESSURE_CPU].threshold_usec },
|
||||
{ "Manager", "DefaultCPUPressureWatch", config_parse_pressure_watch, 0, &arg_defaults.pressure[PRESSURE_CPU].watch },
|
||||
{ "Manager", "CtrlAltDelBurstAction", config_parse_emergency_action, arg_runtime_scope, &arg_cad_burst_action },
|
||||
{ "Manager", "DefaultOOMPolicy", config_parse_oom_policy, 0, &arg_defaults.oom_policy },
|
||||
{ "Manager", "DefaultOOMScoreAdjust", config_parse_oom_score_adjust, 0, NULL },
|
||||
{ "Manager", "ReloadLimitIntervalSec", config_parse_sec, 0, &arg_reload_limit_interval_sec },
|
||||
{ "Manager", "ReloadLimitBurst", config_parse_unsigned, 0, &arg_reload_limit_burst },
|
||||
{ "Manager", "DefaultMemoryZSwapWriteback", config_parse_bool, 0, &arg_defaults.memory_zswap_writeback },
|
||||
{ "Manager", "MinimumUptimeSec", config_parse_sec, 0, &arg_minimum_uptime_usec },
|
||||
#if ENABLE_SMACK
|
||||
{ "Manager", "DefaultSmackProcessLabel", config_parse_string, 0, &arg_defaults.smack_process_label },
|
||||
{ "Manager", "DefaultSmackProcessLabel", config_parse_string, 0, &arg_defaults.smack_process_label },
|
||||
#else
|
||||
{ "Manager", "DefaultSmackProcessLabel", config_parse_warn_compat, DISABLED_CONFIGURATION, NULL },
|
||||
{ "Manager", "DefaultSmackProcessLabel", config_parse_warn_compat, DISABLED_CONFIGURATION, NULL },
|
||||
#endif
|
||||
{}
|
||||
};
|
||||
|
||||
+36
-19
@@ -616,6 +616,8 @@ static char** sanitize_environment(char **l) {
|
||||
l,
|
||||
"CACHE_DIRECTORY",
|
||||
"CONFIGURATION_DIRECTORY",
|
||||
"CPU_PRESSURE_WATCH",
|
||||
"CPU_PRESSURE_WRITE",
|
||||
"CREDENTIALS_DIRECTORY",
|
||||
"EXIT_CODE",
|
||||
"EXIT_STATUS",
|
||||
@@ -796,26 +798,37 @@ static int manager_setup_sigchld_event_source(Manager *m) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int manager_setup_memory_pressure_event_source(Manager *m) {
|
||||
typedef int (*pressure_add_t)(sd_event *, sd_event_source **, sd_event_handler_t, void *);
|
||||
typedef int (*pressure_set_period_t)(sd_event_source *, usec_t, usec_t);
|
||||
|
||||
static const struct {
|
||||
pressure_add_t add;
|
||||
pressure_set_period_t set_period;
|
||||
} pressure_dispatch_table[_PRESSURE_RESOURCE_MAX] = {
|
||||
[PRESSURE_MEMORY] = { sd_event_add_memory_pressure, sd_event_source_set_memory_pressure_period },
|
||||
[PRESSURE_CPU] = { sd_event_add_cpu_pressure, sd_event_source_set_cpu_pressure_period },
|
||||
};
|
||||
|
||||
int manager_setup_pressure_event_source(Manager *m, PressureResource t) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(t >= 0 && t < _PRESSURE_RESOURCE_MAX);
|
||||
|
||||
m->memory_pressure_event_source = sd_event_source_disable_unref(m->memory_pressure_event_source);
|
||||
m->pressure_event_source[t] = sd_event_source_disable_unref(m->pressure_event_source[t]);
|
||||
|
||||
r = sd_event_add_memory_pressure(m->event, &m->memory_pressure_event_source, NULL, NULL);
|
||||
r = pressure_dispatch_table[t].add(m->event, &m->pressure_event_source[t], NULL, NULL);
|
||||
if (r < 0)
|
||||
log_full_errno(ERRNO_IS_NOT_SUPPORTED(r) || ERRNO_IS_PRIVILEGE(r) || (r == -EHOSTDOWN) ? LOG_DEBUG : LOG_NOTICE, r,
|
||||
"Failed to establish memory pressure event source, ignoring: %m");
|
||||
else if (m->defaults.memory_pressure_threshold_usec != USEC_INFINITY) {
|
||||
"Failed to establish %s pressure event source, ignoring: %m", pressure_resource_to_string(t));
|
||||
else if (m->defaults.pressure[t].threshold_usec != USEC_INFINITY) {
|
||||
|
||||
/* If there's a default memory pressure threshold set, also apply it to the service manager itself */
|
||||
r = sd_event_source_set_memory_pressure_period(
|
||||
m->memory_pressure_event_source,
|
||||
m->defaults.memory_pressure_threshold_usec,
|
||||
MEMORY_PRESSURE_DEFAULT_WINDOW_USEC);
|
||||
r = pressure_dispatch_table[t].set_period(
|
||||
m->pressure_event_source[t],
|
||||
m->defaults.pressure[t].threshold_usec,
|
||||
PRESSURE_DEFAULT_WINDOW_USEC);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to adjust memory pressure threshold, ignoring: %m");
|
||||
log_warning_errno(r, "Failed to adjust %s pressure threshold, ignoring: %m", pressure_resource_to_string(t));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1001,9 +1014,11 @@ int manager_new(RuntimeScope runtime_scope, ManagerTestRunFlags test_run_flags,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = manager_setup_memory_pressure_event_source(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
for (PressureResource t = 0; t < _PRESSURE_RESOURCE_MAX; t++) {
|
||||
r = manager_setup_pressure_event_source(m, t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
#if HAVE_LIBBPF
|
||||
if (MANAGER_IS_SYSTEM(m) && bpf_restrict_fs_supported(/* initialize= */ true)) {
|
||||
@@ -1711,7 +1726,8 @@ Manager* manager_free(Manager *m) {
|
||||
sd_event_source_unref(m->user_lookup_event_source);
|
||||
sd_event_source_unref(m->handoff_timestamp_event_source);
|
||||
sd_event_source_unref(m->pidref_event_source);
|
||||
sd_event_source_unref(m->memory_pressure_event_source);
|
||||
FOREACH_ARRAY(pressure_event_source, m->pressure_event_source, _PRESSURE_RESOURCE_MAX)
|
||||
sd_event_source_unref(*pressure_event_source);
|
||||
|
||||
safe_close(m->signal_fd);
|
||||
safe_close(m->notify_fd);
|
||||
@@ -4300,8 +4316,7 @@ int manager_set_unit_defaults(Manager *m, const UnitDefaults *defaults) {
|
||||
m->defaults.oom_score_adjust = defaults->oom_score_adjust;
|
||||
m->defaults.oom_score_adjust_set = defaults->oom_score_adjust_set;
|
||||
|
||||
m->defaults.memory_pressure_watch = defaults->memory_pressure_watch;
|
||||
m->defaults.memory_pressure_threshold_usec = defaults->memory_pressure_threshold_usec;
|
||||
memcpy(m->defaults.pressure, defaults->pressure, sizeof(m->defaults.pressure));
|
||||
|
||||
m->defaults.memory_zswap_writeback = defaults->memory_zswap_writeback;
|
||||
|
||||
@@ -5195,8 +5210,10 @@ void unit_defaults_init(UnitDefaults *defaults, RuntimeScope scope) {
|
||||
.tasks_max = DEFAULT_TASKS_MAX,
|
||||
.timer_accuracy_usec = 1 * USEC_PER_MINUTE,
|
||||
|
||||
.memory_pressure_watch = CGROUP_PRESSURE_WATCH_AUTO,
|
||||
.memory_pressure_threshold_usec = MEMORY_PRESSURE_DEFAULT_THRESHOLD_USEC,
|
||||
.pressure = {
|
||||
[PRESSURE_MEMORY] = { .watch = CGROUP_PRESSURE_WATCH_AUTO, .threshold_usec = PRESSURE_DEFAULT_THRESHOLD_USEC },
|
||||
[PRESSURE_CPU] = { .watch = CGROUP_PRESSURE_WATCH_AUTO, .threshold_usec = PRESSURE_DEFAULT_THRESHOLD_USEC },
|
||||
},
|
||||
|
||||
.oom_policy = OOM_STOP,
|
||||
.oom_score_adjust_set = false,
|
||||
|
||||
+3
-4
@@ -149,8 +149,7 @@ typedef struct UnitDefaults {
|
||||
|
||||
bool memory_zswap_writeback;
|
||||
|
||||
CGroupPressureWatch memory_pressure_watch;
|
||||
usec_t memory_pressure_threshold_usec;
|
||||
CGroupPressure pressure[_PRESSURE_RESOURCE_MAX];
|
||||
|
||||
char *smack_process_label;
|
||||
|
||||
@@ -481,7 +480,7 @@ typedef struct Manager {
|
||||
/* Dump*() are slow, so always rate limit them to 10 per 10 minutes */
|
||||
RateLimit dump_ratelimit;
|
||||
|
||||
sd_event_source *memory_pressure_event_source;
|
||||
sd_event_source *pressure_event_source[_PRESSURE_RESOURCE_MAX];
|
||||
|
||||
/* For NFTSet= */
|
||||
sd_netlink *nfnl;
|
||||
@@ -562,7 +561,7 @@ void manager_unwatch_pidref(Manager *m, const PidRef *pid);
|
||||
|
||||
unsigned manager_dispatch_load_queue(Manager *m);
|
||||
|
||||
int manager_setup_memory_pressure_event_source(Manager *m);
|
||||
int manager_setup_pressure_event_source(Manager *m, PressureResource t);
|
||||
|
||||
int manager_default_environment(Manager *m);
|
||||
int manager_transient_environment_add(Manager *m, char **plus);
|
||||
|
||||
@@ -78,6 +78,8 @@
|
||||
#DefaultLimitRTTIME=
|
||||
#DefaultMemoryPressureThresholdSec=200ms
|
||||
#DefaultMemoryPressureWatch=auto
|
||||
#DefaultCPUPressureThresholdSec=200ms
|
||||
#DefaultCPUPressureWatch=auto
|
||||
#DefaultOOMPolicy=stop
|
||||
#DefaultSmackProcessLabel=
|
||||
#DefaultRestrictSUIDSGID=
|
||||
|
||||
+2
-3
@@ -178,10 +178,9 @@ static void unit_init(Unit *u) {
|
||||
if (u->type != UNIT_SLICE)
|
||||
cc->tasks_max = u->manager->defaults.tasks_max;
|
||||
|
||||
cc->memory_pressure_watch = u->manager->defaults.memory_pressure_watch;
|
||||
cc->memory_pressure_threshold_usec = u->manager->defaults.memory_pressure_threshold_usec;
|
||||
|
||||
cc->memory_zswap_writeback = u->manager->defaults.memory_zswap_writeback;
|
||||
|
||||
memcpy(cc->pressure, u->manager->defaults.pressure, sizeof(cc->pressure));
|
||||
}
|
||||
|
||||
ec = unit_get_exec_context(u);
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
#DefaultLimitRTTIME=
|
||||
#DefaultMemoryPressureThresholdSec=200ms
|
||||
#DefaultMemoryPressureWatch=auto
|
||||
#DefaultCPUPressureThresholdSec=200ms
|
||||
#DefaultCPUPressureWatch=auto
|
||||
#DefaultSmackProcessLabel=
|
||||
#DefaultRestrictSUIDSGID=
|
||||
#ReloadLimitIntervalSec=
|
||||
|
||||
@@ -323,8 +323,10 @@ int unit_cgroup_context_build_json(sd_json_variant **ret, const char *name, void
|
||||
JSON_BUILD_PAIR_UNSIGNED_NON_ZERO("ManagedOOMMemoryPressureLimit", c->moom_mem_pressure_limit),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("ManagedOOMMemoryPressureDurationUSec", c->moom_mem_pressure_duration_usec),
|
||||
SD_JSON_BUILD_PAIR_STRING("ManagedOOMPreference", managed_oom_preference_to_string(c->moom_preference)),
|
||||
SD_JSON_BUILD_PAIR_STRING("MemoryPressureWatch", cgroup_pressure_watch_to_string(c->memory_pressure_watch)),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("MemoryPressureThresholdUSec", c->memory_pressure_threshold_usec),
|
||||
SD_JSON_BUILD_PAIR_STRING("MemoryPressureWatch", cgroup_pressure_watch_to_string(c->pressure[PRESSURE_MEMORY].watch)),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("MemoryPressureThresholdUSec", c->pressure[PRESSURE_MEMORY].threshold_usec),
|
||||
SD_JSON_BUILD_PAIR_STRING("CPUPressureWatch", cgroup_pressure_watch_to_string(c->pressure[PRESSURE_CPU].watch)),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("CPUPressureThresholdUSec", c->pressure[PRESSURE_CPU].threshold_usec),
|
||||
|
||||
/* Others */
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CoredumpReceive", c->coredump_receive));
|
||||
|
||||
@@ -106,8 +106,10 @@ static int manager_context_build_json(sd_json_variant **ret, const char *name, v
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("DefaultTasksAccounting", m->defaults.tasks_accounting),
|
||||
SD_JSON_BUILD_PAIR_CALLBACK("DefaultLimits", rlimit_table_build_json, m->defaults.rlimit),
|
||||
SD_JSON_BUILD_PAIR_UNSIGNED("DefaultTasksMax", cgroup_tasks_max_resolve(&m->defaults.tasks_max)),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("DefaultMemoryPressureThresholdUSec", m->defaults.memory_pressure_threshold_usec),
|
||||
SD_JSON_BUILD_PAIR_STRING("DefaultMemoryPressureWatch", cgroup_pressure_watch_to_string(m->defaults.memory_pressure_watch)),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("DefaultMemoryPressureThresholdUSec", m->defaults.pressure[PRESSURE_MEMORY].threshold_usec),
|
||||
SD_JSON_BUILD_PAIR_STRING("DefaultMemoryPressureWatch", cgroup_pressure_watch_to_string(m->defaults.pressure[PRESSURE_MEMORY].watch)),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("DefaultCPUPressureThresholdUSec", m->defaults.pressure[PRESSURE_CPU].threshold_usec),
|
||||
SD_JSON_BUILD_PAIR_STRING("DefaultCPUPressureWatch", cgroup_pressure_watch_to_string(m->defaults.pressure[PRESSURE_CPU].watch)),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("RuntimeWatchdogUSec", manager_get_watchdog(m, WATCHDOG_RUNTIME)),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("RebootWatchdogUSec", manager_get_watchdog(m, WATCHDOG_REBOOT)),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("KExecWatchdogUSec", manager_get_watchdog(m, WATCHDOG_KEXEC)),
|
||||
|
||||
@@ -1949,8 +1949,7 @@ static int event_add_pressure(
|
||||
assert_return(e->state != SD_EVENT_FINISHED, -ESTALE);
|
||||
assert_return(!event_origin_changed(e), -ECHILD);
|
||||
|
||||
assert(resource >= 0 && resource < _PRESSURE_RESOURCE_MAX);
|
||||
const PressureResourceInfo *info = &pressure_resource_info[resource];
|
||||
const PressureResourceInfo *info = pressure_resource_get_info(resource);
|
||||
|
||||
if (!callback)
|
||||
callback = default_callback;
|
||||
|
||||
@@ -2383,6 +2383,7 @@ static const BusProperty cgroup_properties[] = {
|
||||
{ "ManagedOOMMemoryPressure", bus_append_string },
|
||||
{ "ManagedOOMPreference", bus_append_string },
|
||||
{ "MemoryPressureWatch", bus_append_string },
|
||||
{ "CPUPressureWatch", bus_append_string },
|
||||
{ "DelegateSubgroup", bus_append_string },
|
||||
{ "ManagedOOMMemoryPressureLimit", bus_append_parse_permyriad },
|
||||
{ "MemoryAccounting", bus_append_parse_boolean },
|
||||
@@ -2421,6 +2422,7 @@ static const BusProperty cgroup_properties[] = {
|
||||
{ "SocketBindAllow", bus_append_socket_filter },
|
||||
{ "SocketBindDeny", bus_append_socket_filter },
|
||||
{ "MemoryPressureThresholdSec", bus_append_parse_sec_rename },
|
||||
{ "CPUPressureThresholdSec", bus_append_parse_sec_rename },
|
||||
{ "NFTSet", bus_append_nft_set },
|
||||
{ "BindNetworkInterface", bus_append_string },
|
||||
|
||||
|
||||
@@ -64,6 +64,10 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_FIELD(DefaultMemoryPressureThresholdUSec, SD_VARLINK_INT, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd-system.conf.html#DefaultMemoryPressureWatch="),
|
||||
SD_VARLINK_DEFINE_FIELD(DefaultMemoryPressureWatch, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd-system.conf.html#DefaultCPUPressureThresholdUSec="),
|
||||
SD_VARLINK_DEFINE_FIELD(DefaultCPUPressureThresholdUSec, SD_VARLINK_INT, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd-system.conf.html#DefaultCPUPressureWatch="),
|
||||
SD_VARLINK_DEFINE_FIELD(DefaultCPUPressureWatch, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd-system.conf.html#RuntimeWatchdogSec="),
|
||||
SD_VARLINK_DEFINE_FIELD(RuntimeWatchdogUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd-system.conf.html#RebootWatchdogSec="),
|
||||
|
||||
@@ -228,6 +228,10 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
SD_VARLINK_DEFINE_FIELD(MemoryPressureWatch, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#MemoryPressureThresholdSec="),
|
||||
SD_VARLINK_DEFINE_FIELD(MemoryPressureThresholdUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#CPUPressureWatch="),
|
||||
SD_VARLINK_DEFINE_FIELD(CPUPressureWatch, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#CPUPressureThresholdSec="),
|
||||
SD_VARLINK_DEFINE_FIELD(CPUPressureThresholdUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
|
||||
/* Others */
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether to forward coredumps for processes that crash within this cgroup"),
|
||||
|
||||
@@ -91,7 +91,7 @@ foreach dirname : [
|
||||
'TEST-74-AUX-UTILS',
|
||||
'TEST-75-RESOLVED',
|
||||
'TEST-78-SIGQUEUE',
|
||||
'TEST-79-MEMPRESS',
|
||||
'TEST-79-PRESSURE',
|
||||
'TEST-80-NOTIFYACCESS',
|
||||
'TEST-81-GENERATORS',
|
||||
'TEST-82-SOFTREBOOT',
|
||||
|
||||
@@ -13,7 +13,7 @@ if ! cat /proc/pressure/memory >/dev/null ; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
CGROUP=/sys/fs/cgroup/"$(systemctl show TEST-79-MEMPRESS.service -P ControlGroup)"
|
||||
CGROUP=/sys/fs/cgroup/"$(systemctl show TEST-79-PRESSURE.service -P ControlGroup)"
|
||||
test -d "$CGROUP"
|
||||
|
||||
if ! test -f "$CGROUP"/memory.pressure ; then
|
||||
@@ -61,4 +61,57 @@ systemd-run \
|
||||
|
||||
rm "$SCRIPT"
|
||||
|
||||
# Now test CPU pressure
|
||||
|
||||
if ! cat /proc/pressure/cpu >/dev/null ; then
|
||||
echo "kernel has no CPU PSI support." >&2
|
||||
echo OK >/testok
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! test -f "$CGROUP"/cpu.pressure ; then
|
||||
echo "No CPU accounting/PSI delegated via cgroup, can't test." >&2
|
||||
echo OK >/testok
|
||||
exit 0
|
||||
fi
|
||||
|
||||
UNIT="test-cpupress-$RANDOM.service"
|
||||
SCRIPT="/tmp/cpupress-$RANDOM.sh"
|
||||
|
||||
cat >"$SCRIPT" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
export
|
||||
id
|
||||
|
||||
test -n "$CPU_PRESSURE_WATCH"
|
||||
test "$CPU_PRESSURE_WATCH" != /dev/null
|
||||
test -w "$CPU_PRESSURE_WATCH"
|
||||
|
||||
ls -al "$CPU_PRESSURE_WATCH"
|
||||
|
||||
EXPECTED="$(echo -n -e "some 123000 2000000\x00" | base64)"
|
||||
|
||||
test "$EXPECTED" = "$CPU_PRESSURE_WRITE"
|
||||
|
||||
EOF
|
||||
|
||||
chmod +x "$SCRIPT"
|
||||
|
||||
systemd-run \
|
||||
-u "$UNIT" \
|
||||
-p Type=exec \
|
||||
-p ProtectControlGroups=1 \
|
||||
-p DynamicUser=1 \
|
||||
-p CPUPressureWatch=on \
|
||||
-p CPUPressureThresholdSec=123ms \
|
||||
-p BindPaths=$SCRIPT \
|
||||
`# Make sanitizers happy when DynamicUser=1 pulls in instrumented systemd NSS modules` \
|
||||
-p EnvironmentFile=-/usr/lib/systemd/systemd-asan-env \
|
||||
--wait "$SCRIPT"
|
||||
|
||||
rm "$SCRIPT"
|
||||
|
||||
touch /testok
|
||||
Reference in New Issue
Block a user