|
|
1abbee |
From 128ef85392f68fa32650deab12d6cd2e01ad52cf Mon Sep 17 00:00:00 2001
|
|
|
1abbee |
From: Lennart Poettering <lennart@poettering.net>
|
|
|
1abbee |
Date: Tue, 10 Nov 2015 16:52:52 +0100
|
|
|
1abbee |
Subject: [PATCH] core: accept time units for time-based resource limits
|
|
|
1abbee |
|
|
|
1abbee |
Let's make sure "LimitCPU=30min" can be parsed properly, following the
|
|
|
1abbee |
usual logic how we parse time values. Similar for LimitRTTIME=.
|
|
|
1abbee |
|
|
|
1abbee |
While we are at it, extend a bit on the man page section about resource
|
|
|
1abbee |
limits.
|
|
|
1abbee |
|
|
|
1abbee |
Fixes: #1772
|
|
|
1abbee |
|
|
|
1abbee |
Cherry-picked from: a4c1800284e3546bbfab2dc19eb59bcb91c4a2ca
|
|
|
1abbee |
Related: #1351415
|
|
|
1abbee |
---
|
|
|
1abbee |
man/systemd.exec.xml | 86 ++++++++++++++++++++++-------
|
|
|
1abbee |
src/core/load-fragment-gperf.gperf.m4 | 4 +-
|
|
|
1abbee |
src/core/load-fragment.c | 101 ++++++++++++++++++++++++++++++++++
|
|
|
1abbee |
src/core/load-fragment.h | 2 +
|
|
|
1abbee |
src/test/test-unit-file.c | 61 ++++++++++++++++++++
|
|
|
1abbee |
5 files changed, 231 insertions(+), 23 deletions(-)
|
|
|
1abbee |
|
|
|
1abbee |
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
|
|
|
1abbee |
index 25aea16..cfdcc3d 100644
|
|
|
1abbee |
--- a/man/systemd.exec.xml
|
|
|
1abbee |
+++ b/man/systemd.exec.xml
|
|
|
1abbee |
@@ -559,90 +559,133 @@
|
|
|
1abbee |
of various resources for executed processes. See
|
|
|
1abbee |
<citerefentry><refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
|
|
1abbee |
for details. Use the string <varname>infinity</varname> to
|
|
|
1abbee |
- configure no limit on a specific resource. The multiplicative suffixes
|
|
|
1abbee |
- K (=1024), M (=1024*1024) and so on for G, T, P and E may be used for
|
|
|
1abbee |
- resource limits measured in bytes (e.g. LimitAS=16G).</para></listitem>
|
|
|
1abbee |
+ configure no limit on a specific resource. The multiplicative
|
|
|
1abbee |
+ suffixes K (=1024), M (=1024*1024) and so on for G, T, P and E
|
|
|
1abbee |
+ may be used for resource limits measured in bytes
|
|
|
1abbee |
+ (e.g. LimitAS=16G). For the limits referring to time values,
|
|
|
1abbee |
+ the usual time units ms, s, min, h and so on may be used (see
|
|
|
1abbee |
+ <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
|
|
1abbee |
+ for details). Note that if no time unit is specified for
|
|
|
1abbee |
+ <varname>LimitCPU=</varname> the default unit of seconds is
|
|
|
1abbee |
+ implied, while for <varname>LimitRTTIME=</varname> the default
|
|
|
1abbee |
+ unit of microseconds is implied. Also, note that the effective
|
|
|
1abbee |
+ granularity of the limits might influence their
|
|
|
1abbee |
+ enforcement. For example, time limits specified for
|
|
|
1abbee |
+ <varname>LimitCPU=</varname> will be rounded up implicitly to
|
|
|
1abbee |
+ multiples of 1s.</para>
|
|
|
1abbee |
+
|
|
|
1abbee |
+ <para>Note that most process resource limits configured with
|
|
|
1abbee |
+ these options are per-process, and processes may fork in order
|
|
|
1abbee |
+ to acquire a new set of resources that are accounted
|
|
|
1abbee |
+ independently of the original process, and may thus escape
|
|
|
1abbee |
+ limits set. Also note that <varname>LimitRSS=</varname> is not
|
|
|
1abbee |
+ implemented on Linux, and setting it has no effect. Often it
|
|
|
1abbee |
+ is advisable to prefer the resource controls listed in
|
|
|
1abbee |
+ <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
|
|
1abbee |
+ over these per-process limits, as they apply to services as a
|
|
|
1abbee |
+ whole, may be altered dynamically at runtime, and are
|
|
|
1abbee |
+ generally more expressive. For example,
|
|
|
1abbee |
+ <varname>MemoryLimit=</varname> is a more powerful (and
|
|
|
1abbee |
+ working) replacement for <varname>LimitRSS=</varname>.</para>
|
|
|
1abbee |
|
|
|
1abbee |
|
|
|
1abbee |
<title>Limit directives and their equivalent with ulimit</title>
|
|
|
1abbee |
|
|
|
1abbee |
- <tgroup cols='2'>
|
|
|
1abbee |
+ <tgroup cols='3'>
|
|
|
1abbee |
<colspec colname='directive' />
|
|
|
1abbee |
<colspec colname='equivalent' />
|
|
|
1abbee |
+ <colspec colname='unit' />
|
|
|
1abbee |
|
|
|
1abbee |
<row>
|
|
|
1abbee |
<entry>Directive</entry>
|
|
|
1abbee |
<entry>ulimit equivalent</entry>
|
|
|
1abbee |
+ <entry>Unit</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
|
|
|
1abbee |
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitCPU</entry>
|
|
|
1abbee |
+ <entry>LimitCPU=</entry>
|
|
|
1abbee |
<entry>ulimit -t</entry>
|
|
|
1abbee |
+ <entry>Seconds</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitFSIZE</entry>
|
|
|
1abbee |
+ <entry>LimitFSIZE=</entry>
|
|
|
1abbee |
<entry>ulimit -f</entry>
|
|
|
1abbee |
+ <entry>Bytes</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitDATA</entry>
|
|
|
1abbee |
+ <entry>LimitDATA=</entry>
|
|
|
1abbee |
<entry>ulimit -d</entry>
|
|
|
1abbee |
+ <entry>Bytes</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitSTACK</entry>
|
|
|
1abbee |
+ <entry>LimitSTACK=</entry>
|
|
|
1abbee |
<entry>ulimit -s</entry>
|
|
|
1abbee |
+ <entry>Bytes</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitCORE</entry>
|
|
|
1abbee |
+ <entry>LimitCORE=</entry>
|
|
|
1abbee |
<entry>ulimit -c</entry>
|
|
|
1abbee |
+ <entry>Bytes</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitRSS</entry>
|
|
|
1abbee |
+ <entry>LimitRSS=</entry>
|
|
|
1abbee |
<entry>ulimit -m</entry>
|
|
|
1abbee |
+ <entry>Bytes</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitNOFILE</entry>
|
|
|
1abbee |
+ <entry>LimitNOFILE=</entry>
|
|
|
1abbee |
<entry>ulimit -n</entry>
|
|
|
1abbee |
+ <entry>Number of File Descriptors</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitAS</entry>
|
|
|
1abbee |
+ <entry>LimitAS=</entry>
|
|
|
1abbee |
<entry>ulimit -v</entry>
|
|
|
1abbee |
+ <entry>Bytes</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitNPROC</entry>
|
|
|
1abbee |
+ <entry>LimitNPROC=</entry>
|
|
|
1abbee |
<entry>ulimit -u</entry>
|
|
|
1abbee |
+ <entry>Number of Processes</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitMEMLOCK</entry>
|
|
|
1abbee |
+ <entry>LimitMEMLOCK=</entry>
|
|
|
1abbee |
<entry>ulimit -l</entry>
|
|
|
1abbee |
+ <entry>Bytes</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitLOCKS</entry>
|
|
|
1abbee |
+ <entry>LimitLOCKS=</entry>
|
|
|
1abbee |
<entry>ulimit -x</entry>
|
|
|
1abbee |
+ <entry>Number of Locks</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitSIGPENDING</entry>
|
|
|
1abbee |
+ <entry>LimitSIGPENDING=</entry>
|
|
|
1abbee |
<entry>ulimit -i</entry>
|
|
|
1abbee |
+ <entry>Number of Queued Signals</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitMSGQUEUE</entry>
|
|
|
1abbee |
+ <entry>LimitMSGQUEUE=</entry>
|
|
|
1abbee |
<entry>ulimit -q</entry>
|
|
|
1abbee |
+ <entry>Bytes</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitNICE</entry>
|
|
|
1abbee |
+ <entry>LimitNICE=</entry>
|
|
|
1abbee |
<entry>ulimit -e</entry>
|
|
|
1abbee |
+ <entry>Nice Level</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitRTPRIO</entry>
|
|
|
1abbee |
+ <entry>LimitRTPRIO=</entry>
|
|
|
1abbee |
<entry>ulimit -r</entry>
|
|
|
1abbee |
+ <entry>Realtime Priority</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
<row>
|
|
|
1abbee |
- <entry>LimitRTTIME</entry>
|
|
|
1abbee |
+ <entry>LimitRTTIME=</entry>
|
|
|
1abbee |
<entry>No equivalent</entry>
|
|
|
1abbee |
+ <entry>Microseconds</entry>
|
|
|
1abbee |
</row>
|
|
|
1abbee |
|
|
|
1abbee |
</tgroup>
|
|
|
1abbee |
-
|
|
|
1abbee |
+ </listitem>
|
|
|
1abbee |
</varlistentry>
|
|
|
1abbee |
|
|
|
1abbee |
<varlistentry>
|
|
|
1abbee |
@@ -1266,6 +1309,7 @@
|
|
|
1abbee |
<citerefentry><refentrytitle>systemd.mount</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
|
|
1abbee |
<citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
|
|
1abbee |
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
|
|
1abbee |
+ <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
|
|
1abbee |
<citerefentry><refentrytitle>systemd.directives</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
|
|
1abbee |
<citerefentry><refentrytitle>tmpfiles.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
|
|
1abbee |
<citerefentry project='man-pages'><refentrytitle>exec</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
|
|
1abbee |
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
|
|
|
1abbee |
index c3461a0..ce1397c 100644
|
|
|
1abbee |
--- a/src/core/load-fragment-gperf.gperf.m4
|
|
|
1abbee |
+++ b/src/core/load-fragment-gperf.gperf.m4
|
|
|
1abbee |
@@ -58,7 +58,7 @@ $1.RestrictAddressFamilies, config_parse_address_families, 0,
|
|
|
1abbee |
$1.SystemCallArchitectures, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
|
|
|
1abbee |
$1.SystemCallErrorNumber, config_parse_warn_compat, DISABLED_CONFIGURATION, 0
|
|
|
1abbee |
$1.RestrictAddressFamilies, config_parse_warn_compat, DISABLED_CONFIGURATION, 0')
|
|
|
1abbee |
-$1.LimitCPU, config_parse_limit, RLIMIT_CPU, offsetof($1, exec_context.rlimit)
|
|
|
1abbee |
+$1.LimitCPU, config_parse_sec_limit, RLIMIT_CPU, offsetof($1, exec_context.rlimit)
|
|
|
1abbee |
$1.LimitFSIZE, config_parse_bytes_limit, RLIMIT_FSIZE, offsetof($1, exec_context.rlimit)
|
|
|
1abbee |
$1.LimitDATA, config_parse_bytes_limit, RLIMIT_DATA, offsetof($1, exec_context.rlimit)
|
|
|
1abbee |
$1.LimitSTACK, config_parse_bytes_limit, RLIMIT_STACK, offsetof($1, exec_context.rlimit)
|
|
|
1abbee |
@@ -73,7 +73,7 @@ $1.LimitSIGPENDING, config_parse_limit, RLIMIT_SIGP
|
|
|
1abbee |
$1.LimitMSGQUEUE, config_parse_bytes_limit, RLIMIT_MSGQUEUE, offsetof($1, exec_context.rlimit)
|
|
|
1abbee |
$1.LimitNICE, config_parse_limit, RLIMIT_NICE, offsetof($1, exec_context.rlimit)
|
|
|
1abbee |
$1.LimitRTPRIO, config_parse_limit, RLIMIT_RTPRIO, offsetof($1, exec_context.rlimit)
|
|
|
1abbee |
-$1.LimitRTTIME, config_parse_limit, RLIMIT_RTTIME, offsetof($1, exec_context.rlimit)
|
|
|
1abbee |
+$1.LimitRTTIME, config_parse_usec_limit, RLIMIT_RTTIME, offsetof($1, exec_context.rlimit)
|
|
|
1abbee |
$1.ReadWriteDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_write_dirs)
|
|
|
1abbee |
$1.ReadOnlyDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.read_only_dirs)
|
|
|
1abbee |
$1.InaccessibleDirectories, config_parse_namespace_path_strv, 0, offsetof($1, exec_context.inaccessible_dirs)
|
|
|
1abbee |
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
|
|
|
1abbee |
index dbb45b2..8afe9d7 100644
|
|
|
1abbee |
--- a/src/core/load-fragment.c
|
|
|
1abbee |
+++ b/src/core/load-fragment.c
|
|
|
1abbee |
@@ -1162,6 +1162,107 @@ int config_parse_bytes_limit(const char *unit,
|
|
|
1abbee |
return 0;
|
|
|
1abbee |
}
|
|
|
1abbee |
|
|
|
1abbee |
+int config_parse_sec_limit(
|
|
|
1abbee |
+ const char *unit,
|
|
|
1abbee |
+ const char *filename,
|
|
|
1abbee |
+ unsigned line,
|
|
|
1abbee |
+ const char *section,
|
|
|
1abbee |
+ unsigned section_line,
|
|
|
1abbee |
+ const char *lvalue,
|
|
|
1abbee |
+ int ltype,
|
|
|
1abbee |
+ const char *rvalue,
|
|
|
1abbee |
+ void *data,
|
|
|
1abbee |
+ void *userdata) {
|
|
|
1abbee |
+
|
|
|
1abbee |
+ struct rlimit **rl = data;
|
|
|
1abbee |
+ rlim_t seconds;
|
|
|
1abbee |
+ int r;
|
|
|
1abbee |
+
|
|
|
1abbee |
+ assert(filename);
|
|
|
1abbee |
+ assert(lvalue);
|
|
|
1abbee |
+ assert(rvalue);
|
|
|
1abbee |
+ assert(data);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ rl += ltype;
|
|
|
1abbee |
+
|
|
|
1abbee |
+ if (streq(rvalue, "infinity"))
|
|
|
1abbee |
+ seconds = RLIM_INFINITY;
|
|
|
1abbee |
+ else {
|
|
|
1abbee |
+ usec_t t;
|
|
|
1abbee |
+
|
|
|
1abbee |
+ r = parse_sec(rvalue, &t);
|
|
|
1abbee |
+ if (r < 0) {
|
|
|
1abbee |
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue);
|
|
|
1abbee |
+ return 0;
|
|
|
1abbee |
+ }
|
|
|
1abbee |
+
|
|
|
1abbee |
+ if (t == USEC_INFINITY)
|
|
|
1abbee |
+ seconds = RLIM_INFINITY;
|
|
|
1abbee |
+ else
|
|
|
1abbee |
+ seconds = (rlim_t) (DIV_ROUND_UP(t, USEC_PER_SEC));
|
|
|
1abbee |
+ }
|
|
|
1abbee |
+
|
|
|
1abbee |
+ if (!*rl) {
|
|
|
1abbee |
+ *rl = new(struct rlimit, 1);
|
|
|
1abbee |
+ if (!*rl)
|
|
|
1abbee |
+ return log_oom();
|
|
|
1abbee |
+ }
|
|
|
1abbee |
+
|
|
|
1abbee |
+ (*rl)->rlim_cur = (*rl)->rlim_max = seconds;
|
|
|
1abbee |
+ return 0;
|
|
|
1abbee |
+}
|
|
|
1abbee |
+
|
|
|
1abbee |
+
|
|
|
1abbee |
+int config_parse_usec_limit(
|
|
|
1abbee |
+ const char *unit,
|
|
|
1abbee |
+ const char *filename,
|
|
|
1abbee |
+ unsigned line,
|
|
|
1abbee |
+ const char *section,
|
|
|
1abbee |
+ unsigned section_line,
|
|
|
1abbee |
+ const char *lvalue,
|
|
|
1abbee |
+ int ltype,
|
|
|
1abbee |
+ const char *rvalue,
|
|
|
1abbee |
+ void *data,
|
|
|
1abbee |
+ void *userdata) {
|
|
|
1abbee |
+
|
|
|
1abbee |
+ struct rlimit **rl = data;
|
|
|
1abbee |
+ rlim_t useconds;
|
|
|
1abbee |
+ int r;
|
|
|
1abbee |
+
|
|
|
1abbee |
+ assert(filename);
|
|
|
1abbee |
+ assert(lvalue);
|
|
|
1abbee |
+ assert(rvalue);
|
|
|
1abbee |
+ assert(data);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ rl += ltype;
|
|
|
1abbee |
+
|
|
|
1abbee |
+ if (streq(rvalue, "infinity"))
|
|
|
1abbee |
+ useconds = RLIM_INFINITY;
|
|
|
1abbee |
+ else {
|
|
|
1abbee |
+ usec_t t;
|
|
|
1abbee |
+
|
|
|
1abbee |
+ r = parse_time(rvalue, &t, 1);
|
|
|
1abbee |
+ if (r < 0) {
|
|
|
1abbee |
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse resource value, ignoring: %s", rvalue);
|
|
|
1abbee |
+ return 0;
|
|
|
1abbee |
+ }
|
|
|
1abbee |
+
|
|
|
1abbee |
+ if (t == USEC_INFINITY)
|
|
|
1abbee |
+ useconds = RLIM_INFINITY;
|
|
|
1abbee |
+ else
|
|
|
1abbee |
+ useconds = (rlim_t) t;
|
|
|
1abbee |
+ }
|
|
|
1abbee |
+
|
|
|
1abbee |
+ if (!*rl) {
|
|
|
1abbee |
+ *rl = new(struct rlimit, 1);
|
|
|
1abbee |
+ if (!*rl)
|
|
|
1abbee |
+ return log_oom();
|
|
|
1abbee |
+ }
|
|
|
1abbee |
+
|
|
|
1abbee |
+ (*rl)->rlim_cur = (*rl)->rlim_max = useconds;
|
|
|
1abbee |
+ return 0;
|
|
|
1abbee |
+}
|
|
|
1abbee |
+
|
|
|
1abbee |
#ifdef HAVE_SYSV_COMPAT
|
|
|
1abbee |
int config_parse_sysv_priority(const char *unit,
|
|
|
1abbee |
const char *filename,
|
|
|
1abbee |
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
|
|
|
1abbee |
index 2d509d0..359794d 100644
|
|
|
1abbee |
--- a/src/core/load-fragment.h
|
|
|
1abbee |
+++ b/src/core/load-fragment.h
|
|
|
1abbee |
@@ -57,6 +57,8 @@ int config_parse_exec_secure_bits(const char *unit, const char *filename, unsign
|
|
|
1abbee |
int config_parse_bounding_set(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
|
|
1abbee |
int config_parse_limit(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
|
|
1abbee |
int config_parse_bytes_limit(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
|
|
1abbee |
+int config_parse_sec_limit(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
|
|
1abbee |
+int config_parse_usec_limit(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
|
|
1abbee |
int config_parse_sysv_priority(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
|
|
1abbee |
int config_parse_kill_signal(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
|
|
1abbee |
int config_parse_exec_mount_flags(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
|
|
1abbee |
diff --git a/src/test/test-unit-file.c b/src/test/test-unit-file.c
|
|
|
1abbee |
index 5500983..d151737 100644
|
|
|
1abbee |
--- a/src/test/test-unit-file.c
|
|
|
1abbee |
+++ b/src/test/test-unit-file.c
|
|
|
1abbee |
@@ -545,6 +545,66 @@ static void test_install_printf(void) {
|
|
|
1abbee |
expect(i4, "%U", "0");
|
|
|
1abbee |
}
|
|
|
1abbee |
|
|
|
1abbee |
+
|
|
|
1abbee |
+static void test_config_parse_rlimit(void) {
|
|
|
1abbee |
+ struct rlimit * rl[_RLIMIT_MAX] = {};
|
|
|
1abbee |
+
|
|
|
1abbee |
+ assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "55", rl, NULL) >= 0);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_NOFILE]);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_NOFILE]->rlim_cur == 55);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ assert_se(config_parse_limit(NULL, "fake", 1, "section", 1, "LimitNOFILE", RLIMIT_NOFILE, "infinity", rl, NULL) >= 0);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_NOFILE]);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_NOFILE]->rlim_cur == RLIM_INFINITY);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_NOFILE]->rlim_cur == rl[RLIMIT_NOFILE]->rlim_max);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ rl[RLIMIT_NOFILE] = free(rl[RLIMIT_NOFILE]);
|
|
|
1abbee |
+ assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "56", rl, NULL) >= 0);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_CPU]);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_CPU]->rlim_cur == 56);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "57s", rl, NULL) >= 0);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_CPU]);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_CPU]->rlim_cur == 57);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "infinity", rl, NULL) >= 0);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_CPU]);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_CPU]->rlim_cur == RLIM_INFINITY);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ assert_se(config_parse_sec_limit(NULL, "fake", 1, "section", 1, "LimitCPU", RLIMIT_CPU, "1234ms", rl, NULL) >= 0);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_CPU]);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_CPU]->rlim_cur == 2);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_CPU]->rlim_cur == rl[RLIMIT_CPU]->rlim_max);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ rl[RLIMIT_CPU] = free(rl[RLIMIT_CPU]);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "58", rl, NULL) >= 0);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_RTTIME]);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 58);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "59s", rl, NULL) >= 0);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_RTTIME]);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 59 * USEC_PER_SEC);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "infinity", rl, NULL) >= 0);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_RTTIME]);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_RTTIME]->rlim_cur == RLIM_INFINITY);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ assert_se(config_parse_usec_limit(NULL, "fake", 1, "section", 1, "LimitRTTIME", RLIMIT_RTTIME, "2345ms", rl, NULL) >= 0);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_RTTIME]);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_RTTIME]->rlim_cur == 2345 * USEC_PER_MSEC);
|
|
|
1abbee |
+ assert_se(rl[RLIMIT_RTTIME]->rlim_cur == rl[RLIMIT_RTTIME]->rlim_max);
|
|
|
1abbee |
+
|
|
|
1abbee |
+ rl[RLIMIT_RTTIME] = free(rl[RLIMIT_RTTIME]);
|
|
|
1abbee |
+}
|
|
|
1abbee |
+
|
|
|
1abbee |
int main(int argc, char *argv[]) {
|
|
|
1abbee |
int r;
|
|
|
1abbee |
|
|
|
1abbee |
@@ -553,6 +613,7 @@ int main(int argc, char *argv[]) {
|
|
|
1abbee |
|
|
|
1abbee |
r = test_unit_file_get_set();
|
|
|
1abbee |
test_config_parse_exec();
|
|
|
1abbee |
+ test_config_parse_rlimit();
|
|
|
1abbee |
test_load_env_file_1();
|
|
|
1abbee |
test_load_env_file_2();
|
|
|
1abbee |
test_load_env_file_3();
|