getrlimit(2) | System Calls Manual | getrlimit(2) |
getrlimit, setrlimit, prlimit - Lire et écrire les limites et utilisations des ressources
Bibliothèque C standard (libc, -lc)
#include <sys/resource.h>
int getrlimit(int resource, struct rlimit *rlim); int setrlimit(int resource, const struct rlimit *rlim);
int prlimit(pid_t pid, int resource, const struct rlimit *_Nullable new_limit, struct rlimit *_Nullable old_limit);
prlimit() :
_GNU_SOURCE
Les appels système getrlimit() et setrlimit() lisent ou écrivent les limites des ressources système. Chaque ressource a une limite souple et une limite stricte définies par la structure rlimit :
struct rlimit {
rlim_t rlim_cur; /* limite souple */
rlim_t rlim_max; /* limite stricte (plafond
de rlim_cur) */ };
La limite souple est la valeur que le noyau prend en compte pour la ressource correspondante. La limite stricte agit comme un plafond pour la limite souple : un processus non privilégié peut seulement modifier sa limite souple dans l'intervalle entre zéro et la limite stricte, et diminuer (de manière irréversible) sa limite stricte. Un processus privilégié (sous Linux : un processus ayant la capacité CAP_SYS_RESOURCE dans l'espace de noms initial de l'utilisateur) peut modifier ses deux limites à sa guise.
La valeur RLIM_INFINITY indique une limite infinie pour la ressource (aussi bien pour getrlimit() que pour setrlimit()).
Le paramètre resource doit être l'un des éléments suivants :
bytes = attr.mq_maxmsg * sizeof(struct msg_msg) +
MIN(attr.mq_maxmsg, MQ_PRIO_MAX) *
sizeof(struct posix_msg_tree_node)+
/* Pour le dépassement */
attr.mq_maxmsg * attr.mq_msgsize;
/* Pour les données du message */
bytes = attr.mq_maxmsg * sizeof(struct msg_msg *) +
/* Pour le dépassement */
attr.mq_maxmsg * attr.mq_msgsize;
/* Pour les données du message */
L'appel système prlimit() spécifique à Linux combine et étend les fonctionnalités de setrlimit() et getrlimit(). Il peut être utilisé pour affecter ou récupérer les limites de ressources de tout processus.
Le paramètre resource a le même sens que dans setrlimit() et getrlimit().
Si le paramètre new_limit ne vaut pas NULL, alors la structure rlimit vers laquelle il pointe est utilisée pour affecter de nouvelles valeurs aux limites souples et strictes pour resource. Si le paramètres old_limit ne vaut pas NULL, alors un appel à prlimit() qui réussit place les limites antérieures souples et strictes pour resource dans la structure rlimit pointée par old_limit.
L'argument pid spécifie l'identifiant du processus sur lequel l'appel agit. Si pid vaut 0, alors l'appel s'applique au processus appelant. Pour positionner ou interroger les ressources d'un processus autre que lui-même, l'appelant doit avoir la capacité CAP_SYS_RESOURCE dans l'espace de noms utilisateur du processus dont les limites de ressources vont être modifiées ou bien les identifiants d'utilisateur réel, effectif et le set-UID sauvé du processus cible doivent correspondre à l'identifiant d'utilisateur réel de l'appelant et les identifiants de groupe réel et effectif et le set-GID sauvé du processus cible doivent correspondre à l'identifiant de groupe réel de l'appelant.
Ces appels système renvoient 0 en cas de succès ou -1 en cas d'échec, auquel cas errno est positionné pour indiquer l'erreur.
L'appel système prlimit() est disponible depuis Linux 2.6.36 ; la prise en charge dans la glibc est disponible depuis la version 2.13.
Pour une explication des termes utilisés dans cette section, consulter attributes(7).
Interface | Attribut | Valeur |
getrlimit(), setrlimit(), prlimit() | Sécurité des threads | MT-Safe |
getrlimit(), setrlimit() : POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.
prlimit() : spécifique à Linux.
RLIMIT_MEMLOCK et RLIMIT_NPROC proviennent de BSD et ne sont pas définis dans POSIX.1 ; ils sont présents dans les BSD et Linux, mais dans peu d'autres implémentations. RLIMIT_RSS vient de BSD et n'est pas défini dans POSIX.1 ; cependant, il est présent sur la plupart des implémentations. RLIMIT_MSGQUEUE, RLIMIT_NICE, RLIMIT_RTPRIO, RLIMIT_RTTIME et RLIMIT_SIGPENDING sont spécifiques à Linux.
Un processus enfant créé avec fork(2) hérite des limites de ressource de son parent. Les limites de ressource sont préservées à travers un execve(2).
Les limites de ressource sont des attributs par processus partagés par tous les threads d'un processus.
Descendre la limite souple d'une ressource en dessous de l'actuelle utilisation par le processus de cette ressource fonctionne (mais cela empêchera le processus d'augmenter ultérieurement sa consommation de cette ressource).
On peut définir les limites de ressource de l'interpréteur de commandes en utilisant la commande interne ulimit (limit dans csh(1)). Les limites de ressource de l'interpréteur de commandes sont héritées par les processus qu'il crée pour exécuter les commandes.
À partir de Linux 2.6.24, les limites de ressource de n'importe quel processus peuvent être examinées en consultant /proc/pid/limits ; consultez proc(5).
Les systèmes anciens fournissent une fonction vlimit() qui remplit le même rôle que setrlimit(). Pour des raisons de compatibilité ascendante, la glibc fournit aussi une fonction vlimit(), mais toutes les nouvelles applications devraient utiliser setrlimit().
A partir de la glibc 2.13, les fonctions d'enveloppe getrlimit() et setrlimit() de la glibc n'appellent plus les appels systèmes correspondant, mais utilisent prlimit(), pour les raisons indiquées dans BUGS.
Le nom de la fonction enveloppe dans la glibc est prlimit() ; l'appel système sous-jacent est prlimit64().
Dans les noyaux Linux plus anciens, les signaux SIGXCPU et SIGKILL envoyés lorsqu'un processus dépassait les limites souples et strictes pour RLIMIT_CPU étaient envoyés une seconde (CPU) plus tard qu'ils n'auraient dû l'être. Cela a été corrigé dans Linux 2.6.8.
Dans les noyaux Linux de la série 2.6 antérieurs à Linux 2.6.17, une limite RLIMIT_CPU à 0 est interprétée par erreur comme « pas de limite » (comme RLIM_INFINITY). Depuis Linux 2.6.17, définir la limite à 0 a un effet, mais la limite est en fait d'une seconde.
En raison d'un bogue du noyau, RLIMIT_RTPRIO ne marche pas dans Linux 2.6.12 ; le problème a été corrigé dans Linux 2.6.13.
Dans Linux 2.6.12, il y avait une différence de 1 entre les valeurs de priorité renvoyées par getpriority(2) et RLIMIT_NICE. Du coup, la limite réelle pour la valeur de politesse était calculée comme 19 - rlim_cur. Cela est corrigé depuis Linux 2.6.13.
A partir de Linux 2.6.12, si un processus atteint sa limite souple RLIMIT_CPU et qu'il dispose d'un gestionnaire pour SIGXCPU, alors en plus d'invoquer le gestionnaire de signal, le noyau augmente la limite souple d'une seconde. Ce comportement se répète si le processus continue de consommer du temps processeur, jusqu'à ce que la limite stricte soit atteinte, auquel cas le processus est tué. D'autres implémentations ne modifient pas la limite souple RLIMIT_CPU de cette façon, et le comportement de Linux n'est alors probablement pas conforme aux standards ; pour cette raison, les applications portables doivent éviter de tabler sur ce comportement. La limite propre à Linux RLIMIT_RTTIME se comporte de façon analogue lorsque la limite souple est atteinte.
Les noyaux antérieurs à Linux 2.4.22 ne détectaient pas l'erreur EINVAL pour setrlimit() quand rlim->rlim_cur était plus grand que rlim->rlim_max.
Pour des raisons de compatibilité, Linux ne renvoie pas d'erreur quand une tentative de positionnement de RLIMIT_CPU a échoué.
Les fonctions d'enrobage de la glibc getrlimit() et setrlimit() utilisent un type 64 bits rlim_t, et ce même sur les plateformes 32 bits. Cependant, le type rlim_t utilisé dans les appels systèmes getrlimit() et setrlimit() est en fait un unsigned long (de 32 bits). De plus, sur Linux, le noyau traite les limites de ressources sur les systèmes 32 bits au moyen du type unsigned long. Un type 32 bits n'est pourtant pas assez grand. Dans le cas présent, la limite la plus pertinente est RLIMIT_FSIZE, qui indique la taille maximum que peut atteindre un fichier : pour être utilisable, cette limite doit être représentée par un type de la même taille que celui utilisé pour représenter les positions de curseur dans le fichier — c'est à dire, de la taille d'un off_t 64 bits (en considérant que le programme a été compilé avec l'option _FILE_OFFSET_BITS=64).
Pour contourner cette limitation du noyau, si un programme tente d'affecter à une limite de ressource une valeur trop grande pour être représentée par un type unsigned long de 32 bits, la fonction d'enrobage de la glibc setrlimit() change implicitement la valeur de la limite en RLIM_INFINITY. Autrement dit, l'affectation de la limite de ressource n'est pas prise en compte, et cela sans aucune notification.
Depuis la glibc 2.13, la glibc contourne ces limitations des appels système getrlimit() et setrlimit() en implémentant les fonctions setrlimit() et getrlimit() qui font appel à prlimit().
Le programme ci-dessous démontre l'utilisation de prlimit().
#define _GNU_SOURCE #define _FILE_OFFSET_BITS 64 #include <err.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <sys/resource.h> #include <time.h> int main(int argc, char *argv[]) {
pid_t pid;
struct rlimit old, new;
struct rlimit *newp;
if (!(argc == 2 || argc == 4)) {
fprintf(stderr, "Usage: %s <pid> [<nouvelle-limite-souple> "
"<nouvelle-limite-stricte>]\n", argv[0]);
exit(EXIT_FAILURE);
}
pid = atoi(argv[1]); /* PID du processus cible */
newp = NULL;
if (argc == 4) {
new.rlim_cur = atoi(argv[2]);
new.rlim_max = atoi(argv[3]);
newp = &new;
}
/* Définir la limite de temps CPU du processus cible ;
récupérer et afficher la limite de temps CPU antérieure */
if (prlimit(pid, RLIMIT_CPU, newp, &old) == -1)
err(EXIT_FAILURE, "prlimit-1");
printf("Limites précédentes : souple=%jd; stricte=%jd\n",
(intmax_t) old.rlim_cur, (intmax_t) old.rlim_max);
/* Récupérer et afficher la nouvelle limite de temps CPU */
if (prlimit(pid, RLIMIT_CPU, NULL, &old) == -1)
err(EXIT_FAILURE, "prlimit-2");
printf("Nouvelles limites : souple=%jd; stricte=%jd\n",
(intmax_t) old.rlim_cur, (intmax_t) old.rlim_max);
exit(EXIT_SUCCESS); }
prlimit(1), dup(2), fcntl(2), fork(2), getrusage(2), mlock(2), mmap(2), open(2), quotactl(2), sbrk(2), shmctl(2), malloc(3), sigqueue (3), ulimit(3), core(5), capabilities(7), cgroups(7), credentials(7), signal(7)
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org>, Cédric Boutillier <cedric.boutillier@gmail.com>, Frédéric Hantrais <fhantrais@gmail.com> et Jean-Philippe MENGUAL <jpmengual@debian.org>
Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.
Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.
5 février 2023 | Pages du manuel de Linux 6.03 |