]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: add support for Startup memory limits
authorLuca Boccassi <bluca@debian.org>
Mon, 6 Feb 2023 14:13:09 +0000 (14:13 +0000)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 15 Feb 2023 20:01:16 +0000 (20:01 +0000)
We support separate Startup configurations for CPU and I/O, so
add it for memory too. Only cover cgroupsv2 settings.

man/org.freedesktop.systemd1.xml
man/systemd.resource-control.xml
src/core/cgroup.c
src/core/cgroup.h
src/core/dbus-cgroup.c
src/core/load-fragment-gperf.gperf.in
src/core/load-fragment.c
src/systemctl/systemctl-show.c
test/TEST-55-OOMD/test.sh

index bbb6b1433938c034fb834b4594a41ce2f086a5f7..1592d046ad289e6985b3e1f301ff1b987e838351 100644 (file)
@@ -2720,20 +2720,32 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t DefaultMemoryLow = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t DefaultStartupMemoryLow = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t DefaultMemoryMin = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryMin = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryLow = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryLow = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryHigh = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryHigh = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemorySwapMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemorySwapMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryZSwapMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryZSwapMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryLimit = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly s DevicePolicy = '...';
@@ -3299,20 +3311,32 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
 
     <!--property DefaultMemoryLow is not documented!-->
 
+    <!--property DefaultStartupMemoryLow is not documented!-->
+
     <!--property DefaultMemoryMin is not documented!-->
 
     <!--property MemoryMin is not documented!-->
 
     <!--property MemoryLow is not documented!-->
 
+    <!--property StartupMemoryLow is not documented!-->
+
     <!--property MemoryHigh is not documented!-->
 
+    <!--property StartupMemoryHigh is not documented!-->
+
     <!--property MemoryMax is not documented!-->
 
+    <!--property StartupMemoryMax is not documented!-->
+
     <!--property MemorySwapMax is not documented!-->
 
+    <!--property StartupMemorySwapMax is not documented!-->
+
     <!--property MemoryZSwapMax is not documented!-->
 
+    <!--property StartupMemoryZSwapMax is not documented!-->
+
     <!--property MemoryLimit is not documented!-->
 
     <!--property DevicePolicy is not documented!-->
@@ -3887,20 +3911,32 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
 
     <variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryLow"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="DefaultStartupMemoryLow"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryMin"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryMin"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLow"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryLow"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryHigh"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryHigh"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemorySwapMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryZSwapMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
@@ -4628,20 +4664,32 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t DefaultMemoryLow = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t DefaultStartupMemoryLow = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t DefaultMemoryMin = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryMin = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryLow = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryLow = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryHigh = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryHigh = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemorySwapMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemorySwapMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryZSwapMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryZSwapMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryLimit = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly s DevicePolicy = '...';
@@ -5227,20 +5275,32 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
 
     <!--property DefaultMemoryLow is not documented!-->
 
+    <!--property DefaultStartupMemoryLow is not documented!-->
+
     <!--property DefaultMemoryMin is not documented!-->
 
     <!--property MemoryMin is not documented!-->
 
     <!--property MemoryLow is not documented!-->
 
+    <!--property StartupMemoryLow is not documented!-->
+
     <!--property MemoryHigh is not documented!-->
 
+    <!--property StartupMemoryHigh is not documented!-->
+
     <!--property MemoryMax is not documented!-->
 
+    <!--property StartupMemoryMax is not documented!-->
+
     <!--property MemorySwapMax is not documented!-->
 
+    <!--property StartupMemorySwapMax is not documented!-->
+
     <!--property MemoryZSwapMax is not documented!-->
 
+    <!--property StartupMemoryZSwapMax is not documented!-->
+
     <!--property MemoryLimit is not documented!-->
 
     <!--property DevicePolicy is not documented!-->
@@ -5805,20 +5865,32 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
 
     <variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryLow"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="DefaultStartupMemoryLow"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryMin"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryMin"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLow"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryLow"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryHigh"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryHigh"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemorySwapMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryZSwapMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
@@ -6435,20 +6507,32 @@ node /org/freedesktop/systemd1/unit/home_2emount {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t DefaultMemoryLow = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t DefaultStartupMemoryLow = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t DefaultMemoryMin = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryMin = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryLow = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryLow = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryHigh = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryHigh = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemorySwapMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemorySwapMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryZSwapMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryZSwapMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryLimit = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly s DevicePolicy = '...';
@@ -6962,20 +7046,32 @@ node /org/freedesktop/systemd1/unit/home_2emount {
 
     <!--property DefaultMemoryLow is not documented!-->
 
+    <!--property DefaultStartupMemoryLow is not documented!-->
+
     <!--property DefaultMemoryMin is not documented!-->
 
     <!--property MemoryMin is not documented!-->
 
     <!--property MemoryLow is not documented!-->
 
+    <!--property StartupMemoryLow is not documented!-->
+
     <!--property MemoryHigh is not documented!-->
 
+    <!--property StartupMemoryHigh is not documented!-->
+
     <!--property MemoryMax is not documented!-->
 
+    <!--property StartupMemoryMax is not documented!-->
+
     <!--property MemorySwapMax is not documented!-->
 
+    <!--property StartupMemorySwapMax is not documented!-->
+
     <!--property MemoryZSwapMax is not documented!-->
 
+    <!--property StartupMemoryZSwapMax is not documented!-->
+
     <!--property MemoryLimit is not documented!-->
 
     <!--property DevicePolicy is not documented!-->
@@ -7458,20 +7554,32 @@ node /org/freedesktop/systemd1/unit/home_2emount {
 
     <variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryLow"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="DefaultStartupMemoryLow"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryMin"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryMin"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLow"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryLow"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryHigh"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryHigh"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemorySwapMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryZSwapMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
@@ -8215,20 +8323,32 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t DefaultMemoryLow = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t DefaultStartupMemoryLow = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t DefaultMemoryMin = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryMin = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryLow = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryLow = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryHigh = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryHigh = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemorySwapMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemorySwapMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryZSwapMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryZSwapMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryLimit = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly s DevicePolicy = '...';
@@ -8728,20 +8848,32 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
 
     <!--property DefaultMemoryLow is not documented!-->
 
+    <!--property DefaultStartupMemoryLow is not documented!-->
+
     <!--property DefaultMemoryMin is not documented!-->
 
     <!--property MemoryMin is not documented!-->
 
     <!--property MemoryLow is not documented!-->
 
+    <!--property StartupMemoryLow is not documented!-->
+
     <!--property MemoryHigh is not documented!-->
 
+    <!--property StartupMemoryHigh is not documented!-->
+
     <!--property MemoryMax is not documented!-->
 
+    <!--property StartupMemoryMax is not documented!-->
+
     <!--property MemorySwapMax is not documented!-->
 
+    <!--property StartupMemorySwapMax is not documented!-->
+
     <!--property MemoryZSwapMax is not documented!-->
 
+    <!--property StartupMemoryZSwapMax is not documented!-->
+
     <!--property MemoryLimit is not documented!-->
 
     <!--property DevicePolicy is not documented!-->
@@ -9210,20 +9342,32 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
 
     <variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryLow"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="DefaultStartupMemoryLow"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryMin"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryMin"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLow"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryLow"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryHigh"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryHigh"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemorySwapMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryZSwapMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
@@ -9826,20 +9970,32 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t DefaultMemoryLow = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t DefaultStartupMemoryLow = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t DefaultMemoryMin = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryMin = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryLow = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryLow = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryHigh = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryHigh = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemorySwapMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemorySwapMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryZSwapMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryZSwapMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryLimit = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly s DevicePolicy = '...';
@@ -9979,20 +10135,32 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
 
     <!--property DefaultMemoryLow is not documented!-->
 
+    <!--property DefaultStartupMemoryLow is not documented!-->
+
     <!--property DefaultMemoryMin is not documented!-->
 
     <!--property MemoryMin is not documented!-->
 
     <!--property MemoryLow is not documented!-->
 
+    <!--property StartupMemoryLow is not documented!-->
+
     <!--property MemoryHigh is not documented!-->
 
+    <!--property StartupMemoryHigh is not documented!-->
+
     <!--property MemoryMax is not documented!-->
 
+    <!--property StartupMemoryMax is not documented!-->
+
     <!--property MemorySwapMax is not documented!-->
 
+    <!--property StartupMemorySwapMax is not documented!-->
+
     <!--property MemoryZSwapMax is not documented!-->
 
+    <!--property StartupMemoryZSwapMax is not documented!-->
+
     <!--property MemoryLimit is not documented!-->
 
     <!--property DevicePolicy is not documented!-->
@@ -10139,20 +10307,32 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
 
     <variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryLow"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="DefaultStartupMemoryLow"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryMin"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryMin"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLow"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryLow"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryHigh"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryHigh"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemorySwapMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryZSwapMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
@@ -10323,20 +10503,32 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t DefaultMemoryLow = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t DefaultStartupMemoryLow = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t DefaultMemoryMin = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryMin = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryLow = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryLow = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryHigh = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryHigh = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemorySwapMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemorySwapMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryZSwapMax = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly t StartupMemoryZSwapMax = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly t MemoryLimit = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly s DevicePolicy = '...';
@@ -10496,20 +10688,32 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
 
     <!--property DefaultMemoryLow is not documented!-->
 
+    <!--property DefaultStartupMemoryLow is not documented!-->
+
     <!--property DefaultMemoryMin is not documented!-->
 
     <!--property MemoryMin is not documented!-->
 
     <!--property MemoryLow is not documented!-->
 
+    <!--property StartupMemoryLow is not documented!-->
+
     <!--property MemoryHigh is not documented!-->
 
+    <!--property StartupMemoryHigh is not documented!-->
+
     <!--property MemoryMax is not documented!-->
 
+    <!--property StartupMemoryMax is not documented!-->
+
     <!--property MemorySwapMax is not documented!-->
 
+    <!--property StartupMemorySwapMax is not documented!-->
+
     <!--property MemoryZSwapMax is not documented!-->
 
+    <!--property StartupMemoryZSwapMax is not documented!-->
+
     <!--property MemoryLimit is not documented!-->
 
     <!--property DevicePolicy is not documented!-->
@@ -10686,20 +10890,32 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
 
     <variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryLow"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="DefaultStartupMemoryLow"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="DefaultMemoryMin"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryMin"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLow"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryLow"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryHigh"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryHigh"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemorySwapMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemorySwapMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryZSwapMax"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="StartupMemoryZSwapMax"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="MemoryLimit"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="DevicePolicy"/>
index 4b19b18231a8ae1b766ea6dcfade166d05ec086c..f0112bb36b35c790e6b28e87397ffccaeed9b049 100644 (file)
 
       <varlistentry>
         <term><varname>MemoryMin=<replaceable>bytes</replaceable></varname>, <varname>MemoryLow=<replaceable>bytes</replaceable></varname></term>
+        <term><varname>StartupMemoryLow=<replaceable>bytes</replaceable></varname></term>
 
         <listitem>
           <para>Specify the memory usage protection of the executed processes in this unit.
           in the unit itself.
           Using it to set a default child allocation is only useful on kernels older than 5.7,
           which do not support the <literal>memory_recursiveprot</literal> cgroup2 mount option.</para>
+
+          <para>While <varname>StartupMemoryLow=</varname> applies to the startup and shutdown phases of the system,
+          <varname>MemoryMin=</varname> applies to normal runtime of the system, and if the former is not set also to
+          the startup and shutdown phases. Using <varname>StartupMemoryLow=</varname> allows prioritizing specific services at
+          boot-up and shutdown differently than during normal runtime.</para>
         </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>MemoryHigh=<replaceable>bytes</replaceable></varname></term>
+        <term><varname>StartupMemoryHigh=<replaceable>bytes</replaceable></varname></term>
 
         <listitem>
           <para>Specify the throttling limit on memory usage of the executed processes in this unit. Memory usage may go
           special value <literal>infinity</literal>, no memory throttling is applied. This controls the
           <literal>memory.high</literal> control group attribute. For details about this control group attribute, see
           <ulink url="https://docs.kernel.org/admin-guide/cgroup-v2.html#memory-interface-files">Memory Interface Files</ulink>.</para>
+
+          <para>While <varname>StartupMemoryHigh=</varname> applies to the startup and shutdown phases of the system,
+          <varname>MemoryHigh=</varname> applies to normal runtime of the system, and if the former is not set also to
+          the startup and shutdown phases. Using <varname>StartupMemoryHigh=</varname> allows prioritizing specific services at
+          boot-up and shutdown differently than during normal runtime.</para>
         </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>MemoryMax=<replaceable>bytes</replaceable></varname></term>
+        <term><varname>StartupMemoryMax=<replaceable>bytes</replaceable></varname></term>
 
         <listitem>
           <para>Specify the absolute limit on memory usage of the executed processes in this unit. If memory usage
           assigned the special value <literal>infinity</literal>, no memory limit is applied. This controls the
           <literal>memory.max</literal> control group attribute. For details about this control group attribute, see
           <ulink url="https://docs.kernel.org/admin-guide/cgroup-v2.html#memory-interface-files">Memory Interface Files</ulink>.</para>
+
+          <para>While <varname>StartupMemoryMax=</varname> applies to the startup and shutdown phases of the system,
+          <varname>MemoryMax=</varname> applies to normal runtime of the system, and if the former is not set also to
+          the startup and shutdown phases. Using <varname>StartupMemoryMax=</varname> allows prioritizing specific services at
+          boot-up and shutdown differently than during normal runtime.</para>
         </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>MemorySwapMax=<replaceable>bytes</replaceable></varname></term>
+        <term><varname>StartupMemorySwapMax=<replaceable>bytes</replaceable></varname></term>
 
         <listitem>
           <para>Specify the absolute limit on swap usage of the executed processes in this unit.</para>
           special value <literal>infinity</literal>, no swap limit is applied. These settings control the
           <literal>memory.swap.max</literal> control group attribute. For details about this control group attribute,
           see <ulink url="https://docs.kernel.org/admin-guide/cgroup-v2.html#memory-interface-files">Memory Interface Files</ulink>.</para>
+
+          <para>While <varname>StartupMemorySwapMax=</varname> applies to the startup and shutdown phases of the system,
+          <varname>MemorySwapMax=</varname> applies to normal runtime of the system, and if the former is not set also to
+          the startup and shutdown phases. Using <varname>StartupMemorySwapMax=</varname> allows prioritizing specific services at
+          boot-up and shutdown differently than during normal runtime.</para>
         </listitem>
       </varlistentry>
 
       <varlistentry>
         <term><varname>MemoryZSwapMax=<replaceable>bytes</replaceable></varname></term>
+        <term><varname>StartupMemoryZSwapMax=<replaceable>bytes</replaceable></varname></term>
 
         <listitem>
           <para>Specify the absolute limit on zswap usage of the processes in this unit. Zswap is a lightweight compressed
           special value <literal>infinity</literal>, no limit is applied. These settings control the
           <literal>memory.zswap.max</literal> control group attribute. For details about this control group attribute,
           see <ulink url="https://docs.kernel.org/admin-guide/cgroup-v2.html#memory-interface-files">Memory Interface Files</ulink>.</para>
+
+          <para>While <varname>StartupMemoryZSwapMax=</varname> applies to the startup and shutdown phases of the system,
+          <varname>MemoryZSwapMax=</varname> applies to normal runtime of the system, and if the former is not set also to
+          the startup and shutdown phases. Using <varname>StartupMemoryZSwapMax=</varname> allows prioritizing specific services at
+          boot-up and shutdown differently than during normal runtime.</para>
         </listitem>
       </varlistentry>
 
index 4cac3f6a89b1e7ea051beefbab97f59f17072674..7ac9549f89ed6edc84537292cd8757b4fc166cd3 100644 (file)
@@ -91,7 +91,12 @@ bool unit_has_startup_cgroup_constraints(Unit *u) {
                c->startup_io_weight != CGROUP_WEIGHT_INVALID ||
                c->startup_blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID ||
                c->startup_cpuset_cpus.set ||
-               c->startup_cpuset_mems.set;
+               c->startup_cpuset_mems.set ||
+               c->startup_memory_high_set ||
+               c->startup_memory_max_set ||
+               c->startup_memory_swap_max_set||
+               c->startup_memory_zswap_max_set ||
+               c->startup_memory_low_set;
 }
 
 bool unit_has_host_root_cgroup(Unit *u) {
@@ -149,9 +154,13 @@ void cgroup_context_init(CGroupContext *c) {
                 .startup_cpu_shares = CGROUP_CPU_SHARES_INVALID,
 
                 .memory_high = CGROUP_LIMIT_MAX,
+                .startup_memory_high = CGROUP_LIMIT_MAX,
                 .memory_max = CGROUP_LIMIT_MAX,
+                .startup_memory_max = CGROUP_LIMIT_MAX,
                 .memory_swap_max = CGROUP_LIMIT_MAX,
+                .startup_memory_swap_max = CGROUP_LIMIT_MAX,
                 .memory_zswap_max = CGROUP_LIMIT_MAX,
+                .startup_memory_zswap_max = CGROUP_LIMIT_MAX,
 
                 .memory_limit = CGROUP_LIMIT_MAX,
 
@@ -340,24 +349,41 @@ static int unit_compare_memory_limit(Unit *u, const char *property_name, uint64_
 
         assert_se(c = unit_get_cgroup_context(u));
 
+        bool startup = u->manager && IN_SET(manager_state(u->manager), MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING);
+
         if (streq(property_name, "MemoryLow")) {
                 unit_value = unit_get_ancestor_memory_low(u);
                 file = "memory.low";
+        } else if (startup && streq(property_name, "StartupMemoryLow")) {
+                unit_value = unit_get_ancestor_startup_memory_low(u);
+                file = "memory.low";
         } else if (streq(property_name, "MemoryMin")) {
                 unit_value = unit_get_ancestor_memory_min(u);
                 file = "memory.min";
         } else if (streq(property_name, "MemoryHigh")) {
                 unit_value = c->memory_high;
                 file = "memory.high";
+        } else if (startup && streq(property_name, "StartupMemoryHigh")) {
+                unit_value = c->startup_memory_high;
+                file = "memory.high";
         } else if (streq(property_name, "MemoryMax")) {
                 unit_value = c->memory_max;
                 file = "memory.max";
+        } else if (startup && streq(property_name, "StartupMemoryMax")) {
+                unit_value = c->startup_memory_max;
+                file = "memory.max";
         } else if (streq(property_name, "MemorySwapMax")) {
                 unit_value = c->memory_swap_max;
                 file = "memory.swap.max";
+        } else if (startup && streq(property_name, "StartupMemorySwapMax")) {
+                unit_value = c->startup_memory_swap_max;
+                file = "memory.swap.max";
         } else if (streq(property_name, "MemoryZSwapMax")) {
                 unit_value = c->memory_zswap_max;
                 file = "memory.zswap.max";
+        } else if (startup && streq(property_name, "StartupMemoryZSwapMax")) {
+                unit_value = c->startup_memory_zswap_max;
+                file = "memory.zswap.max";
         } else
                 return -EINVAL;
 
@@ -403,7 +429,11 @@ static char *format_cgroup_memory_limit_comparison(char *buf, size_t l, Unit *u,
          * only complain if the error is not ENOENT. This is similarly the case for memory.zswap.max relying
          * on CONFIG_ZSWAP. */
         if (r > 0 || IN_SET(r, -ENODATA, -EOWNERDEAD) ||
-            (r == -ENOENT && STR_IN_SET(property_name, "MemorySwapMax", "MemoryZSwapMax")))
+            (r == -ENOENT && STR_IN_SET(property_name,
+                                        "MemorySwapMax",
+                                        "StartupMemorySwapMax",
+                                        "MemoryZSwapMax",
+                                        "StartupMemoryZSwapMax")))
                 buf[0] = 0;
         else if (r < 0) {
                 errno = -r;
@@ -424,6 +454,12 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
         char cdc[FORMAT_CGROUP_DIFF_MAX];
         char cdd[FORMAT_CGROUP_DIFF_MAX];
         char cde[FORMAT_CGROUP_DIFF_MAX];
+        char cdf[FORMAT_CGROUP_DIFF_MAX];
+        char cdg[FORMAT_CGROUP_DIFF_MAX];
+        char cdh[FORMAT_CGROUP_DIFF_MAX];
+        char cdi[FORMAT_CGROUP_DIFF_MAX];
+        char cdj[FORMAT_CGROUP_DIFF_MAX];
+        char cdk[FORMAT_CGROUP_DIFF_MAX];
 
         assert(u);
         assert(f);
@@ -464,10 +500,15 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
                 "%sDefaultMemoryLow: %" PRIu64 "\n"
                 "%sMemoryMin: %" PRIu64 "%s\n"
                 "%sMemoryLow: %" PRIu64 "%s\n"
+                "%sStartupMemoryLow: %" PRIu64 "%s\n"
                 "%sMemoryHigh: %" PRIu64 "%s\n"
+                "%sStartupMemoryHigh: %" PRIu64 "%s\n"
                 "%sMemoryMax: %" PRIu64 "%s\n"
+                "%sStartupMemoryMax: %" PRIu64 "%s\n"
                 "%sMemorySwapMax: %" PRIu64 "%s\n"
+                "%sStartupMemorySwapMax: %" PRIu64 "%s\n"
                 "%sMemoryZSwapMax: %" PRIu64 "%s\n"
+                "%sStartupMemoryZSwapMax: %" PRIu64 "%s\n"
                 "%sMemoryLimit: %" PRIu64 "\n"
                 "%sTasksMax: %" PRIu64 "\n"
                 "%sDevicePolicy: %s\n"
@@ -501,10 +542,15 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
                 prefix, c->default_memory_low,
                 prefix, c->memory_min, format_cgroup_memory_limit_comparison(cda, sizeof(cda), u, "MemoryMin"),
                 prefix, c->memory_low, format_cgroup_memory_limit_comparison(cdb, sizeof(cdb), u, "MemoryLow"),
-                prefix, c->memory_high, format_cgroup_memory_limit_comparison(cdc, sizeof(cdc), u, "MemoryHigh"),
-                prefix, c->memory_max, format_cgroup_memory_limit_comparison(cdd, sizeof(cdd), u, "MemoryMax"),
-                prefix, c->memory_swap_max, format_cgroup_memory_limit_comparison(cde, sizeof(cde), u, "MemorySwapMax"),
-                prefix, c->memory_zswap_max, format_cgroup_memory_limit_comparison(cde, sizeof(cde), u, "MemoryZSwapMax"),
+                prefix, c->startup_memory_low, format_cgroup_memory_limit_comparison(cdc, sizeof(cdc), u, "StartupMemoryLow"),
+                prefix, c->memory_high, format_cgroup_memory_limit_comparison(cdd, sizeof(cdd), u, "MemoryHigh"),
+                prefix, c->startup_memory_high, format_cgroup_memory_limit_comparison(cde, sizeof(cde), u, "StartupMemoryHigh"),
+                prefix, c->memory_max, format_cgroup_memory_limit_comparison(cdf, sizeof(cdf), u, "MemoryMax"),
+                prefix, c->startup_memory_max, format_cgroup_memory_limit_comparison(cdg, sizeof(cdg), u, "StartupMemoryMax"),
+                prefix, c->memory_swap_max, format_cgroup_memory_limit_comparison(cdh, sizeof(cdh), u, "MemorySwapMax"),
+                prefix, c->startup_memory_swap_max, format_cgroup_memory_limit_comparison(cdi, sizeof(cdi), u, "StartupMemorySwapMax"),
+                prefix, c->memory_zswap_max, format_cgroup_memory_limit_comparison(cdj, sizeof(cdj), u, "MemoryZSwapMax"),
+                prefix, c->startup_memory_zswap_max, format_cgroup_memory_limit_comparison(cdk, sizeof(cdk), u, "StartupMemoryZSwapMax"),
                 prefix, c->memory_limit,
                 prefix, tasks_max_resolve(&c->tasks_max),
                 prefix, cgroup_device_policy_to_string(c->device_policy),
@@ -721,6 +767,7 @@ int cgroup_add_bpf_foreign_program(CGroupContext *c, uint32_t attach_type, const
 }
 
 UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP(memory_low);
+UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP(startup_memory_low);
 UNIT_DEFINE_ANCESTOR_MEMORY_LOOKUP(memory_min);
 
 static void unit_set_xattr_graceful(Unit *u, const char *cgroup_path, const char *name, const void *data, size_t size) {
@@ -1261,9 +1308,12 @@ static bool unit_has_unified_memory_config(Unit *u) {
 
         assert_se(c = unit_get_cgroup_context(u));
 
-        return unit_get_ancestor_memory_min(u) > 0 || unit_get_ancestor_memory_low(u) > 0 ||
-               c->memory_high != CGROUP_LIMIT_MAX || c->memory_max != CGROUP_LIMIT_MAX ||
-               c->memory_swap_max != CGROUP_LIMIT_MAX || c->memory_zswap_max != CGROUP_LIMIT_MAX;
+        return unit_get_ancestor_memory_min(u) > 0 ||
+               unit_get_ancestor_memory_low(u) > 0 || unit_get_ancestor_startup_memory_low(u) > 0 ||
+               c->memory_high != CGROUP_LIMIT_MAX || c->startup_memory_high_set ||
+               c->memory_max != CGROUP_LIMIT_MAX || c->startup_memory_max_set ||
+               c->memory_swap_max != CGROUP_LIMIT_MAX || c->startup_memory_swap_max_set ||
+               c->memory_zswap_max != CGROUP_LIMIT_MAX || c->startup_memory_zswap_max_set;
 }
 
 static void cgroup_apply_unified_memory_limit(Unit *u, const char *file, uint64_t v) {
@@ -1623,12 +1673,15 @@ static void cgroup_context_apply(
         if ((apply_mask & CGROUP_MASK_MEMORY) && !is_local_root) {
 
                 if (cg_all_unified() > 0) {
-                        uint64_t max, swap_max = CGROUP_LIMIT_MAX, zswap_max = CGROUP_LIMIT_MAX;
+                        uint64_t max, swap_max = CGROUP_LIMIT_MAX, zswap_max = CGROUP_LIMIT_MAX, high = CGROUP_LIMIT_MAX;
 
                         if (unit_has_unified_memory_config(u)) {
-                                max = c->memory_max;
-                                swap_max = c->memory_swap_max;
-                                zswap_max = c->memory_zswap_max;
+                                bool startup = IN_SET(state, MANAGER_STARTING, MANAGER_INITIALIZING, MANAGER_STOPPING);
+
+                                high = startup && c->startup_memory_high_set ? c->startup_memory_high : c->memory_high;
+                                max = startup && c->startup_memory_max_set ? c->startup_memory_max : c->memory_max;
+                                swap_max = startup && c->startup_memory_swap_max_set ? c->startup_memory_swap_max : c->memory_swap_max;
+                                zswap_max = startup && c->startup_memory_zswap_max_set ? c->startup_memory_zswap_max : c->memory_zswap_max;
                         } else {
                                 max = c->memory_limit;
 
@@ -1638,7 +1691,7 @@ static void cgroup_context_apply(
 
                         cgroup_apply_unified_memory_limit(u, "memory.min", unit_get_ancestor_memory_min(u));
                         cgroup_apply_unified_memory_limit(u, "memory.low", unit_get_ancestor_memory_low(u));
-                        cgroup_apply_unified_memory_limit(u, "memory.high", c->memory_high);
+                        cgroup_apply_unified_memory_limit(u, "memory.high", high);
                         cgroup_apply_unified_memory_limit(u, "memory.max", max);
                         cgroup_apply_unified_memory_limit(u, "memory.swap.max", swap_max);
                         cgroup_apply_unified_memory_limit(u, "memory.zswap.max", zswap_max);
index d137e3af4f37bc520c2470fc4dff4e87a0efa483..7d905096420ec3dc51b945af2bb99abee71e54de 100644 (file)
@@ -144,17 +144,29 @@ struct CGroupContext {
 
         uint64_t default_memory_min;
         uint64_t default_memory_low;
+        uint64_t default_startup_memory_low;
         uint64_t memory_min;
         uint64_t memory_low;
+        uint64_t startup_memory_low;
         uint64_t memory_high;
+        uint64_t startup_memory_high;
         uint64_t memory_max;
+        uint64_t startup_memory_max;
         uint64_t memory_swap_max;
+        uint64_t startup_memory_swap_max;
         uint64_t memory_zswap_max;
+        uint64_t startup_memory_zswap_max;
 
         bool default_memory_min_set:1;
         bool default_memory_low_set:1;
+        bool default_startup_memory_low_set:1;
         bool memory_min_set:1;
         bool memory_low_set:1;
+        bool startup_memory_low_set:1;
+        bool startup_memory_high_set:1;
+        bool startup_memory_max_set:1;
+        bool startup_memory_swap_max_set:1;
+        bool startup_memory_zswap_max_set:1;
 
         Set *ip_address_allow;
         Set *ip_address_deny;
@@ -288,6 +300,7 @@ Unit* manager_get_unit_by_pid(Manager *m, pid_t pid);
 
 uint64_t unit_get_ancestor_memory_min(Unit *u);
 uint64_t unit_get_ancestor_memory_low(Unit *u);
+uint64_t unit_get_ancestor_startup_memory_low(Unit *u);
 
 int unit_search_main_pid(Unit *u, pid_t *ret);
 int unit_watch_all_pids(Unit *u);
index b5484eda78ed17cc1a6679deecceaffd4fd14ee2..a3313c417f342125f2f469845acc02bf8b400ab7 100644 (file)
@@ -462,13 +462,19 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
         SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
         SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, memory_accounting), 0),
         SD_BUS_PROPERTY("DefaultMemoryLow", "t", NULL, offsetof(CGroupContext, default_memory_low), 0),
+        SD_BUS_PROPERTY("DefaultStartupMemoryLow", "t", NULL, offsetof(CGroupContext, default_startup_memory_low), 0),
         SD_BUS_PROPERTY("DefaultMemoryMin", "t", NULL, offsetof(CGroupContext, default_memory_min), 0),
         SD_BUS_PROPERTY("MemoryMin", "t", NULL, offsetof(CGroupContext, memory_min), 0),
         SD_BUS_PROPERTY("MemoryLow", "t", NULL, offsetof(CGroupContext, memory_low), 0),
+        SD_BUS_PROPERTY("StartupMemoryLow", "t", NULL, offsetof(CGroupContext, startup_memory_low), 0),
         SD_BUS_PROPERTY("MemoryHigh", "t", NULL, offsetof(CGroupContext, memory_high), 0),
+        SD_BUS_PROPERTY("StartupMemoryHigh", "t", NULL, offsetof(CGroupContext, startup_memory_high), 0),
         SD_BUS_PROPERTY("MemoryMax", "t", NULL, offsetof(CGroupContext, memory_max), 0),
+        SD_BUS_PROPERTY("StartupMemoryMax", "t", NULL, offsetof(CGroupContext, startup_memory_max), 0),
         SD_BUS_PROPERTY("MemorySwapMax", "t", NULL, offsetof(CGroupContext, memory_swap_max), 0),
+        SD_BUS_PROPERTY("StartupMemorySwapMax", "t", NULL, offsetof(CGroupContext, startup_memory_swap_max), 0),
         SD_BUS_PROPERTY("MemoryZSwapMax", "t", NULL, offsetof(CGroupContext, memory_zswap_max), 0),
+        SD_BUS_PROPERTY("StartupMemoryZSwapMax", "t", NULL, offsetof(CGroupContext, startup_memory_zswap_max), 0),
         SD_BUS_PROPERTY("MemoryLimit", "t", NULL, offsetof(CGroupContext, memory_limit), 0),
         SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy, offsetof(CGroupContext, device_policy), 0),
         SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow, 0, 0),
@@ -1057,6 +1063,13 @@ int bus_cgroup_set_property(
                 return r;
         }
 
+        if (streq(name, "StartupMemoryLow")) {
+                r = bus_cgroup_set_memory_protection(u, name, &c->startup_memory_low, message, flags, error);
+                if (r > 0)
+                        c->startup_memory_low_set = true;
+                return r;
+        }
+
         if (streq(name, "DefaultMemoryMin")) {
                 r = bus_cgroup_set_memory_protection(u, name, &c->default_memory_min, message, flags, error);
                 if (r > 0)
@@ -1071,18 +1084,53 @@ int bus_cgroup_set_property(
                 return r;
         }
 
+        if (streq(name, "DefaultStartupMemoryLow")) {
+                r = bus_cgroup_set_memory_protection(u, name, &c->default_startup_memory_low, message, flags, error);
+                if (r > 0)
+                        c->default_startup_memory_low_set = true;
+                return r;
+        }
+
         if (streq(name, "MemoryHigh"))
                 return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, error);
 
+        if (streq(name, "StartupMemoryHigh")) {
+                r = bus_cgroup_set_memory(u, name, &c->startup_memory_high, message, flags, error);
+                if (r > 0)
+                        c->startup_memory_high_set = true;
+                return r;
+        }
+
         if (streq(name, "MemorySwapMax"))
                 return bus_cgroup_set_swap(u, name, &c->memory_swap_max, message, flags, error);
 
+        if (streq(name, "StartupMemorySwapMax")) {
+                r = bus_cgroup_set_swap(u, name, &c->startup_memory_swap_max, message, flags, error);
+                if (r > 0)
+                        c->startup_memory_swap_max_set = true;
+                return r;
+        }
+
         if (streq(name, "MemoryZSwapMax"))
                 return bus_cgroup_set_zswap(u, name, &c->memory_zswap_max, message, flags, error);
 
+        if (streq(name, "StartupMemoryZSwapMax")) {
+                r = bus_cgroup_set_zswap(u, name, &c->startup_memory_zswap_max, message, flags, error);
+                if (r > 0)
+                        c->startup_memory_zswap_max_set = true;
+                return r;
+        }
+
         if (streq(name, "MemoryMax"))
                 return bus_cgroup_set_memory(u, name, &c->memory_max, message, flags, error);
 
+        if (streq(name, "StartupMemoryMax")) {
+                r = bus_cgroup_set_memory(u, name, &c->startup_memory_max, message, flags, error);
+                if (r > 0)
+                        c->startup_memory_max_set = true;
+                return r;
+        }
+
         if (streq(name, "MemoryLimit"))
                 return bus_cgroup_set_memory(u, name, &c->memory_limit, message, flags, error);
 
index 3ea3ca3200a09d46345f5596ec119d830ab7e016..58ace4627913b4f63391d3e7681bb35bede9c973 100644 (file)
 {{type}}.MemoryMin,                        config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
 {{type}}.DefaultMemoryMin,                 config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
 {{type}}.DefaultMemoryLow,                 config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
+{{type}}.DefaultStartupMemoryLow,          config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
 {{type}}.MemoryLow,                        config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
+{{type}}.StartupMemoryLow,                 config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
 {{type}}.MemoryHigh,                       config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
+{{type}}.StartupMemoryHigh,                config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
 {{type}}.MemoryMax,                        config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
+{{type}}.StartupMemoryMax,                 config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
 {{type}}.MemorySwapMax,                    config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
+{{type}}.StartupMemorySwapMax,             config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
 {{type}}.MemoryZSwapMax,                   config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
+{{type}}.StartupMemoryZSwapMax,            config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
 {{type}}.MemoryLimit,                      config_parse_memory_limit,                   0,                                  offsetof({{type}}, cgroup_context)
 {{type}}.DeviceAllow,                      config_parse_device_allow,                   0,                                  offsetof({{type}}, cgroup_context)
 {{type}}.DevicePolicy,                     config_parse_device_policy,                  0,                                  offsetof({{type}}, cgroup_context.device_policy)
index ce15758901ada2a2f09f98b98eb364b445045efd..ec782703a755ca16aaa3590b08fb7ff57a51f2c4 100644 (file)
@@ -3813,6 +3813,7 @@ int config_parse_memory_limit(
         if (isempty(rvalue) && STR_IN_SET(lvalue, "DefaultMemoryLow",
                                                   "DefaultMemoryMin",
                                                   "MemoryLow",
+                                                  "StartupMemoryLow",
                                                   "MemoryMin"))
                 bytes = CGROUP_LIMIT_MIN;
         else if (!isempty(rvalue) && !streq(rvalue, "infinity")) {
@@ -3828,7 +3829,17 @@ int config_parse_memory_limit(
                         bytes = physical_memory_scale(r, 10000U);
 
                 if (bytes >= UINT64_MAX ||
-                    (bytes <= 0 && !STR_IN_SET(lvalue, "MemorySwapMax", "MemoryZSwapMax", "MemoryLow", "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin"))) {
+                    (bytes <= 0 && !STR_IN_SET(lvalue,
+                                               "MemorySwapMax",
+                                               "StartupMemorySwapMax",
+                                               "MemoryZSwapMax",
+                                               "StartupMemoryZSwapMax",
+                                               "MemoryLow",
+                                               "StartupMemoryLow",
+                                               "MemoryMin",
+                                               "DefaultMemoryLow",
+                                               "DefaultstartupMemoryLow",
+                                               "DefaultMemoryMin"))) {
                         log_syntax(unit, LOG_WARNING, filename, line, 0, "Memory limit '%s' out of range, ignoring.", rvalue);
                         return 0;
                 }
@@ -3837,6 +3848,9 @@ int config_parse_memory_limit(
         if (streq(lvalue, "DefaultMemoryLow")) {
                 c->default_memory_low = bytes;
                 c->default_memory_low_set = true;
+        } else if (streq(lvalue, "DefaultStartupMemoryLow")) {
+                c->default_startup_memory_low = bytes;
+                c->default_startup_memory_low_set = true;
         } else if (streq(lvalue, "DefaultMemoryMin")) {
                 c->default_memory_min = bytes;
                 c->default_memory_min_set = true;
@@ -3846,15 +3860,30 @@ int config_parse_memory_limit(
         } else if (streq(lvalue, "MemoryLow")) {
                 c->memory_low = bytes;
                 c->memory_low_set = true;
+        } else if (streq(lvalue, "StartupMemoryLow")) {
+                c->startup_memory_low = bytes;
+                c->startup_memory_low_set = true;
         } else if (streq(lvalue, "MemoryHigh"))
                 c->memory_high = bytes;
-        else if (streq(lvalue, "MemoryMax"))
+        else if (streq(lvalue, "StartupMemoryHigh")) {
+                c->startup_memory_high = bytes;
+                c->startup_memory_high_set = true;
+        } else if (streq(lvalue, "MemoryMax"))
                 c->memory_max = bytes;
-        else if (streq(lvalue, "MemorySwapMax"))
+        else if (streq(lvalue, "StartupMemoryMax")) {
+                c->startup_memory_max = bytes;
+                c->startup_memory_max_set = true;
+        } else if (streq(lvalue, "MemorySwapMax"))
                 c->memory_swap_max = bytes;
-        else if (streq(lvalue, "MemoryZSwapMax"))
+        else if (streq(lvalue, "StartupMemorySwapMax")) {
+                c->startup_memory_swap_max = bytes;
+                c->startup_memory_swap_max_set = true;
+        } else if (streq(lvalue, "MemoryZSwapMax"))
                 c->memory_zswap_max = bytes;
-        else if (streq(lvalue, "MemoryLimit")) {
+        else if (streq(lvalue, "StartupMemoryZSwapMax")) {
+                c->startup_memory_zswap_max = bytes;
+                c->startup_memory_zswap_max_set = true;
+        } else if (streq(lvalue, "MemoryLimit")) {
                 log_syntax(unit, LOG_WARNING, filename, line, 0,
                            "Unit uses MemoryLimit=; please use MemoryMax= instead. Support for MemoryLimit= will be removed soon.");
                 c->memory_limit = bytes;
index 281cf62b2043724eb2ed22d28fc93d718ff827cf..589c91a83b08fe4d6c7f25cc3cf99ebe305244f2 100644 (file)
@@ -249,10 +249,15 @@ typedef struct UnitStatusInfo {
         uint64_t memory_current;
         uint64_t memory_min;
         uint64_t memory_low;
+        uint64_t startup_memory_low;
         uint64_t memory_high;
+        uint64_t startup_memory_high;
         uint64_t memory_max;
+        uint64_t startup_memory_max;
         uint64_t memory_swap_max;
+        uint64_t startup_memory_swap_max;
         uint64_t memory_zswap_max;
+        uint64_t startup_memory_zswap_max;
         uint64_t memory_limit;
         uint64_t memory_available;
         uint64_t cpu_usage_nsec;
@@ -265,6 +270,7 @@ typedef struct UnitStatusInfo {
 
         uint64_t default_memory_min;
         uint64_t default_memory_low;
+        uint64_t default_startup_memory_low;
 
         LIST_HEAD(ExecStatusInfo, exec_status_info_list);
 } UnitStatusInfo;
@@ -700,10 +706,12 @@ static void print_status_info(
         if (i->memory_current != UINT64_MAX) {
                 printf("     Memory: %s", FORMAT_BYTES(i->memory_current));
 
-                if (i->memory_min > 0 || i->memory_low > 0 ||
-                    i->memory_high != CGROUP_LIMIT_MAX || i->memory_max != CGROUP_LIMIT_MAX ||
-                    i->memory_swap_max != CGROUP_LIMIT_MAX ||
-                    i->memory_zswap_max != CGROUP_LIMIT_MAX ||
+                if (i->memory_min > 0 ||
+                    i->memory_low > 0 || i->startup_memory_low > 0 ||
+                    i->memory_high != CGROUP_LIMIT_MAX || i->startup_memory_high != CGROUP_LIMIT_MAX ||
+                    i->memory_max != CGROUP_LIMIT_MAX || i->startup_memory_max != CGROUP_LIMIT_MAX ||
+                    i->memory_swap_max != CGROUP_LIMIT_MAX || i->startup_memory_swap_max != CGROUP_LIMIT_MAX ||
+                    i->memory_zswap_max != CGROUP_LIMIT_MAX || i->startup_memory_zswap_max != CGROUP_LIMIT_MAX ||
                     i->memory_available != CGROUP_LIMIT_MAX ||
                     i->memory_limit != CGROUP_LIMIT_MAX) {
                         const char *prefix = "";
@@ -717,22 +725,42 @@ static void print_status_info(
                                 printf("%slow: %s", prefix, FORMAT_BYTES_CGROUP_PROTECTION(i->memory_low));
                                 prefix = " ";
                         }
+                        if (i->startup_memory_low > 0) {
+                                printf("%slow (startup): %s", prefix, FORMAT_BYTES_CGROUP_PROTECTION(i->startup_memory_low));
+                                prefix = " ";
+                        }
                         if (i->memory_high != CGROUP_LIMIT_MAX) {
                                 printf("%shigh: %s", prefix, FORMAT_BYTES(i->memory_high));
                                 prefix = " ";
                         }
+                        if (i->startup_memory_high != CGROUP_LIMIT_MAX) {
+                                printf("%shigh (startup): %s", prefix, FORMAT_BYTES(i->startup_memory_high));
+                                prefix = " ";
+                        }
                         if (i->memory_max != CGROUP_LIMIT_MAX) {
                                 printf("%smax: %s", prefix, FORMAT_BYTES(i->memory_max));
                                 prefix = " ";
                         }
+                        if (i->startup_memory_max != CGROUP_LIMIT_MAX) {
+                                printf("%smax (startup): %s", prefix, FORMAT_BYTES(i->startup_memory_max));
+                                prefix = " ";
+                        }
                         if (i->memory_swap_max != CGROUP_LIMIT_MAX) {
                                 printf("%sswap max: %s", prefix, FORMAT_BYTES(i->memory_swap_max));
                                 prefix = " ";
                         }
+                        if (i->startup_memory_swap_max != CGROUP_LIMIT_MAX) {
+                                printf("%sswap max (startup): %s", prefix, FORMAT_BYTES(i->startup_memory_swap_max));
+                                prefix = " ";
+                        }
                         if (i->memory_zswap_max != CGROUP_LIMIT_MAX) {
                                 printf("%szswap max: %s", prefix, FORMAT_BYTES(i->memory_zswap_max));
                                 prefix = " ";
                         }
+                        if (i->startup_memory_zswap_max != CGROUP_LIMIT_MAX) {
+                                printf("%szswap max (startup): %s", prefix, FORMAT_BYTES(i->startup_memory_zswap_max));
+                                prefix = " ";
+                        }
                         if (i->memory_limit != CGROUP_LIMIT_MAX) {
                                 printf("%slimit: %s", prefix, FORMAT_BYTES(i->memory_limit));
                                 prefix = " ";
@@ -1988,12 +2016,18 @@ static int show_one(
                 { "MemoryAvailable",                "t",               NULL,           offsetof(UnitStatusInfo, memory_available)                  },
                 { "DefaultMemoryMin",               "t",               NULL,           offsetof(UnitStatusInfo, default_memory_min)                },
                 { "DefaultMemoryLow",               "t",               NULL,           offsetof(UnitStatusInfo, default_memory_low)                },
+                { "DefaultStartupMemoryLow",        "t",               NULL,           offsetof(UnitStatusInfo, default_startup_memory_low)        },
                 { "MemoryMin",                      "t",               NULL,           offsetof(UnitStatusInfo, memory_min)                        },
                 { "MemoryLow",                      "t",               NULL,           offsetof(UnitStatusInfo, memory_low)                        },
+                { "StartupMemoryLow",               "t",               NULL,           offsetof(UnitStatusInfo, startup_memory_low)                },
                 { "MemoryHigh",                     "t",               NULL,           offsetof(UnitStatusInfo, memory_high)                       },
+                { "StartupMemoryHigh",              "t",               NULL,           offsetof(UnitStatusInfo, startup_memory_high)               },
                 { "MemoryMax",                      "t",               NULL,           offsetof(UnitStatusInfo, memory_max)                        },
+                { "StartupMemoryMax",               "t",               NULL,           offsetof(UnitStatusInfo, startup_memory_max)                },
                 { "MemorySwapMax",                  "t",               NULL,           offsetof(UnitStatusInfo, memory_swap_max)                   },
+                { "StartupMemorySwapMax",           "t",               NULL,           offsetof(UnitStatusInfo, startup_memory_swap_max)           },
                 { "MemoryZSwapMax",                 "t",               NULL,           offsetof(UnitStatusInfo, memory_zswap_max)                  },
+                { "StartupMemoryZSwapMax",          "t",               NULL,           offsetof(UnitStatusInfo, startup_memory_zswap_max)          },
                 { "MemoryLimit",                    "t",               NULL,           offsetof(UnitStatusInfo, memory_limit)                      },
                 { "CPUUsageNSec",                   "t",               NULL,           offsetof(UnitStatusInfo, cpu_usage_nsec)                    },
                 { "TasksCurrent",                   "t",               NULL,           offsetof(UnitStatusInfo, tasks_current)                     },
index 4032896061d8b00072a10c6427a3b17ed35738ac..c6dc92c050fd401d57a6ff592b76fe80165c7693 100755 (executable)
@@ -21,7 +21,8 @@ EOF
         mkdir -p "${initdir:?}/etc/systemd/system/init.scope.d/"
         cat >>"${initdir:?}/etc/systemd/system/init.scope.d/test-55-oomd.conf" <<EOF
 [Scope]
-MemoryHigh=10G
+MemoryHigh=infinity
+StartupMemoryHigh=10G
 EOF
     )
 }