Quand tout fonctionne et que tout à coup… 0x040ee119 !
Durant les derniers mois qui se sont écoulés, j’ai eu à mettre en place un système de provisioning permettant d’automatiser le plus que possible nos déploiements OpenStack. La principale étape dans ce genre de procédé étant bien sûr de déployer un système d’exploitation et pour cela il m’a fallu remettre le nez dans la fameuse pile PXE/DHCP/TFTP et cela même si j’utilise Bifrost.
Bifrost consiste à utiliser Ironic (composant de la fondation OpenStack) en mode standalone ce qui signifie qu’il n’est pas nécessaire d’avoir Keystone, Glance, Neutron et Nova d’installés pour utiliser ce dernier.
Le titre de cet article relate parfaitement le comportement que j’avais lors des tentatives de déploiement, un coup cela fonctionnait et le coup d’après j’avais le droit à l’erreur 0x040ee119 sans aucune raison apparente.
De manière générale, la pile sus-citée (pouaahh le mec qui utilise des mots compliqués) fonctionne sans magie, si ça ne fonctionne pas c’est qu’il y a certainement un des composants qui est mal configuré et donc certainement une erreur de votre part (mais je ne blâme personne ^^).
- Mauvaise adresse MAC liée à un profil
- Mauvaise configuration DHCP
- Ports bloqués par un pare-feu
- etc…
Quelques pistes à suivre
Dépendamment des types d’installation, certains problèmes peuvent faire leur apparition…
L’un d’entre eux revient souvent; tous les services se trouvent dans une machine virtuelle et les requêtes (surtout DHCP) timeout. Le problème est certainement lié au fait que la machine virtuelle soit connectée à un bridge Linux et que ce dernier ne soit pas configuré correctement. La solution (qui fonctionne pour la majorité des gens) consiste en deux opérations (plus un bonus):
- Désactivation du STP (Spanning Tree Protocol)
- # brctl stp br-pxe off
- Forward Delay laissé avec sa valeur par défaut (4 secondes)
- # brctl setfd br-pxe 0
- Désactivation du filtrage IPTables sur les interfaces de type bridge
- # sysctl -w « net.bridge.bridge-nf-call-arptables = 0 » -w « net.bridge.bridge-nf-call-ip6tables = 0 » -w « net.bridge.bridge-nf-call-iptables = 0 »
L’autre moins courant mais bien plus casse-pieds (j’essaye de rester poli) est lié au fait que le serveur soit configuré (d’un point de vue réseau) pour fonctionner en LACP (802.3ad). Le LACP c’est cool, ça améliore les performances, ça améliore aussi la redondance mais si ce dernier est mal configuré c’est un vrai calvaire à débugger… (surtout quand on aime pas le réseau)
Ce n’est pas toujours la faute au réseau…
Oui…oui..oui, je te vois derrière ton écran en train de râler…
Putain de merde, les gars de l’équipe réseau ont encore oublié d’ouvrir un port ou de tagger un VLAN. C’est toujours pareil avec eux, ils ferment le ticket en disant que c’est fait mais ils en ont oublié la moitié!
Sauf, comme à ton habitude tu utilises la mauvaise gateway par défaut… PAN ! (c’était facile, pardon…)
Le protocole PXE n’est pas capable de gérer le protocole LACP sans une petite configuration supplémentaire sur les swicth. Cette configuration consiste à activer le fallback sur le port-channel afin que LACP puisse être actif et transférer les paquets et cela même si aucun membre ne faire partie du groupe.
C’est cette option de fallback qui cause l’apparition de l’erreur 0x040ee119 avec iPXE et qui fait que le nœud n’est pas capable d’obtenir une adresse IP du DHCP.
Mais pourquoi !
D’après la capture d’écran suivante, on distingue clairement que c’est iPXE qui timeout ce qui signifie que si ce dernier timeout c’est qu’il existe une valeur définie quelque part dans le code.
La raison est liée au fait que etherchannel-enabled prend « trop » de temps pour passer de l’état « Waiting to be aggregated » à l’état « Independent » durant le processus de boot d’iPXE, sans cet état aucun trafic n’est autorisé.
Cette transition d’état peut prendre plus ou moins de temps en fonction:
- De la charge du switch
- De l’activité sur le réseau
- Et certainement d’autres éléments qui me dépassent
Suite à cela on comprends un peu mieux le côté aléatoire du problème.
À la recherche du timeout perdu…
Le coupable se trouve dans le fichier src/config/dhcp.h dont voici la partie incriminée:
/* * DHCP and PXE Boot Server timeout parameters * * Initial and final timeout for DHCP discovery * * The PXE spec indicates discover request are sent 4 times, with * timeouts of 4, 8, 16, 32 seconds. iPXE by default uses 1, 2, 4, 8. */ #define DHCP_DISC_START_TIMEOUT_SEC 1 #define DHCP_DISC_END_TIMEOUT_SEC 10 //#define DHCP_DISC_START_TIMEOUT_SEC 4 /* as per PXE spec */ //#define DHCP_DISC_END_TIMEOUT_SEC 32 /* as per PXE spec */
On distingue clairement que le timeout est défini à 10 secondes et que d’après les specs de PXE il est recommandé de passer cette valeur à 32 secondes comme indiqué dans le commentaire du code… Voici donc le diff du code après modification:
--- a/src/config/dhcp.h 2017-04-25 10:04:09.291323453 -0400 +++ b/src/config/dhcp.h 2017-04-25 10:04:20.859294021 -0400 @@ -19,10 +19,10 @@ * The PXE spec indicates discover request are sent 4 times, with * timeouts of 4, 8, 16, 32 seconds. iPXE by default uses 1, 2, 4, 8. */ -#define DHCP_DISC_START_TIMEOUT_SEC 1 -#define DHCP_DISC_END_TIMEOUT_SEC 10 -//#define DHCP_DISC_START_TIMEOUT_SEC 4 /* as per PXE spec */ -//#define DHCP_DISC_END_TIMEOUT_SEC 32 /* as per PXE spec */ +//#define DHCP_DISC_START_TIMEOUT_SEC 1 +//#define DHCP_DISC_END_TIMEOUT_SEC 10 +#define DHCP_DISC_START_TIMEOUT_SEC 4 /* as per PXE spec */ +#define DHCP_DISC_END_TIMEOUT_SEC 32 /* as per PXE spec */ /* * Maximum number of discovery deferrals due to blocked links
Une fois le code modifié il est nécessaire de recompiler iPXE afin d’obtenir un nouveau binaire avec le nouveau timeout.
Conclusion
À ce rythme là je ne vais pas tarder à voir des cheveux blancs… Je ne sais pas pourquoi ce timeout et aussi bas dans iPXE alors que les développeurs semblent être au courant des spécificités liées à PXE. Tout ça pour vous dire que suite à cette modification, je n’ai plus JAMAIS rencontré cette erreur. 😯
Liens
- Explications du fonctionnement d’iPXE sur LinuxFR
- Explications sur LACP et le fallback (anglais)
- Agrégation de liens sur Wikipédia
- Source du fichier dhcp.h sur Github
- Comment compiler iPXE à partir des sources
- Spécificités de PXE par Intel (fichier PDF)
Gaëtan Trellu (goldyfruit)
Derniers articles parGaëtan Trellu (goldyfruit) (voir tous)
- Qinling, let’s the journey begin! - 23 mai 2019
- systemd-networkd, l’âge de la maturité ? - 13 mars 2018
- Hyper-V, Nova, VxLAN et Open vSwitch, enfin une belle histoire ! - 31 décembre 2017
iPXE et la fameuse erreur 0x040ee119 qui rend fou ! par Gaëtan Trellu (goldyfruit) est sous Licence Creative Commons Internationale Attribution 4.0.