87

How would you set a ulimit on a systemd service unit?

This stackoverflow question explains that systemd ignores system ulimits

What would the syntax look like to set the following ulimits?

ulimit -c
ulimit -v
ulimit -m

[Unit]
Description=Apache Solr
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
SOLR_INSTALL_DIR=/opt/solr
SOLR_ENV=/etc/default/solr.in.sh
RUNAS=solr

SOLR_PID_DIR="/var/solr"
SOLR_HOME="/opt/solr/server/solr"
LOG4J_PROPS="/var/solr/log4j.properties"
SOLR_LOGS_DIR="/opt/solr/server/logs"
SOLR_PORT="8389"

PIDFile=/var/solr/solr-8389.pid
ExecStart=/opt/solr/bin/solr start
ExecStatus=/opt/solr/bin/solr status
ExecStop=/opt/solr/bin/solr stop
Restart=on-failure
User=solr

SuccessExitStatus=143 0

[Install]
WantedBy=multi-user.target
1
  • 2
    Search for "Limit" in man 5 systemd.exec. Commented Aug 11, 2017 at 9:58

2 Answers 2

157
+50

The mappings of systemd limits to ulimit

Directive        ulimit equivalent     Unit
LimitCPU=        ulimit -t             Seconds      
LimitFSIZE=      ulimit -f             Bytes
LimitDATA=       ulimit -d             Bytes
LimitSTACK=      ulimit -s             Bytes
LimitCORE=       ulimit -c             Bytes
LimitRSS=        ulimit -m             Bytes
LimitNOFILE=     ulimit -n             Number of File Descriptors 
LimitAS=         ulimit -v             Bytes
LimitNPROC=      ulimit -u             Number of Processes 
LimitMEMLOCK=    ulimit -l             Bytes
LimitLOCKS=      ulimit -x             Number of Locks 
LimitSIGPENDING= ulimit -i             Number of Queued Signals 
LimitMSGQUEUE=   ulimit -q             Bytes
LimitNICE=       ulimit -e             Nice Level 
LimitRTPRIO=     ulimit -r             Realtime Priority  
LimitRTTIME=     ulimit -R             Microseconds

If a ulimit is set to 'unlimited' set it to 'infinity' in the systemd config

ulimit -c unlimited is the same as LimitCORE=infinity
ulimit -v unlimited is the same as LimitAS=infinity
ulimit -m unlimited is the same as LimitRSS=infinity

So a final config would look like

[Unit]
Description=Apache Solr
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
WorkingDirectory=/opt/solr/server
User=solr
Group=solr
LimitAS=infinity
LimitRSS=infinity
LimitCORE=infinity
LimitNOFILE=65536
ExecStart=/opt/solr/bin/solr-foo
Restart=on-failure
SuccessExitStatus=143 0
SyslogIdentifier=solr


[Install]
WantedBy=multi-user.target

In this particular case, I don't know the full java path (since it changes based on server type), and systemd isn't happy about relative paths, I wrap the java command in a simple bash script located at /opt/solr/bin/solr-foo

#!/bin/bash

. /opt/solr/bin/solr.in.sh

# Load $JAVA_HOME from 1 of 2 places where it could be defined
# Last one wins
if [[ -f "/etc/profile.d/jdk.sh" ]]; then
  . /etc/profile.d/jdk.sh
fi

if [[ -f "/etc/profile.d/zing.sh" ]]; then
  . /etc/profile.d/zing.sh
fi

exec ${JAVA_HOME}/bin/java -server \
  -Djetty.port=${SOLR_PORT} \
  ${SOLR_JAVA_MEM} \
  ${GC_TUNE} \
  ${GC_LOG_OPTS} \
  -DzkClientTimeout=${ZK_CLIENT_TIMEOUT} \
  -DzkHost=${ZK_HOST} \
  -DSTOP.PORT=7900 \
  -DSTOP.KEY=foobar \
  -Dhost=${SOLR_HOST} \
  -Duser.timezone=${SOLR_TIMEZONE} \
  -Djetty.home=/opt/solr/server \
  -Dsolr.solr.home=${SOLR_HOME} \
  -Dsolr.install.dir=/opt/solr \
  -Dlog4j.configuration=file:/var/solr/log4j.properties \
  -Xss256k \
  -Dbootstrap_conf=true \
  -Dbootstrap_confdir=/opt/solr/server/solr/configsets/foobar/conf \
  -Dcollection.configName=foobar \
  -jar start.jar --module=http
4
  • I wouldn't call that "final". It still needs all of those messed-up settings like RUNAS and SOLR_ENV either corrected or removed. And then there's all of the hooplah in the bin/solr shell script that is completely unnecessary under a service manager. Commented Feb 17, 2017 at 10:54
  • Thanks for pointing that out. I've updated the answer with a cleaner solution that puts all variables in 1 location and doesn't use the bloated bin/solr script. Commented Feb 21, 2017 at 23:07
  • See unix.stackexchange.com/a/320319/5132 for still more that can be fixed, starting with using exec in the shell script. Commented Feb 26, 2017 at 7:48
  • 1
    Thank you wery much. Spent a lot of time until found your post and realize difference in units between systemd (byte) and ulimit (kb) Commented Jul 15, 2020 at 12:55
0

The syntax for setting the limits you asked for is:

# Equivalent of ulimit -c 2
LimitCORE=2
# Functional replacement for both ulimit -m and ulimit -v
MemoryMax=1024M

The equivalent of ulimit -v is LimitAS, however, the systemd documentation states "Don't use. This limits the allowed address range, not memory use! Defaults to unlimited and should not be lowered. To limit memory use, see MemoryMax= in systemd.resource-control(5)".

The equivalent of ulimit -m is LimitRSS, however, the systemd documentation states "Don't use. No effect on Linux." and further explains "Note that most process resource limits configured with these options are per-process, and processes may fork in order to acquire a new set of resources that are accounted independently of the original process, and may thus escape limits set. Also note that LimitRSS= is not implemented on Linux, and setting it has no effect. Often it is advisable to prefer the resource controls listed in systemd.resource-control(5) over these per-process limits, as they apply to services as a whole, may be altered dynamically at runtime, and are generally more expressive. For example, MemoryMax= is a more powerful (and working) replacement for LimitRSS=.".

The full list of systemd equivalents of ulimit is listed here: https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Process%20Properties

MemoryMax, from systemd resource control documentation: https://www.freedesktop.org/software/systemd/man/latest/systemd.resource-control.html#MemoryMax=bytes

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.