Quelques notes sur ulimit.
max@laptop % ulimit -a -H
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) unlimited
-c: core file size (blocks) unlimited
-m: resident set size (kbytes) unlimited
-u: processes 62254
-n: file descriptors 4096
-l: locked-in-memory size (kbytes) 1024
-v: address space (kbytes) unlimited
-x: file locks unlimited
-i: pending signals 62254
-q: bytes in POSIX msg queues 819200
-e: max nice 0
-r: max rt priority 0
-N 15: unlimited
max@laptop % ulimit -a -S
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) unlimited
-m: resident set size (kbytes) unlimited
-u: processes 62254
-n: file descriptors 1024
-l: locked-in-memory size (kbytes) 1024
-v: address space (kbytes) unlimited
-x: file locks unlimited
-i: pending signals 62254
-q: bytes in POSIX msg queues 819200
-e: max nice 0
-r: max rt priority 0
-N 15: unlimited
max@laptop % cat /proc/$$/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 unlimited unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 62254 62254 processes
Max open files 1024 4096 files
Max locked memory 1048576 1048576 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 62254 62254 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
/etc/security/limits.conf et /etc/security/limits.d/* ne sont que des fichier de conf pour pam_limits (module PAM de session).
Si pam_limits n’est pas activé ces fichiers de configuration ne sont pas pris en compte.
Pour que pam_limits soit activé, il faut qu’il soit présent dans la chaine de lancement de session (voir /etc/pam.d) de l’un des processus parent du processus auquel on veut appliquer les limites.
Les limites sont propre à chaque processus ; elles ne se cumule pas pour un utilisateur.
Les limites « Soft » sont les limites appliqué au démarrage des processus sur lesquels elles s’appliquent. Ces processus peuvent augmenter d’eu même leurs limites jusqu’aux limites « Hard ». Seul root à la possibilité de modifier la limite « Hard » d’un processus.
Max open files
Il n’est pas possible de set cette valeur à « unlimited ».
La valeur maximal qu’il est possible de renseigner via ulimit est égal à 1048576. Il est possible de modifier cette valeur.
max@laptop % sysctl fs.nr_open
fs.nr_open = 1048576
Attention, la somme des « open files » (nombre de file descriptor) de tous les processus du système ne peut dépasser « fs.file-max » :
max@laptop % sysctl fs.file-max
fs.file-max = 1590902
Changer les limites d’un processus
avec prlimit
Il est possible de changer les limites d’un processus (déjà lancé), via la commande prlimit.
Par exemple pour augmenter le nombre de “max open files” d’un processus :
prlimit -n1048576 -p 123
sans prlimit
Sources:
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/resource.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \
} while (0)
int
main(int argc, char *argv[])
{
struct rlimit old, new;
struct rlimit *newp;
pid_t pid;
if (!(argc == 2 || argc == 4)) {
fprintf(stderr, "Usage: %s <pid> [<new-soft-limit> "
"<new-hard-limit>]\n", argv[0]);
exit(EXIT_FAILURE);
}
pid = atoi(argv[1]); /* PID of target process */
newp = NULL;
if (argc == 4) {
new.rlim_cur = atoi(argv[2]);
new.rlim_max = atoi(argv[3]);
newp = &new;
}
/* Set nofile limit of target process; retrieve and display
previous limit */
if (prlimit(pid, RLIMIT_NOFILE, newp, &old) == -1)
errExit("prlimit-1");
printf("Previous limits: soft=%lld; hard=%lld\n",
(long long) old.rlim_cur, (long long) old.rlim_max);
/* Retrieve and display new nofile limit */
if (prlimit(pid, RLIMIT_NOFILE, NULL, &old) == -1)
errExit("prlimit-2");
printf("New limits: soft=%lld; hard=%lld\n",
(long long) old.rlim_cur, (long long) old.rlim_max);
exit(0);
}
avec gdb
Il ne faut pas utiliser cette technique, elle locks tous les threads du process.
root@host # gdb -p 32422 -batch -ex 'set $rlim = &{0ll, 0ll}' -ex 'print getrlimit(7, $rlim)' -ex 'print *$rlim' -ex 'set (*$rlim)[0] = 1048575' -ex 'set (*$rlim)[1] = 1048575' -ex 'print *$rlim' -ex 'print setrlimit(7, $rlim)'
0x00007f14b24fd310 in read () from /lib/x86_64-linux-gnu/libc.so.6
$1 = 0
$2 = {1048575, 1048575}
$3 = {1048575, 1048575}
$4 = 0
root@host #