Retrouvez cet article dans : Linux Magazine Hors série 36
Lecteurs assidus de GLMF, nous nous étions quittés sur une fausse note en fin d’année, à l’occasion du numéro 100, alors que notre serveur Zone0 repartait subir une intervention chirurgicale. Trois mois plus tard, depuis le début du mois de mars, il est en ligne. Pendant tout ce temps, nous avons peaufiné notre configuration, corrigé d’importants bugs et, finalement, rendu cette machine production-ready. Nous allons voir dans cet article une série d’opérations de maintenance auxquelles vous pourriez être un jour confronté.
|
1 |
Souvenez-vous, Zone0, ’rmidable |
Pour rappel, Zone0 est un serveur de type SuperMicro, muni d’un CPU Intel Quad Core, de 6 gigas de mémoire vive et d’un contrôleur RAID1 de type 3ware. Ces éléments hardware sont importants pour la suite, puisqu’ils sont tous à un moment ou un autre impliqués dans un dysfonctionnement. Pour rappel toujours, il s’agit d’un serveur entièrement articulé autour de Xen 3.1. Le dom0 est une Debian stable 64 bits, et quatre domUs répondent aux services par le biais d’une translation de ports. Deux domUs, services et shells tournent sous OpenBSD 4.1 i386, et les deux autres, gcu et www2 tournent sous NetBSD 4.0 i386. Tous les domUs fonctionnent en mode HVM.
|
2 |
Leur ADN est différent monsieur |
Nous le verrons plus loin, des interventions peu banales ont dû être effectuées dans le code source du noyau de la machine. Pour ce faire, nous avons évidemment dû télécharger les sources de ce dernier, opération classique s’il en est, qui a été le point de départ d’un véritable cauchemar.
Après le téléchargement du tar.bz2, un tar jtvf nous fait savoir que l’archive est corrompue. Un peu surpris, nous renouvelons l’opération, puis tout semble se dérouler correctement. Alors qu’un second administrateur avait également besoin de télécharger une archive, ce dernier me communique qu’après trois téléchargements consécutifs, le fichier compressé a eu trois fois un checksum différent. Et l’inquiétude monte.
Naïfs, nous soupçonnons un problème réseau, peut-être un problème de driver, des lutins farceurs, des cafards dans le connecteur RJ45… ou un problème disque ? Encore ? Incrédules, nous effectuons quelques recherches à l’issue desquelles nous nous rendons à l’évidence : nous aurions finalement dû filer un euro à cette voyante dans la rue qui menaçait de faire tomber le malheur sur nous le cas échéant.
Voici ce que nous pouvons lire sur la base de connaissances du constructeur de notre carte RAID 3ware :
|
If you have an Intel 64-bit EM64T system with 4 GB or more of system RAM, then you should not use the 7000/8000 series in kernel driver 3w-xxxx if you are using Linux kernels 2.6.15 through 2.6.22. Instead you should use the driver source from this KB article to compile a new driver. |
Avons-nous un système 64 bits ? Oui.
Avons-nous plus de 4 gigaoctets de mémoire vive ? Oui.
Notre carte contrôleur RAID est-elle de type 7000/8000 ?
|
0a:01.0 RAID bus controller: 3ware Inc 7xxx/8xxx-series PATA/SATA-RAID (rev 01) |
Oui.
Enfin, utilisons-nous un noyau compris entre 2.6.15 et 2.6.22 ?… Oui.
Il apparaît donc clairement que nous devons recompiler un noyau. Si cette opération n’est pas des plus complexes, modifier puis compiler un noyau en environnement Xen dans l’optique de changer le driver du contrôleur disque sur une machine qui se trouve à 20 € de taxi ne met pas spécialement en confiance, mais nous n’avons pour ainsi dire pas le choix : exécution.
L’archive fournie par 3ware contient les fichiers suivants :
|
imil@zone0:~$ ls src/driver/ 3w-xxxx.c 3w-xxxx.h Makefile |
Un rapide diff entre le code stock du driver et celui fourni par le constructeur nous informe que nous suivons probablement la bonne voie :
|
+ 1.26.02.002 - Free irq handler in __tw_shutdown(). + Turn on RCD bit for caching mode page. + Serialize reset code. + 1.26.03.000 - Use default DMA data direction to prevent data corruption + when using SWIOTLB with 4GB+ on EM64T. |
Nous entreprenons donc de remplacer les fichiers 3w-xxxx.c et 3w-xxxx.h par leurs versions corrigées, puis recréons l’archive linux-2.6.18.tar.bz2, utilisée par l’installation source de Xen.
Il faut maintenant télécharger (plusieurs fois, jusqu’à ce que l’archive ait le bon checksum) l’archive d’installation par les sources de Xen 3.1 (http://bits.xensource.com/oss-xen/release/3.1.3/xen-3.1.3.tar.gz), et suivre la procédure de compilation puis d’installation :
|
$ tar zxvf xen-3.1.0-src.tgz $ cd xen-3.1.0-src $ sudo -s # make world # make install # depmod 2.6.18-xen |
Reste à regénérer un initrd associé
|
# mkinitramfs -o /boot/initrd.img-2.6.18-xen 2.6.18-xen |
et à rester figé devant son xterm pendant vingt bonnes minutes avec le doigt sur [Entrée] en relisant frénétiquement la ligne suivante :
|
# sync; sync; reboot |
Un reboot plus tard, divers tests de téléchargements massifs nous font chaud au cœur. Ce problème-là est réglé.
|
3 |
Docteur, si la température monte encore, nous allons le perdre |
Ah, ah ! Enfin ! La machine est là , elle est stable, nous allons pouvoir comm[reboot intempestif].
Pensez-y, la prochaine fois que vous croisez une voyante, ne lui manquez pas de respect, parlez-lui un peu, demandez-lui des nouvelles de la petite famille, donnez-lui un euro ou deux en lui souhaitant bonne journée et bon courage pour son rude travail, faites mine de compatir, vraiment.
Nous voici devant un nouveau comportement cauchemardesque. Je résume :
Zone0 peut rester up plusieurs jours sans problèmes lorsqu’elle " ne fait rien ".
Lorsqu’elle a de l’activité, c’est-à -dire que tous les domUs sont chargés, translatés, accessibles depuis l’Internet et qu’ils génèrent du trafic, elle reboote de manière aléatoire au bout de plusieurs heures ou plusieurs jours. Le comportement n’est pas reproductible.
Le reboot ne produit aucune forme de log, syslog est désespérément muet lorsque le bug se produit.
Son load average est quasi nul.
Les coupables potentiels, après plusieurs heures d’expériences, sont :
Un mauvais refroidissement entraînant une température excessive.
ipvs : n’ayant jamais vu œuvrer ipvs dans une architecture Xen, nous envisageons la possibilité d’un bug engageant ipvs et les interfaces virtuelles montées par Xen. Mais, je vous l’accorde, ce n’est que pure supposition.
Le BIOS de la machine : un bug lié au BIOS ? Pourquoi pas ! Les architectures 64 bits en production ne sont finalement pas légion, encore moins avec les instructions VT (http://en.wikipedia.org/wiki/X86_virtualization) activées.
Pour écarter la première hypothèse, une seule solution : installer lm-sensors pour connaître la température du système en temps réel, en espérant que notre système soit supporté, bien que le noyau Xen ne soit pas tout récent. Les premiers tests suggèrent des capteurs intégrés dans le Super-I/O (un Winbond W83627HF). Super, se dit-on naïvement, c’est supporté depuis longtemps, ça va marcher tout seul.
Sauf que… CPU à 0.0 volt, ventilateurs tous arrêtés, température système 127 degrés Celsius. Soit la machine vient de brûler, soit quelque chose cloche dans les mesures. Le serveur répondant toujours, c’est fatalement les mesures qui sont fausses, et il faut se rendre à l’évidence : les capteurs du W83627HF ne sont pas connectés. Peut-on envisager que SuperMicro ait bêtement omis cette fonctionnalité ? Impensable, pas le genre de la maison. Il y a forcément une explication, encore faut-il la trouver à tâtons dans l’obscurité.
Une version plus récente de sensors-detect, le script de détection des capteurs, semble éclaircir la situation. Si celle-ci indique toujours la présence du W83627HF, elle trouve également un deuxième composant de mesure : un Winbond W83793G, composant de mesure dédié, qui était passé sous le radar la première fois, car trop récent. La présence du W83793G explique pourquoi les capteurs du W83627HF ne sont pas branchés : SuperMicro a fait le choix d’un composant de mesure dédié, plus précis et plus fonctionnel que les capteurs intégrés au Super-I/O. Tout est clair maintenant.
Notre joie est cependant de courte durée quand nous découvrons que le support pour le W83793G n’a été rajouté que dans le noyau 2.6.20. Notre noyau Xen 2.6.18 n’est simplement pas assez équipé. Mais pas de panique, il est tout à fait possible de porter ce genre de pilote vers une version antérieure du noyau, et c’est exactement ce que nous avons fait, avec succès. Une fois le pilote chargé, il ne reste plus qu’à ajuster le fichier de configuration (/etc/sensors.conf) pour notre carte SuperMicro. Le manuel de la carte se révèle un précieux allié dans cet exercice et un quart d’heure plus tard, nous avons sous les yeux les résultats suivants :
|
w83793-i2c-0-2f Adapter: SMBus I801 adapter at 1100 Vcore: +1.22 V (min = +1.08 V, max = +1.32 V) +1.5V: +1.54 V (min = +1.35 V, max = +1.65 V) Vtt: +1.21 V (min = +1.08 V, max = +1.33 V) -12V: -12.28 V (min = -12.94 V, max = -11.37 V) Vdimm: +1.82 V (min = +1.62 V, max = +1.98 V) +3.3V: +3.38 V (min = +2.96 V, max = +3.63 V) +12V: +11.81 V (min = +10.75 V, max = +13.25 V) +5V: +5.00 V (min = +4.64 V, max = +5.65 V) 5VSB: +5.05 V (min = +4.64 V, max = +5.65 V) Vbat: +3.25 V (min = +2.99 V, max = +3.66 V) Fan1: 4455 RPM (min = 3994 RPM) Fan2: 4485 RPM (min = 3994 RPM) CPU Temp: +60.8°C (high = +80.0°C, hyst = +70.0°C) Sys Temp: +56°C (high = +80°C, hyst = +75°C) temp6: +51°C (high = +60°C, hyst = +55°C) |
Vous trouverez le sensors.conf associé à cette adresse : http://khali.linux-fr.org/devel/lm-sensors/sensors-Supermicro-PDSMi+.conf.
Verdict : le patient est en bonne santé. Les voltages sont tous corrects, les ventilateurs ronronnent et la température d’environ 60 degrés Celsius est somme toute raisonnable pour un boîtier 1U. Une conclusion qui nous renvoie à nos chères études : si la température n’est pas en cause, de quelle maladie exotique mystérieuse souffre donc notre serveur ?
|
4 |
Une nuit au datacenter |
Si nous pouvons intervenir sur ipvs à distance, ne disposant pas de module IPMI sur notre serveur, l’upgrade de BIOS lui, devra se faire sur place. Il est donc indispensable de correctement préparer l’intervention.
Nous nous rendons sur la page http://www.supermicro.com/support/bios/ où, munis des informations livrées par la section Base Board de dmidecode, nous téléchargeons le fichier zip correspondant. Comme d’habitude, et bien malheureusement dans ce genre de situation, les upgrades se font par le biais d’un programme DOS. Au moins, il ne s’agit pas d’un exécutable Windows-only, c’est déjà ça. Notre machine ne disposant pas de lecteur de disquettes, nous entreprenons donc de générer un live CD FreeDOS qui contiendra notre nécessaire de secours.
En suivant scrupuleusement les informations publiées sur le wiki de FreeDOS, nous téléchargeons tout d’abord l’image iso fdfullws.iso à cette adresse : http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/distributions/1.0/fdfullws.iso, puis exécutons :
|
# mount -o loop fdfullws.iso /mnt $ mkdir -p ~/wrk/freedos/fdos/bios $ (cd /mnt && tar cvf - .)|(cd /home/imil/wrk/freedos && tar xvf -) $ cd fdos/bios $ unzip /path/vers/UPDATE-BIOS.zip $ cd ../.. $ mkisofs -R -D -V "FreeDOS 1.0" -o freedos.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table ./fdfullws/ |
Reste à graver l’iso générée, freedos.iso à l’aide de votre logiciel de gravure favori. C’est prêt. Afin de vous assurer que votre image iso est correcte, testez-la à l’aide, par exemple, de QEMU ou KVM :
|
kvm -boot d -cdrom freedos.iso |
Oh, une petite " astuce ", j’ai passé 20 minutes à comprendre que le CD-ROM est désigné par la lettre X:. Je sais pas pour vous, mais ça doit bien faire 10 ans que j’avais pas touché un DOS.

On est prêts, on y croit. Taxi !
À la lumière des néons de RedBus Interhouse, nous faisons fébrilement booter le serveur sur le live CD, et exécutons, comme nous l’explique le fichier readme.txt contenu dans l’archive .zip, les commandes suivantes :
|
A:\> X: X:\> cd fdos\bios X:\> flash.bat FICHIER_D_UPGRADE.rom |
Après quelques minutes assez stressantes, la mise à jour est terminée. Les données du BIOS sont évidemment réinitialisées. Nous réactivons donc le support des instructions VT et redémarrons la machine. Upgrade réussi.
|
5 |
Pardon Krusty :( |
Nous l’avons dit plus haut, nous avons identifié deux coupables potentiels, le BIOS et ipvs. Pour rappel, le choix du load balancer ipvs avait été dicté lors de la configuration initiale de la machine (voir GLMF #100) pour la simple raison que, d’aucune façon, nous n’avions réussi à faire fonctionner la redirection de port de l’IP publique du serveur vers les domUs. Pour rappel toujours, cette architecture était imposée par le fait que nous ne disposons que d’une seule IP publique, mais avons décidé de séparer les services en quatre domUs différents. Pour rappel enfin, nous nous étions dit, et nous nous allons bientôt comprendre que c’était une erreur, que, puisque nous disposons de deux interfaces réseau distinctes, il serait du meilleur effet de bridger nos domUs sur l’interface eth1 dans l’hypothèse où un second serveur viendrait un jour s’y connecter, nous permettant ainsi de créer une sorte de LAN privé entre domUs.
Des heures durant, nous avons (ré)essayé l’intégralité des combinaisons possibles :
" domU en mode bridgé : network-script network-bridge / vif-script vif-bridge ;
" domU en mode natté : network-script network-nat / vif-script vif-nat ;
" domU en mode routé : network-script network-route / vif-script vif-route.
Avec à chaque fois, évidemment, une configuration IP adaptée. Aucune d’entre elles n’a daigné laisser durer la session TCP plus loin que la première négociation.
À cours de cartouches, la solution surgit de la bouche de Kmikze, membre du canal. Ce dernier nous dit qu’il possède une configuration fonctionnelle sur une base similaire. La seule différence réside dans l’utilisation de l’interface… dummy. Celle-là même que nous vous conseillions d’utiliser dans notre précédent article si vous n’aviez pas la " chance " de posséder plusieurs interfaces. Ironie, quand tu nous tiens. Notons pour notre défense qu’un récent apt-get upgrade montre que les packages xen* remplacent les appels aux network-scripts network-bridge par network-dummy.
Après avoir automatisé le chargement du module dummy, nous renseignons donc le fichier /etc/xen/xend-config.sxp avec les valeurs suivantes :
|
(network-script network-dummy) (vif-script vif-bridge) |
Voici un exemple de sortie du brctl show correspondant :
|
bridge name bridge id STP enabled interfaces xenbr0 8000.1a87802de454 no dummy0 vif1.0 tap0 tap1 vif49.0 tap2 vif34.0 tap3 vif35.0 |
Reste à tester une redirection de port classique à l’aide de Netfilter :
|
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.0.3:80 |
Et à vérifier, incrédules, cette translation de port :
|
imil@tatooine:~$ telnet zone0.gcu.info 80 Trying 212.85.147.21... Connected to zone0.gcu.info. Escape character is ‘^]’. GET / NetBSD gcu.gcu-squad.org 4.0.0_PATCH NetBSD 4.0.0_PATCH (GENERIC_GCU) #0: Sun Jan 27 15:08:48 CET 2008 root@gcu.gcu-squad.org:/usr/src/sys/arch/i386/compile/GENERIC_GCU i386 Connection closed by foreign host. |
En un mot comme en cent : pardon Krusty.
Voici la version définitive de notre script d’initialisation de Netfilter, comprenant filtrage et NAT :
|
#!/bin/sh PATH=${PATH}:/sbin:/usr/sbin # interfaces WAN=eth0 # init iptables -F iptables -t nat -F iptables -t mangle -F # initial rules iptables -P INPUT ACCEPT # drop at the end iptables -P OUTPUT ACCEPT iptables -P FORWARD ACCEPT # pass all on lo |
|
iptables -A INPUT -i lo -j ACCEPT iptables -A OUTPUT -o lo -j ACCEPT iptables -A FORWARD -i lo -j ACCEPT iptables -A FORWARD -o lo -j ACCEPT # replies iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # rules iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT # ssh to zone0 iptables -A INPUT -p tcp --dport 22 -j ACCEPT # ssh to shells iptables -A INPUT -p tcp --dport 2222 -j ACCEPT # smtp to services iptables -A INPUT -p tcp --dport 25 -j ACCEPT # imaps to services iptables -A INPUT -p tcp --dport 993 -j ACCEPT # pop3s to services iptables -A INPUT -p tcp --dport 995 -j ACCEPT # www to gcu iptables -A INPUT -p tcp --dport 80 -j ACCEPT # https to gcu iptables -A INPUT -p tcp --dport 443 -j ACCEPT # ftp to gcu iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A INPUT -p tcp --dport 21 -j ACCEPT iptables -A INPUT -p tcp --sport 20 -m state --state ESTABLISHED,RELATED -j ACCEPT # DNS TCP to services iptables -A INPUT -p tcp --dport 53 -j ACCEPT # DNS UDP to services iptables -A INPUT -p udp --dport 53 -j ACCEPT # drop in all iptables -A INPUT -i ${WAN} -j DROP # masquerading iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE # Port forwarding iptables -t nat -A PREROUTING -i ${WAN} -p tcp --dport 53 -j DNAT --to 192.168.0.1:53 iptables -t nat -A PREROUTING -i ${WAN} -p udp --dport 53 -j DNAT --to 192.168.0.1:53 iptables -t nat -A PREROUTING -i ${WAN} -p tcp --dport 25 -j DNAT --to 192.168.0.1:25 iptables -t nat -A PREROUTING -i ${WAN} -p tcp --dport 993 -j DNAT --to 192.168.0.1:993 iptables -t nat -A PREROUTING -i ${WAN} -p tcp --dport 995 -j DNAT --to 192.168.0.1:995 iptables -t nat -A PREROUTING -i ${WAN} -p tcp --dport 2222 -j DNAT --to 192.168.0.2:22 iptables -t nat -A PREROUTING -i ${WAN} -p tcp --dport 80 -j DNAT --to 192.168.0.3:80 iptables -t nat -A PREROUTING -i ${WAN} -p tcp --dport 443 -j DNAT --to 192.168.0.3:443 iptables -t nat -A PREROUTING -i ${WAN} -p tcp --dport 20 -j DNAT --to 192.168.0.3:20 iptables -t nat -A PREROUTING -i ${WAN} -p tcp --dport 21 -j DNAT --to 192.168.0.3:21 |
Et notre /etc/modules :
|
dummy ip_conntrack ip_conntrack_ftp ip_nat_ftp |
Vous noterez dans ces deux fichiers les particularités liées à l’immonde protocole FTP. Un jour, l’humanité s’éveillera, un jour…
|
6 |
Hmmm, upgrades |
C’est un peu par hasard que nous avons découvert un troisième coupable potentiel. En même temps que nous réparions notre machine, un autre membre du canal, dzen, effectuait des tests de charge dans une configuration similaire à la nôtre avec un dom0 Linux et plusieurs domUs NetBSD. Ce dernier nous a fait savoir que son serveur de test avait subitement rebooté au bout de deux jours. À peu près dans le même temps, alors que j’utilisais une console VNC branchée sur un des domUs NetBSD, sous mes yeux, a lieu un kernel panic de cet OS invité, et l’arrêt sur ddb, le débuggeur noyau que nous avons activé, nous indique que c’est le driver ne2000 qui vient de faire crasher notre domU.
Rappel, le choix de l’émulation d’une carte ne2000 sur les domUs OpenBSD et NetBSD est lié au fait que le driver du contrôleur présenté par défaut par Xen/QEMU, re0 pour une Realtek 8139, fonctionnait extrêmement mal. Au bout de quelques secondes de transfert, ce dernier stoppait toute transaction et nous affichait des watchdog timeout.
À l’époque de la mise en place du serveur, NetBSD 4.0 était encore une release candidate. Aussi, nous avions opté pour la sûreté et avions installé des versions 3.1 sur les domUs gcu et www2, mais à la lecture de certains threads sur le sujet watchdog timeout sur les listes de diffusion NetBSD, il semblait que des correctifs avaient été apportés dans la branche 4.0. De plus, en janvier, lorsque nous avons retrouvé notre serveur, NetBSD 4.0 était releasé. Aussi, nous entreprenons une mise à jour de l’OS.
Pour réaliser cette opération, nous allons utiliser la méthode binaire. Téléchargeons tout d’abord les sets binaires :
|
$ mkdir ~/nb4 $ cd ~/nb4 && lftp ftp://ftp.fr.netbsd.org/pub/NetBSD/NetBSD-4.0/i386/binary/sets $ lftp ftp.fr.netbsd.org:/pub/NetBSD/NetBSD-4.0/i386/binary/sets> mget * |
Effectuons quelques backups :
|
# tar zcvfp etc-3.1.tgz /etc # cp /netbsd /netbsd.3.1 |
Mettons d’abord à jour le noyau :
|
# tar zxvfp kern-GENERIC.NOACPI.tgz -C / |
Notez que nous choisissons la version NOACPI correspondant à la directive acpi=0 du fichier de configuration du domU. Ce choix est dicté par diverses documentations.
Il est évidemment nécessaire de rebooter sur ce nouveau noyau pour s’assurer que toutes les nouvelles fonctions des sets que nous allons décompresser sont bien supportées. Nous pouvons alors mettre à jour l’espace utilisateur :
|
# tar zxvfp base.tgz -C / # tar zxvfp comp.tgz -C / # tar zxvfp man.tgz -C / # tar zxvfp misc.tgz -C / # tar zxvfp text.tgz -C / |
Le nettoyage des fichiers dépassés, la mise à jour d’/etc, l’indexation des nouveaux fichiers installés, en un mot, la mise à jour post-installation, se fait à l’aide de l’outil etcupdate. Son utilisation est la suivante :
|
# mkdir /tmp/tmproot # tar zxvpf etc.tgz -C /tmp/tmproot # etcupdate -s /tmp/tmproot/etc |
Le switch -s spécifie l’endroit dans lequel l’outil pourra trouver la version témoin d’un /etc à jour. S’ensuit alors une série de questions parfaitement explicites, essentiellement des diffs entre les fichiers présents sur votre système de fichier et les fichiers témoins. À la fin de ces comparaisons, etcupdate éliminera les fichiers dépassés (liens, bibliothèques, binaires…), recréera les index de la nouvelle arborescence, créera éventuellement de nouveaux devices dans /dev et, finalement, fera appel à l’outil postinstall afin de vérifier la cohérence de l’upgrade.
Si tout s’est déroulé correctement, un nouveau reboot sera nécessaire à la relecture de l’ensemble des scripts d’initialisation. Vous êtes maintenant à jour.
|
7 |
Le chien aboie, le paquet ne passe pas |
Notre système invité maintenant à jour, c’est un peu méfiants que nous remplaçons
|
vif = [ ‘type=ioemu, bridge=xenbr0, model=ne2k_pci’ ] |
par :
|
vif = [ ‘mac=00:50:56:10:20:01, type=ioemu, bridge=xenbr0’ ] |
Comme nous l’avons déjà expliqué, l’absence de la directive model= implique que le contrôleur réseau qui sera présenté au domU sera de type Realtek 8139. Un reboot et un transfert plus tard, c’est les doigts crispés que nous lisons :
|
re0: watchdog timeout |
Fatigue…
À force de recherches, nous finissons par trouver un mail de Monsieur Manuel Bouyer (http://mail-index4.netbsd.org/port-xen/2006/10/25/0001.html), mainteneur de la branche Xen de NetBSD, qui explique qu’il n’est pas improbable qu’il subsiste un bug dans le driver re*, et que, par conséquent, il serait judicieux de le désactiver afin de laisser le driver historique rtk* prendre la main. Nous voici partis dans une nouvelle compilation de noyau.
Récupérons tout d’abord l’arbre des sources de NetBSD dans sa version 4.0 :
|
# cd /usr # cvs -d anoncvs@anoncvs.fr.netbsd.org:/cvsroot co -rnetbsd-4-0 src |
Puis préparons notre propre fichier de configuration pour notre noyau custom :
|
# cd /usr/src/sys/arch/i386/conf # cp GENERIC GENERIC_GCU |
Commentons la référence au driver re* et assurons-nous que le driver rtk* est bien présent :
|
#re* at pci? dev ? function ? # Realtek 8139C+/8169/8169S/8110S rtk* at pci? dev ? function ? # Realtek 8129/8139 |
Préparons maintenant l’environnement de compilation :
|
# config GENERIC_GCU |
Et démarrons la compilation effective :
|
# cd ../compile/GENERIC_GCU # make depend # make |
À l’issue de cette compilation, un nouveau noyau est disponible, reste à le copier à la racine du système, puis à redémarrer :
|
# cp netbsd / # sync; sync; reboot |
Le dmesg devrait indiquer :
|
rtk0 at pci0 dev 4 function 0: Realtek 8139 10/100BaseTX (rev. 0x20) rtk0: interrupting at irq 5 rtk0: Ethernet address 00:50:56:00:00:02 rlphy0 at rtk0 phy 7: Realtek internal PHY rlphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto |
ifconfig devrait alors confirmer le fonctionnement à vitesse optimale :
|
# ifconfig rtk0 rtk0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500 address: 00:50:56:00:00:02 media: Ethernet autoselect (100baseTX full-duplex) status: active inet 192.168.100.4 netmask 0xffffff00 broadcast 192.168.100.255 inet6 fe80::250:56ff:fe00:2%rtk0 prefixlen 64 scopeid 0x1 |
C’est gagné.
Depuis cette opération, nos domUs NetBSD n’ont jamais plus montré aucun signe de faiblesse et sont effectivement capables d’effectuer des transferts jusqu’à 10 mégaoctets par seconde.
|
8 |
Gardez la ligne pour l’été |
J’adore NetBSD. Vraiment. Pour un tas de raisons diverses et variées, j’adore ce système. J’aime aussi beaucoup pkgsrc, son système de packaging, qui, comme son OS d’origine, a été pensé pour être portable sur un maximum de systèmes possibles. Notons par exemple DragonFlyBSD qui en a fait son système de packaging officiel ou encore Draco Linux, une sorte de slackware utilisant pkgsrc. Pkgsrc est portable, oui, très propre aussi, mais pkgsrc est un cauchemar à upgrader. La target update existe bien, mais une seule erreur de compilation par exemple lors de l’upgrade d’une dépendance, et c’est toute la chaîne qui se retrouve bancale. Exemple : je dois upgrader, au hasard, ap22-php5, qui a comme dépendance php5, apache22, apr, apr-utils. Sachant qu’il existe également des versions de package plus récentes pour tous ces packages, la première opération qui sera effectuée sera de les pkg_delete afin de les upgrader. Seulement voilà , si, pour une raison ou pour une autre, une compilation de la chaîne échoue, ces packages, à l’instar de ce que réalise portupgrade sous FreeBSD, ne seront pas rollbackés, et les portes de l’enfer s’entrouvriront…
Une solution relativement élégante existe cependant : il s’agit de l’utilitaire pkg_comp. Ce script shell écrit par Julio " jmmv " M. Merino Vidal permet, via une configuration claire, de préparer un upgrade dans un environnement chrooté. L’idée consiste à préparer l’ensemble des packages sous forme d’archives binaires, utilisables entre autres par pkg_add ou encore pkg_chk. Une fois l’ensemble des packages binaires compilés, un upgrade massif à la façon d’un apt-get upgrade pourra être effectué à l’aide de pkg_chk. pkg_chk est également un script shell destiné à la gestion de packages pkgsrc. Lorsqu’il est invoqué avec les switches -u et -a, ce dernier vérifie le contenu du fichier /usr/pkgsrc/pkgchk.conf, lui-même généré avec l’option -g de pkg_chk, qui liste l’ensemble des paquets sur lesquels nous souhaitons qu’il y ait une opération. Si un package binaire est disponible et que ce dernier correspond bien à la version indiquée dans l’arbre pkgsrc, pkg_chk l’utilisera pour mettre à jour le paquet. Le cas échéant, pkg_chk invoquera une compilation classique du package, entraînant un risque potentiel de rupture de la chaîne de mise à jour. Pour cette raison, nous utiliserons l’option -b qui force pkg_chk à n’utiliser que des paquets binaires lors de la mise à jour.
La création de l’environnement chrooté est triviale. On crée tout d’abord un template de configuration destiné à pkg_comp :
|
$ sudo pkg_comp maketemplate |
On édite ensuite le fichier généré, ${HOME}/pkg_comp/default.conf afin de renseigner certaines valeurs propres à notre système :
|
# les sets binaires se trouvent dans ${DISTRIBDIR}/binary/sets DISTRIBDIR="/home/imil/nb4" # nous ne souhaitons pas utiliser X11 sur cette machine SETS_X11="no" |
Notons que :
" Le répertoire /usr/src doit exister, même s’il n’est pas peuplé de son contenu.
" L’environnement chrooté sera placé dans ${DESTDIR}, soit par défaut : /var/chroot/pkg_comp/default.
Créons maintenant l’environnement :
|
$ sudo pkg_comp makeroot |
À l’issue de cette commande, il est désormais possible d’entrer dans le chroot par le biais de pkg_comp :
|
$ sudo pkg_comp chroot |
On peut évidemment passer des arguments à la suite de cette commande, par exemple :
|
$ sudo pkg_comp chroot grep CLEAN /etc/mk.conf |
En entrant dans le chroot, vous remarquerez certainement certains messages intéressants, par exemple :
|
PKG_COMP ==> Mounting sandboxed filesystems |
En effet, lorsque pkg_comp est invoqué, ce dernier facilite grandement le travail de recherche de paquets binaires en utilisant directement l’arbre pkgsrc de l’hôte (l’hôte qui est en réalité un système invité dans notre cas… vous suivez toujours ?) :
|
/usr/src on /var/chroot/pkg_comp/default/usr/src type null (read-only, local) /usr/pkgsrc on /var/chroot/pkg_comp/default/usr/pkgsrc type null (read-only, local) /usr/pkgsrc/distfiles on /var/chroot/pkg_comp/default/pkg_comp/distfiles type null (local) /usr/pkgsrc/packages on /var/chroot/pkg_comp/default/pkg_comp/packages type null (local) |
Ce petit tour de passe-passe est effectué grâce au système de fichiers nullfs, qui permet, entre autres, de mounter une partie du filesystem dans une autre partie du même filesystem. Ainsi, dans notre cas, /usr/pkgsrc est par exemple mounté dans un sous-répertoire du chroot pkg_comp, /var/chroot/pkg_comp/default/usr/pkgsrc. Pratique.
Nous utiliserons la possibilité d’entrer dans le chroot pour, par exemple, ajouter quelques préférences au fichier /etc/mk.conf :
|
# les scripts de démarrage seront installés dans /etc/rc.d PKG_RCD_SCRIPTS=YES # pas de X11 MKX11=no # on préfère cet ordre de choix de mirroirs MASTER_SORT=.fr .uk .de # on nettoie les dépendances lors d’un make clean CLEANDEPENDS=yes # on spécifie que le package apr-util doit supporter LDAP PKG_OPTIONS.apr-util=ldap # on accepte la license de vim ACCEPTABLE_LICENSES+=vim-license # les fichiers temporaires de pkg_chk seront créés dans le chroot PKGCHK_UPDATE_CONF = /pkg_comp/obj/pkgsrc |
Assurons-nous que le package pkg_install est bien à jour dans notre chroot :
|
pkg_comp:default.conf# cd /usr/pkgsrc/pkgtools/pkg_install pkg_comp:default.conf# make update clean |
Et nous pouvons alors démarrer la séance de compilation massive :
|
$ sudo for pkg in `grep -v ^# /usr/pkgsrc/pkgchk.conf`;do pkg_comp build $pkg;done |
À l’issue d’un – potentiellement très – long moment, le répertoire /usr/pkgsrc/packages/All de l’hôte devrait être peuplé de l’ensemble des packages mentionnés dans le fichier /usr/pkgsrc/pkgchk.conf. Aussi, après vous être assuré qu’aucun ne manque à l’appel, vous pouvez sereinement invoquer pkg_chk de cette façon :
|
# pkg_chk -uab |
La mise à jour ne devrait alors pas prendre plus de temps qu’un simple apt-get upgrade sur une Debian ou équivalent.
Votre environnement chrooté étant parfaitement opérationnel, il ne vous reste, pour garantir une mise à jour régulière et sans risques de la machine cible, qu’à réaliser quotidiennement une vérification de type :
|
$ sudo pkg_comp chroot pkg_chk -uan |
L’option -n de pkg_chk garantit qu’aucune opération ne sera menée, mais ce dernier vous résumera les actions qu’il aurait effectuées. Aussi, lorsque vous le jugerez opportun, vous pourrez sans risque demander une génération de nouveaux packages par le chroot en invoquant
|
$ sudo pkg_comp chroot pkg_chk -ua |
puis mettre à jour l’environnement cible via pkg_chk -uab.
Cette technique n’est pas forcément triviale, mais elle est efficace et sûre.
|
9 |
Share ! |
Nos deux domUs NetBSD sont évidemment sortis du même moule, pire, le second n’est qu’un dd du premier. Petit fainéant que je suis, j’avais préféré cette option à une réinstallation complète. On ne se refait pas. De fait, les besoins de l’un et l’autre sont relativement similaires, d’autant que leur rôle à tous deux est de " servir du web ". Il nous a donc paru naturel de partager entre ces deux machines les deux arbres /usr/src et /usr/pkgsrc. Cette configuration est aisée. Sur le serveur NFS, il vous suffit d’ajouter au fichier /etc/rc.conf
|
rpcbind=yes mountd=yes nfs_server=yes lockd=yes statd=yes |
de renseigner le fichier /etc/exports
|
# pkgsrc doit être accessible en écriture sur les deux domUs /usr/pkgsrc -alldirs -maproot=root -network 192.168.0.0 -mask 255.255.255.0 # pas /usr/src /usr/src -network 192.168.0.0 -mask 255.255.255.0 |
puis de (re)démarrer :
|
# /etc/rc.d/rpcbind restart # /etc/rc.d/mountd restart # /etc/rc.d/nfsd restart # /etc/rc.d/nfslocking restart |
Sur le client NFS, il faudra ajouter au fichier /etc/rc.conf
|
rpcbind=yes nfs_client=yes lockd=yes statd=yes |
puis (re)démarrer :
|
# /etc/rc.d/rpcbind restart # /etc/rc.d/nfslocking restart |
Enfin, pour automatiser le montage de ces répertoires sur le client, on ajoute à sa fstab :
|
192.168.0.4:/usr/pkgsrc /usr/pkgsrc nfs rw 192.168.0.4:/usr/src /usr/src nfs ro |
Et on mounte le plus simplement du monde :
|
# mount /usr/src # mount /usr/pkgsrc |
Si on peut se rendre la vie un peu plus facile hein…
|
10 |
ping ? |
Oui, Zone0 est en ligne et en production depuis début février 2008. C’est elle qui sert le site principal, les sites tiers, nos mails, notre DNS primaire et master, ainsi que les serveurs FTP et CVS. Ce fut une expérience très enrichissante, bien qu’un peu (beaucoup) stressante… et coûteuse ! Mon seul regret sera de ne pas savoir avec exactitude lequel des trois suspects était responsable des reboots intempestifs du serveur. Bien que j’aie une petite préférence pour le BIOS, rien ne me permet d’affirmer que le problème venait effectivement de là . J’ajoute que, comme je l’expliquais dans le précédent article, j’utilise ipvs en milieu professionnel dans des conditions bien plus extrêmes qu’un simple serveur web/mail/DNS. Aussi, ne prenez pas s’il vous plaît cette expérience comme acquise. Là non plus, rien ne nous permet d’affirmer qu’il était d’une manière ou d’une autre incriminé dans le dysfonctionnement du serveur. Je finirais par de massifs remerciements à tous ceux qui sont intervenus, directement ou indirectement, dans cette aventure : je vous fais des bisous, plein.
|
Liens |
|
Les patchs 3ware pour les cartes de type 7xxx/8xxx : Téléchargement de Xen sous forme de binaire ou code source : La virtualisation x86 sur Wikipédia : FreeDOS wiki : http://wiki.fdos.org/pmwiki.php Krusty le clown : http://fr.wikipedia.org/wiki/Krusty_le_clown Compilation d’un noyau NetBSD : Draco Linux : http://www.dracolinux.org/ Upgrade de pkgsrc sur le Wiki NetBSD : |
Retrouvez cet article dans : Linux Magazine Hors série 36


