50

Is there any way to check the usage of the ulimits for a given user? I know that you can change ulimits for a single process when you start it up or for a single shell when running but I want to be able to "monitor" how close a user is to hitting their limits. I am planning on writing a bash script that will report back to statsd the current usage percentage. Specifically, I want to track:

  1. open files (ulimit -n)
  2. max user processes (ulimit -u)
  3. pending signals (ulimit -i)

What I want out is the percentage of usage (0-100).

3
  • if you have process accounting turned on in your kernel you can collect detailed usage statistics about your users.
    – casey
    Sep 17, 2015 at 20:37
  • How do you turn on process accounting?
    – hazmat
    Sep 17, 2015 at 21:09
  • And how much overhead does this add?
    – hazmat
    Sep 17, 2015 at 21:09

3 Answers 3

41

Maybe this helps for the first question:

If you know the process IDs (PID) of the specific user you can get the limits for each process with:

cat /proc/<PID>/limits

You can get the number of opened files for each PID with:

ls -1 /proc/<PID>/fd | wc -l

And then just compare the value of Max open files with the number of open file descriptors from the second command to get a percentage.

28

Output the current user's percentage of open files, proc, and pending signals, by several inconvenient methods and standard tools:

paste <(grep 'open files\|processes\|pending signals' \
              /proc/self/limits | cut -c27-38)        \
      <(i=`whoami`
        lsof -n -u $i 2> /dev/null | 
             tail -n +2 | 
             awk {'print $9'} | 
             wc -l
        ps --no-headers -U $i -u $i u | wc -l
        ps -u $i -o pid= | 
             xargs printf "/proc/%s/status\n" |
             xargs grep -s 'SigPnd' |
             sed 's/.*\t//' | 
             paste -sd+ | 
             bc ; ) \
      <(grep 'open files\|processes\|pending signals' \
             /proc/self/limits | 
                   cut -c1-19) | 
while read a b name ; do 
    printf '%3i%%  %s\n' $((${b}00/a)) "$name"
done

Output on my system:

 16%  Max processes
 12%  Max open files
  0%  Max pending signals

Assuming those numbers are good, what this answer shows is that it can be done in shell, but probably shouldn't, unless there are much better shell methods. Rather, this Q would be better done with gcc, or python, etc.

2
  • 3
    Thank, I expanded on this by printing the label on each line in gitlab.com/-/snippets/2079836 Feb 20, 2021 at 19:51
  • nice. Is there a way to add the info on the number of threads (here you count processes) ? (or, maybe, other commonly restricted ulimits?) Apr 5 at 12:36
-8

Ulimits are properties of processes and are inherited to child processes.

You cannot get the limits for another process.

4
  • 6
    Nonsense. man lsof, man ps, … Sep 17, 2015 at 23:43
  • 1
    You seem to missunderstand how UNIX works and how lsof gets it's results. lsof reads kernel memory to get values, there is no documented interface that is used by lsof, so lsof will fail in case even minor changes have been made to internal kernel data structures.
    – schily
    Sep 18, 2015 at 9:05
  • 2
    That's a headache for the lsof maintainer, sure. But not relevant for the end-user. Also incorrect in the context of this question, since it's asking specifically about Linux, which has documented interfaces (man proc). Sep 18, 2015 at 9:44
  • You are talking about undocumented interfaces that are subject to changes without notice in this case.
    – schily
    Sep 18, 2015 at 9:56

You must log in to answer this question.

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