cgroups(7) Miscellaneous Information Manual cgroups(7) NOM cgroups - Groupes de controle de Linux DESCRIPTION Les groupes de controle, habituellement appeles cgroups, sont une fonctionnalite du noyau Linux qui permet d'organiser les processus en groupes hierarchiques afin de limiter et de superviser leur utilisation de types divers de ressource. L'interface cgroup du noyau est fournie a travers un pseudo-systeme de fichiers appele cgroupfs. Le regroupement est implemente dans le code central cgroup du noyau, tandis que le suivi et les limites de ressources sont implementes dans un ensemble de sous-systemes de type par ressource (memoire, CPU, etc.). Terminologie Un cgroup est une collection de processus qui sont lies a un ensemble de limites ou de parametres definis a l'aide du systeme de fichiers cgroup. Un sous-systeme est un composant du noyau qui modifie le comportement des processus dans un cgroup. Divers sous-systemes ont ete implementes, rendant possible de faire des choses comme la limitation de temps CPU et de memoire disponibles pour un cgroup, la comptabilisation du temps CPU utilise dans un cgroup et le gel ou la reprise de l'execution des processus dans un cgroup. Les sous-systemes sont parfois connus comme controleurs de ressource (ou simplement, controleurs). Les cgroups pour un controleur sont agences dans une hierarchie. Celle-ci est definie en creant, supprimant et renommant des sous-repertoires dans le systeme de fichiers cgroup. A chaque niveau de la hierarchie, des attributs (par exemple, des limites) peuvent etre definis. Les limites, le controle et la comptabilisation fournis par les cgroups ont generalement des effets partout dans la sous-hierarchie du cgroup ou les attributs sont definis. Par consequent, par exemple, les limites placees dans un cgroup d'un niveau superieur dans la hierarchie ne peuvent etre franchies par des cgroups descendants. Cgroups version 1 et version 2 La publication initiale de l'implementation des cgroups a ete faite dans Linux 2.6.24. Au cours du temps, divers controleurs de cgroup ont ete ajoutes pour permettre la gestion de divers types de ressources. Cependant, le developpement de ces controleurs n'a pas ete coordonne en grande partie avec pour resultat l'apparition de nombreuses incoherences entre les controleurs et une complexite accrue de la gestion des hierarchies de cgroup. Une description plus complete de ces problemes peut etre trouvee dans le fichier des sources du noyau Documentation/admin-guide/cgroup-v2.rst (ou Documentation/cgroup-v2.txt dans Linux version 4.17 et precedentes). A cause des problemes avec l'implementation initiale des cgroups (cgroups version 1), des travaux ont commence, a partir de Linux 3.10, sur une nouvelle implementation independante pour remedier a ces problemes. Au depart marquee comme experimentale, et dissimulee derriere l'option de montage -o __DEVEL__sane_behavior, la nouvelle version (cgroups version 2) est devenue finalement officielle avec la publication de Linux 4.5. Les differences entre les deux versions sont decrites dans le texte qui suit. Le fichier cgroup.sane_behavior, present dans cgroups version 1, est un vestige de cette option de montage. Le fichier indique toujours << 0 >> et n'est conserve que pour la retrocompatibilite. Bien que cgroups version 2 soit destine a remplacer la version 1, l'ancien systeme continue a exister (et pour des raisons de compatibilite, ne sera vraisemblablement pas supprime). Actuellement, cgroups version 2 implemente un sous-ensemble de controleurs disponibles dans cgroups version 1. Les deux systemes sont implementes de facon que les controleurs version 1 et 2 puissent etre montes sur le meme systeme. Ainsi, par exemple, il est possible d'utiliser les controleurs qui sont pris en charge par la version 2, tout en utilisant aussi des controleurs version 1 la ou la version 2 ne les prend pas encore en charge. La seule restriction ici est qu'un controleur ne peut pas etre employe simultanement dans une hierarchie de cgroups version 1 et dans une hierarchie de cgroups version 2. CGROUPS VERSION 1 Sous cgroups version 1, chaque controleur peut etre monte pour un systeme de fichiers cgroup distinct qui fournit sa propre organisation hierarchique des processus dans le systeme. Il est aussi possible de co-monter plusieurs (et meme tous) les controleurs de cgroups version 1 pour le meme systeme de fichiers cgroup, ce qui signifie que les controleurs co-montes gerent la meme organisation hierarchique des processus. Pour chaque hierarchie montee, l'arbre de repertoires reflete la hierarchie de groupes de controle. Chaque groupe de controle est represente par un repertoire, avec chaque cgroup de controle enfant represente par un repertoire enfant. Par exemple, /user/joe/1.session represente le groupe de controle 1.session, qui est un enfant du cgroup joe, qui est un enfant de /user. Sous chaque repertoire cgroup existe un ensemble de fichiers qui peuvent etre lus ou ecrits, refletant les limites de ressources et quelques proprietes generales du cgroup. Taches (threads) versus processus Dans cgroups version 1, une distinction est faite entre les processus et les taches. De ce fait, un processus peut consister en plusieurs taches (plus couramment appelees threads, du point de vue espace utilisateur, et appelees ainsi dans la suite de cette page de manuel). Dans cgroups version 1, il est possible de manipuler independamment l'appartenance de cgroup des threads d'un processus. La capacite de cgroups version 1 de repartir les threads dans des cgroups differents cause des problemes dans certains cas. Par exemple, cela n'a aucun sens pour le controleur de memoire, puisque tous les threads d'un processus partagent un meme espace d'adressage. A cause de cela, la capacite de manipuler independamment l'appartenance de cgroup des threads dans un processus a ete retiree dans l'implementation initiale de cgroups version 2, et ulterieurement restauree dans une forme plus limitee (voir l'explication sur le << mode threads >> ci-apres). Montage de controleurs version 1 L'utilisation de cgroups requiert un noyau construit avec l'option CONFIG_CGROUP. De plus, chaque controleur version 1 possede une option de configuration associee qui doit etre definie pour utiliser ce controleur. Pour utiliser un controleur version 1, il doit etre monte pour un systeme de fichiers de cgroup. L'emplacement habituel de tels montages est sous le systeme de fichiers tmpfs(5) monte dans /sys/fs/cgroup. Par consequent, un montage du controleur cpu peut etre realise ainsi : mount -t cgroup -o cpu none /sys/fs/cgroup/cpu Il est possible de co-monter plusieurs controleurs pour la meme hierarchie. Ici par exemple, les controleurs cpu et cpuacct sont co-montes pour une meme hierarchie : mount -t cgroup -o cpu,cpuacct none /sys/fs/cgroup/cpu,cpuacct Le co-montage de controleurs fait qu'un processus est dans le meme cgroup pour tous les controleurs co-montes. Separer le montage de controleurs permet a un processus d'etre dans le cgroup /toto1 pour un controleur tout en etant dans /toto2/toto3 pour un autre. Il est possible de co-monter tous les controleurs version 1 pour la meme hierarchie : mount -t cgroup -o all cgroup /sys/fs/cgroup (Le meme resultat peut etre obtenu en omettant -o all, puisque c'est le comportement par defaut si aucun controleur n'est explicitement precise.) Il n'est pas possible de monter le meme controleur pour plusieurs hierarchies de cgroup. Par exemple, il n'est pas possible de monter a la fois les controleurs cpu et cpuacct pour une meme hierarchie et de monter le controleur cpu seul pour une autre hierarchie. Il est possible de creer plusieurs montages avec exactement le meme ensemble de controleurs co-montes. Dans ce cas cependant, tout cela aboutit a ce que plusieurs points de montage fournissent une vue de la meme hierarchie. Remarquez que sur de nombreux systemes, les controleurs version 1 sont automatiquement montes sous /sys/fs/cgroup. En particulier, systemd(1) cree automatiquement de tels montages. Demontage des controleurs version 1 Un systeme de fichiers cgroup monte peut etre demonte en utilisant la commande umount(8) comme dans l'exemple suivant : umount /sys/fs/cgroup/pids Bien remarquer qu'un systeme de fichiers de cgroup est demonte seulement s'il n'est pas en cours d'utilisation, c'est-a-dire qu'il n'a pas de cgroups enfants. Si ce n'est pas le cas, le seul effet de umount(8) est de rendre le montage invisible. Par consequent, pour etre sur que le montage est reellement retire, les cgroups enfants doivent d'abord etre retires, ce qui a son tour ne peut etre fait qu'apres que tous les processus membres ont ete deplaces de ces cgroups vers le cgroup racine. Controleurs de cgroups version 1 Chacun de ces controleurs de cgroups version 1 est regi par une option de configuration du noyau (liste ci-apres). De plus, la disponibilite de la fonctionnalite des cgroups est regie par l'option de configuration CONFIG_CGROUPS du noyau. cpu (depuis Linux 2.6.24 ; CONFIG_CGROUP_SCHED) Un nombre minimal de << partages de CPU >> peut etre garanti quand un systeme est actif. Cela ne limite pas l'utilisation de CPU par un cgroup si les CPU ne sont pas actifs. Pour plus d'informations, consultez Documentation/scheduler/sched-design-CFS.rst (ou Documentation/scheduler/sched-design-CFS.txt dans Linux 5.2 et les versions anterieures). Dans Linux 3.2, ce controleur a ete etendu pour fournir un controle de la << bande passante >> du CPU. Si le noyau est configure avec CONFIG_CFS_BANDWIDTH, il est possible de definir une limite haute du temps CPU alloue aux processus d'un cgroup a chaque periode de planification (definie a l'aide d'un fichier dans le repertoire de cgroup). La limite haute s'applique meme s'il n'existe aucune competition pour le CPU. Plus d'informations sont disponibles dans le fichier des sources du noyau Documentation/scheduler/sched-bwc.rst (ou Documentation/scheduler/sched-bwc.txt dans Linux 5.2 et les versions anterieures). cpuacct (depuis 2.6.24 ; CONFIG_CGROUP_CPUACCT) Ce controleur fournit la comptabilisation de l'utilisation du CPU par des groupes de processus. Plus d'informations sont disponibles dans le fichier des sources du noyau Documentation/admin-guide/cgroup-v1/cpuacct.rst (ou Documentation/cgroup-v1/cpuacct.txt dans Linux 5.2 et les versions anterieures). cpuset (depuis Linux 2.6.24 ; CONFIG_CPUSETS) Ce cgroup peut etre utilise pour lier les processus dans un cgroup a un ensemble specifie de CPU ou de noeuds NUMA. Plus d'informations sont disponibles dans le fichier des sources du noyau Documentation/admin-guide/cgroup-v1/cpusets.rst (ou Documentation/cgroup-v1/cpusets.txt dans Linux 5.2 et les versions precedentes). memory (depuis Linux 2.6.25 ; CONFIG_MEMCG) Le controleur de memoire prend en charge le rapport et la limitation de la memoire du processus, de la memoire du noyau et de la partition d'echange utilisees par les cgroups. Plus d'informations sont disponibles dans le fichier des sources du noyau Documentation/admin-guide/cgroup-v1/memory.rst (ou Documentation/cgroup-v1/memory.txt dans Linux 5.2 et les versions anterieures). devices (depuis Linux 2.6.26 ; CONFIG_CGROUP_DEVICE) Ce controleur prend en charge la definition des processus qui pourront creer (mknod) des peripheriques et les ouvrir en lecture ou ecriture. Les politiques peuvent etre precisees dans des listes d'autorisations ou de refus. La hierarchie est imposee, aussi des regles nouvelles ne doivent pas violer les regles existantes pour la cible ou pour des cgroups ancetres. Plus d'informations sont disponibles dans le fichier des sources du noyau Documentation/admin-guide/cgroup-v1/devices.rst (ou Documentation/cgroup-v1/devices.txt dans Linux 5.2 et les versions anterieures). freezer (depuis Linux 2.6.28 ; CONFIG_CGROUP_FREEZER) Le cgroup freezer peut suspendre ou restaurer (reprendre) tous les processus d'un cgroup. Geler un cgroup /A fait que ses enfants, par exemple les processus dans /A/B, sont geles. Plus d'informations sont disponibles dans le fichier des sources du noyau Documentation/admin-guide/cgroup-v1/freezer-subsystem.rst (ou Documentation/cgroup-v1/freezer-subsystem.txt dans Linux 5.2 et les versions anterieures). net_cls (depuis Linux 2.6.29 ; CONFIG_CGROUP_NET_CLASSID) Ce controleur place un identificateur de classe (classid), precise pour le cgroup, sur des paquets reseau crees par un cgroup. Ces identificateurs peuvent etre utilises dans des regles de pare-feu, ainsi que pour canaliser le trafic en utilisant tc(8). Cela s'applique aux paquets quittant le cgroup, pas au trafic y arrivant. Plus d'informations sont disponibles dans le fichier des sources du noyau Documentation/admin-guide/cgroup-v1/net_cls.rst (ou Documentation/cgroup-v1/net_cls.txt dans Linux 5.2 et les versions anterieures). blkio (depuis Linux 2.6.33 ; CONFIG_BLK_CGROUP) Le cgroup blkio controle et limite l'acces aux peripheriques en mode bloc indiques en appliquant un controle d'E/S sous forme de restrictions et de limites d'acces a l'encontre de noeuds feuilles et de noeuds intermediaires dans la hierarchie de stockage. Deux politiques sont possibles. La premiere est une division du disque proportionnelle au poids basee sur la duree et implementee avec CFQ (Completely Fair Queuing -- file d'attente completement equitable). C'est le cas pour les noeuds feuilles utilisant CFQ. La seconde est une politique d'etranglement qui precise les limites superieures de taux d'E/S sur un peripherique. Plus d'informations sont disponibles dans le fichier des sources du noyau Documentation/admin-guide/cgroup-v1/blkio-controller.rst (ou Documentation/cgroup-v1/blkio-controller.txt dans Linux 5.2 et les versions anterieures). perf_event (depuis Linux 2.6.39 ; CONFIG_CGROUP_PERF) Ce controleur permet a perf de superviser l'ensemble des processus groupes dans un cgroup. Plus d'informations sont disponibles dans le fichier des sources du noyau. net_prio (depuis Linux 3.3 ; CONFIG_CGROUP_NET_PRIO) Ce controleur permet de definir des priorites par interface reseau pour les cgroups. Plus d'informations sont disponibles dans le fichier des sources du noyau Documentation/admin-guide/cgroup-v1/net_prio.rst (ou Documentation/cgroup-v1/net_prio.txt dans Linux 5.2 et les versions anterieures). hugetlb (depuis Linux 3.5 ; CONFIG_CGROUP_HUGETLB) Ce controleur prend en charge la limitation de l'utilisation de tres grandes pages par les cgroups. Plus d'informations sont disponibles dans le fichier des sources du noyau Documentation/admin-guide/cgroup-v1/hugetlb.rst (ou Documentation/cgroup-v1/hugetlb.txt dans Linux 5.2 et les versions anterieures). pids (depuis Linux 4.3 ; CONFIG_CGROUP_PIDS) Ce controleur permet de limiter le nombre de processus pouvant etre crees dans un cgroup (et ses descendants). Plus d'informations sont disponibles dans le fichier des sources du noyau Documentation/admin-guide/cgroup-v1/pids.rst (ou Documentation/cgroup-v1/pids.txt dans Linux 5.2 et les versions anterieures). rdma (depuis Linux 4.11 ; CONFIG_CGROUP_RDMA) Le controleur RDMA permet de limiter l'utilisation de ressources specifiques a RDMA/IB. Plus d'informations sont disponibles dans le fichier des sources du noyau Documentation/admin-guide/cgroup-v1/rdma.rst (ou Documentation/cgroup-v1/rdma.txt dans Linux 5.2 et les versions anterieures). Creation de cgroups et deplacement de processus Un systeme de fichiers de cgroup contient initialement un seul cgroup racine, << / >>, auquel tous les processus appartiennent. Un nouveau cgroup est cree en creant un repertoire dans le systeme de fichiers de cgroup : mkdir /sys/fs/cgroup/cpu/cg1 Cette commande cree un nouveau cgroup vide. Un processus peut etre transfere dans ce cgroup en ecrivant son PID dans le fichier cgroup.procs du cgroup : echo $$ > /sys/fs/cgroup/cpu/cg1/cgroup.procs Un seul PID a la fois peut etre ecrit dans ce fichier. Ecrire la valeur 0 dans un fichier cgroup.procs fait que le processus ecrivain est transfere dans le cgroup correspondant. Quand un PID est ecrit dans le fichier cgroup.procs, tous les threads du processus sont transferes ensemble dans le nouveau cgroup. Dans une hierarchie, un processus peut etre membre d'un et un seul cgroup. Ecrire un PID de processus dans un fichier cgroup.procs le retire automatiquement du cgroup auquel il appartenait precedemment. Le fichier cgroup.procs peut etre lu pour obtenir une liste des processus qui sont membres d'un cgroup. L'absence de doublons dans la liste renvoyee des PID n'est pas garantie et cette derniere ne sera pas forcement triee. Par exemple, un PID peut etre recycle pendant la lecture de la liste. Dans cgroups version 1, un thread individuel peut etre transfere dans un autre cgroup en ecrivant son ID de thread (c'est-a-dire l'ID de thread du noyau renvoye par clone(2) et gettid(2)) dans le fichier tasks d'un repertoire de cgroup. Ce fichier peut etre lu pour decouvrir l'ensemble des threads membres du cgroup. Suppression de cgroups Pour supprimer un cgroup, il doit tout d'abord n'avoir aucun cgroup enfant et ne contenir aucun processus (non zombie). Tant que c'est le cas, on peut simplement supprimer le nom de chemin de repertoire correspondant. Remarquez que les fichiers dans le repertoire de cgroup ne peuvent et n'ont pas besoin d'etre supprimes. Notification de publication de cgroups version 1 Deux fichiers peuvent etre utilises pour determiner si le noyau fournit des notifications quand un cgroup devient vide. Un cgroup est considere comme vide quand il ne contient ni cgroup enfant, ni processus membre. Un fichier special dans le repertoire racine de chaque hierarchie de cgroup, release_agent, peut etre utilise pour enregistrer le nom de chemin d'un programme pouvant etre invoque quand un cgroup dans la hierarchie devient vide. Le nom de chemin du cgroup nouvellement vide (relatif au point de montage du cgroup) est fourni comme seul argument de ligne de commande quand le programme release_agent est invoque. Le programme release_agent pourrait supprimer le repertoire du cgroup ou, peut etre, le repeupler avec un processus. Par defaut, le fichier release_agent est vide, signifiant qu'aucun agent de publication n'est invoque. Le contenu du fichier release_agent peut etre specifie a l'aide d'une option de montage quand le systeme de fichiers de cgroup est monte : mount -o release_agent=pathname ... Que le programme release_agent soit invoque ou pas quand un cgroup particulier devient vide est determine par la valeur inscrite dans le fichier notify_on_release dans le repertoire de cgroup correspondant. Si ce fichier contient la valeur 0, alors le programme release_agent n'est pas invoque. Si cette valeur est 1, le programme release_agent est invoque. La valeur par defaut inscrite dans ce fichier dans le cgroup racine est 0. Au moment de la creation d'un nouveau cgroup, la valeur dans ce fichier est heritee du fichier correspondant dans le cgroup parent. Hierarchies nommees de cgroups version 1 Dans cgroups version 1, il est possible de monter une hierarchie de cgroup qui n'a pas de controleurs attaches. mount -t cgroup -o none,name=un_nom none /un/point/de/montage Plusieurs instances de telles hierarchies peuvent etre montees, chaque hierarchie devant avoir un nom unique. Le seul but de telles hierarchies est de suivre les processus (consultez les explications de notification de publication ci-dessous). La hierarchie de cgroup name=systemd qui est utilisee par systemd(1) pour suivre les services et les sessions d'utilisateur en est un exemple. Depuis Linux 5.0, l'option d'amorcage cgroup_no_v1 du noyau (decrite ci-apres) peut etre utilisee pour desactiver les hierarchies nommees de cgroups version 1, en specifiant cgroup_no_v1=named. CGROUPS VERSION 2 Dans cgroups version 2, tous les controleurs montes resident dans une seule hierarchie unifiee. Alors que des controleurs (differents) peuvent etre montes simultanement dans des hierarchies version 1 ou 2, il n'est pas possible de monter le meme controleur simultanement dans les deux hierarchies version 1 et version 2. Les nouveaux comportements dans cgroups version 2 sont resumes ici et, dans quelques cas, developpes dans les sous-sections suivantes. - Les cgroups version 2 fournissent une hierarchie unifiee pour laquelle tous les controleurs sont montes. - Les processus << internes >> ne sont pas autorises. A l'exception du cgroup racine, les processus ne peuvent resider que dans les noeuds feuilles (les cgroups qui ne contiennent pas eux-memes de cgroups enfants). Les details sont un peu plus subtils que ca et sont decrits ci-apres. - Les cgroups actifs doivent etre indiques a l'aide des fichiers cgroup.controllers et cgroup.subtree_control. - Le fichier tasks et le fichier cgroup.clone_children qui est utilise par le controleur cpuset ont ete supprimes. - Un mecanisme ameliore pour la notification de cgroups vides est fourni par le fichier cgroup.events. Pour plus de details sur les modifications, consultez le fichier Documentation/admin-guide/cgroup-v2.rst dans les sources du noyau (ou Documentation/cgroup-v2.txt dans Linux 4.17 et les versions anterieures). Certains de ces nouveaux comportements integrent une modification avec l'ajout dans Linux 4.14 du << mode thread >> (decrit ci-apres). Hierarchie unifiee de cgroups version 2 Dans les cgroups version 1, la possibilite de monter differents controleurs pour differentes hierarchies etait voulue pour permettre une grande flexibilite dans la conception des applications. En pratique, la flexibilite s'est averee moins utile qu'esperee et, dans de nombreux de cas, a ajoute de la complexite. Par consequent, dans cgroups version 2, tous les controleurs disponibles sont montes pour une seule hierarchie. Les controleurs disponibles sont automatiquement montes, ce qui signifie qu'il n'est pas necessaire (ou possible) d'indiquer les controleurs lors du montage d'un systeme de fichiers cgroups version 2 en utilisant une commande telle que la suivante : mount -t cgroup2 none /mnt/cgroup2 Un controleur cgroups version 2 est disponible seulement s'il n'est pas en cours d'utilisation a l'aide d'un montage pour une hierarchie de cgroups version 1. Ou, pour dire les choses autrement, il n'est pas possible d'employer le meme controleur pour les deux hierarchies version 1 et version 2 unifiee. Cela signifie qu'il peut etre necessaire d'abord de demonter un controleur version 1 (comme decrit ci-dessus) avant que ce controleur soit disponible en version 2. Puisque systemd(1) utilise abondamment quelques controleurs version 1 par defaut, il peut dans certains cas etre plus simple d'amorcer le systeme avec ces controleurs version 1 desactives. Pour ce faire, specifier l'option cgroup_no_v1=list sur la ligne de commande d'amorcage du noyau. list est une liste de noms separes par des virgules des controleurs a desactiver ou le mot all pour desactiver tous les controleurs version 1. Cette situation est geree correctement par systemd(1), ce qui revient a un amorcage sans ces controleurs. Remarquez que sur de nombreux systemes modernes, systemd(1) monte automatiquement le systeme de fichiers cgroup2 dans /sys/fs/cgroup/unified lors du processus d'amorcage. Options de montage pour cgroups version 2 Les options suivantes (mount -o) peuvent etre specifiees lors du montage de systemes de fichiers de groupe version 2 : nsdelegate (depuis Linux 4.15) Traitement des espaces de noms cgroup comme des limites de delegation. Pour plus de details, voir ci-dessous. memory_localevents (depuis Linux 5.2) memory.events devrait afficher des statistiques seulement pour le cgroup lui-meme, pas pour les cgroups descendants. C'etait le comportement avant Linux 5.2. Depuis Linux 5.2, le comportement par defaut consiste a inclure des statistiques pour les cgroups descendants dans memory.events et cette option de montage peut etre utilisee pour revenir au comportement traditionnel. Cette option s'applique au systeme entier et peut etre definie au moment du montage ou modifiee a travers un remontage seulement a partir de l'espace de noms montage initial. Elle est silencieusement ignoree dans les espaces de noms non initiaux. Controleurs de cgroups version 2 Les controleurs suivants, documentes dans le fichier source du noyau Documentation/admin-guide/cgroup-v2.rst (ou Documentation/cgroup-v2.txt dans Linux 4.17 et les versions anterieures) sont pris en charge dans cgroups version 2 : cpu (depuis Linux 4.15) C'est le successeur des controleurs version 1 cpu et cpuacct. cpuset (depuis Linux 5.0) C'est le successeur du controleur version 1 cpuset. freezer (depuis Linux 5.2) C'est le successeur du controleur version 1 freezer. hugetlb (depuis Linux 5.6) C'est le successeur du controleur version 1 hugetlb. io (depuis Linux 4.5) C'est le successeur du controleur version 1 blkio. memory (depuis Linux 4.5) C'est le successeur du controleur version 1 memory. perf_event (depuis Linux 4.11) Identique au controleur version 1 perf_event. pids (depuis Linux 4.5) Identique au controleur version 1 pids. rdma (depuis Linux 4.11) Identique au controleur version 1 rdma. Il n'existe pas d'equivalent direct des controleurs net_cls et net_prio de cgroups version 1. A la place, une prise en charge a ete ajoutee a iptables(8) pour permettre aux filtres eBPF qui s'attachent aux noms de chemin de cgroups version 2 de prendre des decisions a partir du trafic reseau selon le cgroup. Les controleurs version 2 devices ne fournissent pas de fichiers d'interface. A la place, le controle de peripherique est securise en attachant un programme eBPF (BPF_CGROUP_DEVICE) a un cgroup version 2. Controle de sous-arbres de cgroups version 2 Chaque cgroup dans une hierarchie version 2 contient les deux fichiers suivants : cgroup.controllers Ce fichier en lecture seule contient une liste des controleurs qui sont disponibles dans ce cgroup. Le contenu de ce fichier correspond au contenu du fichier cgroup.subtree_control dans le cgroup parent. cgroup.subtree_control Ce fichier contient une liste de controleurs qui sont actifs (permis) dans le cgroup. L'ensemble des controleurs dans ce fichier est un sous-ensemble de l'ensemble cgroup.controllers de ce cgroup. L'ensemble des controleurs actifs est modifie en ecrivant des chaines dans ce fichier contenant des noms de controleurs separes par des espaces, chacun etant precede par un << + >> (pour autoriser le controleur) ou un << - >> (pour interdire le controleur), comme dans l'exemple suivant : echo '+pids -memory' > x/y/cgroup.subtree_control Un essai pour autoriser un controleur qui n'est pas present dans cgroup.controllers provoque une erreur ENOENT lors d'une ecriture dans le fichier cgroup.subtree_control. Parce que la liste de controleurs dans cgroup.subtree_control est un sous-ensemble de ces cgroup.controllers, un controleur qui n'est plus autorise dans un cgroup de la hierarchie ne peut jamais etre reautorise dans un sous-arbre de ce cgroup. Un fichier cgroup.subtree_control de cgroup determine l'ensemble des controleurs qui sont actives dans les cgroups enfants. Quand un controleur (par exemple, pids) est present dans le fichier cgroup.subtree_control d'un cgroup parent, les fichiers correspondants interface-controleur (par exemple, pids.max) sont automatiquement crees dans l'enfant de ce cgroup et peuvent etre utilises pour exercer le controle des ressources dans les cgroups enfants. Regle << pas de processus internes >> pour cgroups version 2 Cgroups version 2 applique une regle appelee << pas de processus internes >>. En gros, cette regle veut dire que, a l'exception du cgroup racine, les processus ne peuvent resider que dans les noeuds feuilles (des cgroups ne contenant pas eux-memes de cgroup enfant). Cela evite d'avoir a decider comment partager les ressources entre les processus qui sont membres du cgroup A et les processus dans des cgroups enfants de A. Par exemple, si le cgroup /cg1/cg2 existe, un processus peut resider dans /cg1/cg2, mais pas dans /cg1. Cela permet d'eviter une ambiguite dans cgroups version 1 par rapport a la delegation de ressources entre les processus dans /cg1 et les cgroups enfants. L'approche recommandee dans cgroups version 2 consiste a creer un sous-repertoire appele feuille pour n'importe quel cgroup non feuille qui contiendrait des processus mais pas de cgroup enfant. Ainsi, les processus qui auparavant seraient alles dans /cg1 iraient maintenant dans /cg1/feuille. Cela a l'avantage de rendre explicite la relation entre les processus dans /cg1/feuille et les autres enfants de /cg1. La regle << pas de processus internes >> est en fait plus subtile que ce qui est decrit ci-dessus. Plus precisement, la regle stipule qu'un cgroup (non racine) ne peut pas a la fois avoir des processus membres et distribuer des ressources aux cgroups enfants -- c'est-a-dire avoir un fichier cgroup.subtree_control non vide. Par consequent, il est possible pour un cgroup d'avoir a la fois des processus membres et des cgroups enfants, mais pour que les controleurs puissent etre autorises pour ce cgroup, les processus membres doivent etre deplaces en dehors du cgroup (par exemple, dans les cgroups enfants). Avec l'addition dans Linux 4.14 du << mode thread >> (decrit ci-apres), la regle << pas de processus internes >> a ete assouplie dans certains cas. Fichier cgroup.events de cgroups version 2 Chaque cgroup non racine dans la hierarchie version 2 contient un fichier en lecture seule, cgroup.events, dont le contenu consiste en paires cle-valeur (delimitees par des caracteres de nouvelle ligne, avec les cles et valeurs separees par des espaces) fournissant des informations d'etat sur le cgroup : $ cat mygrp/cgroup.events populated 1 frozen 0 Les cles suivantes peuvent apparaitre dans ce fichier : populated La valeur de cette cle est soit 1 si ce cgroup ou n'importe lequel de ses descendants a des processus membres, soit 0 dans le cas contraire. frozen (depuis Linux 5.2) La valeur de cette cle est 1 si ce cgroup est actuellement gele ou 0 s'il ne l'est pas. Le fichier cgroup.events peut etre surveille dans le but de recevoir des notifications quand la valeur d'une des cles change. Cette surveillance peut etre realisee en utilisant inotify(7), qui notifie les changements tels que les evenements IN_MODIFY ou poll(2) qui notifie les changements en renvoyant les bits POLLPRI et POLLERR dans le champ revents. Notification de liberation de cgroups version 2 Les cgroups version 2 fournissent un nouveau mecanisme pour recevoir des notifications lorsqu'un cgroup devient vide. Les fichiers cgroups version 1 release_agent et notify_on_release sont supprimes et remplaces par la cle populated dans le fichier cgroup.events. Cette cle a soit la valeur 0, signifiant que le cgroup (et ses descendants) ne contient aucun processus membre (non zombie), ou 1, signifiant que le cgroup (ou un de ses descendants) contient des processus membres. Le mecanisme de notification de liberation de cgroups version 2 offre les avantages suivants par rapport au mecanisme release_agent de cgroups version 1 : - IL permet une notification moins couteuse puisqu'un seul processus peut controler plusieurs fichiers cgroup.events (en utilisant les techniques decrites precedemment). En revanche, le mecanisme de cgroups version 1 requiert la charge de creer un processus pour chaque notification. - Les notifications pour des sous-hierarchies differentes de cgroup peuvent etre deleguees a des processus differents. En revanche, le mecanisme de cgroups version 1 permet seulement un agent de notification pour la hierarchie complete. Fichier cgroup.stat de cgroups version 2 Chaque cgroup d'une hierarchie version 2 contient un fichier cgroup.stat en lecture seule (introduit en premier dans Linux 4.14) qui consiste en lignes contenant des paires cle-valeur. Les cles suivantes apparaissent actuellement dans ce fichier : nr_descendants C'est le nombre total de cgroups descendants visibles (c'est-a-dire en vivants) en dessous de ce cgroup. nr_dying_descendants C'est le nombre de cgroups descendants mourants en dessous de ce cgroup. Un cgroup devient mourant apres avoir ete supprime. Il reste dans cet etat pour une periode indefinie (qui depend de la charge du systeme) pendant que les ressources sont liberees avant que le cgroup soit detruit. Remarquez que la presence de quelques cgroups dans l'etat mourant est normal et n'indique pas un quelconque probleme. Un processus ne peut devenir membre d'un cgroup mourant et celui-ci ne peut redevenir actif. Limitation du nombre de cgroups descendants Chaque cgroup dans une hierarchie version 2 contient les fichiers suivants qui peuvent etre utilises pour afficher et definir les limites du nombre de cgroups descendants dans ce cgroup : cgroup.max.depth (depuis Linux 4.14) Ce fichier definit une limite sur le niveau d'imbrication de cgroups descendants. Une valeur de 0 dans ce fichier signifie qu'aucun cgroup descendant ne peut etre cree. Un essai de creation dont le niveau d'imbrication excede la limite echouera (mkdir(2) echoue avec l'erreur EAGAIN). Ecrire la chaine "max" dans ce fichier signifie qu'aucune limite n'est imposee. La valeur par defaut dans ce fichier est "max". cgroup.max.descendants (depuis Linux 4.14) Ce fichier definit une limite du nombre de cgroups descendants actifs que ce cgroup peut posseder. Un essai de creer plus de descendants qu'autorises par la limite echoue (mkdir(2) echoue avec l'erreur EAGAIN). Ecrire la chaine "max" dans ce fichier signifie qu'aucune limite n'est imposee. La valeur par defaut dans ce fichier est "max". DELEGATION DE CGROUPS A UN UTILISATEUR AVEC DES PRIVILEGES MOINDRES Dans le contexte de cgroups, deleguer signifie transmettre la gestion d'un sous-arbre de la hierarchie de cgroup a un utilisateur non privilegie. Cgroups version 1 fournit une prise en charge de la delegation basee sur les permissions de fichier dans la hierarchie de cgroup, mais avec des regles de confinement moins strictes que dans la version 2 (comme signale ci-dessous). Cgroups version 2 gere la delegation avec confinement selon un modele explicite. L'explication dans cette section se concentre sur la delegation dans cgroups version 2, avec quelques differences pour cgroups version 1 signalees au fur et a mesure. Un peu de terminologie est necessaire pour expliquer la delegation. Un delegant est un utilisateur privilegie (c'est-a-dire le superutilisateur) qui possede un cgroup parent. Un delegue est un utilisateur non privilegie a qui sont accordees les permissions necessaires pour gerer une sous-hierarchie sous le cgroup parent, connue comme le sous-arbre delegue. Pour realiser la delegation, le delegant autorise l'ecriture par le delegue sur certains repertoires et fichiers, typiquement en transferant la propriete des objets a l'ID utilisateur du delegue. En supposant une delegation de hierarchie de racine (par exemple) /dlgt_grp et qu'il n'y a pas encore de cgroup enfant sous ce cgroup, la propriete de ce qui suit est transferee a l'ID utilisateur du delegue : /dlgt_grp Modifier le proprietaire de la racine d'un sous-arbre signifie que n'importe quel cgroup nouvellement cree dans ce sous-arbre (et les fichiers qu'il contient) sera aussi la propriete du delegue. /dlgt_grp/cgroup.procs Modifier le proprietaire de ce fichier signifie que le delegue peut deplacer les processus dans la racine du sous-arbre delegue. /dlgt_grp/cgroup.subtree_control (cgroups version 2 seulement) Modifier le proprietaire de ce fichier signifie que le delegue peut activer des controleurs (qui sont presents dans /dlgt_grp/cgroup.controllers) dans le but d'une redistribution posterieure des ressources a des niveaux inferieurs du sous-arbre. Comme alternative au changement de proprietaire de ce fichier, le delegant pourrait a la place ajouter les controleurs selectionnes dans ce fichier. /dlgt_grp/cgroup.threads (cgroups version 2 seulement) Modifier le proprietaire de ce fichier est necessaire si un sous-arbre threaded est sous le coup d'une delegation (consultez la description du << mode thread >> ci-dessous). Cela permet au delegue d'ecrire des ID de thread dans ce fichier. Le proprietaire de ce fichier peut etre aussi change lors de la delegation d'un sous-arbre de domaine, mais actuellement cela ne sert a rien puisque, comme decrit ci-dessous, il n'est pas possible de deplacer un thread entre des cgroups de domaine en inscrivant son ID de thread dans le fichier cgroup.threads. Pour les cgroups version 1, le fichier correspondant qui doit etre delegue est le fichier tasks. Le delegant ne doit pas changer le proprietaire de n'importe quel fichier d'interface de controleur (par exemple, pids.max, memory.high) dans dlgt_grp. Ces fichiers sont utilises au niveau juste au-dessus du sous-arbre delegue dans le but de distribuer les ressources dans le sous-arbre, et le delegant ne doit pas avoir la permission de modifier les ressources qui sont distribuees dans le sous-arbre delegue. Consultez aussi l'explication dans le fichier /sys/kernel/cgroup/delegate dans NOTES pour des informations sur les autres fichiers delegables dans cgroups version 2. Apres que les etapes precitees aient ete realisees, le delegue peut creer des cgroups enfants dans le sous-arbre delegue (les sous-repertoires et les fichiers de cgroup qu'ils contiennent seront la propriete du delegue) et deplacer des processus entre des cgroups dans le sous-arbre. Si quelques controleurs sont presents dans dlgt_grp/cgroup.subtree_control, ou si la propriete de ce fichier a ete transferee au delegue, celui-ci peut aussi controler une prochaine redistribution des ressources correspondantes dans le sous-arbre delegue. Delegation de cgroups version 2 : nsdelegate et espace de noms cgroup Depuis Linux 4.13, une seconde maniere existe pour realiser une delegation de cgroup dans une hierarchie de cgroups version 2. Cela est fait en montant ou remontant le systeme de fichiers de cgroups version 2 avec l'option de montage nsdelegate. Par exemple, si un systeme de fichiers de cgroups version 2 a deja ete monte, il est possible de le remonter avec l'option nsdelegate comme suit : mount -t cgroup2 -o remount,nsdelegate \ none /sys/fs/cgroup/unified L'effet de cette option de montage est que l'espace de noms cgroup deviennent automatiquement les limites de delegation. Plus particulierement, les restrictions suivantes s'appliquent pour les processus a l'interieur de l'espace de noms cgroup : - Inscrire les fichiers des interfaces de controleur dans le repertoire racine de l'espace de noms echouera avec l'erreur EPERM. Les processus a l'interieur de l'espace de noms cgroup peuvent toujours ecrire dans les fichiers delegables dans le repertoire racine de l'espace de noms cgroup tels que cgroup.procs et cgroup.subtree_control, et peuvent creer des sous-hierarchies au-dessous du repertoire racine. - Les essais de migrer des processus a travers des limites d'espace de noms sont interdits (avec l'erreur ENOENT). Les processus a l'interieur d'un espace de noms cgroup peuvent toujours (soumis aux regles de confinement decrites ci-apres) deplacer des processus entre cgroups a l'interieur de la sous-hierarchie sous l'espace de noms racine. La possibilite de definir des espaces de noms cgroup comme des limites de delegation rend les espaces de noms cgroup beaucoup plus utiles. Pour en comprendre la raison, supposons qu'il existe deja une hierarchie de cgroup qui a ete deleguee a un utilisateur non privilegie, cecilia, en utilisant la technique ancienne de delegation decrite ci-dessus. Supposons que plus tard cecilia veuille deleguer une sous-hierarchie sous la hierarchie deleguee existante (par exemple, la hierarchie deleguee peut etre associee avec un conteneur non privilegie execute par cecilia). Meme si un espace de noms cgroup etait employe, parce que les deux hierarchies sont la propriete de l'utilisateur cecilia non privilegie, les actions illegitimes suivantes pourraient etre realisees : - Un processus dans la hierarchie inferieure pourrait modifier les reglages du controleur de ressources dans le repertoire racine de cette hierarchie (ces reglages sont concus pour permettre le controle a exercer a partir du cgroup parent ; un processus dans le cgroup enfant ne devrait pas pouvoir les modifier) ; - un processus a l'interieur de hierarchie subalterne pourrait deplacer des processus dans ou en dehors de la hierarchie inferieure si les cgroups dans la hierarchie superieure etaient de quelque facon visibles. L'utilisation de l'option de montage nsdelegate empeche les deux possibilites. L'option de montage nsdelegate a seulement un effet lorsque elle est utilisee dans l'espace de noms initial montage, dans d'autres espaces de noms montage cette option est ignoree silencieusement. Remarque : sur certains systemes, systemd(1) monte automatiquement le systeme de fichiers de cgroup version 2. Dans le but de tester l'operation nsdelegate, il peut etre utile d'amorcer le noyau avec les options de ligne de commande suivantes : cgroup_no_v1=all systemd.legacy_systemd_cgroup_controller Ces options font que le noyau amorce avec les controleurs cgroups version 1 desactives (signifiant que les controleurs sont disponibles dans une hierarchie version 2) et indique a systemd(1) de ne pas monter et utiliser la hierarchie de cgroup version 2, de facon que la hierarchie version 2 puisse etre montee manuellement avec les options desirees apres l'amorcage. Regles de confinement de delegation de cgroup Certaines regles de confinement de delegation assurent que le delegue peut deplacer des processus entre des cgroups a l'interieur du sous-arbre delegue, mais ne puisse pas deplacer les processus de l'exterieur du sous-arbre delegue dans le sous-arbre ou vice versa. Un processus non privilegie (c'est-a-dire le delegue) peut ecrire le PID d'un processus << cible >> dans un fichier cgroup.procs seulement si toutes les conditions suivantes sont remplies : - l'ecrivain a la permission d'ecriture dans le fichier cgroup.procs du cgroup de destination ; - l'ecrivain a la permission d'ecrire dans le fichier cgroup.procs dans le plus proche ancetre commun des cgroups source et de destination. Remarquez que dans certains cas, ce plus proche ancetre commun peut etre le cgroup source ou celui de destination eux-memes. Ce besoin n'est pas impose pour les hierarchies version 1, avec pour consequence que le confinement dans la version 1 est moins strict que dans la version 2 (par exemple, dans cgroups version 1 l'utilisateur possedant deux sous-hierarchies deleguees distinctes peut deplacer un processus entre les hierarchies) ; - si le systeme de fichiers d'un cgroup version 2 a ete monte avec l'option nsdelegate, l'ecrivain doit etre capable de voir les cgroups source et destination a partir de son espace de noms cgroup ; - Dans cgroups version 1, l'UID effectif de l'ecrivain (c'est-a-dire le delegue) correspond a l'ID reel utilisateur ou au set-user-ID enregistre du processus cible. Avant Linux 4.11, cette exigence s'appliquait aussi dans cgroups version 2 (c'etait une exigence historique heritee de cgroups version 1 qui a ete plus tard estimee non necessaire, puisque les autres regles suffisent pour le confinement dans cgroups version 2). Remarque : une consequence des ces regles de confinement de delegation est que le delegue non privilegie ne peut placer le premier processus dans le sous-arbre delegue. A la place, le delegant doit placer le premier processus (un processus possede par le delegue) dans le sous-arbre delegue. MODE THREAD DE CGROUPS VERSION 2 Parmi les restrictions imposees par cgroups version 2 qui n'etaient pas presentes dans cgroups version 1 : - pas controle de granularite au niveau thread : tous les threads d'un processus doivent etre dans le meme cgroup ; - pas de processus internes : un cgroup ne peut a la fois avoir des processus membres et mettre en oeuvre des controleurs sur des cgroups enfants. Ces deux restrictions ont ete ajoutees parce que l'absence de ces restrictions a cause des problemes dans cgroups version 1. En particulier, la possibilite de cgroups version 1 de permettre une granularite au niveau threads pour l'appartenance a un cgroup n'avait aucun sens pour certains controleurs. Un exemple notable etait le controleur memory : puisque les threads partagent un espace d'adressage, cela n'avait aucun sens de repartir les threads a travers des cgroups memory differents. Malgre le fait de la decision initiale de conception de cgroups version 2, des cas d'utilisation existaient pour certains controleurs, notablement le controleur cpu, pour lesquels la granularite au niveau thread du controle etait justifiee et utile. Pour tenir compte de tels cas, Linux 4.14 a ajoute le mode thread pour cgroups version 2. Le mode thread permet les choses suivantes : - la creation de sous-arbres threaded dans lesquels les threads d'un processus peuvent etre repartis a travers des cgroups a l'interieur de l'arbre (un sous-arbre threaded peut contenir plusieurs processus multithreads) ; - le concept de controleurs threaded qui peuvent distribuer des ressources a travers les cgroups dans un sous-arbre threaded ; - un relachement de la regle << pas de processus internes >>, de facon a ce que, a l'interieur d'un sous-arbre threaded, un cgroup puisse a la fois avoir des processus membres et mettre en oeuvre des controleurs de ressources de cgroups enfants. Avec l'ajout du mode thread, chaque cgroup non racine contient desormais un nouveau fichier, cgroup.type, qui expose, et dans certaines circonstances qui peut etre utilise pour modifier, le << type >> d'un cgroup. Ce fichier contient une des valeurs de type suivantes : domain C'est un cgroup version 2 normal fournissant un controle de niveau de granularite processus. Si un processus est membre de ce cgroup, alors tous les threads de ce processus sont (par definition) dans le meme cgroup. C'est le type par defaut de cgroup et il fournit le meme comportement qui etait fourni pour les cgroups dans l'implementation initiale de cgroups version 2. threaded Ce cgroup est un membre d'un sous-arbre threaded. Des threads peuvent etre ajoutes a ce cgroup et des controleurs peuvent etre actives pour le cgroup. domain threaded C'est un cgroup domain qui sert de racine a un sous-arbre threaded. Ce type de cgroup est aussi connu comme << threaded root >>. domain invalid C'est un cgroup a l'interieur d'un sous-arbre threaded qui est dans un etat << invalid >>. Un processus ne peut etre ajoute au cgroup et un controleur ne peut etre active pour le cgroup. La seule chose qui puisse etre faite avec ce cgroup (a part le supprimer) est de le convertir en cgroup threaded en inscrivant la chaine << threaded >> dans le fichier cgroup.type. La raison de l'existence de ce type << transitoire >> lors de la creation d'un sous-arbre threaded (plutot que le noyau ne convertisse simplement immediatement tous les cgroups sous la racine threaded au type threaded) est de permettre des extensions futures au modele de mode thread. Threaded versus controleurs de domaine Avec l'ajout du mode threads, cgroups version 2 distingue desormais deux types de controleurs de ressource : - controleurs Threaded : ces controleurs gerent la granularite au niveau thread pour le controle des ressources et peuvent etre actives a l'interieur de sous-arbres threaded avec pour resultat que les fichiers de l'interface de controleur correspondants apparaissent dans les cgroups du sous-arbre threaded. Depuis Linux 4.19, les controleurs suivants sont threaded : cpu, perf_event, et pids ; - controleurs Domain : ces controleurs gerent seulement une granularite au niveau processus pour le controle de ressource. Du point de vue controleur de domaine, tous les threads d'un processus sont toujours dans le meme cgroup. Les controleurs de domaine ne peuvent etre actives a l'interieur d'un sous-arbre threaded. Creation d'un sous-arbre threaded Il existe deux manieres qui conduisent a la creation de sous-arbre threaded. La premiere maniere fonctionne comme ceci : (1) Nous ecrivons La chaine << threaded >> dans le fichier cgroup.type d'un cgroup y/z ayant actuellement le type domain. Cela a les effets suivants : - le type du cgroup y/z devient threaded ; - le type du cgroup parent, y, devient domain threaded. Le cgroup parent est la racine d'un sous-arbre threaded (aussi connu comme << threaded root >> - racine threaded) ; - Tous les autres cgroups sous y qui n'etaient pas deja de type threaded (parce qu'ils etaient deja dans des sous-arbres threaded existants sous la nouvelle racine root threaded) sont convertis au type domain invalid. Tout cgroup cree apres sous y aura aussi le type domain invalid. (2) Nous ecrivons La chaine << threaded >> pour chacun des cgroups domain invalid sous y, dans le but de les convertir au type threaded. Comme consequence de cette etape, tous les threads sous la racine threaded ont desormais le type threaded et le sous-arbre threaded est desormais pleinement utilisable. Les conditions necessaires pour ecrire << threaded >> pour chacun de ces cgroups sont quelque peu laborieuses, mais permettent de futures extensions au modele de mode thread. La second maniere de creer un sous-arbre threaded est la suivante : (1) Dans un cgroup existant, z, qui actuellement a le type domain, nous (1.1) activons un ou plusieurs controleurs threaded et (1.2) faisons d'un processus un membre de z (ces deux etapes pouvant etre realisees dans n'importe quel ordre). Cela a les consequences suivantes : - le type de z devient domain threaded ; - tous les cgroups descendants de x qui n'etaient deja de type threaded sont convertis au type domain invalid. (2) Comme auparavant, nous rendons le sous-arbre threaded utilisable en ecrivant la chaine << threaded >> pour chacun des cgroups domain invalid sous y, dans le but de les convertir au type threaded. Une des consequences des manieres ci-dessus de creer un sous-arbre threaded est qu'un cgroup de racine threaded peut etre un parent pour seulement des cgroups threaded (et domain invalid). Le cgroup racine threaded ne peut pas etre un parent d'un cgroup domain et un cgroup threaded ne peut avoir de frere qui soit un cgroup domain. Utilisation de sous-arbre threaded A l'interieur d'un sous-arbre threaded, des controleurs threaded peuvent etre actives dans chaque sous-groupe dont le type a ete change a threaded. Ce faisant, les fichiers de l'interface de controleur correspondants apparaissent dans l'enfant de ce cgroup. Un processus peut etre deplace dans un sous-arbre threaded en ecrivant son PID dans le fichier cgroup.procs dans un des cgroups de l'arbre. Cela a pour effet de rendre tous les threads du processus membres du cgroup correspondant et de faire du processus un membre du sous-arbre threaded. Les threads du processus peuvent etre repartis a travers le sous-arbre threaded en ecrivant leurs ID de thread (voir gettid(2)) dans les fichiers cgroup.threads dans differents cgroups a l'interieur du sous-arbre. Les threads d'un processus doivent tous resider dans le meme sous-arbre threaded. Comme pour l'ecriture dans cgroup.procs, quelques regles de confinement s'appliquent pour l'ecriture dans le fichier cgroup.threads : - l'ecrivain doit avoir la permission d'ecriture dans le fichier cgroup.threads dans le cgroup de destination ; - l'ecrivain doit avoir la permission d'ecriture dans le fichier cgroup.procs dans l'ancetre commun des cgroups source et destination (dans certains cas, cet ancetre peut etre le cgroup source ou destination eux-memes) ; - les cgroups source et destination doivent etre dans le meme sous-arbre threaded (en dehors d'un sous-arbre threaded, un essai de deplacer un thread en ecrivant son ID de thread dans le fichier cgroup.threads dans un cgroup domain different echoue avec l'erreur EOPNOTSUPP). Le fichier cgroup.threads est present dans chaque cgroup (incluant les cgroups domain) et peut etre lu pour decouvrir l'ensemble de threads presents dans le cgroup. L'ensemble d'ID de threads obtenu lors de la lecture de ce fichier n'est pas garanti d'etre ordonne ou ne pas avoir de doublons. Le fichier cgroup.procs dans la racine threaded affiche le PID de tous les processus membres du sous-arbre threaded. Les fichiers cgroup.procs dans les autres cgroups du sous-arbre ne sont pas lisibles. Les controleurs de domaine ne peuvent etre actives dans un sous-arbre threaded. Aucun fichier d'interface de controleur n'apparait dans les cgroups sous la racine threaded. Du point de vue du controleur de domaine, les sous-arbres threaded sont invisibles : un processus multithreaded a l'interieur d'un sous-arbre threaded apparait pour un controleur de domaine comme un processus qui reside dans le cgroup racine threaded. Dans un sous-arbre threaded, la regle << pas de processus internes >> ne s'applique pas : un cgroup peut contenir des processus membres (ou des threads) et utiliser des controleurs sur des cgroups enfants. Regles pour ecrire dans cgroup.type et creer des sous-arbres threaded Un certain nombre de regles s'appliquent lors de l'ecriture dans le fichier cgroup.type : - seule la chaine << threaded >> peut etre ecrite. En d'autres mots, la seule transition explicite possible est de convertir un cgroup domain au type threaded ; - l'effet d'ecrire << threaded >> depend de la valeur en cours dans cgroup.type, comme suit : - domain ou domain threaded : debut de la creation d'un sous-arbre threaded (dont la racine est le parent de ce cgroup) a l'aide de la premiere des manieres decrites ci-dessus, - domain invalid : conversion de ce cgroup (qui est a l'interieur d'un sous-arbre threaded) pour etre dans un etat utilisable (c'est-a-dire threaded), - threaded : aucun effet (une << no-op >>) ; - il n'est pas possible d'ecrire dans un fichier cgroup.type si le type du parent est domain invalid. En d'autres mots, les cgroups d'un sous-arbre threaded doivent etre convertis dans l'etat threaded d'une maniere descendante. Quelques contraintes doivent aussi etre satisfaites pour creer un sous-arbre threaded dont la racine est le cgroup x : - il ne peut exister de processus membres dans les cgroups descendants de x (le cgroup_x peut lui avoir des processus membres) ; - aucun controleur de domaine ne peut etre active dans le fichier cgroup.subtree_control de x. Si n'importe laquelle des contraintes ci-dessus n'est pas satisfaite, alors un essai d'ecrire << threaded >> dans un fichier cgroup.type echouera avec l'erreur ENOTSUP. Le type << domain threaded >> de cgroup Selon les chemins decrits ci-dessus, le type d'un cgroup peut changer a domain threaded dans chacun des cas suivants : - la chaine << threaded >> est ecrite pour un cgroup enfant ; - un controleur threaded est active dans le cgroup et un processus est fait membre du cgroup. Un cgroup domain threaded, x, peut redevenir du type domain si les conditions ci-dessus ne sont plus vraies, c'est-a-dire si tous les cgroups enfants threaded de x ont ete supprimes et si x n'a plus de controleurs threaded actives ou n'a plus de processus membres. Quand un cgroup domain threaded x redevient du type domain : - tous les descendants domain invalid de x qui ne sont pas dans des sous-arbres threaded de bas niveau redeviennent du type domain ; - les cgroups racines dans n'importe quels sous-arbres threaded de bas niveau redeviennent de type domain threaded. Exceptions pour le cgroup racine Le cgroup racine de la hierarchie version 2 est traite exceptionnellement : il peut etre le parent a la fois de cgroups domain et threaded. Si la chaine << threaded >> est ecrite dans le fichier cgroup.type d'un des enfants du cgroup racine, alors : - le type de ce cgroup devient threaded ; - le type de tous les descendants de ce cgroup qui ne fait pas partie de sous-arbres threaded de bas niveau change a domain invalid. Remarquez que dans ce cas, il n'y a pas de cgroup qui deviennent domain threaded (theoriquement, le cgroup racine peut etre considere comme la racine threaded pour le cgroup dont le type a ete change a threaded). Le but de ce traitement exceptionnel pour le cgroup racine est de permettre a un cgroup threaded qui emploie le controleur cpu d'etre place aussi haut que possible dans la hierarchie, de facon a minimiser le (faible) cout de parcourir la hierarchie de cgroup. Le controleur << cpu >> de cgroups version 2 et les threads en temps reel Depuis Linux 4.19, le controleur cpu de cgroups version 2 ne prend pas en charge le controle des threads en temps reel (particulierement les threads ordonnances sous les politiques SCHED_FIFO, SCHED_RR, SCHED_DEADLINE ; voir sched(7)). Par consequent, le controleur cpu ne peut etre active dans le cgroup racine seulement si tous les threads en temps reel sont dans le cgroup racine (si des threads en temps reel sont dans des cgroups non racines, alors une ecriture write(2) de la chaine << +cpu >> dans le fichier cgroup.subtree_control echoue avec l'erreur EINVAL). Dans certains systemes, systemd(1) place certains threads en temps reel dans des cgroups non racines dans la hierarchie version 2. Pour de tels systemes, ces threads doivent d'abord etre deplaces dans le cgroup racine avant que le controleur cpu ne soit active. ERREURS Les erreurs suivantes peuvent survenir pour mount(2) : EBUSY Un essai de monter un systeme de fichiers cgroup version 1 n'indiquait ni l'option name= (pour monter une hierarchie nommee) ni un nom de controleur (ou all). NOTES Un processus enfant cree a l'aide de fork(2) herite des appartenances de cgroup de son parent. Les appartenances de cgroup de processus sont preservees a travers execve(2). Le drapeau CLONE_INTO_CGROUP de clone3(2) peut etre utilise pour creer un processus enfant qui debute son existence dans un cgroup version 2 different du processus parent. Fichiers /proc /proc/cgroups (depuis Linux 2.6.24) Ce fichier contient des informations sur les controleurs qui sont compiles dans le noyau. Un exemple du contenu de ce fichier (reformate pour une meilleure lisibilite) est ce qui suit : #subsys_name hierarchy num_cgroups enabled cpuset 4 1 1 cpu 8 1 1 cpuacct 8 1 1 blkio 6 1 1 memory 3 1 1 devices 10 84 1 freezer 7 1 1 net_cls 9 1 1 perf_event 5 1 1 net_prio 9 1 1 hugetlb 0 1 0 pids 2 1 1 Les champs dans ce fichier sont de gauche a droite : [1] Le nom du controleur. [2] L'ID unique de la hierarchie de cgroup pour laquelle le controleur est monte. Si plusieurs controleurs de cgroups version 1 sont lies a la meme hierarchie, chacun d'entre eux affichera le meme ID de hierarchie dans ce champ. La valeur dans ce champ sera zero si : - le controleur n'est pas monte pour une hierarchie de cgroups version 1 ; - le controleur est lie a la seule hierarchie unifiee de cgroups version 2 ; - le controleur est desactive (voir ci-dessous). [3] Le nombre de groupes de controle dans cette hierarchie utilisant ce controleur. [4] Ce champ contient la valeur 1 si le controleur est active ou zero s'il a ete desactive (a l'aide du parametre cgroup_disable d'amorcage du noyau dans la ligne de commande). /proc/pid/cgroup (depuis Linux 2.6.24) Ce fichier decrit les groupes de controle auxquels le processus ayant le PID correspondant appartient. L'information affichee differe pour les hierarchies version 1 et version 2 de cgroups. Pour chaque hierarchie de cgroup dont le processus est membre, il existe une entree contenant trois champs separes par des deux-points : ID_hierarchie:liste_controleurs:chemin_cgroup Par exemple : 5:cpuacct,cpu,cpuset:/daemons De gauche a droite, ces trois champs separes par des deux-points sont : [1] Pour les hierarchies de cgroups version 1, ce champ contient un numero d'ID unique de hierarchie qui peut etre compare avec un ID de hierarchie dans /proc/cgroups. Pour les hierarchies de cgroups version 2, ce champ contient la valeur 0. [2] Pour les hierarchies de cgroups version 1, ce champ contient une liste separee par des virgules de controleurs lies a la hierarchie. Pour les hierarchies de cgroups version 2, ce champ est vide. [3] Ce champ contient le chemin du groupe de controle dans la hierarchie a laquelle le processus appartient. Ce chemin est relatif au point de montage de la hierarchie. Fichiers /sys/kernel/cgroup /sys/kernel/cgroup/delegate (depuis Linux 4.15) Ce fichier exporte une liste de fichiers cgroups version 2 (un par ligne) qui sont delegables (c'est-a-dire dont la propriete peut etre changee a l'ID utilisateur du delegue). Dans le futur, l'ensemble des fichiers delegables peut etre modifie ou grossir, et ce fichier fournit un moyen pour le noyau d'informer les applications en espace utilisateur quels fichiers doivent etre delegues. Depuis Linux 4.15, il est possible de voir ce qui suit lors de l'inspection de ce fichier : $ cat /sys/kernel/cgroup/delegate cgroup.procs cgroup.subtree_control cgroup.threads /sys/kernel/cgroup/features (depuis Linux 4.15) Avec le temps, l'ensemble de fonctionnalites de cgroups version 2 fournies par le noyau peut evoluer ou grossir, ou certaines fonctionnalites pourraient ne pas etre activees par defaut. Ce fichier fournit un moyen aux applications en espace utilisateur de decouvrir quelles fonctionnalites le noyau utilise gere et a d'activees. Les fonctionnalites sont listees, une par ligne : $ cat /sys/kernel/cgroup/features nsdelegate memory_localevents Les entrees pouvant apparaitre dans ce fichier sont : memory_localevents (depuis Linux 5.2) Le noyau gere l'option de montage memory_localevents. nsdelegate (depuis Linux 4.15) Le noyau gere l'option de montage nsdelegate. memory_recursiveprot (depuis Linux 5.7) Le noyau gere l'option de montage memory_recursiveprot. VOIR AUSSI prlimit(1), systemd(1), systemd-cgls(1), systemd-cgtop(1), clone(2), ioprio_set(2), perf_event_open(2), setrlimit(2), cgroup_namespaces(7), cpuset(7), namespaces(7), sched(7), user_namespaces(7) Le fichier des sources du noyau Documentation/admin-guide/cgroup-v2.rst. TRADUCTION La traduction francaise de cette page de manuel a ete creee par Christophe Blaess , Stephan Rafin , Thierry Vignaud , Francois Micaux, Alain Portal , Jean-Philippe Guerard , Jean-Luc Coulon (f5ibh) , Julien Cristau , Thomas Huriaux , Nicolas Francois , Florentin Duneau , Simon Paillard , Denis Barbier , David Prevot et Jean-Paul Guillonneau Cette traduction est une documentation libre ; veuillez vous reporter a la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITE LEGALE. Si vous decouvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message a . Pages du manuel de Linux 6.06 31 octobre 2023 cgroups(7)