]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #18444 from anitazha/proprename
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 4 Feb 2021 11:53:10 +0000 (12:53 +0100)
committerGitHub <noreply@github.com>
Thu, 4 Feb 2021 11:53:10 +0000 (12:53 +0100)
oom: parse properties with 1/10000 precision instead of 1/100

27 files changed:
docs/TRANSIENT-SETTINGS.md
man/oomd.conf.xml
man/org.freedesktop.systemd1.xml
man/systemd.resource-control.xml
src/basic/parse-util.c
src/basic/parse-util.h
src/core/cgroup.c
src/core/cgroup.h
src/core/core-varlink.c
src/core/dbus-cgroup.c
src/core/dbus-util.c
src/core/dbus-util.h
src/core/load-fragment-gperf.gperf.m4
src/core/load-fragment.c
src/oom/oomd-manager.c
src/oom/oomd-manager.h
src/oom/oomd-util.c
src/oom/oomd.c
src/oom/oomd.conf
src/shared/bus-get-properties.c
src/shared/bus-get-properties.h
src/shared/bus-unit-util.c
src/shared/conf-parser.c
src/shared/conf-parser.h
src/test/test-parse-util.c
test/units/testsuite-56-workload.slice
test/units/testsuite-56.sh

index 50b9a42fa11d00d7a426debf53d9d0a7778c4509..50370602543d46a05a8529d629d2ebd557d83e95 100644 (file)
@@ -272,7 +272,7 @@ All cgroup/resource control settings are available for transient units
 ✓ IPAddressDeny=
 ✓ ManagedOOMSwap=
 ✓ ManagedOOMMemoryPressure=
-✓ ManagedOOMMemoryPressureLimitPercent=
+✓ ManagedOOMMemoryPressureLimit=
 ```
 
 ## Process Killing Settings
index bb5da87c5485930a7679aec6c817c0f1014ac09c..2a12be8cadfc7b11ec82b0802fd516517cd0628c 100644 (file)
       </varlistentry>
 
       <varlistentry>
-        <term><varname>DefaultMemoryPressureLimitPercent=</varname></term>
+        <term><varname>DefaultMemoryPressureLimit=</varname></term>
 
         <listitem><para>Sets the limit for memory pressure on the unit's cgroup before <command>systemd-oomd</command>
-        will take action. A unit can override this value with <varname>ManagedOOMMemoryPressureLimitPercent=</varname>.
+        will take action. A unit can override this value with <varname>ManagedOOMMemoryPressureLimit=</varname>.
         The memory pressure for this property represents the fraction of time in a 10 second window in which all tasks
         in the cgroup were delayed. For each monitored cgroup, if the memory pressure on that cgroup exceeds the
         limit set for longer than the duration set by <varname>DefaultMemoryPressureDurationSec=</varname>,
@@ -78,7 +78,7 @@
 
         <listitem><para>Sets the amount of time a unit's cgroup needs to have exceeded memory pressure limits before
         <command>systemd-oomd</command> will take action. Memory pressure limits are defined by
-        <varname>DefaultMemoryPressureLimitPercent=</varname> and <varname>ManagedOOMMemoryPressureLimitPercent=</varname>.
+        <varname>DefaultMemoryPressureLimit=</varname> and <varname>ManagedOOMMemoryPressureLimit=</varname>.
         Defaults to 30 seconds when this property is unset or set to 0.</para></listitem>
       </varlistentry>
 
index 6783d19b215c9d90e6da679f07d2b0a8d4206aea..7543a617b7853c810121dd7b782ae2ad7f5f0f41 100644 (file)
@@ -2449,7 +2449,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly s ManagedOOMMemoryPressure = '...';
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-      readonly s ManagedOOMMemoryPressureLimitPercent = '...';
+      readonly u ManagedOOMMemoryPressureLimitPermyriad = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly as Environment = ['...', ...];
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@@ -2972,7 +2972,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
 
     <!--property ManagedOOMMemoryPressure is not documented!-->
 
-    <!--property ManagedOOMMemoryPressureLimitPercent is not documented!-->
+    <!--property ManagedOOMMemoryPressureLimitPermyriad is not documented!-->
 
     <!--property EnvironmentFiles is not documented!-->
 
@@ -3536,7 +3536,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
 
     <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
 
-    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPermyriad"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
 
@@ -4203,7 +4203,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly s ManagedOOMMemoryPressure = '...';
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-      readonly s ManagedOOMMemoryPressureLimitPercent = '...';
+      readonly u ManagedOOMMemoryPressureLimitPermyriad = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly as Environment = ['...', ...];
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@@ -4754,7 +4754,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
 
     <!--property ManagedOOMMemoryPressure is not documented!-->
 
-    <!--property ManagedOOMMemoryPressureLimitPercent is not documented!-->
+    <!--property ManagedOOMMemoryPressureLimitPermyriad is not documented!-->
 
     <!--property EnvironmentFiles is not documented!-->
 
@@ -5316,7 +5316,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
 
     <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
 
-    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPermyriad"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
 
@@ -5896,7 +5896,7 @@ node /org/freedesktop/systemd1/unit/home_2emount {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly s ManagedOOMMemoryPressure = '...';
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-      readonly s ManagedOOMMemoryPressureLimitPercent = '...';
+      readonly u ManagedOOMMemoryPressureLimitPermyriad = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly as Environment = ['...', ...];
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@@ -6375,7 +6375,7 @@ node /org/freedesktop/systemd1/unit/home_2emount {
 
     <!--property ManagedOOMMemoryPressure is not documented!-->
 
-    <!--property ManagedOOMMemoryPressureLimitPercent is not documented!-->
+    <!--property ManagedOOMMemoryPressureLimitPermyriad is not documented!-->
 
     <!--property EnvironmentFiles is not documented!-->
 
@@ -6855,7 +6855,7 @@ node /org/freedesktop/systemd1/unit/home_2emount {
 
     <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
 
-    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPermyriad"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
 
@@ -7556,7 +7556,7 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly s ManagedOOMMemoryPressure = '...';
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-      readonly s ManagedOOMMemoryPressureLimitPercent = '...';
+      readonly u ManagedOOMMemoryPressureLimitPermyriad = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly as Environment = ['...', ...];
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@@ -8021,7 +8021,7 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
 
     <!--property ManagedOOMMemoryPressure is not documented!-->
 
-    <!--property ManagedOOMMemoryPressureLimitPercent is not documented!-->
+    <!--property ManagedOOMMemoryPressureLimitPermyriad is not documented!-->
 
     <!--property EnvironmentFiles is not documented!-->
 
@@ -8487,7 +8487,7 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
 
     <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
 
-    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPermyriad"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="Environment"/>
 
@@ -9041,7 +9041,7 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly s ManagedOOMMemoryPressure = '...';
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-      readonly s ManagedOOMMemoryPressureLimitPercent = '...';
+      readonly u ManagedOOMMemoryPressureLimitPermyriad = ...;
   };
   interface org.freedesktop.DBus.Peer { ... };
   interface org.freedesktop.DBus.Introspectable { ... };
@@ -9176,7 +9176,7 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
 
     <!--property ManagedOOMMemoryPressure is not documented!-->
 
-    <!--property ManagedOOMMemoryPressureLimitPercent is not documented!-->
+    <!--property ManagedOOMMemoryPressureLimitPermyriad is not documented!-->
 
     <!--Autogenerated cross-references for systemd.directives, do not edit-->
 
@@ -9316,7 +9316,7 @@ node /org/freedesktop/systemd1/unit/system_2eslice {
 
     <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
 
-    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPermyriad"/>
 
     <!--End of Autogenerated section-->
 
@@ -9476,7 +9476,7 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly s ManagedOOMMemoryPressure = '...';
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
-      readonly s ManagedOOMMemoryPressureLimitPercent = '...';
+      readonly u ManagedOOMMemoryPressureLimitPermyriad = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly s KillMode = '...';
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@@ -9627,7 +9627,7 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
 
     <!--property ManagedOOMMemoryPressure is not documented!-->
 
-    <!--property ManagedOOMMemoryPressureLimitPercent is not documented!-->
+    <!--property ManagedOOMMemoryPressureLimitPermyriad is not documented!-->
 
     <!--property KillMode is not documented!-->
 
@@ -9793,7 +9793,7 @@ node /org/freedesktop/systemd1/unit/session_2d1_2escope {
 
     <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressure"/>
 
-    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPercent"/>
+    <variablelist class="dbus-property" generated="True" extra-ref="ManagedOOMMemoryPressureLimitPermyriad"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="KillMode"/>
 
index 2e547d8b82198b5998b802af63f8ff23a390a626..be9c35057db955878b0a1b3e729583535d66aeb6 100644 (file)
@@ -901,7 +901,7 @@ DeviceAllow=/dev/loop-control
       </varlistentry>
 
       <varlistentry>
-        <term><varname>ManagedOOMMemoryPressureLimitPercent=</varname></term>
+        <term><varname>ManagedOOMMemoryPressureLimit=</varname></term>
 
         <listitem>
           <para>Overrides the default memory pressure limit set by
index 2a7280fc3821a1afbf3d993c0711886ff4835e56..97d224f16545c12e099da65a44327d847930f589 100644 (file)
@@ -627,11 +627,11 @@ int parse_fractional_part_u(const char **p, size_t digits, unsigned *res) {
         return 0;
 }
 
-int parse_percent_unbounded(const char *p) {
+static int parse_parts_value_whole(const char *p, const char *symbol) {
         const char *pc, *n;
         int r, v;
 
-        pc = endswith(p, "%");
+        pc = endswith(p, symbol);
         if (!pc)
                 return -EINVAL;
 
@@ -645,6 +645,74 @@ int parse_percent_unbounded(const char *p) {
         return v;
 }
 
+static int parse_parts_value_with_tenths_place(const char *p, const char *symbol) {
+        const char *pc, *dot, *n;
+        int r, q, v;
+
+        pc = endswith(p, symbol);
+        if (!pc)
+                return -EINVAL;
+
+        dot = memchr(p, '.', pc - p);
+        if (dot) {
+                if (dot + 2 != pc)
+                        return -EINVAL;
+                if (dot[1] < '0' || dot[1] > '9')
+                        return -EINVAL;
+                q = dot[1] - '0';
+                n = strndupa(p, dot - p);
+        } else {
+                q = 0;
+                n = strndupa(p, pc - p);
+        }
+        r = safe_atoi(n, &v);
+        if (r < 0)
+                return r;
+        if (v < 0)
+                return -ERANGE;
+        if (v > (INT_MAX - q) / 10)
+                return -ERANGE;
+
+        v = v * 10 + q;
+        return v;
+}
+
+static int parse_parts_value_with_hundredths_place(const char *p, const char *symbol) {
+        const char *pc, *dot, *n;
+        int r, q, v;
+
+        pc = endswith(p, symbol);
+        if (!pc)
+                return -EINVAL;
+
+        dot = memchr(p, '.', pc - p);
+        if (dot) {
+                if (dot + 3 != pc)
+                        return -EINVAL;
+                if (dot[1] < '0' || dot[1] > '9' || dot[2] < '0' || dot[2] > '9')
+                        return -EINVAL;
+                q = (dot[1] - '0') * 10 + (dot[2] - '0');
+                n = strndupa(p, dot - p);
+        } else {
+                q = 0;
+                n = strndupa(p, pc - p);
+        }
+        r = safe_atoi(n, &v);
+        if (r < 0)
+                return r;
+        if (v < 0)
+                return -ERANGE;
+        if (v > (INT_MAX - q) / 100)
+                return -ERANGE;
+
+        v = v * 100 + q;
+        return v;
+}
+
+int parse_percent_unbounded(const char *p) {
+        return parse_parts_value_whole(p, "%");
+}
+
 int parse_percent(const char *p) {
         int v;
 
@@ -656,46 +724,13 @@ int parse_percent(const char *p) {
 }
 
 int parse_permille_unbounded(const char *p) {
-        const char *pc, *pm, *dot, *n;
-        int r, q, v;
+        const char *pm;
 
         pm = endswith(p, "‰");
-        if (pm) {
-                n = strndupa(p, pm - p);
-                r = safe_atoi(n, &v);
-                if (r < 0)
-                        return r;
-                if (v < 0)
-                        return -ERANGE;
-        } else {
-                pc = endswith(p, "%");
-                if (!pc)
-                        return -EINVAL;
-
-                dot = memchr(p, '.', pc - p);
-                if (dot) {
-                        if (dot + 2 != pc)
-                                return -EINVAL;
-                        if (dot[1] < '0' || dot[1] > '9')
-                                return -EINVAL;
-                        q = dot[1] - '0';
-                        n = strndupa(p, dot - p);
-                } else {
-                        q = 0;
-                        n = strndupa(p, pc - p);
-                }
-                r = safe_atoi(n, &v);
-                if (r < 0)
-                        return r;
-                if (v < 0)
-                        return -ERANGE;
-                if (v > (INT_MAX - q) / 10)
-                        return -ERANGE;
+        if (pm)
+                return parse_parts_value_whole(p, "‰");
 
-                v = v * 10 + q;
-        }
-
-        return v;
+        return parse_parts_value_with_tenths_place(p, "%");
 }
 
 int parse_permille(const char *p) {
@@ -708,6 +743,30 @@ int parse_permille(const char *p) {
         return v;
 }
 
+int parse_permyriad_unbounded(const char *p) {
+        const char *pm;
+
+        pm = endswith(p, "‱");
+        if (pm)
+                return parse_parts_value_whole(p, "‱");
+
+        pm = endswith(p, "‰");
+        if (pm)
+                return parse_parts_value_with_tenths_place(p, "‰");
+
+        return parse_parts_value_with_hundredths_place(p, "%");
+}
+
+int parse_permyriad(const char *p) {
+        int v;
+
+        v = parse_permyriad_unbounded(p);
+        if (v > 10000)
+                return -ERANGE;
+
+        return v;
+}
+
 int parse_nice(const char *p, int *ret) {
         int n, r;
 
index 1ff76ded446c468d0aea374f4f8e9978705f768d..29e04cf5628f70a823a91a5763aa918a057cba41 100644 (file)
@@ -133,6 +133,9 @@ int parse_percent(const char *p);
 int parse_permille_unbounded(const char *p);
 int parse_permille(const char *p);
 
+int parse_permyriad_unbounded(const char *p);
+int parse_permyriad(const char *p);
+
 int parse_nice(const char *p, int *ret);
 
 int parse_ip_port(const char *s, uint16_t *ret);
index cebead5eb5199394f4e97a1d38cefc7e85d4704d..c881a1952675dcb5517158a5843758e1c1c5f852 100644 (file)
@@ -417,7 +417,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
                 "%sDelegate: %s\n"
                 "%sManagedOOMSwap: %s\n"
                 "%sManagedOOMMemoryPressure: %s\n"
-                "%sManagedOOMMemoryPressureLimitPercent: %d%%\n",
+                "%sManagedOOMMemoryPressureLimit: %" PRIu32 ".%02" PRIu32 "%%\n",
                 prefix, yes_no(c->cpu_accounting),
                 prefix, yes_no(c->io_accounting),
                 prefix, yes_no(c->blockio_accounting),
@@ -450,7 +450,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
                 prefix, yes_no(c->delegate),
                 prefix, managed_oom_mode_to_string(c->moom_swap),
                 prefix, managed_oom_mode_to_string(c->moom_mem_pressure),
-                prefix, c->moom_mem_pressure_limit);
+                prefix, c->moom_mem_pressure_limit_permyriad / 100, c->moom_mem_pressure_limit_permyriad % 100);
 
         if (c->delegate) {
                 _cleanup_free_ char *t = NULL;
index 66f3a63b8210b8a71714273002c3fb79a3ab4666..9fbfabbb7e3da28a685b72d5b1c9a01639a576a2 100644 (file)
@@ -163,7 +163,7 @@ struct CGroupContext {
         /* Settings for systemd-oomd */
         ManagedOOMMode moom_swap;
         ManagedOOMMode moom_mem_pressure;
-        int moom_mem_pressure_limit;
+        uint32_t moom_mem_pressure_limit_permyriad;
 };
 
 /* Used when querying IP accounting data */
index d695106658bff89da7087b5a035601d4ec02a6b8..df542e82d1ab5b9c43d736426d8d39e561547709 100644 (file)
@@ -83,7 +83,7 @@ static int build_managed_oom_json_array_element(Unit *u, const char *property, J
                                  JSON_BUILD_PAIR("mode", JSON_BUILD_STRING(mode)),
                                  JSON_BUILD_PAIR("path", JSON_BUILD_STRING(u->cgroup_path)),
                                  JSON_BUILD_PAIR("property", JSON_BUILD_STRING(property)),
-                                 JSON_BUILD_PAIR_CONDITION(use_limit, "limit", JSON_BUILD_UNSIGNED(c->moom_mem_pressure_limit))));
+                                 JSON_BUILD_PAIR_CONDITION(use_limit, "limit", JSON_BUILD_UNSIGNED(c->moom_mem_pressure_limit_permyriad))));
 }
 
 int manager_varlink_send_managed_oom_update(Unit *u) {
index a7d9312d9781ed4ed245de19a9ac2313d38ab33e..6f309feb236c42750bbca74ac3116908c39bfe7f 100644 (file)
@@ -394,7 +394,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
         SD_BUS_PROPERTY("DisableControllers", "as", property_get_cgroup_mask, offsetof(CGroupContext, disable_controllers), 0),
         SD_BUS_PROPERTY("ManagedOOMSwap", "s", property_get_managed_oom_mode, offsetof(CGroupContext, moom_swap), 0),
         SD_BUS_PROPERTY("ManagedOOMMemoryPressure", "s", property_get_managed_oom_mode, offsetof(CGroupContext, moom_mem_pressure), 0),
-        SD_BUS_PROPERTY("ManagedOOMMemoryPressureLimitPercent", "s", bus_property_get_percent, offsetof(CGroupContext, moom_mem_pressure_limit), 0),
+        SD_BUS_PROPERTY("ManagedOOMMemoryPressureLimitPermyriad", "u", NULL, offsetof(CGroupContext, moom_mem_pressure_limit_permyriad), 0),
         SD_BUS_VTABLE_END
 };
 
@@ -1696,14 +1696,24 @@ int bus_cgroup_set_property(
                 return 1;
         }
 
-        if (streq(name, "ManagedOOMMemoryPressureLimitPercent")) {
+        if (streq(name, "ManagedOOMMemoryPressureLimitPermyriad")) {
+                uint32_t v;
+
                 if (!UNIT_VTABLE(u)->can_set_managed_oom)
                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot set %s for this unit type", name);
 
-                r = bus_set_transient_percent(u, name, &c->moom_mem_pressure_limit, message, flags, error);
+                r = sd_bus_message_read(message, "u", &v);
                 if (r < 0)
                         return r;
 
+                if (v > 10000)
+                        return -ERANGE;
+
+                if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
+                        c->moom_mem_pressure_limit_permyriad = v;
+                        unit_write_settingf(u, flags, name, "ManagedOOMMemoryPressureLimit=%" PRIu32 ".%02" PRIu32 "%%", v / 100, v % 100);
+                }
+
                 if (c->moom_mem_pressure == MANAGED_OOM_KILL)
                         (void) manager_varlink_send_managed_oom_update(u);
 
index 6a6dd1ff41267c17139f7429ab9779664a73f568..44a2ccfca066d7da719151d8376c15d4488ee1e6 100644 (file)
@@ -93,35 +93,6 @@ int bus_set_transient_bool(
         return 1;
 }
 
-int bus_set_transient_percent(
-                Unit *u,
-                const char *name,
-                int *p,
-                sd_bus_message *message,
-                UnitWriteFlags flags,
-                sd_bus_error *error) {
-
-        const char *v;
-        int r;
-
-        assert(p);
-
-        r = sd_bus_message_read(message, "s", &v);
-        if (r < 0)
-                return r;
-
-        r = parse_percent(v);
-        if (r < 0)
-                return r;
-
-        if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
-                *p = r;
-                unit_write_settingf(u, flags, name, "%s=%d%%", name, r);
-        }
-
-        return 1;
-}
-
 int bus_set_transient_usec_internal(
                 Unit *u,
                 const char *name,
index bd4fd081c5c878d065686bcf56e16870d5a7818a..799136737ba225b2a169b9f87ae8bf8413fcac79 100644 (file)
@@ -241,7 +241,6 @@ int bus_set_transient_user_relaxed(Unit *u, const char *name, char **p, sd_bus_m
 int bus_set_transient_path(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
 int bus_set_transient_string(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
 int bus_set_transient_bool(Unit *u, const char *name, bool *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
-int bus_set_transient_percent(Unit *u, const char *name, int *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
 int bus_set_transient_usec_internal(Unit *u, const char *name, usec_t *p, bool fix_0, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
 static inline int bus_set_transient_usec(Unit *u, const char *name, usec_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) {
         return bus_set_transient_usec_internal(u, name, p, false, message, flags, error);
index 6bf22c336aeef28a9fc99fa2f4689bd37600ca07..81f4561a572221d001542cc67bd8472c04b5269d 100644 (file)
@@ -229,7 +229,7 @@ $1.IPIngressFilterPath,                  config_parse_ip_filter_bpf_progs,
 $1.IPEgressFilterPath,                   config_parse_ip_filter_bpf_progs,            0,                                  offsetof($1, cgroup_context.ip_filters_egress)
 $1.ManagedOOMSwap,                       config_parse_managed_oom_mode,               0,                                  offsetof($1, cgroup_context.moom_swap)
 $1.ManagedOOMMemoryPressure,             config_parse_managed_oom_mode,               0,                                  offsetof($1, cgroup_context.moom_mem_pressure)
-$1.ManagedOOMMemoryPressureLimitPercent, config_parse_managed_oom_mem_pressure_limit, 0,                                  offsetof($1, cgroup_context.moom_mem_pressure_limit)
+$1.ManagedOOMMemoryPressureLimit,        config_parse_managed_oom_mem_pressure_limit, 0,                                  offsetof($1, cgroup_context.moom_mem_pressure_limit_permyriad)
 $1.NetClass,                             config_parse_warn_compat,                    DISABLED_LEGACY,                    0'
 )m4_dnl
 Unit.Description,                        config_parse_unit_string_printf,             0,                                  offsetof(Unit, description)
index f3c2958b057c3f55abdf9d8a3d9a932bb06fb334..06b71aaf1575a10b5132eeefc4fd9660f031b76f 100644 (file)
@@ -3875,7 +3875,7 @@ int config_parse_managed_oom_mem_pressure_limit(
                 const char *rvalue,
                 void *data,
                 void *userdata) {
-        int *limit = data;
+        uint32_t *limit = data;
         UnitType t;
         int r;
 
@@ -3890,9 +3890,9 @@ int config_parse_managed_oom_mem_pressure_limit(
                 return 0;
         }
 
-        r = parse_percent(rvalue);
+        r = parse_permyriad(rvalue);
         if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse limit percent value, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse memory pressure limit value, ignoring: %s", rvalue);
                 return 0;
         }
 
index 3efa629002e72b8fecd040350de2842ef306b670..338935b3ec6681a43940f4742a2caa7d3f375281 100644 (file)
@@ -100,10 +100,10 @@ static int process_managed_oom_reply(
                 limit = m->default_mem_pressure_limit;
 
                 if (streq(reply.property, "ManagedOOMMemoryPressure")) {
-                        if (reply.limit > 100)
+                        if (reply.limit > 10000)
                                 continue;
                         else if (reply.limit != 0) {
-                                ret = store_loadavg_fixed_point((unsigned long) reply.limit0, &limit);
+                                ret = store_loadavg_fixed_point((unsigned long) reply.limit / 100, (unsigned long) reply.limit % 100, &limit);
                                 if (ret < 0)
                                         continue;
                         }
@@ -478,8 +478,8 @@ static int manager_connect_bus(Manager *m) {
         return 0;
 }
 
-int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressure_limit, usec_t mem_pressure_usec) {
-        unsigned long l;
+int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressure_limit_permyriad, usec_t mem_pressure_usec) {
+        unsigned long l, f;
         int r;
 
         assert(m);
@@ -489,8 +489,16 @@ int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressur
         m->swap_used_limit = swap_used_limit != -1 ? swap_used_limit : DEFAULT_SWAP_USED_LIMIT;
         assert(m->swap_used_limit <= 100);
 
-        l = mem_pressure_limit != -1 ? mem_pressure_limit : DEFAULT_MEM_PRESSURE_LIMIT;
-        r = store_loadavg_fixed_point(l, 0, &m->default_mem_pressure_limit);
+        if (mem_pressure_limit_permyriad != -1) {
+                assert(mem_pressure_limit_permyriad <= 10000);
+
+                l = mem_pressure_limit_permyriad / 100;
+                f = mem_pressure_limit_permyriad % 100;
+        } else {
+                l = DEFAULT_MEM_PRESSURE_LIMIT_PERCENT;
+                f = 0;
+        }
+        r = store_loadavg_fixed_point(l, f, &m->default_mem_pressure_limit);
         if (r < 0)
                 return r;
 
@@ -530,12 +538,12 @@ int manager_get_dump_string(Manager *m, char **ret) {
         fprintf(f,
                 "Dry Run: %s\n"
                 "Swap Used Limit: %u%%\n"
-                "Default Memory Pressure Limit: %lu%%\n"
+                "Default Memory Pressure Limit: %lu.%02lu%%\n"
                 "Default Memory Pressure Duration: %s\n"
                 "System Context:\n",
                 yes_no(m->dry_run),
                 m->swap_used_limit,
-                LOAD_INT(m->default_mem_pressure_limit),
+                LOAD_INT(m->default_mem_pressure_limit), LOAD_FRAC(m->default_mem_pressure_limit),
                 format_timespan(buf, sizeof(buf), m->default_mem_pressure_duration_usec, USEC_PER_SEC));
         oomd_dump_system_context(&m->system_context, f, "\t");
 
index ee17abced267c28ef8443c06762e99228ef463fe..521665e0a824df2aedd71d82a7dc872f4eff188c 100644 (file)
@@ -17,7 +17,7 @@
  * Generally 60 or higher might be acceptable for something like system.slice with no memory.high set; processes in
  * system.slice are assumed to be less latency sensitive. */
 #define DEFAULT_MEM_PRESSURE_DURATION_USEC (30 * USEC_PER_SEC)
-#define DEFAULT_MEM_PRESSURE_LIMIT 60
+#define DEFAULT_MEM_PRESSURE_LIMIT_PERCENT 60
 #define DEFAULT_SWAP_USED_LIMIT 90
 
 #define RECLAIM_DURATION_USEC (30 * USEC_PER_SEC)
@@ -56,7 +56,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
 
 int manager_new(Manager **ret);
 
-int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressure_limit, usec_t mem_pressure_usec);
+int manager_start(Manager *m, bool dry_run, int swap_used_limit, int mem_pressure_limit_permyriad, usec_t mem_pressure_usec);
 
 int manager_get_dump_string(Manager *m, char **ret);
 
index cec656f6faf418e830b50a6c300aa40f961bf01f..fcccddb92eae3ff7d35ecd7306412ed79cc84395 100644 (file)
@@ -415,11 +415,11 @@ void oomd_dump_memory_pressure_cgroup_context(const OomdCGroupContext *ctx, FILE
 
         fprintf(f,
                 "%sPath: %s\n"
-                "%s\tMemory Pressure Limit: %lu%%\n"
+                "%s\tMemory Pressure Limit: %lu.%02lu%%\n"
                 "%s\tPressure: Avg10: %lu.%02lu Avg60: %lu.%02lu Avg300: %lu.%02lu Total: %s\n"
                 "%s\tCurrent Memory Usage: %s\n",
                 strempty(prefix), ctx->path,
-                strempty(prefix), LOAD_INT(ctx->mem_pressure_limit),
+                strempty(prefix), LOAD_INT(ctx->mem_pressure_limit), LOAD_FRAC(ctx->mem_pressure_limit),
                 strempty(prefix),
                 LOAD_INT(ctx->memory_pressure.avg10), LOAD_FRAC(ctx->memory_pressure.avg10),
                 LOAD_INT(ctx->memory_pressure.avg60), LOAD_FRAC(ctx->memory_pressure.avg60),
index 3f3ef944ee17988db07b9fc345da2100ee5b4ac0..a5b445191363a8ef692ee0e9612668182b64de4b 100644 (file)
 
 static bool arg_dry_run = false;
 static int arg_swap_used_limit = -1;
-static int arg_mem_pressure_limit = -1;
+static int arg_mem_pressure_limit_permyriad = -1;
 static usec_t arg_mem_pressure_usec = 0;
 
 static int parse_config(void) {
         static const ConfigTableItem items[] = {
-                { "OOM", "SwapUsedLimitPercent",              config_parse_percent, 0, &arg_swap_used_limit    },
-                { "OOM", "DefaultMemoryPressureLimitPercent", config_parse_percent, 0, &arg_mem_pressure_limit },
-                { "OOM", "DefaultMemoryPressureDurationSec",  config_parse_sec,     0, &arg_mem_pressure_usec  },
+                { "OOM", "SwapUsedLimitPercent",             config_parse_percent,   0, &arg_swap_used_limit              },
+                { "OOM", "DefaultMemoryPressureLimit",       config_parse_permyriad, 0, &arg_mem_pressure_limit_permyriad },
+                { "OOM", "DefaultMemoryPressureDurationSec", config_parse_sec,       0, &arg_mem_pressure_usec            },
                 {}
         };
 
@@ -159,7 +159,7 @@ static int run(int argc, char *argv[]) {
         if (r < 0)
                 return log_error_errno(r, "Failed to create manager: %m");
 
-        r = manager_start(m, arg_dry_run, arg_swap_used_limit, arg_mem_pressure_limit, arg_mem_pressure_usec);
+        r = manager_start(m, arg_dry_run, arg_swap_used_limit, arg_mem_pressure_limit_permyriad, arg_mem_pressure_usec);
         if (r < 0)
                 return log_error_errno(r, "Failed to start up daemon: %m");
 
index 766cb1717f7b6c62c9e139ebdc2256125bed6161..bd6a9391c6e87fc213adf2b6b81593395a3fd94a 100644 (file)
@@ -13,5 +13,5 @@
 
 [OOM]
 #SwapUsedLimitPercent=90%
-#DefaultMemoryPressureLimitPercent=60%
+#DefaultMemoryPressureLimit=60%
 #DefaultMemoryPressureDurationSec=30s
index 32f68d5e6a869fa9ff5a81f3e32d5f4d4a83cdbc..a5ce7ef17f0185b3803b6f3ebed30b702a72608c 100644 (file)
@@ -55,23 +55,6 @@ int bus_property_get_id128(
                 return sd_bus_message_append_array(reply, 'y', id->bytes, 16);
 }
 
-int bus_property_get_percent(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        char pstr[DECIMAL_STR_MAX(int) + 2];
-        int p = *(int*) userdata;
-
-        xsprintf(pstr, "%d%%", p);
-
-        return sd_bus_message_append_basic(reply, 's', pstr);
-}
-
 #if __SIZEOF_SIZE_T__ != 8
 int bus_property_get_size(
                 sd_bus *bus,
index 9832c0d067f224bd3026950a029bacc32b8ff9ca..26f3e8588cb8a6a5848367fa8879d752fef96d88 100644 (file)
@@ -8,7 +8,6 @@
 int bus_property_get_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
 int bus_property_set_bool(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error);
 int bus_property_get_id128(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
-int bus_property_get_percent(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);
 
 #define bus_property_get_usec ((sd_bus_property_get_t) NULL)
 #define bus_property_set_usec ((sd_bus_property_set_t) NULL)
index 8fd2f89adc7eb63694425705c0fe4e25bfb9d5b4..84f57d94d2358e14458f8d512ee607fe4a356328 100644 (file)
@@ -435,10 +435,25 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
         if (STR_IN_SET(field, "DevicePolicy",
                               "Slice",
                               "ManagedOOMSwap",
-                              "ManagedOOMMemoryPressure",
-                              "ManagedOOMMemoryPressureLimitPercent"))
+                              "ManagedOOMMemoryPressure"))
                 return bus_append_string(m, field, eq);
 
+        if (STR_IN_SET(field, "ManagedOOMMemoryPressureLimit")) {
+                char *n;
+
+                r = parse_permyriad(eq);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
+
+                n = strjoina(field, "Permyriad");
+
+                r = sd_bus_message_append(m, "(sv)", n, "u", (uint32_t) r);
+                if (r < 0)
+                        return bus_log_create_error(r);
+
+                return 1;
+        }
+
         if (STR_IN_SET(field, "CPUAccounting",
                               "MemoryAccounting",
                               "IOAccounting",
index 0a1f2d67d43a66ea349cb1d984e500c48f69f612..f838d4513d65dd92e59a04c2613ab000157ae81a 100644 (file)
@@ -1356,3 +1356,4 @@ int config_parse_hwaddrs(
 }
 
 DEFINE_CONFIG_PARSE(config_parse_percent, parse_percent, "Failed to parse percent value");
+DEFINE_CONFIG_PARSE(config_parse_permyriad, parse_permyriad, "Failed to parse permyriad value");
index b19482193701bd1eca7c36b9c227325ef2d9a269..283d60a47326986115a9a4b8ead24c28dee83784 100644 (file)
@@ -150,6 +150,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_vlanprotocol);
 CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr);
 CONFIG_PARSER_PROTOTYPE(config_parse_hwaddrs);
 CONFIG_PARSER_PROTOTYPE(config_parse_percent);
+CONFIG_PARSER_PROTOTYPE(config_parse_permyriad);
 
 typedef enum Disabled {
         DISABLED_CONFIGURATION,
index 1c969091ef7052bd108bb56c1f3bb635be3a99b7..6e23efe13482870c8f9c9d26aa5b0186167cc4ba 100644 (file)
@@ -790,6 +790,72 @@ static void test_parse_permille_unbounded(void) {
         assert_se(parse_permille_unbounded("429496729.6%") == -ERANGE);
 }
 
+static void test_parse_permyriad(void) {
+        assert_se(parse_permyriad("") == -EINVAL);
+        assert_se(parse_permyriad("foo") == -EINVAL);
+        assert_se(parse_permyriad("0") == -EINVAL);
+        assert_se(parse_permyriad("50") == -EINVAL);
+        assert_se(parse_permyriad("100") == -EINVAL);
+        assert_se(parse_permyriad("-1") == -EINVAL);
+
+        assert_se(parse_permyriad("0‱") == 0);
+        assert_se(parse_permyriad("555‱") == 555);
+        assert_se(parse_permyriad("1000‱") == 1000);
+        assert_se(parse_permyriad("-7‱") == -ERANGE);
+        assert_se(parse_permyriad("10007‱") == -ERANGE);
+        assert_se(parse_permyriad("‱") == -EINVAL);
+        assert_se(parse_permyriad("‱‱") == -EINVAL);
+        assert_se(parse_permyriad("‱1") == -EINVAL);
+        assert_se(parse_permyriad("1‱‱") == -EINVAL);
+        assert_se(parse_permyriad("3.2‱") == -EINVAL);
+
+        assert_se(parse_permyriad("0‰") == 0);
+        assert_se(parse_permyriad("555.5‰") == 5555);
+        assert_se(parse_permyriad("1000.0‰") == 10000);
+        assert_se(parse_permyriad("-7‰") == -ERANGE);
+        assert_se(parse_permyriad("1007‰") == -ERANGE);
+        assert_se(parse_permyriad("‰") == -EINVAL);
+        assert_se(parse_permyriad("‰‰") == -EINVAL);
+        assert_se(parse_permyriad("‰1") == -EINVAL);
+        assert_se(parse_permyriad("1‰‰") == -EINVAL);
+        assert_se(parse_permyriad("3.22‰") == -EINVAL);
+
+        assert_se(parse_permyriad("0%") == 0);
+        assert_se(parse_permyriad("55%") == 5500);
+        assert_se(parse_permyriad("55.53%") == 5553);
+        assert_se(parse_permyriad("100%") == 10000);
+        assert_se(parse_permyriad("-7%") == -ERANGE);
+        assert_se(parse_permyriad("107%") == -ERANGE);
+        assert_se(parse_permyriad("%") == -EINVAL);
+        assert_se(parse_permyriad("%%") == -EINVAL);
+        assert_se(parse_permyriad("%1") == -EINVAL);
+        assert_se(parse_permyriad("1%%") == -EINVAL);
+        assert_se(parse_permyriad("3.212%") == -EINVAL);
+}
+
+static void test_parse_permyriad_unbounded(void) {
+        assert_se(parse_permyriad_unbounded("1001‱") == 1001);
+        assert_se(parse_permyriad_unbounded("4000‱") == 4000);
+        assert_se(parse_permyriad_unbounded("2147483647‱") == 2147483647);
+        assert_se(parse_permyriad_unbounded("2147483648‱") == -ERANGE);
+        assert_se(parse_permyriad_unbounded("4294967295‱") == -ERANGE);
+        assert_se(parse_permyriad_unbounded("4294967296‱") == -ERANGE);
+
+        assert_se(parse_permyriad_unbounded("101‰") == 1010);
+        assert_se(parse_permyriad_unbounded("400‰") == 4000);
+        assert_se(parse_permyriad_unbounded("214748364.7‰") == 2147483647);
+        assert_se(parse_permyriad_unbounded("214748364.8‰") == -ERANGE);
+        assert_se(parse_permyriad_unbounded("429496729.5‰") == -ERANGE);
+        assert_se(parse_permyriad_unbounded("429496729.6‰") == -ERANGE);
+
+        assert_se(parse_permyriad_unbounded("99%") == 9900);
+        assert_se(parse_permyriad_unbounded("40%") == 4000);
+        assert_se(parse_permyriad_unbounded("21474836.47%") == 2147483647);
+        assert_se(parse_permyriad_unbounded("21474836.48%") == -ERANGE);
+        assert_se(parse_permyriad_unbounded("42949672.95%") == -ERANGE);
+        assert_se(parse_permyriad_unbounded("42949672.96%") == -ERANGE);
+}
+
 static void test_parse_nice(void) {
         int n;
 
@@ -987,6 +1053,8 @@ int main(int argc, char *argv[]) {
         test_parse_percent_unbounded();
         test_parse_permille();
         test_parse_permille_unbounded();
+        test_parse_permyriad();
+        test_parse_permyriad_unbounded();
         test_parse_nice();
         test_parse_dev();
         test_parse_errno();
index 45b04914c632b62b74a1799188593d03ce2e4c08..8c32b28094f18b9977f8e43fce906e047362d693 100644 (file)
@@ -7,4 +7,4 @@ MemoryAccounting=true
 IOAccounting=true
 TasksAccounting=true
 ManagedOOMMemoryPressure=kill
-ManagedOOMMemoryPressureLimitPercent=1%
+ManagedOOMMemoryPressureLimit=1%
index 4dc9d8c7a86c408b67c6d14a820b7678ba14edc1..8b01fe37ed4d56e7ab950a75d6302af2cb3127d3 100755 (executable)
@@ -20,7 +20,7 @@ systemctl start testsuite-56-testbloat.service
 
 # Verify systemd-oomd is monitoring the expected units
 oomctl | grep "/testsuite-56-workload.slice"
-oomctl | grep "1%"
+oomctl | grep "1.00%"
 oomctl | grep "Default Memory Pressure Duration: 5s"
 
 # systemd-oomd watches for elevated pressure for 30 seconds before acting.