Depuis l'agitation provoquée par le patch noyau de Mike Galbraith permettant une meilleure réactivité des applications desktop, beaucoup de gens semblent découvrir (ou redécouvrir) les Control Groups, ou plus simplement cgroups. Cet article a pour vocation de vous aider à mieux comprendre leur fonctionnement et à les utiliser efficacement sur votre système. Nous verrons ainsi pourquoi ce patch, maintenant inclus dans le noyau 2.6.38, ne présente pas la solution ultime aux problèmes de latences sous Linux.
Qu'est-ce qu'un cgroup ?
Un cgroup n'est rien de plus qu'un groupe de processus. Pourquoi faire ? Pour mieux les contrôler ! Par exemple, sur un serveur Web, l'administrateur peut vouloir s'assurer que les processus httpd, php et mysqld aient toujours la priorité sur les autres, afin que le serveur reste le plus réactif possible. Il suffit de regrouper ces 3 processus ensemble dans un cgroup, et de donner à celui-ci une priorité CPU élevée, ainsi que la priorité sur l'accès aux disques durs.
Les cgroups permettent de contrôler les processus d'une façon beaucoup plus complète et détaillée que les niveaux de priorité (nice) d'UNIX. Cela est dû au fait qu'il est possible d'associer un ou plusieurs contrôleurs à un cgroup :
- cpuset : allocation de resources CPU et mémoire vive
- cpuacct : permet de comptabiliser la consommation de cycle CPU
- memory : contrôle de la mémoire vive et du cache d'un groupe
- devices : autorise ou refuse l'accès à un périphérique
- net_cls : gère l'accès au réseau
- blkio : gère l'accès aux périphériques de type block (disque durs...)
Attention: ces contrôleurs ne sont pas forcement tous disponibles sur votre système. Tout dépend de la configuration du noyau. Vous pouvez obtenir la liste des contrôleurs disponibles avec un `cat /proc/cgroups`.
Utiliser les cgroups
Sans outil, l'utilisation des cgroups telle qu'indiquée dans la documentation du noyau est assez fastidieuse. Comme pour les autres fonctionnalités de Linux, tout se contrôle au moyen d'un système de fichiers. Il faut donc créer un point de montage, créer une arborescence avec les bons droits, et enfin remplir les fichiers avec les bonnes informations.
Heureusement, il existe des outils dédiés à cette tâche. Le projet libcg (http://libcg.sf.net) fournit une bibliothèque ainsi que des utilitaires pour gérer les cgroups. Nous avons le choix entre créer des groupes à la volée avec cgcreate, cgexec et cgclassify, ou bien les créer "en dur" au moyen d'un service système et de fichiers de configuration. Nous allons nous concentrer sur cette dernière méthode, vu que c'est elle qui est la plus susceptible de nous être utile dans la conception d'un système embarqué.
Commençons d'abord par installer les outils nécessaires. Sous Debian/Ubuntu, installez libcgroup et cgroup-bin qui contiennent respectivement la bibliothèque et les utilitaires. Sous Fedora, libcgroups suffit. Une fois installés, rendez-vous dans /etc et observons le fichier cgconfig.conf qui vient d'être créé. Ce fichier contient les déclarations de chaque cgroup, avec pour chacun, l'UID/GID de l'utilisateur capable de lancer des processus avec ce groupe, l'UID/GID de l'administrateur du groupe, et les propriétés de contrôle du groupe comme la limitation d'usage du CPU. Voici un exemple :
group hiperf { perm { task { uid = olivier; gid = olivier; } admin { uid = root; gid = root; } } cpu { cpu.shares = 1000; } blkio { blkio.weight = 500; } } mount { cpu = /dev/cgroups/cpu; cpuacct = /mnt/cgroups/cpuacct; blkio = /dev/cgroups/blkio; }
Notez la rubrique "mount". Celle-ci va créer un point de montage pour chaque contrôleur que nous souhaitons utiliser. Dans ce cas, si l'on avait utilisé le contrôleur net_cls dans le group hiperf, le fichier de configuration aurait été invalide puisque net_cls n'a pas de point de montage et est donc inutilisable.
Très bonne introduction au paramétrage des cgroup. Merci.