Empaquetage d’un module tierce pour Debian avec DKMS

Vincent Bernat

DKMS est un système conçu pour permettre la mise à jour individuelle de modules noyau sans changer le noyau en entier. Il est également très facile de reconstruire des modules lorsque vous mettez à jour le noyau.

Sur les systèmes de type Debian1, DKMS permet l’installation de différents pilotes, de ZFS aux modules VirtualBox ou NVIDIA. Ces modules externes ne sont pas distribués sous forme binaire : une fois installés, ils doivent être compilés pour votre noyau actuel. Tout se fait automatiquement :

# apt install zfs-dkms
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  binutils cpp cpp-6 dkms fakeroot gcc gcc-6 gcc-6-base libasan3 libatomic1 libc-dev-bin libc6-dev
  libcc1-0 libcilkrts5 libfakeroot libgcc-6-dev libgcc1 libgomp1 libisl15 libitm1 liblsan0 libmpc3
  libmpfr4 libmpx2 libnvpair1linux libquadmath0 libstdc++6 libtsan0 libubsan0 libuutil1linux libzfs2linux
  libzpool2linux linux-compiler-gcc-6-x86 linux-headers-4.9.0-6-amd64 linux-headers-4.9.0-6-common
  linux-headers-amd64 linux-kbuild-4.9 linux-libc-dev make manpages manpages-dev patch spl spl-dkms
  zfs-zed zfsutils-linux
[…]
3 upgraded, 44 newly installed, 0 to remove and 3 not upgraded.
Need to get 42.1 MB of archives.
After this operation, 187 MB of additional disk space will be used.
Do you want to continue? [Y/n]
[…]
# dkms status
spl, 0.6.5.9, 4.9.0-6-amd64, x86_64: installed
zfs, 0.6.5.9, 4.9.0-6-amd64, x86_64: installed
# modinfo zfs | head
filename:       /lib/modules/4.9.0-6-amd64/updates/dkms/zfs.ko
version:        0.6.5.9-5
license:        CDDL
author:         OpenZFS on Linux
description:    ZFS
srcversion:     42C4AB70887EA26A9970936
depends:        spl,znvpair,zcommon,zunicode,zavl
retpoline:      Y
vermagic:       4.9.0-6-amd64 SMP mod_unload modversions
parm:           zvol_inhibit_dev:Do not create zvol device nodes (uint)

Lors de l’installation d’un nouveau noyau, la compilation du module est automatiquement déclenchée.

Construction d’un paquet compatible DKMS#

Supposons que vous avez mis la main sur un serveur avec une carte réseau Intel XXV710-DA2. Cette carte est gérée par le pilote i40e. Malheureusement, elle n’est prise en charge que depuis Linux 4.10 et vous utilisez un noyau 4.9 issu de Debian Stretch. DKMS fournit ici une solution simple !

Téléchargez les sources du pilote chez Intel, décompressez-les dans un répertoire et ajoutez un sous-répertoire debian/ avec les fichiers suivants :

  • debian/changelog:

    i40e-dkms (2.4.6-0) stretch; urgency=medium
    
      * Initial package.
    
     -- Vincent Bernat <bernat@debian.org>  Tue, 27 Feb 2018 17:20:58 +0100
    
  • debian/control:

    Source: i40e-dkms
    Maintainer: Vincent Bernat <bernat@debian.org>
    Build-Depends: debhelper (>= 9), dkms
    
    Package: i40e-dkms
    Architecture: all
    Depends: ${misc:Depends}
    Description: DKMS source for the Intel i40e network driver
    
  • debian/rules:

    #!/usr/bin/make -f
    
    include /usr/share/dpkg/pkg-info.mk
    
    %:
            dh $@ --with dkms
    
    override_dh_install:
            dh_install src/* usr/src/i40e-$(DEB_VERSION_UPSTREAM)/
    
    override_dh_dkms:
            dh_dkms -V $(DEB_VERSION_UPSTREAM)
    
    override_dh_auto_configure:
    override_dh_auto_build:
    override_dh_auto_test:
    override_dh_auto_install:
    override_dh_auto_clean:
    
  • debian/i40e-dkms.dkms:

    PACKAGE_NAME="i40e"
    PACKAGE_VERSION="#MODULE_VERSION#"
    BUILT_MODULE_NAME[0]="$PACKAGE_NAME"
    DEST_MODULE_LOCATION[0]="/updates/dkms"
    AUTOINSTALL="YES"
    REMAKE_INITRD="YES"
    
  • debian/compat:

    9
    

Le fichier debian/changelog permet essentiellement de spécifier la version du paquet. Celle du pilote est 2.4.6. Par conséquent, nous utilisons 2.4.6-0 comme version de paquet. Dans debian/rules, nous copions les sources du pilote dans /usr/src/i40e-2.4.6 (la version est extraite de debian/changelog).

Le contenu de debian/i40e-dkms.dkms est décrit en détail dans la page de manuel dkms(8). Le pilote i40e est assez standard et dkms sait comment le compiler. Cependant, si un module noyau ne suit pas les conventions habituelles, c’est le bon endroit pour remplacer la commande de construction.

Une fois tous les fichiers en place, vous pouvez transformer le répertoire en un paquet Debian à l’aide, par exemple, de la commande dpkg-buildpackage command2. Vous obtenez un paquet compatible DKMS : i40e-dkms_2.4.6-0_all.deb. Placez le dans votre dépôt interne et installez-le sur le serveur cible.

Éviter la phase de compilation#

Mise à jour (03.2024)

Les mainteneurs de DKMS ont supprimé la commande dkms mkbmdeb, rendant cette partie de l’article non pertinente. Cela concerne les versions à partir de la 2.8.8, y compris celles fournies dans Debian Bookworm et Ubuntu Noble. Voir le bug Debian #1009179 pour plus d’informations.

Si la présence d’outils de développement sur un serveur en production vous rend nerveux, il y a une solution ! Depuis la version 2.2.0.3-53, grâce à Thijs Kinkhorst, dkms peut construire des paquets contenant uniquement les modules précompilés. Pour chaque version du noyau, un tel paquet peut être construit via votre système d’intégration :

KERNEL_VERSION=4.9.0-6-amd64 # could be a Jenkins parameter
apt -qyy install \
      i40e-dkms \
      linux-image-${KERNEL_VERSION} \
      linux-headers-${KERNEL_VERSION}

DRIVER_VERSION=$(dkms status i40e | awk -F', ' '{print $2}')
dkms mkbmdeb i40e/${DRIVER_VERSION} -k ${KERNEL_VERSION}

cd /var/lib/dkms/i40e/${DRIVER_VERSION}/bmdeb/
dpkg -c i40e-modules-${KERNEL_VERSION}_*
dpkg -I i40e-modules-${KERNEL_VERSION}_*

Voici la sortie abbrégée des deux dernières commandes :

# dpkg -c i40e-modules-${KERNEL_VERSION}_*
[…]
-rw-r--r-- root/root    551664 2018-03-01 19:16 ./lib/modules/4.9.0-6-amd64/updates/dkms/i40e.ko
[…]
# dpkg -I i40e-modules-${KERNEL_VERSION}_*
 new debian package, version 2.0.
[…]
 Package: i40e-modules-4.9.0-6-amd64
 Source: i40e-dkms-bin
 Version: 2.4.6
 Architecture: amd64
 Installed-Size: 555
 Depends: linux-image-4.9.0-6-amd64
 Provides: i40e-modules
 Section: misc
 Priority: optional
 Description: i40e binary drivers for linux-image-4.9.0-6-amd64
  This package contains i40e drivers for the 4.9.0-6-amd64 Linux kernel,
  built from i40e-dkms for the amd64 architecture.

Le paquet Debian ainsi créé contient le pilote précompilé et ne dépend que du noyau associé. Vous pouvez l’installer sans tirer des dizaines de dépendances supplémentaires.


  1. DKMS est également compatible avec les distributions à base de RPM mais le contenu de cet article ne s’applique pas à celles-ci. ↩︎

  2. Quelques paquets additionels sont nécessaires : build-essential, fakeroot et debhelper↩︎

  3. Disponible pour Debian Stretch ainsi que pour Debian Jessie, via un rétroportage. Toutefois, la version dans Ubuntu Xenial est trop ancienne. ↩︎