Suppression automatique de modules non utilisés avec un noyau 2.6.

Depuis la sortie du noyau 2.6, l’option autoclean de rmmod (rmmod -a) qui permettait de supprimer facilement de la mémoire les modules du noyau non utilisés n’est plus disponible.

Cet article donne une façon de rétablir une telle fonctionnalité.

Avertissement: Si cette possibilité a disparu du noyau 2.6, c’est pour une très bonne raison. La suppression de certains modules n’est pas conseillée et est susceptible de rendre un système instable, voire même de le planter. Même si cette fonctionnalité était disponible avec les noyaux 2.4.x, elle était tout aussi dangereuse.

Le contexte.

Il m’arrive de temps en temps de lire des disquettes ou des CD-ROM. Je trouve très dommage d’encombrer en permanence la mémoire de ma machine avec des drivers rarement utilisés, surtout quand la machine dispose de très peu de mémoire.

D’où l’idée de compiler en module les drivers du lecteur de disquettes, du lecteur de CDROM et les systèmes de fichier iso 9660, ext2 et fat et de les charger en mémoire seulement quand c’est nécessaire.

Le chargement automatique de ces modules lorsqu’on monte une disquette ou un CDROM n’a posé aucun problème, mais une fois qu’on en a fini avec eux, les modules restent en mémoire si on ne les supprime pas manuellement.

Une solution.

Tout d’abord, le noyau doit être compilé avec les options nécessaires:

– Le système de fichier /proc (CONFIG_PROC_FS).
– L’option permettant de supprimer des modules pour les noyaux 2.6 uniquement (CONFIG_MODULE_UNLOAD).
Par défaut, cette dernière option n’est pas compilée.

Pour détecter et décharger les modules inutiles, j’ai écrit un script bash (appelé autoclean). Il recherche dans /proc/modules les modules dont le compteur d’utilisation est à zéro puis les supprime avec rmmod.

Certains drivers ne mettent pas ce compteur à jour lorsqu’ils sont compilés sous forme de modules. C’est notamment le cas de certains drivers de souris ou de clavier (comment décider si le driver d’une souris est utilisé ?). De tels modules risquent donc d’être supprimés alors qu’ils sont utilisés et nécessaires à la bonne marche du système.

Afin d’éviter ce genre de problèmes, j’ai prévu d’utiliser un fichier de configuration (/usr/local/etc/autoclean.conf). Le script vérifie que les modules dont le compteur est à zéro ne sont pas présents dans ce fichier avant de les supprimer. Ce fichier, dont les lignes commençant par un # sont ignorées, n’a pas de format particulier.

Voici le source de ce script:


#!/bin/bash

EXCLUDE=/usr/local/etc/autoclean.conf

cat /proc/modules | egrep "[[:space:]]0[[:space:]]" |
while read MODULE NOT_USED; do
if ! (sed -e "/^#/d" $EXCLUDE | grep "<$MODULE>") &> /dev/null ; then
/sbin/rmmod $MODULE
fi
done

exit 0

Pour une suppression automatique des modules, il suffit d’ajouter un appel à ce script dans une cron table. Par exemple, dans ma cron table root, j’ai ajouté la directive suivante:


*/15 * * * * /usr/local/sbin/autoclean

Cette directive lance une recherche et une suppression des modules non utilisés toutes les 15 minutes.

Conclusion.

Cette méthode s’est montrée très fiable chez moi et m’a permis de réduire de façon substancielle l’empreinte mémoire de mon noyau sans sacrifier la moindre fonctionnalité.

Cependant, il faut rester très prudent avec la suppression des modules. Certains modules ne doivent pas être supprimés du tout et d’autres ne peuvent pas l’être par cette méthode car il n’y a aucun moyen fiable de savoir quand ils sont utilisés et quand ils ne le sont pas.