Compilation d’un pilote additionnel pour ESXi 5.0

Lors du montage de ma white box ESXi 5.0, j’ai voulu essayer d’utiliser un contrôleur SIL 3124 pour ajouter 4 ports SATA en passthrough. Mon idée originelle était de déléguer ce contrôleur (non supporté en natif par ESXi) à une VM OpenIndiana (OpenSolaris). Cependant dès que je rajoute la carte SATA dans le PC, la fonctionnalité direct IO d’ESXi est désactivée…

Je me suis alors demandé si cela venait du fait que le contrôleur n’était pas reconnu par ESXi. J’ai donc voulu rajouter un driver pour voir ce qu’il en était.

Trouver des drivers pour votre white box ESXi

Une bonne source pour trouver les drivers manquants à ESXi est http://www.vm-help.com, et plus particulièrement le forum.
Cependant dans mon cas, le driver pour le SIL 3124 n’existe pour ESXi 4 et n’est pas compatible avec ESXi 5 (à cause de symboles manquants). Voir ce topic

Compiler les drivers d’ESXi 5.0

ESXi n’est pas basé sur le noyau Linux. Il dispose cependant d’un module lui permettant d’utiliser les pilotes de ce dernier.
VMWare a recemment mis à disposition du public les sources de ces pilotes: VMware-esx-public-source-5.0.0-434156.tar.gz.

Pour compiler un module ESXi, j’ai utilisé une VM CentOS 5.8, avec les packages de développement (gcc, binutils, etc.) dont les versions sont compatibles avec ESXi 5.0.

Il suffit alors d’extraire le fichier vmkdrivers-gpl.tgz planqué au fin fond de l’archive téléchargée sur le site VMWare (VMware-esx-public-source-5.0.0-434156.tar.gz\\build\mts\release\bora-460350\publish\VMware-esx-public-source-5.0.0-434156.tar\vmkdrivers-gpl.tgz\\build\mts\release\bora-460350\rm-rd-tools\osspkg\build\workingarea\esx\vmkdrivers-gpl.tgz).

Une fois cette archive décompressée dans un répertoire de travail, il suffit d’éditer le fichier build-vmkdrivers.sh en indiquant les paths vers gcc et LD dans les variables appropriées:

#!/bin/sh
# Use gcc version 4.1.2-9
# Below is the internal VMWare location.  Please change as required for your
# installed location.
CC=/usr/bin/gcc

# Use ld from binutils-2.17.50.0.15-modcall
# Below is the internal VMWare location.  Please change as required for your
# installed location.
LD=/usr/bin/ld
...

Il suffit alors d’exécuter le script qui devrait compiler les modules inclus dans ESXi (avec un certain nombre de warnings de compilation).

Ajouter un driver

Pour compiler le pilote pour le chipset SIL 3124, il faut récupérer son code source depuis les sources du noyau linux (2.6.25 dans mon cas): sata_sil24.c.
Le plus simple est ensuite de créer une copie du script de compilation ne comprenant que notre nouveau pilote:

build-vmkdrivers2.sh 
#!/bin/sh

# Use gcc version 4.1.2-9
# Below is the internal VMWare location.  Please change as required for your
# installed location.
CC=/build/toolchain/lin32/gcc-4.1.2-9/bin/x86_64-linux-gcc
CC=/usr/bin/gcc

# Use ld from binutils-2.17.50.0.15-modcall
# Below is the internal VMWare location.  Please change as required for your
# installed location.
LD=/build/toolchain/lin32/binutils-2.17.50.0.15-modcall/bin/x86_64-linux-ld
LD=/usr/bin/ld

# Use GNU grep 2.5.1
GREP=grep
# Use GNU sed 4.5.1
SED=sed
# Use GNU xargs 4.2.27
XARGS=xargs
# Use mkdir from GNU coreutils 5.97
MKDIR=mkdir

# Create output directories
$GREP -v -e "SED" build-vmkdrivers2.sh \
| $GREP -o -e "-o [^ ]*\."            \
| $SED -e 's?-o \(.*\)/[^/]*\.?\1?'   \
| $GREP -v -e "\*"                    \
| $XARGS $MKDIR -p

# Compiler flags assume being compiled natively on a x86-64 machine
$CC -fwrapv -fno-working-directory -g -ggdb3 -O2 -fno-strict-aliasing -Wall -Werror -Wstrict-prototypes -fPIE -falign-functions=4 -falign-jumps=4 -falign-loops=4 -ffreestanding -fno-common -fno-omit-frame-pointer -fno-strength-reduce -march=x86-64 -mcmodel=small -minline-all-stringops -mno-red-zone -nostartfiles -nostdlib --sysroot=/nowhere -Wall -Wdeclaration-after-statement -Wno-unused-value -Wno-pointer-sign -Wno-strict-prototypes -Wno-declaration-after-statement -Wno-declaration-after-statement -DCONFIG_COMPAT -DCPU=x86-64 -DDEBUG_STUB -DEXPORT_SYMTAB -DGPLED_CODE -DKBUILD_MODNAME=\"sata_sil24\" -DLINUX_MODULE_AUX_HEAP_NAME=vmklnx_sata_sil24 -DLINUX_MODULE_HEAP_INITIAL=64*1024 -DLINUX_MODULE_HEAP_MAX=8*1024*1024 -DLINUX_MODULE_HEAP_NAME=vmklnx_sata_sil24 -DLINUX_MODULE_VERSION=\"1.1\" -DMODULE -DVMKERNEL_MODULE -DVMK_DEVKIT_HAS_API_VMKAPI_BASE -DVMK_DEVKIT_HAS_API_VMKAPI_DEVICE -DVMK_DEVKIT_HAS_API_VMKAPI_ISCSI -DVMK_DEVKIT_HAS_API_VMKAPI_NET -DVMK_DEVKIT_HAS_API_VMKAPI_SCSI -DVMK_DEVKIT_IS_DDK -DVMK_DEVKIT_USES_BINARY_COMPATIBLE_APIS -DVMK_DEVKIT_USES_PUBLIC_APIS -DVMNIX -DVMX86_RELEASE -DVMX86_SERVER -DVMX86_VPROBES -D_LINUX -D_VMKDRVEI -D__KERNEL__ -D__VMKERNEL_MODULE__ -D__VMKERNEL__ -D__VMKLNX__ -D__VMK_GCC_BUG_ALIGNMENT_PADDING__ -D__VMWARE__ -Ivmkdrivers/src_9/drivers/ata -IBLD/build/version -IBLD/build/HEADERS/vmkdrivers-vmkernel/vmkernel64/release -Ivmkdrivers/src_9/include -Ivmkdrivers/src_9/include/vmklinux_9 -IBLD/build/HEADERS/CUR-9-vmkdrivers-asm-x64/vmkernel64/release -IBLD/build/HEADERS/vmkapi-current-all-public-bincomp/vmkernel64/release -IBLD/build/HEADERS/CUR-9-vmkdrivers-namespace/vmkernel64/release/sata_sil24 -include bora/vmkernel/distribute/push-hidden.h -include vmkdrivers/src_9/include/linux/autoconf.h -c -o BLD/build/vmkdriver-sata_sil24-CUR/release/vmkernel64/SUBDIRS/vmkdrivers/src_9/drivers/ata/sata_sil24.o vmkdrivers/src_9/drivers/ata/sata_sil24.c
$CC -fwrapv -fno-working-directory -g -ggdb3 -O2 -fno-strict-aliasing -Wall -Werror -Wstrict-prototypes -fPIE -falign-functions=4 -falign-jumps=4 -falign-loops=4 -ffreestanding -fno-common -fno-omit-frame-pointer -fno-strength-reduce -march=x86-64 -mcmodel=small -minline-all-stringops -mno-red-zone -nostartfiles -nostdlib --sysroot=/nowhere -Wall -Wdeclaration-after-statement -Wno-unused-value -Wno-pointer-sign -Wno-strict-prototypes -Wno-declaration-after-statement -Wno-declaration-after-statement -DCONFIG_COMPAT -DCPU=x86-64 -DDEBUG_STUB -DEXPORT_SYMTAB -DGPLED_CODE -DKBUILD_MODNAME=\"sata_sil24\" -DLINUX_MODULE_AUX_HEAP_NAME=vmklnx_sata_sil24 -DLINUX_MODULE_HEAP_INITIAL=64*1024 -DLINUX_MODULE_HEAP_MAX=8*1024*1024 -DLINUX_MODULE_HEAP_NAME=vmklnx_sata_sil24 -DLINUX_MODULE_VERSION=\"1.1\" -DMODULE -DVMKERNEL_MODULE -DVMK_DEVKIT_HAS_API_VMKAPI_BASE -DVMK_DEVKIT_HAS_API_VMKAPI_DEVICE -DVMK_DEVKIT_HAS_API_VMKAPI_ISCSI -DVMK_DEVKIT_HAS_API_VMKAPI_NET -DVMK_DEVKIT_HAS_API_VMKAPI_SCSI -DVMK_DEVKIT_IS_DDK -DVMK_DEVKIT_USES_BINARY_COMPATIBLE_APIS -DVMK_DEVKIT_USES_PUBLIC_APIS -DVMNIX -DVMX86_RELEASE -DVMX86_SERVER -DVMX86_VPROBES -D_LINUX -D_VMKDRVEI -D__KERNEL__ -D__VMKERNEL_MODULE__ -D__VMKERNEL__ -D__VMKLNX__ -D__VMK_GCC_BUG_ALIGNMENT_PADDING__ -D__VMWARE__ -Ivmkdrivers/src_9/drivers/ata -IBLD/build/version -IBLD/build/HEADERS/vmkdrivers-vmkernel/vmkernel64/release -Ivmkdrivers/src_9/include -Ivmkdrivers/src_9/include/vmklinux_9 -IBLD/build/HEADERS/CUR-9-vmkdrivers-asm-x64/vmkernel64/release -IBLD/build/HEADERS/vmkapi-current-all-public-bincomp/vmkernel64/release -IBLD/build/HEADERS/CUR-9-vmkdrivers-namespace/vmkernel64/release/sata_sil24 -include bora/vmkernel/distribute/push-hidden.h -include vmkdrivers/src_9/include/linux/autoconf.h -c -o BLD/build/vmkdriver-sata_sil24-CUR/release/vmkernel64/SUBDIRS/vmkdrivers/src_9/common/vmklinux_module.o vmkdrivers/src_9/common/vmklinux_module.c
$LD -r -o BLD/build/vmkdriver-sata_sil24-CUR/release/vmkernel64/sata_sil24 --whole-archive BLD/build/vmkdriver-sata_sil24-CUR/release/vmkernel64/SUBDIRS/vmkdrivers/src_9/drivers/ata/sata_sil24.o BLD/build/vmkdriver-sata_sil24-CUR/release/vmkernel64/SUBDIRS/vmkdrivers/src_9/common/vmklinux_module.o

La compilation se déroule sans erreurs, mais comme déjà lu sur le forum de vm-help, le module ne peut etre loadé sur ESXi à cause de symboles manquants (ata_eh_freeze_port, sata_link_debounce, and ata_link_abort)…
En fouillant dans les sources fournies par VMWare, j’ai fini par me rendre compte qu’ils avaient décidé de ne pas exporter l’intégralité des symboles normalement fournis par la libata ! Voir les #ifdef dans vmkdrivers/src_9/drivers/ata/libata-core.c.

La solution propre consisterait à re-délivrer une nouvelle libata avec les symboles exportés. J’ai cependant craint d’impacter les drivers existants, et j’ai donc décidé de faire un patch bien sale pour mes tests, en copiant/collant l’implémentation des fonctions manquantes dans mon sata_sil24.c…

Le module compilé a le mérite de fonctionner : ma carte a été reconnue par ESXi et j’ai pu utiliser les 3 disques durs qui y étaient reliés.

Références

Le topic Sil3132 sur vm-help.com
Utilitaire de packaging des fichiers VIB
Création de fichiers VIB
http://www.kernelcrash.com/blog/using-a-marvell-lan-card-with-esxi-4/2009/08/22/

5 réflexions au sujet de « Compilation d’un pilote additionnel pour ESXi 5.0 »

    1. Vilbrekin Auteur de l’article

      Bonjour,

      Je pense qu’il est plus simple d’utiliser centos, étant donné que c’est la distribution utilisée par VMWare pour construire les pilotes.

      Mais j’imagine que n’importe quelle autre distribution pourra faire l’affaire, pour peu qu’on utilise les bonnes version des outils (listées dans le README du package).

      Répondre
  1. IvanP.

    Bonjour,

    article extrêmement intéressant. Pour ma part, je cherche une façon d'activer le spindown des disques durs pour des raisons de bruits et de consommation électrique. Croiyez-vous que l'on pourrait le faire en modifiant les drivers ? J'ai tenté le passthrough de mon contrôleur SATA Lynx point, et malheureusement ça ne fonctionne pas (et en plus il faudrait créer une VM "NAS" et connecter les autres dessus, ce qui ne va pas nécessairement améilorer les perfs).

    Merci,

      Ivan.

    Répondre
    1. Vilbrekin Auteur de l’article

      Bonjour. Merci pour les retours. Je n'utilise plus ESXi depuis un moment maintenant, donc je n'ai pas testé la 5.5. Quant à désactiver le spin down, j'imagine qu'une modification des drivers doit être possible, mais il faudrait creuser beaucoup plus pour confirmer.

      Bonne chance 🙂

      Répondre

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *