]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: optionally, accept a percentage value for MemoryLimit= and related settings
authorLennart Poettering <lennart@poettering.net>
Wed, 8 Jun 2016 17:36:09 +0000 (19:36 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 14 Jun 2016 17:50:38 +0000 (19:50 +0200)
If a percentage is used, it is taken relative to the installed RAM size. This
should make it easier to write generic unit files that adapt to the local system.

man/systemd.resource-control.xml
src/core/load-fragment.c

index d4c8fa709196ab2752ad189b945c13d1caa47bb9..0551d750269508af7e6296e9d07b424b536f23af 100644 (file)
           reclaimed as long as memory can be reclaimed from unprotected units.</para>
 
           <para>Takes a memory size in bytes. If the value is suffixed with K, M, G or T, the specified memory size is
-          parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. This controls the
-          <literal>memory.low</literal> control group attribute. For details about this control group attribute, see
-          <ulink url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">cgroup-v2.txt</ulink>.</para>
+          parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. Alternatively, a
+          percentage value may be specified, which is taken relative to the installed physical memory on the
+          system. This controls the <literal>memory.low</literal> control group attribute. For details about this
+          control group attribute, see <ulink
+          url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">cgroup-v2.txt</ulink>.</para>
 
           <para>Implies <literal>MemoryAccounting=true</literal>.</para>
 
           aggressively in such cases. This is the main mechanism to control memory usage of a unit.</para>
 
           <para>Takes a memory size in bytes. If the value is suffixed with K, M, G or T, the specified memory size is
-          parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. If assigned the
+          parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. Alternatively, a
+          percentage value may be specified, which is taken relative to the installed physical memory on the
+          system. If assigned the
           special value <literal>infinity</literal>, no memory limit is applied. This controls the
           <literal>memory.high</literal> control group attribute. For details about this control group attribute, see
           <ulink url="https://www.kernel.org/doc/Documentation/cgroup-v2.txt">cgroup-v2.txt</ulink>.</para>
           last line of defense.</para>
 
           <para>Takes a memory size in bytes. If the value is suffixed with K, M, G or T, the specified memory size is
-          parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. If assigned the
-          special value <literal>infinity</literal>, no memory limit is applied. This controls the
+          parsed as Kilobytes, Megabytes, Gigabytes, or Terabytes (with the base 1024), respectively. Alternatively, a
+          percentage value may be specified, which is taken relative to the installed physical memory on the system. If
+          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://www.kernel.org/doc/Documentation/cgroup-v2.txt">cgroup-v2.txt</ulink>.</para>
 
         <term><varname>MemoryLimit=<replaceable>bytes</replaceable></varname></term>
 
         <listitem>
-          <para>Specify the limit on maximum memory usage of the
-          executed processes. The limit specifies how much process and
-          kernel memory can be used by tasks in this unit. Takes a
-          memory size in bytes. If the value is suffixed with K, M, G
-          or T, the specified memory size is parsed as Kilobytes,
-          Megabytes, Gigabytes, or Terabytes (with the base 1024),
-          respectively. If assigned the special value
-          <literal>infinity</literal>, no memory limit is applied. This
-          controls the <literal>memory.limit_in_bytes</literal>
-          control group attribute. For details about this control
-          group attribute, see <ulink
+          <para>Specify the limit on maximum memory usage of the executed processes. The limit specifies how much
+          process and kernel memory can be used by tasks in this unit. Takes a memory size in bytes. If the value is
+          suffixed with K, M, G or T, the specified memory size is parsed as Kilobytes, Megabytes, Gigabytes, or
+          Terabytes (with the base 1024), respectively. Alternatively, a percentage value may be specified, which is
+          taken relative to the installed physical memory on the system. If assigned the special value
+          <literal>infinity</literal>, no memory limit is applied. This controls the
+          <literal>memory.limit_in_bytes</literal> control group attribute. For details about this control group
+          attribute, see <ulink
           url="https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt">memory.txt</ulink>.</para>
 
           <para>Implies <literal>MemoryAccounting=true</literal>.</para>
index fe60bee789180b4536cd589c905f6659139b183d..05852cc7e3e7a1b48da2a1674125b6379e1c164b 100644 (file)
@@ -2812,9 +2812,19 @@ int config_parse_memory_limit(
         int r;
 
         if (!isempty(rvalue) && !streq(rvalue, "infinity")) {
-                r = parse_size(rvalue, 1024, &bytes);
-                if (r < 0 || bytes < 1) {
-                        log_syntax(unit, LOG_ERR, filename, line, r, "Memory limit '%s' invalid. Ignoring.", rvalue);
+
+                r = parse_percent(rvalue);
+                if (r < 0) {
+                        r = parse_size(rvalue, 1024, &bytes);
+                        if (r < 0) {
+                                log_syntax(unit, LOG_ERR, filename, line, r, "Memory limit '%s' invalid. Ignoring.", rvalue);
+                                return 0;
+                        }
+                } else
+                        bytes = (((physical_memory() / page_size()) * (uint64_t) r) / 100) * page_size();
+
+                if (bytes < 1) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Memory limit '%s' too small. Ignoring.", rvalue);
                         return 0;
                 }
         }