14

I recently checked one of our redis processes to what ulimits where applied using:

cat /proc/<redis-pid>/limits

And was suprised to learn that is was at the low default value:

Limit                     Soft Limit           Hard Limit           
Max open files            4016                 4016 

I was suprised, because we have the following configured:

# /etc/sysctl.conf 
fs.file-max = 100000

.

# /etc/security/limits.conf
* soft nofile 100000
* hard nofile 100000

.

# /etc/ssh/sshd_config
UsePAM yes

.

# /etc/pam.d/sshd
session required pam_limits.so

Can anyone tell me why the increased ulimit is not being applied to the running redis process?

The redis process is running as the user 'redis', the server has been rebooted since the limits were increased. We are on Debian Squeeze.

19

In Linux resource limits can be set in various locations based on the type of requirement.

  1. /etc/security/limits.conf file.
  2. /etc/sysctl.conf file.
  3. ulimit command

/etc/security/limits.conf is part of pam_limits and so the limits that are set in this file is read by pam_limits module during login sessions. The login session can be by ssh or through terminal. And pam_limits will not affect the daemon processes as mentioned here.

/etc/sysctl.conf is a system wide global configuration, we cannot set user specific configuration here. It sets the maximum amount of resource that can be used by all users/processes put to gether.

ulimit command is used to set the limits of the shell. And so when a limit is set with ulimit on a shell, the process which gets spawned from the shell gets that value too because of the rule that the child process inherits the parent processes properties.

And so for your case, as the redis is started as part of init none of the above will help you directly. The proper way of doing this is that, you have to use the ulimit command to set the new value in the init script itself. Like below in the script,

ulimit -n 100000
if start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid redis:redis --exec $DAEMON -- $DAEMON_ARGS.

There is already a bug filed in wishlist to add ulimit feature to start-stop-daemon .

Also check in redis configuration if there is any way of providing limits there.

  • Great summary Kannan! I've now gone ahead and added the ulimit to the startup script. It's a pity there is no way of just setting the limit for the user which will work with deamonised processes (as we have multiple startup scripts), but this works. Thank you! – UpTheCreek Nov 5 '14 at 6:07
  • Great answer. The child process inheriting the parent process's properties was what surprised me, the limits all looked correct for the user running the child process but it was the limit from the owner of the parent process which was being used. – sync Mar 13 '16 at 22:32
2

The sysctl fs.file-max parameter is wide global system limit, i don't think is a good idea setting in ulimit the same value.

If you set in ulimit 100000 and in sysctl.conf 100000 too, one user can block the system

Any way, talking about your problem, you neet to be sure, your system use pam_limits

man pam_limits
grep -i limit /etc/pam.d/*
  • Thanks - I'll consider raising the fs.file-max value then. Regarding pam - I believe we are using this (I've added some extra config to the question). I'm not really sure I understand PAM though, as our settings seem to be relate to SSH, which is not used by this user. Is there any other file I need to configure? I could always put a ulimit setting in the init scripts for redis, but would rather not have to do this. – UpTheCreek Nov 4 '14 at 14:14
2

You've enabled pam_limits for sshd, but is this command being executed from an SSH session? You may need to add the same line to /etc/pam.d/login and/or /etc/pam.d/su and/or /etc/pam.d/sudo.

  • Thanks. I suspected that wasn't quite right. The process is being started this line in an init.d script : if start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid redis:redis --exec $DAEMON -- $DAEMON_ARGS. Which pam would be appropriate in this case? – UpTheCreek Nov 4 '14 at 14:21
  • in your script you can use ulimit -n 100000 – c4f4t0r Nov 4 '14 at 14:48
  • Does the init.d script use a su [user] -c command to start the script as another user, or does your program run as root? If it's using su, then you'd put it in /etc/pam.d/su. If you're running as root, you're probably better off with c4f4t0r's suggestion of adding the ulimit command in your init script. root is allowed to set any limits it wants, so you don't really need to worry about pam for that case. – Omnipresence Nov 4 '14 at 14:55
  • 1
    Thanks. It uses --chuid redis:redis on start-stop-daemon. I've added the ulimit to the startup script now. – UpTheCreek Nov 5 '14 at 6:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.