Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Linux
  3. Modules
Extrait - Linux Administration avancée - Maintenance et exploitation de vos serveurs (3e édition)
Extraits du livre
Linux Administration avancée - Maintenance et exploitation de vos serveurs (3e édition) Revenir à la page d'achat du livre

Modules

Introduction

Un module ou Loadable Kernel Module (LKM) en anglais est un morceau de code qui peut être chargé et déchargé dans le noyau Linux sur demande. Il apporte à ce dernier une fonctionnalité telle qu’un pilote de périphérique, un pare-feu (firewall), un protocole réseau, etc.

Les modules s’exécutent en mode kernel (anneau 0).

Le fait de créer une fonctionnalité en tant que module au lieu de l’intégrer au sein du noyau évite d’alourdir celui-ci. Il n’est pas nécessaire d’inclure dans le noyau du code que l’on n’utilise pas souvent, voire jamais.

Des tiers peuvent ainsi développer des modules qui sont fournis à part. L’administrateur peut les installer et ensuite les charger sans qu’il soit nécessaire de recompiler le noyau.

Compiler et installer un module

Un module est compilé pour une version précise du noyau Linux.

Si, durant la mise à jour de votre système, une nouvelle version du noyau est installée, alors tous les modules fournis par la distribution seront compilés de nouveau. Par contre, les modules que vous avez ajoutés personnellement ne seront pas recompilés. Vous devrez les recompiler manuellement.

1. Prérequis à la compilation

La compilation nécessite un ensemble d’outils tels que le compilateur gcc, l’utilitaire make...

a. Debian

Vous devez installer les paquets gcc, build-essential et les fichiers d’en-têtes (headers) du noyau :

root@system1:~# apt-get install gcc build-essential 
linux-headers-$(uname -r) 

b. Red Hat

Installez les outils de développement :

[root@system2 ~]# yum group install "Development tools" 

Installez aussi le paquet de développement du noyau qui correspond à la version de votre noyau. Utilisez la commande uname que nous avons vue dans le chapitre Architecture du système GNU/Linux pour l’identifier.

[root@system2 ~]# yum install kernel-devel-3.10.0-862.14.4.el7.x86_64 
Modules complémentaires chargés : fastestmirror, langpacks 
Loading mirror speeds from cached hostfile 
 * base: centos.mirror.fr.planethoster.net 
 * extras: centos.mirror.fr.planethoster.net 
 * updates: centos.mirror.fr.planethoster.net 
Résolution des dépendances 
--> Lancement de la transaction de test 
---> Le paquet kernel-devel.x86_64 0:3.10.0-862.14.4.el7 sera installé 
--> Résolution des dépendances terminée 
 
Dépendances résolues 
 
======================================================================= 
 Package        Architecture    Version                 Dépôt    Taille 
======================================================================= 
Installation : 
 kernel-devel ...

Charger un module

Le chargement d’un module s’effectue avec les commandes insmod ou modprobe. Mais commençons par l’installer.

1. Installer le module hello

Exécutez make install :

[root@system2 ~]# make install  
cp ./hello.ko* /lib/modules/3.10.0-862.14.4.el7.x86_64/kernel/drivers/misc 

Le fichier hello.ko ou hello.ko.xz est alors copié dans le dossier /lib/modules/$(uname -r)/kernel/drivers/misc :

[root@system2 ~]# ls /lib/modules/$(uname -r)/kernel/drivers/misc/hello* 
/lib/modules/3.10.0-862.14.4.el7.x86_64/kernel/drivers/misc/hello.ko.xz 

2. insmod

La commande insmod accepte n’importe quel emplacement du module, lequel n’a pas besoin de résider dans le répertoire /lib/modules/$(uname-r). Cependant, les dépendances ne sont pas chargées automatiquement.

Utilisé par modprobe, c’est un programme de bas niveau pour charger les modules. 

Syntaxe

insmod <nom_du_module_à_charger> 

Charger le module hello.ko.xz

[root@system2 ~]# insmod /lib/modules/$(uname -r)/kernel/drivers/
misc/hello.ko.xz 

3. Gérer les dépendances

Le fichier modules.dep contient la liste des dépendances de chargement de chaque module qui est utilisé par modprobe.

Utilisez la commande depmod lorsqu’un changement sur les modules survient pour s’assurer que toutes les dépendances soient chargées. Elle reconstruit le fichier...

Décharger un module

rmmod décharge un module du noyau si aucun processus ne l’utilise. Si c’était le cas, ajoutez le commutateur -w (ou --wait). Ainsi, le processus est isolé en attendant qu’il ne soit plus utilisé puis il sera déchargé.

Syntaxe

rmmod <option> <nom_du_module_à_décharger> 

Options utiles :

Option

Description

courte

longue

-f

--force

Force le déchargement du module.

-w

--wait

Isole le module et attend que le module ne soit plus utilisé.

modprobe peut décharger un module de la même façon que rmmod.

Syntaxe

modprobe <options> <nom_du_module_à_décharger> 

Options nécessaires :

Option

Description

courte

longue

-r

--remove

Décharge le module mentionné.

-v

--verbose

Mode verbeux.

Décharger le module hello

[root@system2 ~]# rmmod hello 

ou bien :

[root@system2 ~]# modprobe -rv hello  
rmmod hello 

Vérifiez avec lsmod et grep que le module est bien déchargé :

[root@system2 ~]# lsmod |grep hello 

Consultez le journal /var/log/messages pour Debian et CentOS :

[root@system2 ~]# cat /var/log/messages 
*** sortie tronquée ***  
 
Nov 20 22:08:49 system2 nm-dispatcher: req:1 'dhcp4-change'  
[enp0s8]: start running ordered scripts... 
Nov 20 22:09:05 system2 kernel: [Hello world] - La fonction  
cleanup_module()...

Lister les modules

1. Lister tous les modules disponibles

Pour répertorier les modules disponibles, le commutateur -l de la commande modprobe, n’existe plus.

Il faut alors parcourir avec find le dossier /lib/modules/$(uname -r) et répertorier les fichiers dont l’extension est .ko. awk va permettre d’afficher uniquement le nom du fichier :

[root@system2 ~]# find /lib/modules/$(uname -r) -name '*.ko*' |  
awk -F "/" '{print $NF}' | sort  
3w-9xxx.ko.xz 
3w-sas.ko.xz 
6lowpan.ko.xz 
8021q.ko.xz 
8139cp.ko.xz 
8139too.ko.xz 
a8293.ko.xz 
aacraid.ko.xz 
abituguru3.ko.xz 
abituguru.ko.xz 
ablk_helper.ko.xz 
ac97_bus.ko.xz 
acard-ahci.ko.xz 
acecad.ko.xz  
*** sortie tronquée *** 

2. Lister les modules chargés

lsmod affiche des modules chargés. Les informations sont issues du fichier /proc/modules :

[root@system2 ~]# lsmod  
hello                  12426  0  
binfmt_misc            17468  1  
nls_utf8               12557  1  
isofs                  39844  1  
ip6t_rpfilter          12595  1  
ipt_REJECT             12541 ...

Obtenir des informations

modinfo affiche les informations d’un module telles que le nom du fichier et son emplacement, sa licence, une description, le ou les auteurs, les dépendances et sa version.

Syntaxe

modinfo <nom_du_module> 

Les informations du module ext3

Vous constatez, par la même occasion, que ext3 est en fait un alias de ext4.

[root@system2 ~]# modinfo ext3 
filename: /lib/modules/3.10.0-862.14.4.el7.x86_64/kernel/fs/ext4/
ext4.ko.xz 
license:      GPL 
description:  Fourth Extended Filesystem 
author:       Remy Card, Stephen Tweedie, Andrew Morton, 
Andreas Dilger, Theodore Ts'o and others 
alias:        fs-ext4 
alias:        ext3 
alias:        fs-ext3 
alias:        ext2 
alias:        fs-ext2 
retpoline:    Y 
rhelversion:  7.5 
srcversion:   8BDF72C8A0EF1E5EA5D28E7 
depends:      mbcache,jbd2 
intree:       Y 
vermagic:     3.10.0-862.14.4.el7.x86_64 SMP mod_unload modversions 
signer:       CentOS Linux kernel signing key 
sig_key:      E4:A1:B6:8F:46:8A:CA:5C:22:84:50:53:18:FD:9D:AD:72:4B:13:03 
sig_hashalgo: sha256 

Les dépendances peuvent être affichées également avec modprobe.

Syntaxe...

Bloquer un module

Pour des soucis de stabilité, de compatibilité avec d’autres programmes ou pour toute autre raison, un module peut être bloqué ou « blacklisté ».

Vous avez la possibilité de créer votre propre fichier pour bloquer les modules que vous souhaitez dans le dossier /etc/modprobe.d. Il est conseillé de le nommer de façon explicite et il doit porter l’extension .conf.

Le dossier /etc/modprobe.d n’a pas le même contenu par défaut d’une distribution à l’autre. Le contenu de celui-ci dans Debian 9 est vide contrairement à RHEL 7 :

[root@system2 ~]# ls -1 /etc/modprobe.d/ 
dccp-blacklist.conf 
firewalld-sysctls.conf 
tuned.conf 

La syntaxe de ce dernier est blacklist <nom-du-pilote> comme par exemple : blacklist dccp.

Bloquer le module hello

Créez un fichier blacklist-hello.conf dans le dossier /etc/modprobe.d/ :

# Bloquer le module de noyau hello  
blacklist hello 

Journaux système

Lorsque le système d’exploitation est amorcé, le noyau Linux est chargé en mémoire. Chaque pilote de périphérique chargé fait une tentative de détection du matériel concerné. Si l’opération est réussie alors un message de diagnostic détaille ce qu’il a trouvé.

Vous pouvez consulter, par l’intermédiaire de la commande journalctl qui remplace dmesg les messages du buffer (mémoire tampon) du noyau.

Syntaxe

journalctl <option> 

Option :

Option

Description

courte

longue

-k

--desmg

Afficher uniquement les messages du noyau.

Exemple

[root@system2 ~]# journalctl -k 
-- Logs begin at mar. 2018-11-20 18:52:41 CET, end at 
mar. 2018-11-20 23:20:01 CET. - 
nov. 20 18:52:41 system2.staff.local kernel: Initializing 
cgroup subsys cpuset 
nov. 20 18:52:41 system2.staff.local kernel: Initializing 
cgroup subsys cpu  
nov. 20 18:52:41 system2.staff.local kernel: Initializing 
cgroup subsys cpuacct 
*** sortie tronquée *** 

Il est à noter que la commande dmesg et son fichier /var/log/dmesg sont encore présents pour assurer la compatibilité antérieure. Ils pourraient bien disparaître dans la version RHEL 8.

Recherche d’informations sur une carte réseau Intel

[root@system2 ~]# journalctl -k |grep e1000 
nov. 20 18:52:41 system2.staff.local kernel:...

Exercice

1. Créez un répertoire LKM dans votre répertoire de base et entrez dans celui-ci.

2. Écrivez le code suivant :

#include <linux/module.h> 
#include <linux/kernel.h> 
 
MODULE_LICENSE("GPL");  
MODULE_AUTHOR("John Doe");  
MODULE_DESCRIPTION("Module hello world");  
MODULE_VERSION("Version 1.00");  
 
int init_module(void)  
{  
     printk(KERN_INFO "[Hello world] - La fonction init_module() 
est appelée.\n"); 
     return 0;  
}  
 
void cleanup_module(void)  
{  
     printk(KERN_INFO "[Hello world] - La fonction 
cleanup_module() est appelée.\n");  
} 

3. Écrivez le fichier Makefile :

obj-m += hello.o  
  
all:  
     make -C /lib/modules/$(shell uname -r)/build M=$(PWD)   
modules  
  
clean:  
     make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean 
  
install:  
     cp ./hello.ko /lib/modules/$(shell uname   
-r)/kernel/drivers/misc 

4. Compilez puis installez.

5. Chargez le module automatiquement au démarrage du système.

6. Vérifiez le chargement après...