TIP Charger des modules différents pour chaque noyau

Un article de Gentoo Linux Wiki.

Cet article fait partie des Trucs et Astuces.

Terminaux / Shells CD Live X Portage Système Systèmes de fichier Autres


Certaines parties du noyau Linux peuvent être compilées sous forme de modules. Ces modules doivent être ensuite chargés afin d'accéder aux fonctionnalités qu'ils proposent. Le service /etc/init.d/modules permet de charger automatiquement certains de ces modules au démarrage, affranchissant ainsi l'administrateur de le faire manuellement à chaque redémarrage.

Cependant, il est des cas où les modules à charger sont différents selon le noyau sur lequel le système démarre. Le service /etc/init.d/modules distingue les noyaux 2.4 des noyaux 2.6 et offre de spécifier une liste différente pour chacune de ces version. Ceci est largement suffisant pour un système simple mais la situation se complique lorsque le système possède plusieurs noyaux d'une même version.

L'objet de cette astuce est de modifier le service /etc/init.d/modules pour qu'il affine sa distinction entre les noyaux et permette de spécifier, pour chacun d'eux, une liste différente de modules à charger, tout en gardant une totale compatibilité avec le mode de fonctionnement actuel.


Isolement du problème

Pour ceux qui ne sont pas sûr de la manière dont fonctionne le service /etc/init.d/modules, c'est très simple : il regarde quelle est la version du kernel en cours de fonctionnement à l'aide de la commande uname et charge les modules indiqués dans le fichier /etc/modules.autoload.d/kernel-VERSION.

La limitation de ce script vient du fait qu'il ne fait pas une distinction très détaillée entre les noyaux : tout au plus, il va différencier un 2.4 d'un 2.6. Ça serait quand même bien pratique qu'il puisse faire la différence entre :

  • un 2.4.22 et un 2.4.24
  • un 2.4.22-gentoo et un 2.4.22-ck
  • un 2.4.22-gentoo-r6 et un 2.4.22-gentoo-r7
  • un 2.4.22-gentoo-r6 #1 et un 2.4.22-gentoo-r6 #3

Dans le dernier exemple, le premier noyau correspond à la première compilation (#1) tandis que le deuxième correspond à la troisième (#3). On peut connaître le numéro de compilation en faisant : uname -rv.


Explication de la solution

J'ai donc modifié un peu le script /etc/init.d/modules pour qu'il prenne en compte ces différences, à chaque niveau.

Ainsi, le fichier /etc/modules.autoload.d/kernel-2.4.22-gentoo-r6#3 listera les modules à charger pour le noyau du même nom. Pour simplifier la tâche, le script prévoit qu'on ne soit pas forcément obligé de nommer ce fichier de manière aussi précise. On peut se limiter à /etc/modules.autoload.d/kernel-2.4.22 par exemple, auquel cas la liste des modules qu'il contient sera chargée pour tous les noyau 2.4.22 qui n'ont pas leur propre fichier. En fait, on peut choisir le niveau de détection : depuis 2.4 jusqu'à 2.4.22-gentoo-r7#1 (voir les exemples plus haut).


Le patch en question

Fichier : modules.patch
--- ./modules   2004-03-18 23:31:29.000000000 +0000
+++ /etc/init.d/modules 2004-03-18 23:48:50.000000000 +0000
@@ -92,25 +92,28 @@
        if [ -f /etc/modules.autoload -a ! -L /etc/modules.autoload ]
        then
                # Loop over every line in /etc/modules.autoload.
+               #
                load_modules /etc/modules.autoload
        else
-               local KV="$(uname -r)"
-               local KV_MAJOR="`KV_major "${KV}"`"
-               local KV_MINOR="`KV_minor "${KV}"`"
-
                # New support for /etc/modules.autoload/kernel-$KV
-               if [ "$(get_KV)" -ge "$(KV_to_int '2.5.48')" ] && \
-                  [ -f /etc/modules.autoload.d/kernel-"${KV_MAJOR}.${KV_MINOR}" ]
-               then
-                       load_modules /etc/modules.autoload.d/kernel-"${KV_MAJOR}.${KV_MINOR}"
+
+               local KV=kernel-$(uname -rv | awk '{gsub("[.\\-#]","?"); print $1$2}')
+
+                while [ ! $(ls /etc/modules.autoload.d/${KV} 2>/dev/null) ]
+               do
+                       KV_reduced=$(echo ${KV} | awk '{sub("\\?[^\\?]*$",""); print}')
+
+                       if [ ${KV_reduced} == ${KV} ]
+                       then
+                               KV=$(ls -1 /etc/modules.autoload.d/ | awk '{if(!drop)print;drop++}')
+                               ewarn "Missing /etc/modules.autoload.d/kernel-VERSION"
+                                break
+                       fi
 
-               elif [ ! -f /etc/modules.autoload.d/kernel-"${KV_MAJOR}.${KV_MINOR}" ]
-               then
-                       ewarn "Missing /etc/modules.autoload.d/kernel-${KV_MAJOR}.${KV_MINOR}"
-                       load_modules /etc/modules.autoload.d/kernel-2.4
-               else
-                       load_modules /etc/modules.autoload.d/kernel-2.4
-               fi
+                       KV=${KV_reduced}
+               done
+
+                [ ${KV} ] && load_modules $(ls /etc/modules.autoload.d/${KV})
        fi
 
        #

Vous trouverez également, dans le premier message du fil de discussion d'où proviennent ces informations, le code commenté du patch dans sa première version (celle donnée ici en est la seconde version).

De plus, ce sujet a fait l'objet d'un rapport de bug auprès de l'équipe de développement de Gentoo. Deux autres contributeurs y ont proposé différentes manières de résoudre le problème. Ce bug est toujours ouvert pour l'instant, ce qui signifie que l'équipe de développement n'est pas encore prête à intégrer cette solution aux releases officielles. Ce rapport de bug est disponible à cette adresse: http://bugs.gentoo.org/show_bug.cgi?id=35872


MAJ : 19/03/2004
Source : http://forums.gentoo.org/viewtopic.php?t=149836
Auteur initial : Yaubi