18

I need, for mysql to use large-pages, to set a ulimit - I've done this in limits.conf. However, limits.conf (pam_limits.so), doesn't get read in for init, only for "real" shells. I solved this before by adding a "ulimit -l" to the initscript start function. I need some sort of repeatable way to do this, now that the boxes are managed with chef, and we don't want to take over a file that's actually owned by the RPM.

1

9 Answers 9

7
$ echo "* hard nofile 102400" >> /etc/security/limits.conf
$ echo "* soft nofile 102400" >> /etc/security/limits.conf
$ sysctl -w fs.file-max=102400
$ sysctl -p

The 4 steps can change your system's limits immediately, and can still work after your reboot. You can change the number "102400" to the number of max open-file in your linux system as you want. and

$ sysctl -p

to load in sysctl settings from the file specified or /etc/sysctl.conf if none given.

3
  • 4
    limits.conf is not read by inittab because limit.so is not read for it. You might be able to hack PAM but I cant figure out which file it might read.
    – Xarses
    Jul 17, 2012 at 4:10
  • Note that the wildcard * does not work for root user, you'll have to specify root explicitly...
    – Matt
    Jun 18, 2017 at 7:19
  • 1
    @Xarses is right. limit.conf will not get applied for some daemon starting at boot time. I don't believe this answers the question.
    – Alchemist
    Feb 13, 2018 at 16:53
2

/etc/sysctl.conf should be able to set the ulimits items. I've not been able to test this well but survey says you should be able to stop after it's set in sysctl.conf.

I've found various topics that show it's still a problem though and my team and I have discussed some options around this we have found two potential workarounds.

Option 1: Most rhel initscripts source /etc/init.d/functions, you could change the ulimit settings there

Option 2: init claims that /etc/initscript is sourced everytime before init spawns whatever see: http://linux.die.net/man/5/initscript. Interestingly enough they say its where people can set ulimit =)

1

My solution was simply doing this in our chef recipe:

# Ensure ulimits are properly set for the initscript
bash "Set Ulimits" do
    user "root"
    code <<-EOH
    echo -e "n#Setting ulimits. Performed by chef recipe MYSQLULIMIT\nulimit -l" >> /etc/sysconfig/init
    EOH
    not_if "grep MYSQLULIMIT /etc/sysconfig/init"
end

This causes the ulimit -l to get set for all initscripts, which may be undesirable in some environments, but is fine for mine.

In a perfect world, I'd get the RPM updated to include a /etc/sysconfig/mysqld, and put the same ulimit -l command in there.

1

Self-contained recipe snippet based on this url:

http://pro.benjaminste.in/post/318453669/increase-the-number-of-file-descriptors-on-centos-

Recipe Snippet:

ruby_block "edit /etc/sysctl.conf" do
  _file = "/etc/sysctl.conf"
  _comment = "# TWEAK BY CHEF"
  _content = "fs.file-max = 512000"
  block do
    file = Chef::Util::FileEdit.new(_file)
    file.insert_line_if_no_match(/#{Regexp.escape(_comment)}/, "#{_comment}\n#{_content}")
    file.write_file
  end
  not_if "cat #{_file} | grep '#{_comment}'"
  notifies :run, "execute[sysctl -p]", :immediately
end

execute "sysctl -p" do
  command "sysctl -p"
  returns 255 # which would normally signify error, but doesn't on sysctl on CentOS
  action :nothing
end

ruby_block "edit /etc/security/limits.conf" do
  _file = "/etc/security/limits.conf"
  _comment = "# TWEAK BY CHEF"
  _content = "* - nofile 65535"
  block do
    file = Chef::Util::FileEdit.new(_file)
    file.insert_line_if_no_match(/#{Regexp.escape(_comment)}/, "#{_comment}\n#{_content}")
    file.write_file
  end
  not_if "cat #{_file} | grep '#{_comment}'"
end
1

The RedHat way, as described in article 253043 (subscription required) is to add appropriate ulimit statements to /etc/sysconfig/<service name>. For example:

# echo "ulimit -SHn 10240   # nfile" >> /etc/sysconfig/myServiceName

(Use the existing file for your service instead of myServiceName.)

For daemons that start without using the RedHat "sysconfig" script, you would need to add the appropriate ulimit lines to the daemon startup script.

0

Not sure of how distro-specific this is, but I have just incorporated a security limit increase by using /etc/security/limits.d/20-somefile.conf in Ubuntu.

Rather than having to modify an existing file, I have an ERB template in my cookbook, set default attributes in an attributes file and then don't have to worry about using ruby blocks with "insert_line_if_no_match" stuff - that seems a little more intricate and the recipe is a bit more readable like this:

execute "activate_sysctl" do
  user "root"
  command "sysctl -p /etc/sysctl.d/10-filemax.conf"
  action :nothing
end

template "/etc/sysctl.d/10-filemax.conf" do
  source "system/filemax.conf"
  action :create
  notifies :run, "execute[activate_sysctl]", :immediately
end

and then this is my template file:

fs.filemax = <%= node[:mycookbook][:system_fs_filemax] %>
0

according to man page ulimit is deprecated. You need to use setrlimit. The problem is that is a system call instead of a bash command.

I had this problem with supervisor and this is what I found out. If the process doesn't have a config file that allows you to make a call to setrlimit() system call. Set it with ulimit on its /etc/init.d bash script. That's the service script that starts your process.

If the process has a config file, like supervisor d then you can use that config file to set the number of files and have the process make the call directly to setrlimits().

Supervisor: http://supervisord.org/configuration.html#supervisord-section-settings

TomcaT: http://www.jayway.com/2012/02/11/how-to-really-fix-the-too-many-open-files-problem-for-tomcat-in-ubuntu/

-1

Try setting that up in /etc/sysctl.conf file

1
  • There are pieces of configuration required to do this that belong in sysctl.conf, and those are in place -- we just need to modify ulimits to allow those hugepages to be accessed.
    – jayofdoom
    Mar 29, 2012 at 14:29
-1

I actually wrote a private chef cookbook that is used to set ulimit for us and it works pretty well. For ubuntu we found the following trick is required if you want a global ulimit setting:

Add the following to your common-session:

session required        pam_limits.so

and in limit.conf you must have the following:

* soft  nofile  64000
* hard  nofile  65000

root  soft  nofile  64000
root  hard  nofile  65000

The root part is important as it seems without that some init script will not work correctly. So we have a chef cookbook that setup the following and it works great.

Another option we used to use for Tomcat was to deploy Tomcat and then overwrite the init script with a custom which we would set the ulimit for and restart tomcat. This works great but is a bit more hacky then the first.

I hope this help, and maybe someday I can opensource the cookbook we have internally since its pretty dead simple but might be helpful to others like you.

1
  • This wont solve the poster's issue. Pam is only invoked when a user opens a session (shell). Since the init system is started independently of user sessions, pam does not apply.
    – phemmer
    Mar 31, 2012 at 5:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .