Set ulimits for a script started using systemd

In my previous post I demonstrated how easy it was to start a script on boot usig systemd in Linux. In this post I am going to show how you can set ulimits for the same script at startup. I will use the same script I used earlier even though it does not need any higher limits.

I have a script monitor.sh that simply runs a curl command in an endless while loop. This particular example does not do anything other than run the curl, but you could easily add a check and send alert if the curl statement fails.

Procedure

Let us write our monitor.sh script first which runs the curl in an endless loop. Using an editor you are comfortable with, save the following code in a file /home/ubuntu/monitor.sh


#!/bin/bash

while true;
do
    echo "Running monitor..."
    curl -o /dev/null -k https://blog.skbali.com &> /dev/null
    sleep 75
done

Make sure you have execute permission set.


chmod u+x /home/ubuntu/monitor.sh

Next, we will setup the systemd configuration file. Create a new file sudo vi /etc/systemd/system/mymonitor.service.


[Unit]
Description=My Monitor Service
After=network.target

[Service]
User=ubuntu
Group=ubuntu
ExecStart=/home/ubuntu/monitor.sh
Restart=always
RestartSec=5
LimitNOFILE=1024:4096

[Install]
WantedBy=multi-user.target

Let us examine the new lines I added to the configuration.

  • In the [Service] section I added LimitNOFILE to set soft limit of 1024 and hard limit of 4096. This sets the soft and hard limit for number of open files by this process.
  • If you just want to set a higher hard limit you could change it to LimitNOFILE=10240

Let us go ahead and reload the systemd daemon to ensure it picks up the new configuration file. Stop and start the service.


systemctl daemon-reload
systemctl stop mymonitor.service
systemctl start mymonitor.service

Now let us check the ps and limits again.


ps -ef | grep monitor
ubuntu    8293     1  0 19:54 ?        00:00:00 /bin/bash /home/ubuntu/monitor.sh

 cat /proc/8293/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             3900                 3900                 processes
Max open files            1024                 4096                 files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       3900                 3900                 signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

You can see that the soft and hard limit has changed for this process.

We can also set other limits if we wanted to change them The table below lists them.

Referenced from this page

Directiveulimit equivalentUnit
LimitCPU=ulimit -tSeconds
LimitFSIZE=ulimit -fBytes
LimitDATA=ulimit -dBytes
LimitSTACK=ulimit -sBytes
LimitCORE=ulimit -cBytes
LimitRSS=ulimit -mBytes
LimitNOFILE=ulimit -nNumber of File Descriptors
LimitAS=ulimit -vBytes
LimitNPROC=ulimit -uNumber of Processes
LimitMEMLOCK=ulimit -lBytes
LimitLOCKS=ulimit -xNumber of Locks
LimitSIGPENDING=ulimit -iNumber of Queued Signals
LimitMSGQUEUE=ulimit -qBytes
LimitNICE=ulimit -eNice Level
LimitRTPRIO=ulimit -rRealtime Priority
LimitRTTIME=No equivalentMicroseconds

Conclusion

Changing ulimits for a process that starts up on boot can be easily done in your systemd unit file.

Note: If you make any changes to your script monitor.sh, make sure to stop and start your service so that a new process is launched.

Further reading

Leave a Reply