core: Add I/O pressure support
This commit is contained in:
committed by
Daan De Meyer
parent
316d17fcbd
commit
594659da06
@@ -556,6 +556,10 @@ node /org/freedesktop/systemd1 {
|
||||
readonly t DefaultCPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s DefaultCPUPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t DefaultIOPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s DefaultIOPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly t TimerSlackNSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
@@ -801,6 +805,10 @@ node /org/freedesktop/systemd1 {
|
||||
|
||||
<!--property DefaultCPUPressureWatch is not documented!-->
|
||||
|
||||
<!--property DefaultIOPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property DefaultIOPressureWatch is not documented!-->
|
||||
|
||||
<!--property TimerSlackNSec is not documented!-->
|
||||
|
||||
<!--property DefaultOOMPolicy is not documented!-->
|
||||
@@ -1255,6 +1263,10 @@ node /org/freedesktop/systemd1 {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultCPUPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultIOPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultIOPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="TimerSlackNSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="DefaultOOMPolicy"/>
|
||||
@@ -3082,6 +3094,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t CPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s IOPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t IOPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiss) NFTSet = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b CoredumpReceive = ...;
|
||||
@@ -3755,6 +3771,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<!--property CPUPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property IOPressureWatch is not documented!-->
|
||||
|
||||
<!--property IOPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property NFTSet is not documented!-->
|
||||
|
||||
<!--property CoredumpReceive is not documented!-->
|
||||
@@ -4451,6 +4471,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="IOPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="IOPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFTSet"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CoredumpReceive"/>
|
||||
@@ -5354,6 +5378,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t CPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s IOPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t IOPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiss) NFTSet = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b CoredumpReceive = ...;
|
||||
@@ -6043,6 +6071,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
||||
|
||||
<!--property CPUPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property IOPressureWatch is not documented!-->
|
||||
|
||||
<!--property IOPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property NFTSet is not documented!-->
|
||||
|
||||
<!--property CoredumpReceive is not documented!-->
|
||||
@@ -6713,6 +6745,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="IOPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="IOPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFTSet"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CoredumpReceive"/>
|
||||
@@ -7439,6 +7475,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t CPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s IOPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t IOPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiss) NFTSet = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b CoredumpReceive = ...;
|
||||
@@ -8052,6 +8092,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
|
||||
|
||||
<!--property CPUPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property IOPressureWatch is not documented!-->
|
||||
|
||||
<!--property IOPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property NFTSet is not documented!-->
|
||||
|
||||
<!--property CoredumpReceive is not documented!-->
|
||||
@@ -8630,6 +8674,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="IOPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="IOPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFTSet"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CoredumpReceive"/>
|
||||
@@ -9489,6 +9537,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t CPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s IOPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t IOPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiss) NFTSet = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b CoredumpReceive = ...;
|
||||
@@ -10084,6 +10136,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
|
||||
|
||||
<!--property CPUPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property IOPressureWatch is not documented!-->
|
||||
|
||||
<!--property IOPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property NFTSet is not documented!-->
|
||||
|
||||
<!--property CoredumpReceive is not documented!-->
|
||||
@@ -10644,6 +10700,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="IOPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="IOPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFTSet"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CoredumpReceive"/>
|
||||
@@ -11356,6 +11416,10 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t CPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s IOPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t IOPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiss) NFTSet = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b CoredumpReceive = ...;
|
||||
@@ -11533,6 +11597,10 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
|
||||
|
||||
<!--property CPUPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property IOPressureWatch is not documented!-->
|
||||
|
||||
<!--property IOPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property NFTSet is not documented!-->
|
||||
|
||||
<!--property CoredumpReceive is not documented!-->
|
||||
@@ -11725,6 +11793,10 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="IOPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="IOPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFTSet"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CoredumpReceive"/>
|
||||
@@ -11940,6 +12012,10 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t CPUPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly s IOPressureWatch = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly t IOPressureThresholdUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly a(iiss) NFTSet = [...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly b CoredumpReceive = ...;
|
||||
@@ -12131,6 +12207,10 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
|
||||
|
||||
<!--property CPUPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property IOPressureWatch is not documented!-->
|
||||
|
||||
<!--property IOPressureThresholdUSec is not documented!-->
|
||||
|
||||
<!--property NFTSet is not documented!-->
|
||||
|
||||
<!--property CoredumpReceive is not documented!-->
|
||||
@@ -12347,6 +12427,10 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CPUPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="IOPressureWatch"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="IOPressureThresholdUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NFTSet"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="CoredumpReceive"/>
|
||||
@@ -12560,8 +12644,10 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
||||
<function>KillUnitSubgroup()</function> were added in version 258.</para>
|
||||
<para><varname>TransactionsWithOrderingCycle</varname> was added in version 259.</para>
|
||||
<para><varname>DefaultMemoryZSwapWriteback</varname>,
|
||||
<varname>DefaultCPUPressureThresholdUSec</varname> and
|
||||
<varname>DefaultCPUPressureWatch</varname> were added in version 261.</para>
|
||||
<varname>DefaultCPUPressureThresholdUSec</varname>,
|
||||
<varname>DefaultCPUPressureWatch</varname>,
|
||||
<varname>DefaultIOPressureThresholdUSec</varname>, and
|
||||
<varname>DefaultIOPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Unit Objects</title>
|
||||
@@ -12653,8 +12739,10 @@ $ 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>
|
||||
<para><varname>CPUPressureThresholdUSec</varname>,
|
||||
<varname>CPUPressureWatch</varname>,
|
||||
<varname>IOPressureThresholdUSec</varname>, and
|
||||
<varname>IOPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Socket Unit Objects</title>
|
||||
@@ -12725,8 +12813,10 @@ $ 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>
|
||||
<para><varname>CPUPressureThresholdUSec</varname>,
|
||||
<varname>CPUPressureWatch</varname>,
|
||||
<varname>IOPressureThresholdUSec</varname>, and
|
||||
<varname>IOPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Mount Unit Objects</title>
|
||||
@@ -12792,8 +12882,10 @@ $ 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>
|
||||
<para><varname>CPUPressureThresholdUSec</varname>,
|
||||
<varname>CPUPressureWatch</varname>,
|
||||
<varname>IOPressureThresholdUSec</varname>, and
|
||||
<varname>IOPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Swap Unit Objects</title>
|
||||
@@ -12857,8 +12949,10 @@ $ 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>
|
||||
<para><varname>CPUPressureThresholdUSec</varname>,
|
||||
<varname>CPUPressureWatch</varname>,
|
||||
<varname>IOPressureThresholdUSec</varname>, and
|
||||
<varname>IOPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Slice Unit Objects</title>
|
||||
@@ -12892,8 +12986,10 @@ $ 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>
|
||||
<para><varname>CPUPressureThresholdUSec</varname>,
|
||||
<varname>CPUPressureWatch</varname>,
|
||||
<varname>IOPressureThresholdUSec</varname>, and
|
||||
<varname>IOPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Scope Unit Objects</title>
|
||||
@@ -12925,8 +13021,10 @@ $ 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>
|
||||
<para><varname>CPUPressureThresholdUSec</varname>,
|
||||
<varname>CPUPressureWatch</varname>,
|
||||
<varname>IOPressureThresholdUSec</varname>, and
|
||||
<varname>IOPressureWatch</varname> were added in version 261.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Job Objects</title>
|
||||
|
||||
@@ -609,8 +609,11 @@ manpages = [
|
||||
['sd_event_add_memory_pressure',
|
||||
'3',
|
||||
['sd_event_add_cpu_pressure',
|
||||
'sd_event_add_io_pressure',
|
||||
'sd_event_source_set_cpu_pressure_period',
|
||||
'sd_event_source_set_cpu_pressure_type',
|
||||
'sd_event_source_set_io_pressure_period',
|
||||
'sd_event_source_set_io_pressure_type',
|
||||
'sd_event_source_set_memory_pressure_period',
|
||||
'sd_event_source_set_memory_pressure_type',
|
||||
'sd_event_trim_memory'],
|
||||
|
||||
@@ -25,7 +25,11 @@
|
||||
<refname>sd_event_source_set_cpu_pressure_type</refname>
|
||||
<refname>sd_event_source_set_cpu_pressure_period</refname>
|
||||
|
||||
<refpurpose>Add and configure an event source run as result of memory or CPU pressure</refpurpose>
|
||||
<refname>sd_event_add_io_pressure</refname>
|
||||
<refname>sd_event_source_set_io_pressure_type</refname>
|
||||
<refname>sd_event_source_set_io_pressure_period</refname>
|
||||
|
||||
<refpurpose>Add and configure an event source for memory, CPU, or IO pressure notifications</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
@@ -76,6 +80,27 @@
|
||||
<paramdef>uint64_t <parameter>window_usec</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_event_add_io_pressure</function></funcdef>
|
||||
<paramdef>sd_event *<parameter>event</parameter></paramdef>
|
||||
<paramdef>sd_event_source **<parameter>ret_source</parameter></paramdef>
|
||||
<paramdef>sd_event_handler_t <parameter>handler</parameter></paramdef>
|
||||
<paramdef>void *<parameter>userdata</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_event_source_set_io_pressure_type</function></funcdef>
|
||||
<paramdef>sd_event_source *<parameter>source</parameter></paramdef>
|
||||
<paramdef>const char *<parameter>type</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_event_source_set_io_pressure_period</function></funcdef>
|
||||
<paramdef>sd_event_source *<parameter>source</parameter></paramdef>
|
||||
<paramdef>uint64_t <parameter>threshold_usec</parameter></paramdef>
|
||||
<paramdef>uint64_t <parameter>window_usec</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_event_trim_memory</function></funcdef>
|
||||
<paramdef>void</paramdef>
|
||||
@@ -88,19 +113,24 @@
|
||||
|
||||
<para><function>sd_event_add_memory_pressure()</function> adds a new event source that is triggered
|
||||
whenever memory pressure is seen. Similarly,
|
||||
<function>sd_event_add_cpu_pressure()</function> adds a new event source that is triggered whenever CPU
|
||||
pressure is seen. This functionality is built around the Linux kernel's <ulink
|
||||
<function>sd_event_add_cpu_pressure()</function> and <function>sd_event_add_io_pressure()</function> add
|
||||
new event sources that are triggered whenever CPU or IO pressure is seen, respectively. This functionality
|
||||
is built around the Linux kernel's <ulink
|
||||
url="https://docs.kernel.org/accounting/psi.html">Pressure Stall Information (PSI)</ulink> logic.</para>
|
||||
|
||||
<para>Both functions expect an event loop object as first parameter, and return the allocated event source
|
||||
<para>These functions expect an event loop object as first parameter, and return the allocated event source
|
||||
object in the second parameter, on success. The <parameter>handler</parameter> parameter is a function to
|
||||
call when pressure is seen, or <constant>NULL</constant>. The handler function will be passed the
|
||||
<parameter>userdata</parameter> pointer, which may be chosen freely by the caller. The handler may return
|
||||
negative to signal an error (see below), other return values are ignored. If
|
||||
<parameter>handler</parameter> is <constant>NULL</constant>, a default handler that compacts allocation
|
||||
caches maintained by <filename>libsystemd</filename> as well as glibc (via <citerefentry
|
||||
project='man-pages'><refentrytitle>malloc_trim</refentrytitle><manvolnum>3</manvolnum></citerefentry>)
|
||||
will be used.</para>
|
||||
<parameter>handler</parameter> is <constant>NULL</constant>, a default handler is used. For
|
||||
<function>sd_event_add_memory_pressure()</function>, the default handler compacts allocation caches
|
||||
maintained by <filename>libsystemd</filename> as well as glibc (via <citerefentry
|
||||
project='man-pages'><refentrytitle>malloc_trim</refentrytitle><manvolnum>3</manvolnum></citerefentry>).
|
||||
For <function>sd_event_add_cpu_pressure()</function> and
|
||||
<function>sd_event_add_io_pressure()</function>, the default handler is a no-op. It is recommended to
|
||||
pass a custom handler for CPU and IO pressure to take meaningful action when pressure is
|
||||
detected.</para>
|
||||
|
||||
<para>To destroy an event source object use
|
||||
<citerefentry><refentrytitle>sd_event_source_unref</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||
@@ -110,8 +140,8 @@
|
||||
<citerefentry><refentrytitle>sd_event_source_set_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||
with <constant>SD_EVENT_OFF</constant>.</para>
|
||||
|
||||
<para>If the second parameter of <function>sd_event_add_memory_pressure()</function> or
|
||||
<function>sd_event_add_cpu_pressure()</function> is
|
||||
<para>If the second parameter of <function>sd_event_add_memory_pressure()</function>,
|
||||
<function>sd_event_add_cpu_pressure()</function>, or <function>sd_event_add_io_pressure()</function> is
|
||||
<constant>NULL</constant> no reference to the event source object is returned. In this case, the event
|
||||
source is considered "floating", and will be destroyed implicitly when the event loop itself is
|
||||
destroyed.</para>
|
||||
@@ -146,6 +176,11 @@
|
||||
provides the <literal>some</literal> line, not the <literal>full</literal> line, so only
|
||||
<literal>some</literal> is valid when watching at the system level.</para>
|
||||
|
||||
<para>The IO pressure event source follows the same logic, but uses the
|
||||
<varname>$IO_PRESSURE_WATCH</varname>/<varname>$IO_PRESSURE_WRITE</varname> environment variables,
|
||||
the <filename>io.pressure</filename> cgroup file, and the system-wide PSI interface file
|
||||
<filename>/proc/pressure/io</filename> instead.</para>
|
||||
|
||||
<para>Or in other words: preferably any explicit configuration passed in by an invoking service manager
|
||||
(or similar) is used as notification source, before falling back to local notifications of the service,
|
||||
and finally to global notifications of the system.</para>
|
||||
@@ -189,12 +224,15 @@
|
||||
|
||||
<para>Similarly, <function>sd_event_source_set_cpu_pressure_type()</function> and
|
||||
<function>sd_event_source_set_cpu_pressure_period()</function> can be used to fine-tune the PSI
|
||||
parameters for CPU pressure notifications. They work identically to their memory pressure counterparts.
|
||||
parameters for CPU pressure notifications, and
|
||||
<function>sd_event_source_set_io_pressure_type()</function> and
|
||||
<function>sd_event_source_set_io_pressure_period()</function> can be used to fine-tune the PSI
|
||||
parameters for IO pressure notifications. They work identically to their memory pressure counterparts.
|
||||
The type parameter takes either <literal>some</literal> or <literal>full</literal>, and the period
|
||||
function takes threshold and period times in microseconds. The same constraints apply: these calls must
|
||||
be invoked immediately after allocating the event source, and will fail if CPU pressure parameterization
|
||||
has been passed in via the
|
||||
<varname>$CPU_PRESSURE_WATCH</varname>/<varname>$CPU_PRESSURE_WRITE</varname> environment
|
||||
be invoked immediately after allocating the event source, and will fail if pressure parameterization
|
||||
has been passed in via the corresponding
|
||||
<varname>$*_PRESSURE_WATCH</varname>/<varname>$*_PRESSURE_WRITE</varname> environment
|
||||
variables.</para>
|
||||
|
||||
<para>The <function>sd_event_trim_memory()</function> function releases various internal allocation
|
||||
@@ -242,9 +280,9 @@
|
||||
<varlistentry>
|
||||
<term><constant>-EHOSTDOWN</constant></term>
|
||||
|
||||
<listitem><para>The <varname>$MEMORY_PRESSURE_WATCH</varname> or
|
||||
<varname>$CPU_PRESSURE_WATCH</varname> variable has been set to the literal
|
||||
string <filename>/dev/null</filename>, in order to explicitly disable pressure
|
||||
<listitem><para>The <varname>$MEMORY_PRESSURE_WATCH</varname>,
|
||||
<varname>$CPU_PRESSURE_WATCH</varname>, or <varname>$IO_PRESSURE_WATCH</varname> variable has been
|
||||
set to the literal string <filename>/dev/null</filename>, in order to explicitly disable pressure
|
||||
handling.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
|
||||
@@ -253,9 +291,9 @@
|
||||
<varlistentry>
|
||||
<term><constant>-EBADMSG</constant></term>
|
||||
|
||||
<listitem><para>The <varname>$MEMORY_PRESSURE_WATCH</varname> or
|
||||
<varname>$CPU_PRESSURE_WATCH</varname> variable has been set to an invalid
|
||||
string, for example a relative rather than an absolute path.</para>
|
||||
<listitem><para>The <varname>$MEMORY_PRESSURE_WATCH</varname>,
|
||||
<varname>$CPU_PRESSURE_WATCH</varname>, or <varname>$IO_PRESSURE_WATCH</varname> variable has been
|
||||
set to an invalid string, for example a relative rather than an absolute path.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
|
||||
</varlistentry>
|
||||
@@ -263,9 +301,9 @@
|
||||
<varlistentry>
|
||||
<term><constant>-ENOTTY</constant></term>
|
||||
|
||||
<listitem><para>The <varname>$MEMORY_PRESSURE_WATCH</varname> or
|
||||
<varname>$CPU_PRESSURE_WATCH</varname> variable points to a regular file
|
||||
outside of the procfs or cgroupfs file systems.</para>
|
||||
<listitem><para>The <varname>$MEMORY_PRESSURE_WATCH</varname>,
|
||||
<varname>$CPU_PRESSURE_WATCH</varname>, or <varname>$IO_PRESSURE_WATCH</varname> variable points
|
||||
to a regular file outside of the procfs or cgroupfs file systems.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
|
||||
</varlistentry>
|
||||
@@ -273,9 +311,9 @@
|
||||
<varlistentry>
|
||||
<term><constant>-EOPNOTSUPP</constant></term>
|
||||
|
||||
<listitem><para>No configuration via <varname>$MEMORY_PRESSURE_WATCH</varname> or
|
||||
<varname>$CPU_PRESSURE_WATCH</varname> has been specified and the local kernel does not support the
|
||||
PSI interface.</para>
|
||||
<listitem><para>No configuration via <varname>$MEMORY_PRESSURE_WATCH</varname>,
|
||||
<varname>$CPU_PRESSURE_WATCH</varname>, or <varname>$IO_PRESSURE_WATCH</varname> has been specified
|
||||
and the local kernel does not support the PSI interface.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
|
||||
</varlistentry>
|
||||
@@ -286,7 +324,9 @@
|
||||
<listitem><para>This is returned by <function>sd_event_source_set_memory_pressure_type()</function>,
|
||||
<function>sd_event_source_set_memory_pressure_period()</function>,
|
||||
<function>sd_event_source_set_cpu_pressure_type()</function>,
|
||||
and <function>sd_event_source_set_cpu_pressure_period()</function> if invoked on event sources
|
||||
<function>sd_event_source_set_cpu_pressure_period()</function>,
|
||||
<function>sd_event_source_set_io_pressure_type()</function>,
|
||||
and <function>sd_event_source_set_io_pressure_period()</function> if invoked on event sources
|
||||
at a time later than immediately after allocating them.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
|
||||
@@ -329,8 +369,11 @@
|
||||
<function>sd_event_source_set_memory_pressure_period()</function>, and
|
||||
<function>sd_event_trim_memory()</function> were added in version 254.</para>
|
||||
<para><function>sd_event_add_cpu_pressure()</function>,
|
||||
<function>sd_event_source_set_cpu_pressure_type()</function>, and
|
||||
<function>sd_event_source_set_cpu_pressure_period()</function> were added in version 261.</para>
|
||||
<function>sd_event_source_set_cpu_pressure_type()</function>,
|
||||
<function>sd_event_source_set_cpu_pressure_period()</function>,
|
||||
<function>sd_event_add_io_pressure()</function>,
|
||||
<function>sd_event_source_set_io_pressure_type()</function>, and
|
||||
<function>sd_event_source_set_io_pressure_period()</function> were added in version 261.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
||||
@@ -340,6 +340,20 @@
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>DefaultIOPressureWatch=</varname></term>
|
||||
<term><varname>DefaultIOPressureThresholdSec=</varname></term>
|
||||
|
||||
<listitem><para>Configures the default settings for the per-unit
|
||||
<varname>IOPressureWatch=</varname> and <varname>IOPressureThresholdSec=</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 IO pressure monitoring threshold for the service manager itself.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@@ -4717,6 +4717,18 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
|
||||
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$IO_PRESSURE_WATCH</varname></term>
|
||||
<term><varname>$IO_PRESSURE_WRITE</varname></term>
|
||||
|
||||
<listitem><para>If IO 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>
|
||||
|
||||
|
||||
@@ -1706,6 +1706,55 @@ DeviceAllow=/dev/loop-control
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>IOPressureWatch=</varname></term>
|
||||
|
||||
<listitem><para>Controls IO 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 IO pressure events, by setting the <varname>$IO_PRESSURE_WATCH</varname>
|
||||
environment variable to the literal string <filename>/dev/null</filename>. If <literal>yes</literal>,
|
||||
tells the service to watch for IO pressure events. This enables IO accounting for the
|
||||
service, and ensures the <filename>io.pressure</filename> cgroup attribute file is accessible for
|
||||
reading and writing by the service's user. It then sets the <varname>$IO_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>IOPressureThresholdSec=</varname> is encoded in
|
||||
the <varname>$IO_PRESSURE_WRITE</varname> environment variable. If the <literal>auto</literal>
|
||||
value is set the protocol is enabled if IO accounting is anyway enabled for the unit (e.g. because
|
||||
<varname>IOWeight=</varname> or <varname>IODeviceWeight=</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. IO 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_io_pressure</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||
to watch for and handle IO pressure events.</para>
|
||||
|
||||
<para>If not explicitly set, defaults to the <varname>DefaultIOPressureWatch=</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>IOPressureThresholdSec=</varname></term>
|
||||
|
||||
<listitem><para>Sets the IO pressure threshold time for IO pressure monitor as configured via
|
||||
<varname>IOPressureWatch=</varname>. Specifies the maximum IO stall time before an IO
|
||||
pressure event is signalled to the service, per 2s window. If not specified, defaults to the
|
||||
<varname>DefaultIOPressureThresholdSec=</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>
|
||||
|
||||
@@ -116,11 +116,17 @@ const PressureResourceInfo pressure_resource_info[_PRESSURE_RESOURCE_MAX] = {
|
||||
.env_watch = "CPU_PRESSURE_WATCH",
|
||||
.env_write = "CPU_PRESSURE_WRITE",
|
||||
},
|
||||
[PRESSURE_IO] = {
|
||||
.name = "io",
|
||||
.env_watch = "IO_PRESSURE_WATCH",
|
||||
.env_write = "IO_PRESSURE_WRITE",
|
||||
},
|
||||
};
|
||||
|
||||
static const char* const pressure_resource_table[_PRESSURE_RESOURCE_MAX] = {
|
||||
[PRESSURE_MEMORY] = "memory",
|
||||
[PRESSURE_CPU] = "cpu",
|
||||
[PRESSURE_IO] = "io",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(pressure_resource, PressureResource);
|
||||
|
||||
@@ -12,6 +12,7 @@ typedef enum PressureType {
|
||||
typedef enum PressureResource {
|
||||
PRESSURE_MEMORY,
|
||||
PRESSURE_CPU,
|
||||
PRESSURE_IO,
|
||||
_PRESSURE_RESOURCE_MAX,
|
||||
_PRESSURE_RESOURCE_INVALID = -EINVAL,
|
||||
} PressureResource;
|
||||
|
||||
@@ -188,6 +188,7 @@ void cgroup_context_init(CGroupContext *c) {
|
||||
.pressure = {
|
||||
[PRESSURE_MEMORY] = { .watch = _CGROUP_PRESSURE_WATCH_INVALID, .threshold_usec = USEC_INFINITY },
|
||||
[PRESSURE_CPU] = { .watch = _CGROUP_PRESSURE_WATCH_INVALID, .threshold_usec = USEC_INFINITY },
|
||||
[PRESSURE_IO] = { .watch = _CGROUP_PRESSURE_WATCH_INVALID, .threshold_usec = USEC_INFINITY },
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -531,6 +532,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||||
"%sManagedOOMPreference: %s\n"
|
||||
"%sMemoryPressureWatch: %s\n"
|
||||
"%sCPUPressureWatch: %s\n"
|
||||
"%sIOPressureWatch: %s\n"
|
||||
"%sCoredumpReceive: %s\n",
|
||||
prefix, yes_no(c->io_accounting),
|
||||
prefix, yes_no(c->memory_accounting),
|
||||
@@ -568,6 +570,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||||
prefix, managed_oom_preference_to_string(c->moom_preference),
|
||||
prefix, cgroup_pressure_watch_to_string(c->pressure[PRESSURE_MEMORY].watch),
|
||||
prefix, cgroup_pressure_watch_to_string(c->pressure[PRESSURE_CPU].watch),
|
||||
prefix, cgroup_pressure_watch_to_string(c->pressure[PRESSURE_IO].watch),
|
||||
prefix, yes_no(c->coredump_receive));
|
||||
|
||||
if (c->delegate_subgroup)
|
||||
@@ -586,6 +589,10 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||||
fprintf(f, "%sCPUPressureThresholdSec: %s\n",
|
||||
prefix, FORMAT_TIMESPAN(c->pressure[PRESSURE_CPU].threshold_usec, 1));
|
||||
|
||||
if (c->pressure[PRESSURE_IO].threshold_usec != USEC_INFINITY)
|
||||
fprintf(f, "%sIOPressureThresholdSec: %s\n",
|
||||
prefix, FORMAT_TIMESPAN(c->pressure[PRESSURE_IO].threshold_usec, 1));
|
||||
|
||||
if (c->moom_mem_pressure_duration_usec != USEC_INFINITY)
|
||||
fprintf(f, "%sManagedOOMMemoryPressureDurationSec: %s\n",
|
||||
prefix, FORMAT_TIMESPAN(c->moom_mem_pressure_duration_usec, 1));
|
||||
|
||||
@@ -376,6 +376,14 @@ static inline bool cgroup_context_want_pressure(const CGroupContext *c, Pressure
|
||||
c->startup_cpu_weight != CGROUP_WEIGHT_INVALID ||
|
||||
c->cpu_quota_per_sec_usec != USEC_INFINITY;
|
||||
|
||||
case PRESSURE_IO:
|
||||
return c->io_accounting ||
|
||||
c->io_weight != CGROUP_WEIGHT_INVALID ||
|
||||
c->startup_io_weight != CGROUP_WEIGHT_INVALID ||
|
||||
c->io_device_weights ||
|
||||
c->io_device_latencies ||
|
||||
c->io_device_limits;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
|
||||
@@ -431,6 +431,8 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
|
||||
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("IOPressureWatch", "s", bus_property_get_cgroup_pressure_watch, offsetof(CGroupContext, pressure[PRESSURE_IO].watch), 0),
|
||||
SD_BUS_PROPERTY("IOPressureThresholdUSec", "t", bus_property_get_usec, offsetof(CGroupContext, pressure[PRESSURE_IO].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),
|
||||
|
||||
@@ -714,11 +716,12 @@ static int bus_cgroup_set_transient_property(
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "MemoryPressureWatch", "CPUPressureWatch")) {
|
||||
} else if (STR_IN_SET(name, "MemoryPressureWatch", "CPUPressureWatch", "IOPressureWatch")) {
|
||||
CGroupPressureWatch p;
|
||||
const char *t;
|
||||
|
||||
PressureResource pt = streq(name, "MemoryPressureWatch") ? PRESSURE_MEMORY : PRESSURE_CPU;
|
||||
PressureResource pt = streq(name, "MemoryPressureWatch") ? PRESSURE_MEMORY :
|
||||
streq(name, "CPUPressureWatch") ? PRESSURE_CPU : PRESSURE_IO;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &t);
|
||||
if (r < 0)
|
||||
@@ -739,10 +742,11 @@ static int bus_cgroup_set_transient_property(
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "MemoryPressureThresholdUSec", "CPUPressureThresholdUSec")) {
|
||||
} else if (STR_IN_SET(name, "MemoryPressureThresholdUSec", "CPUPressureThresholdUSec", "IOPressureThresholdUSec")) {
|
||||
uint64_t t;
|
||||
|
||||
PressureResource pt = streq(name, "MemoryPressureThresholdUSec") ? PRESSURE_MEMORY : PRESSURE_CPU;
|
||||
PressureResource pt = streq(name, "MemoryPressureThresholdUSec") ? PRESSURE_MEMORY :
|
||||
streq(name, "CPUPressureThresholdUSec") ? PRESSURE_CPU : PRESSURE_IO;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &t);
|
||||
if (r < 0)
|
||||
|
||||
@@ -2984,6 +2984,8 @@ const sd_bus_vtable bus_manager_vtable[] = {
|
||||
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("DefaultIOPressureThresholdUSec", "t", bus_property_get_usec, offsetof(Manager, defaults.pressure[PRESSURE_IO].threshold_usec), 0),
|
||||
SD_BUS_PROPERTY("DefaultIOPressureWatch", "s", bus_property_get_cgroup_pressure_watch, offsetof(Manager, defaults.pressure[PRESSURE_IO].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),
|
||||
|
||||
@@ -287,6 +287,10 @@ static int exec_cgroup_context_serialize(const CGroupContext *c, FILE *f) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = serialize_item(f, "exec-cgroup-context-io-pressure-watch", cgroup_pressure_watch_to_string(c->pressure[PRESSURE_IO].watch));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = serialize_item(f, "exec-cgroup-context-delegate-subgroup", c->delegate_subgroup);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -303,6 +307,12 @@ static int exec_cgroup_context_serialize(const CGroupContext *c, FILE *f) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (c->pressure[PRESSURE_IO].threshold_usec != USEC_INFINITY) {
|
||||
r = serialize_usec(f, "exec-cgroup-context-io-pressure-threshold-usec", c->pressure[PRESSURE_IO].threshold_usec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
LIST_FOREACH(device_allow, a, c->device_allow) {
|
||||
r = serialize_item_format(f, "exec-cgroup-context-device-allow", "%s %s",
|
||||
a->path,
|
||||
@@ -638,6 +648,10 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) {
|
||||
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-io-pressure-watch="))) {
|
||||
c->pressure[PRESSURE_IO].watch = cgroup_pressure_watch_from_string(val);
|
||||
if (c->pressure[PRESSURE_IO].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)
|
||||
@@ -650,6 +664,10 @@ static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) {
|
||||
r = deserialize_usec(val, &c->pressure[PRESSURE_CPU].threshold_usec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-io-pressure-threshold-usec="))) {
|
||||
r = deserialize_usec(val, &c->pressure[PRESSURE_IO].threshold_usec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if ((val = startswith(l, "exec-cgroup-context-device-allow="))) {
|
||||
_cleanup_free_ char *path = NULL, *rwm = NULL;
|
||||
CGroupDevicePermissions p;
|
||||
|
||||
@@ -280,6 +280,8 @@
|
||||
{{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}}.IOPressureThresholdSec, config_parse_sec, 0, offsetof({{type}}, cgroup_context.pressure[PRESSURE_IO].threshold_usec)
|
||||
{{type}}.IOPressureWatch, config_parse_pressure_watch, 0, offsetof({{type}}, cgroup_context.pressure[PRESSURE_IO].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)
|
||||
|
||||
@@ -821,6 +821,8 @@ static int parse_config_file(void) {
|
||||
{ "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", "DefaultIOPressureThresholdSec", config_parse_sec, 0, &arg_defaults.pressure[PRESSURE_IO].threshold_usec },
|
||||
{ "Manager", "DefaultIOPressureWatch", config_parse_pressure_watch, 0, &arg_defaults.pressure[PRESSURE_IO].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 },
|
||||
|
||||
@@ -621,6 +621,8 @@ static char** sanitize_environment(char **l) {
|
||||
"CREDENTIALS_DIRECTORY",
|
||||
"EXIT_CODE",
|
||||
"EXIT_STATUS",
|
||||
"IO_PRESSURE_WATCH",
|
||||
"IO_PRESSURE_WRITE",
|
||||
"INVOCATION_ID",
|
||||
"JOURNAL_STREAM",
|
||||
"LISTEN_FDNAMES",
|
||||
@@ -807,6 +809,7 @@ static const struct {
|
||||
} 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 },
|
||||
[PRESSURE_IO] = { sd_event_add_io_pressure, sd_event_source_set_io_pressure_period },
|
||||
};
|
||||
|
||||
int manager_setup_pressure_event_source(Manager *m, PressureResource t) {
|
||||
@@ -5213,6 +5216,7 @@ void unit_defaults_init(UnitDefaults *defaults, RuntimeScope scope) {
|
||||
.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 },
|
||||
[PRESSURE_IO] = { .watch = CGROUP_PRESSURE_WATCH_AUTO, .threshold_usec = PRESSURE_DEFAULT_THRESHOLD_USEC },
|
||||
},
|
||||
|
||||
.oom_policy = OOM_STOP,
|
||||
|
||||
@@ -80,6 +80,8 @@
|
||||
#DefaultMemoryPressureWatch=auto
|
||||
#DefaultCPUPressureThresholdSec=200ms
|
||||
#DefaultCPUPressureWatch=auto
|
||||
#DefaultIOPressureThresholdSec=200ms
|
||||
#DefaultIOPressureWatch=auto
|
||||
#DefaultOOMPolicy=stop
|
||||
#DefaultSmackProcessLabel=
|
||||
#DefaultRestrictSUIDSGID=
|
||||
|
||||
@@ -56,6 +56,8 @@
|
||||
#DefaultMemoryPressureWatch=auto
|
||||
#DefaultCPUPressureThresholdSec=200ms
|
||||
#DefaultCPUPressureWatch=auto
|
||||
#DefaultIOPressureThresholdSec=200ms
|
||||
#DefaultIOPressureWatch=auto
|
||||
#DefaultSmackProcessLabel=
|
||||
#DefaultRestrictSUIDSGID=
|
||||
#ReloadLimitIntervalSec=
|
||||
|
||||
@@ -327,6 +327,8 @@ int unit_cgroup_context_build_json(sd_json_variant **ret, const char *name, void
|
||||
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),
|
||||
SD_JSON_BUILD_PAIR_STRING("IOPressureWatch", cgroup_pressure_watch_to_string(c->pressure[PRESSURE_IO].watch)),
|
||||
JSON_BUILD_PAIR_FINITE_USEC("IOPressureThresholdUSec", c->pressure[PRESSURE_IO].threshold_usec),
|
||||
|
||||
/* Others */
|
||||
SD_JSON_BUILD_PAIR_BOOLEAN("CoredumpReceive", c->coredump_receive));
|
||||
|
||||
@@ -110,6 +110,8 @@ static int manager_context_build_json(sd_json_variant **ret, const char *name, v
|
||||
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("DefaultIOPressureThresholdUSec", m->defaults.pressure[PRESSURE_IO].threshold_usec),
|
||||
SD_JSON_BUILD_PAIR_STRING("DefaultIOPressureWatch", cgroup_pressure_watch_to_string(m->defaults.pressure[PRESSURE_IO].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)),
|
||||
|
||||
@@ -1099,4 +1099,7 @@ global:
|
||||
sd_event_add_cpu_pressure;
|
||||
sd_event_source_set_cpu_pressure_type;
|
||||
sd_event_source_set_cpu_pressure_period;
|
||||
sd_event_add_io_pressure;
|
||||
sd_event_source_set_io_pressure_type;
|
||||
sd_event_source_set_io_pressure_period;
|
||||
} LIBSYSTEMD_260;
|
||||
|
||||
@@ -27,6 +27,7 @@ typedef enum EventSourceType {
|
||||
SOURCE_INOTIFY,
|
||||
SOURCE_MEMORY_PRESSURE,
|
||||
SOURCE_CPU_PRESSURE,
|
||||
SOURCE_IO_PRESSURE,
|
||||
_SOURCE_EVENT_SOURCE_TYPE_MAX,
|
||||
_SOURCE_EVENT_SOURCE_TYPE_INVALID = -EINVAL,
|
||||
} EventSourceType;
|
||||
|
||||
@@ -77,6 +77,7 @@ static const char* const event_source_type_table[_SOURCE_EVENT_SOURCE_TYPE_MAX]
|
||||
[SOURCE_INOTIFY] = "inotify",
|
||||
[SOURCE_MEMORY_PRESSURE] = "memory-pressure",
|
||||
[SOURCE_CPU_PRESSURE] = "cpu-pressure",
|
||||
[SOURCE_IO_PRESSURE] = "io-pressure",
|
||||
};
|
||||
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(event_source_type, int);
|
||||
@@ -101,7 +102,8 @@ DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(event_source_type, int);
|
||||
SOURCE_DEFER, \
|
||||
SOURCE_INOTIFY, \
|
||||
SOURCE_MEMORY_PRESSURE, \
|
||||
SOURCE_CPU_PRESSURE)
|
||||
SOURCE_CPU_PRESSURE, \
|
||||
SOURCE_IO_PRESSURE)
|
||||
|
||||
/* This is used to assert that we didn't pass an unexpected source type to event_source_time_prioq_put().
|
||||
* Time sources and ratelimited sources can be passed, so effectively this is the same as the
|
||||
@@ -566,7 +568,7 @@ static int source_child_pidfd_register(sd_event_source *s, int enabled) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define EVENT_SOURCE_IS_PRESSURE(s) IN_SET((s)->type, SOURCE_MEMORY_PRESSURE, SOURCE_CPU_PRESSURE)
|
||||
#define EVENT_SOURCE_IS_PRESSURE(s) IN_SET((s)->type, SOURCE_MEMORY_PRESSURE, SOURCE_CPU_PRESSURE, SOURCE_IO_PRESSURE)
|
||||
|
||||
static void source_pressure_unregister(sd_event_source *s) {
|
||||
assert(s);
|
||||
@@ -1052,6 +1054,7 @@ static void source_disconnect(sd_event_source *s) {
|
||||
|
||||
case SOURCE_MEMORY_PRESSURE:
|
||||
case SOURCE_CPU_PRESSURE:
|
||||
case SOURCE_IO_PRESSURE:
|
||||
source_pressure_remove_from_write_list(s);
|
||||
source_pressure_unregister(s);
|
||||
break;
|
||||
@@ -1198,6 +1201,7 @@ static sd_event_source* source_new(sd_event *e, bool floating, EventSourceType t
|
||||
[SOURCE_INOTIFY] = endoffsetof_field(sd_event_source, inotify),
|
||||
[SOURCE_MEMORY_PRESSURE] = endoffsetof_field(sd_event_source, pressure),
|
||||
[SOURCE_CPU_PRESSURE] = endoffsetof_field(sd_event_source, pressure),
|
||||
[SOURCE_IO_PRESSURE] = endoffsetof_field(sd_event_source, pressure),
|
||||
};
|
||||
|
||||
sd_event_source *s;
|
||||
@@ -2110,8 +2114,8 @@ static int event_add_pressure(
|
||||
* fd with the epoll right-away. Instead, we just add the event source to a list of pressure event
|
||||
* sources on which writes must be executed before the first event loop iteration is executed. (We
|
||||
* could also write the data here, right away, but we want to give the caller the freedom to call
|
||||
* sd_event_source_set_{memory,cpu}_pressure_type() and
|
||||
* sd_event_source_set_{memory,cpu}_pressure_period() before we write it. */
|
||||
* sd_event_source_set_{memory,cpu,io}_pressure_type() and
|
||||
* sd_event_source_set_{memory,cpu,io}_pressure_period() before we write it. */
|
||||
|
||||
if (s->pressure.write_buffer_size > 0)
|
||||
source_pressure_add_to_write_list(s);
|
||||
@@ -2160,6 +2164,25 @@ _public_ int sd_event_add_cpu_pressure(
|
||||
PRESSURE_CPU);
|
||||
}
|
||||
|
||||
static int io_pressure_callback(sd_event_source *s, void *userdata) {
|
||||
assert(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_event_add_io_pressure(
|
||||
sd_event *e,
|
||||
sd_event_source **ret,
|
||||
sd_event_handler_t callback,
|
||||
void *userdata) {
|
||||
|
||||
return event_add_pressure(
|
||||
e, ret, callback, userdata,
|
||||
SOURCE_IO_PRESSURE,
|
||||
io_pressure_callback,
|
||||
PRESSURE_IO);
|
||||
}
|
||||
|
||||
static void event_free_inotify_data(sd_event *e, InotifyData *d) {
|
||||
assert(e);
|
||||
|
||||
@@ -2962,6 +2985,7 @@ static int event_source_offline(
|
||||
|
||||
case SOURCE_MEMORY_PRESSURE:
|
||||
case SOURCE_CPU_PRESSURE:
|
||||
case SOURCE_IO_PRESSURE:
|
||||
source_pressure_unregister(s);
|
||||
break;
|
||||
|
||||
@@ -3054,6 +3078,7 @@ static int event_source_online(
|
||||
|
||||
case SOURCE_MEMORY_PRESSURE:
|
||||
case SOURCE_CPU_PRESSURE:
|
||||
case SOURCE_IO_PRESSURE:
|
||||
/* As documented in sd_event_add_{memory,cpu,io}_pressure(), we can only register the PSI fd
|
||||
* with epoll after writing the watch string. */
|
||||
if (s->pressure.write_buffer_size == 0) {
|
||||
@@ -4308,6 +4333,7 @@ static int source_dispatch(sd_event_source *s) {
|
||||
|
||||
case SOURCE_MEMORY_PRESSURE:
|
||||
case SOURCE_CPU_PRESSURE:
|
||||
case SOURCE_IO_PRESSURE:
|
||||
r = s->pressure.callback(s, s->userdata);
|
||||
break;
|
||||
|
||||
@@ -4723,6 +4749,7 @@ static int process_epoll(sd_event *e, usec_t timeout, int64_t threshold, int64_t
|
||||
|
||||
case SOURCE_MEMORY_PRESSURE:
|
||||
case SOURCE_CPU_PRESSURE:
|
||||
case SOURCE_IO_PRESSURE:
|
||||
r = process_pressure(s, i->events);
|
||||
break;
|
||||
|
||||
@@ -5418,6 +5445,13 @@ _public_ int sd_event_source_set_cpu_pressure_type(sd_event_source *s, const cha
|
||||
return event_source_set_pressure_type(s, ty);
|
||||
}
|
||||
|
||||
_public_ int sd_event_source_set_io_pressure_type(sd_event_source *s, const char *ty) {
|
||||
assert_return(s, -EINVAL);
|
||||
assert_return(s->type == SOURCE_IO_PRESSURE, -EDOM);
|
||||
|
||||
return event_source_set_pressure_type(s, ty);
|
||||
}
|
||||
|
||||
static int event_source_set_pressure_period(sd_event_source *s, uint64_t threshold_usec, uint64_t window_usec) {
|
||||
_cleanup_free_ char *b = NULL;
|
||||
_cleanup_free_ void *w = NULL;
|
||||
@@ -5478,3 +5512,10 @@ _public_ int sd_event_source_set_cpu_pressure_period(sd_event_source *s, uint64_
|
||||
|
||||
return event_source_set_pressure_period(s, threshold_usec, window_usec);
|
||||
}
|
||||
|
||||
_public_ int sd_event_source_set_io_pressure_period(sd_event_source *s, uint64_t threshold_usec, uint64_t window_usec) {
|
||||
assert_return(s, -EINVAL);
|
||||
assert_return(s->type == SOURCE_IO_PRESSURE, -EDOM);
|
||||
|
||||
return event_source_set_pressure_period(s, threshold_usec, window_usec);
|
||||
}
|
||||
|
||||
@@ -2384,6 +2384,7 @@ static const BusProperty cgroup_properties[] = {
|
||||
{ "ManagedOOMPreference", bus_append_string },
|
||||
{ "MemoryPressureWatch", bus_append_string },
|
||||
{ "CPUPressureWatch", bus_append_string },
|
||||
{ "IOPressureWatch", bus_append_string },
|
||||
{ "DelegateSubgroup", bus_append_string },
|
||||
{ "ManagedOOMMemoryPressureLimit", bus_append_parse_permyriad },
|
||||
{ "MemoryAccounting", bus_append_parse_boolean },
|
||||
@@ -2423,6 +2424,7 @@ static const BusProperty cgroup_properties[] = {
|
||||
{ "SocketBindDeny", bus_append_socket_filter },
|
||||
{ "MemoryPressureThresholdSec", bus_append_parse_sec_rename },
|
||||
{ "CPUPressureThresholdSec", bus_append_parse_sec_rename },
|
||||
{ "IOPressureThresholdSec", bus_append_parse_sec_rename },
|
||||
{ "NFTSet", bus_append_nft_set },
|
||||
{ "BindNetworkInterface", bus_append_string },
|
||||
|
||||
|
||||
@@ -68,6 +68,10 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
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#DefaultIOPressureThresholdUSec="),
|
||||
SD_VARLINK_DEFINE_FIELD(DefaultIOPressureThresholdUSec, SD_VARLINK_INT, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd-system.conf.html#DefaultIOPressureWatch="),
|
||||
SD_VARLINK_DEFINE_FIELD(DefaultIOPressureWatch, 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="),
|
||||
|
||||
@@ -232,6 +232,10 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
|
||||
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),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#IOPressureWatch="),
|
||||
SD_VARLINK_DEFINE_FIELD(IOPressureWatch, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("https://www.freedesktop.org/software/systemd/man/"PROJECT_VERSION_STR"/systemd.resource-control.html#IOPressureThresholdSec="),
|
||||
SD_VARLINK_DEFINE_FIELD(IOPressureThresholdUSec, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
|
||||
/* Others */
|
||||
SD_VARLINK_FIELD_COMMENT("Reflects whether to forward coredumps for processes that crash within this cgroup"),
|
||||
|
||||
@@ -98,6 +98,7 @@ int sd_event_add_post(sd_event *e, sd_event_source **ret, sd_event_handler_t cal
|
||||
int sd_event_add_exit(sd_event *e, sd_event_source **ret, sd_event_handler_t callback, void *userdata);
|
||||
int sd_event_add_memory_pressure(sd_event *e, sd_event_source **ret, sd_event_handler_t callback, void *userdata);
|
||||
int sd_event_add_cpu_pressure(sd_event *e, sd_event_source **ret, sd_event_handler_t callback, void *userdata);
|
||||
int sd_event_add_io_pressure(sd_event *e, sd_event_source **ret, sd_event_handler_t callback, void *userdata);
|
||||
|
||||
int sd_event_prepare(sd_event *e);
|
||||
int sd_event_wait(sd_event *e, uint64_t timeout);
|
||||
@@ -165,6 +166,8 @@ int sd_event_source_set_memory_pressure_type(sd_event_source *s, const char *ty)
|
||||
int sd_event_source_set_memory_pressure_period(sd_event_source *s, uint64_t threshold_usec, uint64_t window_usec);
|
||||
int sd_event_source_set_cpu_pressure_type(sd_event_source *s, const char *ty);
|
||||
int sd_event_source_set_cpu_pressure_period(sd_event_source *s, uint64_t threshold_usec, uint64_t window_usec);
|
||||
int sd_event_source_set_io_pressure_type(sd_event_source *s, const char *ty);
|
||||
int sd_event_source_set_io_pressure_period(sd_event_source *s, uint64_t threshold_usec, uint64_t window_usec);
|
||||
int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t callback);
|
||||
int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t *ret);
|
||||
int sd_event_source_get_floating(sd_event_source *s);
|
||||
|
||||
@@ -154,6 +154,14 @@ TEST(fake_cpu_pressure) {
|
||||
test_fake_pressure("cpu", fake_cpu_pressure_wrapper);
|
||||
}
|
||||
|
||||
static int fake_io_pressure_wrapper(sd_event *e, sd_event_source **ret, sd_event_handler_t callback, void *userdata) {
|
||||
return sd_event_add_io_pressure(e, ret, callback, userdata);
|
||||
}
|
||||
|
||||
TEST(fake_io_pressure) {
|
||||
test_fake_pressure("io", fake_io_pressure_wrapper);
|
||||
}
|
||||
|
||||
/* Shared infrastructure for real pressure tests */
|
||||
|
||||
struct real_pressure_context {
|
||||
@@ -452,7 +460,142 @@ TEST(real_cpu_pressure) {
|
||||
ASSERT_EQ(ex, 31);
|
||||
}
|
||||
|
||||
/* IO pressure real test */
|
||||
|
||||
static int real_io_pressure_callback(sd_event_source *s, void *userdata) {
|
||||
struct real_pressure_context *c = ASSERT_PTR(userdata);
|
||||
const char *d;
|
||||
|
||||
ASSERT_NOT_NULL(s);
|
||||
ASSERT_OK(sd_event_source_get_description(s, &d));
|
||||
|
||||
log_notice("real io pressure event: %s", d);
|
||||
|
||||
ASSERT_NOT_NULL(c->pid);
|
||||
ASSERT_OK(sd_event_source_send_child_signal(c->pid, SIGKILL, NULL, 0));
|
||||
c->pid = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_noreturn_ static void real_pressure_eat_io(int pipe_fd) {
|
||||
char x;
|
||||
ASSERT_EQ(read(pipe_fd, &x, 1), 1); /* Wait for the GO! */
|
||||
|
||||
/* Write and fsync in a loop to generate IO pressure */
|
||||
for (;;) {
|
||||
_cleanup_close_ int fd = -EBADF;
|
||||
|
||||
fd = open("/var/tmp/.io-pressure-test", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0600);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
|
||||
char buf[4096];
|
||||
memset(buf, 'x', sizeof(buf));
|
||||
for (int i = 0; i < 256; i++)
|
||||
if (write(fd, buf, sizeof(buf)) < 0)
|
||||
break;
|
||||
(void) fsync(fd);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(real_io_pressure) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_event_source_unrefp) sd_event_source *es = NULL, *cs = NULL;
|
||||
_cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
_cleanup_close_pair_ int pipe_fd[2] = EBADF_PAIR;
|
||||
_cleanup_(sd_event_unrefp) sd_event *e = NULL;
|
||||
_cleanup_free_ char *scope = NULL;
|
||||
const char *object;
|
||||
int r;
|
||||
|
||||
if (getuid() == 0)
|
||||
r = sd_bus_open_system(&bus);
|
||||
else
|
||||
r = sd_bus_open_user(&bus);
|
||||
if (r < 0)
|
||||
return (void) log_tests_skipped_errno(r, "can't connect to bus");
|
||||
|
||||
ASSERT_OK(bus_wait_for_jobs_new(bus, &w));
|
||||
|
||||
ASSERT_OK(bus_message_new_method_call(bus, &m, bus_systemd_mgr, "StartTransientUnit"));
|
||||
ASSERT_OK(asprintf(&scope, "test-%" PRIu64 ".scope", random_u64()));
|
||||
ASSERT_OK(sd_bus_message_append(m, "ss", scope, "fail"));
|
||||
ASSERT_OK(sd_bus_message_open_container(m, 'a', "(sv)"));
|
||||
ASSERT_OK(sd_bus_message_append(m, "(sv)", "PIDs", "au", 1, 0));
|
||||
ASSERT_OK(sd_bus_message_append(m, "(sv)", "IOAccounting", "b", true));
|
||||
ASSERT_OK(sd_bus_message_close_container(m));
|
||||
ASSERT_OK(sd_bus_message_append(m, "a(sa(sv))", 0));
|
||||
|
||||
r = sd_bus_call(bus, m, 0, &error, &reply);
|
||||
if (r < 0)
|
||||
return (void) log_tests_skipped_errno(r, "can't issue transient unit call");
|
||||
|
||||
ASSERT_OK(sd_bus_message_read(reply, "o", &object));
|
||||
|
||||
ASSERT_OK(bus_wait_for_jobs_one(w, object, /* flags= */ BUS_WAIT_JOBS_LOG_ERROR, /* extra_args= */ NULL));
|
||||
|
||||
ASSERT_OK(sd_event_default(&e));
|
||||
|
||||
ASSERT_OK_ERRNO(pipe2(pipe_fd, O_CLOEXEC));
|
||||
|
||||
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
|
||||
r = pidref_safe_fork("(eat-io)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM, &pidref);
|
||||
ASSERT_OK(r);
|
||||
if (r == 0) {
|
||||
real_pressure_eat_io(pipe_fd[0]);
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
ASSERT_OK(event_add_child_pidref(e, &cs, &pidref, WEXITED, real_pressure_child_callback, NULL));
|
||||
ASSERT_OK(sd_event_source_set_child_process_own(cs, true));
|
||||
|
||||
ASSERT_OK_ERRNO(unsetenv("IO_PRESSURE_WATCH"));
|
||||
ASSERT_OK_ERRNO(unsetenv("IO_PRESSURE_WRITE"));
|
||||
|
||||
struct real_pressure_context context = {
|
||||
.pid = cs,
|
||||
};
|
||||
|
||||
r = sd_event_add_io_pressure(e, &es, real_io_pressure_callback, &context);
|
||||
if (r < 0)
|
||||
return (void) log_tests_skipped_errno(r, "can't allocate io pressure fd");
|
||||
|
||||
ASSERT_OK(sd_event_source_set_description(es, "real pressure event source"));
|
||||
ASSERT_OK_ZERO(sd_event_source_set_io_pressure_type(es, "some"));
|
||||
/* Unprivileged writes require a minimum of 2s otherwise the kernel will refuse the write. */
|
||||
ASSERT_OK_POSITIVE(sd_event_source_set_io_pressure_period(es, 70 * USEC_PER_MSEC, 2 * USEC_PER_SEC));
|
||||
ASSERT_OK_ZERO(sd_event_source_set_io_pressure_period(es, 70 * USEC_PER_MSEC, 2 * USEC_PER_SEC));
|
||||
ASSERT_OK(sd_event_source_set_enabled(es, SD_EVENT_ONESHOT));
|
||||
|
||||
m = sd_bus_message_unref(m);
|
||||
|
||||
ASSERT_OK(bus_message_new_method_call(bus, &m, bus_systemd_mgr, "SetUnitProperties"));
|
||||
ASSERT_OK(sd_bus_message_append(m, "sb", scope, true));
|
||||
ASSERT_OK(sd_bus_message_open_container(m, 'a', "(sv)"));
|
||||
ASSERT_OK(sd_bus_message_open_container(m, 'r', "sv"));
|
||||
ASSERT_OK(sd_bus_message_append(m, "s", "IOWriteBandwidthMax"));
|
||||
ASSERT_OK(sd_bus_message_open_container(m, 'v', "a(st)"));
|
||||
ASSERT_OK(sd_bus_message_append(m, "a(st)", 1, "/var/tmp", (uint64_t) 1024*1024)); /* 1M/s */
|
||||
ASSERT_OK(sd_bus_message_close_container(m));
|
||||
ASSERT_OK(sd_bus_message_close_container(m));
|
||||
ASSERT_OK(sd_bus_message_close_container(m));
|
||||
|
||||
ASSERT_OK(sd_bus_call(bus, m, 0, NULL, NULL));
|
||||
|
||||
/* Now start eating IO */
|
||||
ASSERT_EQ(write(pipe_fd[1], &(const char) { 'x' }, 1), 1);
|
||||
|
||||
ASSERT_OK(sd_event_loop(e));
|
||||
int ex = 0;
|
||||
ASSERT_OK(sd_event_get_exit_code(e, &ex));
|
||||
ASSERT_EQ(ex, 31);
|
||||
}
|
||||
|
||||
static int outro(void) {
|
||||
(void) unlink("/var/tmp/.io-pressure-test");
|
||||
hashmap_trim_pools();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -114,4 +114,57 @@ systemd-run \
|
||||
|
||||
rm "$SCRIPT"
|
||||
|
||||
# Now test IO pressure
|
||||
|
||||
if ! cat /proc/pressure/io >/dev/null ; then
|
||||
echo "kernel has no IO PSI support." >&2
|
||||
echo OK >/testok
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! test -f "$CGROUP"/io.pressure ; then
|
||||
echo "No IO accounting/PSI delegated via cgroup, can't test." >&2
|
||||
echo OK >/testok
|
||||
exit 0
|
||||
fi
|
||||
|
||||
UNIT="test-iopress-$RANDOM.service"
|
||||
SCRIPT="/tmp/iopress-$RANDOM.sh"
|
||||
|
||||
cat >"$SCRIPT" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
export
|
||||
id
|
||||
|
||||
test -n "$IO_PRESSURE_WATCH"
|
||||
test "$IO_PRESSURE_WATCH" != /dev/null
|
||||
test -w "$IO_PRESSURE_WATCH"
|
||||
|
||||
ls -al "$IO_PRESSURE_WATCH"
|
||||
|
||||
EXPECTED="$(echo -n -e "some 123000 2000000\x00" | base64)"
|
||||
|
||||
test "$EXPECTED" = "$IO_PRESSURE_WRITE"
|
||||
|
||||
EOF
|
||||
|
||||
chmod +x "$SCRIPT"
|
||||
|
||||
systemd-run \
|
||||
-u "$UNIT" \
|
||||
-p Type=exec \
|
||||
-p ProtectControlGroups=1 \
|
||||
-p DynamicUser=1 \
|
||||
-p IOPressureWatch=on \
|
||||
-p IOPressureThresholdSec=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