diff options
-rw-r--r-- | man/org.freedesktop.systemd1.xml | 216 | ||||
-rw-r--r-- | man/systemd.resource-control.xml | 30 | ||||
-rw-r--r-- | src/core/cgroup.c | 81 | ||||
-rw-r--r-- | src/core/cgroup.h | 13 | ||||
-rw-r--r-- | src/core/dbus-cgroup.c | 48 | ||||
-rw-r--r-- | src/core/load-fragment-gperf.gperf.in | 6 | ||||
-rw-r--r-- | src/core/load-fragment.c | 39 | ||||
-rw-r--r-- | src/systemctl/systemctl-show.c | 42 | ||||
-rwxr-xr-x | test/TEST-55-OOMD/test.sh | 3 |
9 files changed, 454 insertions, 24 deletions
diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml index bbb6b14339..1592d046ad 100644 --- a/man/org.freedesktop.systemd1.xml +++ b/man/org.freedesktop.systemd1.xml @@ -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"/> diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml index 4b19b18231..f0112bb36b 100644 --- a/man/systemd.resource-control.xml +++ b/man/systemd.resource-control.xml @@ -252,6 +252,7 @@ <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. @@ -284,11 +285,17 @@ 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 @@ -302,11 +309,17 @@ 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 @@ -320,11 +333,17 @@ 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> @@ -334,11 +353,17 @@ 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 @@ -352,6 +377,11 @@ 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> diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 4cac3f6a89..7ac9549f89 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -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); diff --git a/src/core/cgroup.h b/src/core/cgroup.h index d137e3af4f..7d90509642 100644 --- a/src/core/cgroup.h +++ b/src/core/cgroup.h @@ -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); diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index b5484eda78..a3313c417f 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -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); diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in index 3ea3ca3200..58ace46279 100644 --- a/src/core/load-fragment-gperf.gperf.in +++ b/src/core/load-fragment-gperf.gperf.in @@ -202,11 +202,17 @@ {{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) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index ce15758901..ec782703a7 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -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; diff --git a/src/systemctl/systemctl-show.c b/src/systemctl/systemctl-show.c index 281cf62b20..589c91a83b 100644 --- a/src/systemctl/systemctl-show.c +++ b/src/systemctl/systemctl-show.c @@ -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) }, diff --git a/test/TEST-55-OOMD/test.sh b/test/TEST-55-OOMD/test.sh index 4032896061..c6dc92c050 100755 --- a/test/TEST-55-OOMD/test.sh +++ b/test/TEST-55-OOMD/test.sh @@ -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 ) } |