- La prise en charge de Plan 9, annoncée comme un poisson d’avril, a débouché sur une vraie PR ainsi que sur des modifications du noyau et de Go ; au 2 avril 2025, Tailscale fonctionne sur Plan 9
- Il ne s’agissait pas simplement d’un problème de build
GOOS=plan9 GOARCH=386: le port Plan 9 de Go a d’abord révélé des plantages du runtime et des problèmes de traitements spéciaux dans le compilateur - Les modifications apportées par Russ Cox au noyau Plan 9 ainsi qu’au runtime et au compilateur Go ont permis de régler en parallèle des problèmes liés à SSE, au contexte en virgule flottante, au temps monotone, au DNS et à l’environnement de développement
- Tailscale s’est appuyé sur l’interface fichier
/netde Plan 9 pour ajouter une implémentation proche de TUN, le routage, Tailscale SSH, MagicDNS et la collecte de services, mais certaines parties restent provisoires ou inachevées - La validation actuelle porte principalement sur 9legacy et
GOARCH=386; 9front, amd64, les exit nodes et la prise en charge denet/netnsdans Go nécessitent des vérifications supplémentaires ou une refonte
Une blague du 1er avril devenue un vrai portage
- Tailscale a annoncé la prise en charge de Plan 9 le 1er avril 2025, puis a expliqué le lendemain que cette annonce reposait sur un portage réellement fonctionnel
- Le travail a donné lieu à une PR Tailscale et à plusieurs modifications de Plan 9 et de Go
- L’approche initiale partait de l’idée qu’il suffirait de compiler deux binaires Go de Tailscale avec
GOOS=plan9 GOARCH=386 go install ./cmd/tailscale{,d} - Lors de la première tentative, en août 2023, une partie du build avançait, mais l’exécution provoquait des plantages anormaux
- Le port Plan 9 de Go n’étant pas un port de premier rang, des régressions étaient restées non corrigées
- Il est aussi possible que Tailscale ait poussé Go plus loin que d’habitude sur Plan 9
- Le portage est resté en pause pendant toute l’année 2024, avant de reprendre en mars 2025 avec l’idée du poisson d’avril
SSE et remise en ordre de la prise en charge de Plan 9 dans Go
- Les instructions SSE, introduites avec l’Intel Pentium III en 1999, ont été l’un des principaux points de départ de ce travail
- Le compilateur Go cherchait à éviter l’utilisation de SSE pour la cible Plan 9
- Le noyau Plan 9 ne sauvegardait ni ne restaurait les registres SSE dans les note handlers
- Le compilateur Go ne pouvait pas savoir quel code s’exécutait dans un note handler, et cherchait donc à désactiver SSE globalement
- Ce traitement spécial cassait souvent, et les exceptions
plan9se multipliaient dans le compilateur
- Russ Cox a modifié le noyau Plan 9 pour gérer le contexte virgule flottante et SIMD dans les note handlers
- Côté 386, le correctif sys/src/9: allow floating point in note handlers a été intégré
- Dans le noyau 9k amd64, d’autres problèmes ont été découverts : aliasing de l’état FP après fork, SIMD dans les note handlers, perte de registres avec
noted(NCONT), etc.
- Côté Go, la suppression des traitements spéciaux de génération de code pour Plan 9 a permis à
tailscaledde s’exécuter plus longtemps
IPC et environnement de développement
- Par la suite,
tailscaleds’est mis à planter non plus à cause d’une corruption de pile, mais par manque de mémoire - Une tentative précédente de portage sur Plan 9 avait introduit, dans le paquet IPC
safesocketde Tailscale, un bug créant un nombre infini de goroutines - Le problème a été résolu dans un premier temps en basculant sur TCP localhost
- Cela correspond moins bien à l’approche « tout est fichier » de Plan 9, mais il a été confirmé que d’autres services Plan 9 utilisent aussi TCP localhost
- À l’avenir, une meilleure approche pourrait consister à exposer la LocalAPI via le paquet srv9p que Russ a porté en Go
- L’implémentation actuelle ne peut pas ajouter l’authentification localhost comme sur les autres plateformes ; il est donc explicitement indiqué de ne pas l’utiliser sur des machines Plan 9 partagées
- Le développement initial s’est fait dans une VM basée sur une image CD 9legacy, avec un cycle lent consistant à télécharger les binaires en HTTP puis à les exécuter
- rsc/plan9, créé par Russ Cox, inclut les sources de Plan 9, des binaires précompilés et le script
./boot/qemu- La VM qemu démarre sans disque et utilise comme système de fichiers racine un dépôt Git fourni par un serveur 9P localhost
- Le partage du système de fichiers entre la machine de développement et Plan 9 a réduit les itérations de quelques minutes à quelques secondes
- qemu utilise aussi virtio, ce qui le rend plus rapide
Intégration réseau : TUN, routage, MagicDNS
- Le premier Tailscale fonctionnel utilisait un mode de réseau en espace utilisateur, sans recourir à la pile réseau du noyau
- TCP, UDP, ICMP, etc. étaient traités via le netstack de gVisor
- Pour accéder au tailnet depuis une machine Plan 9, il fallait utiliser le proxy HTTP/SOCKS5 de
tailscaled - Très peu de programmes Plan 9 reconnaissent les variables d’environnement
HTTP_PROXYouALL_PROXY, ce qui n’était pas idéal
- L’implémentation de type TUN de Plan 9 était très simple
- Ouvrir
/net/ipifc/cloneet lire le nouveau numéro d’interface - Écrire
"bind pkt\n"dans le fd de contrôle crée une nouvelle interface comme/net/ipifc/2/* - Ouvrir
/net/ipifc/2/datapermet de lire et d’écrire directement des paquets IP - Aucun ioctl ni framing de longueur séparé n’est nécessaire
- Ouvrir
- La manipulation de la table de routage se fait également via le fichier
/net/iproute- Écrire
"tag tail\n"ajoute le tagtailaux routes ajoutées ensuite - Des routes sont ajoutées avec des messages comme
"add 100.64.0.0 /106 100.102.103.104" - Comme Plan 9 est centré en interne sur IPv6 et traite IPv4 comme des adresses IPv6 IPv4-mapped, le CGNAT
100.64.0.0/10est représenté sous une forme comme/106
- Écrire
- MagicDNS consistait à permettre d’accéder aux peers depuis Plan 9 avec des noms comme
foooufoo.tailnet-name.ts.net- Des solutions consistant à intercepter les requêtes
/net/dnsou/net/csont aussi été discutées - Finalement, Russ a modifié Plan 9 pour permettre de spécifier un serveur DNS alternatif pour certains suffixes DNS
- Un problème de mise en cache négative incorrecte des requêtes DNS a également été corrigé
- Des solutions consistant à intercepter les requêtes
Tailscale SSH et collecte de services
- Tailscale SSH est un serveur SSH intégré à
tailscaled, qui authentifie l’utilisateur via l’identité Tailscale connue associée à la clé WireGuard connectée aux paquets - Au départ, le shell Plan 9
/bin/rcétait lancé avecos/exec.Command, avec stdin/stdout connectés- Le shell se lançait, mais l’echo, la navigation, l’interruption de processus et d’autres fonctions ne marchaient pas correctement
- Russ a ajouté l’exemple netshell à 9fans/go
- Cet exemple ressemblait à un serveur telnet très peu sûr, mais suffisait pour être placé derrière Tailscale SSH
- Il est ensuite devenu plus facile de récupérer le contenu de
/dev/snarfde Plan 9 via SSH, ou de cross-compiler des tests Go sur un ordinateur portable puis de les exécuter par SSH
- La fonctionnalité optionnelle de Tailscale de collecte de services a également été adaptée à Plan 9
- Parcourir
/proc/NNN/fdpour trouver les processus ayant ouvert/net/tcp/clone - Faire correspondre le QID du fd avec
/net/tcp/NNN/{status,local}pour vérifier l’état listening et le port - La méthode qui calcule le numéro TCP à partir du QID reste regrettable, car fragile face aux évolutions de l’implémentation du noyau
- Parcourir
Temps, démo web et v86
- Il arrivait que
tailscaledplante parce que le netstack de gVisor signalait que le temps monotone reculait- L’implémentation du temps de Plan 9 dans Go utilisait le wall time comme temps monotone
- Lorsque ntpd reculait l’horloge, l’hypothèse de temps monotone du netstack était violée
- Russ a ajouté le temps monotone à
/dev/bintimedans Plan 9, puis a modifié Go pour l’utiliser - v86 a été utilisé pour exécuter Plan 9 dans le navigateur
- v86 exécute des systèmes d’exploitation 32 bits en WASM et propose plusieurs modes réseau
- C’est aussi l’une des raisons de se concentrer sur
GOARCH=386
- Au départ, Tailscale a ajouté à son environnement de simulation réseau la prise en charge du protocole wsproxy pour envoyer des trames Ethernet via un relay websocket
- Cela fonctionne dans un environnement de tests d’intégration qui simule ARP, DHCP, DNS, NAT, le control plane, DERP, etc. avec le netstack de gVisor
- Mais à cause des allers-retours DHCP, si le relay est éloigné, le démarrage de
rio, l’interface graphique de Plan 9, ralentit
- Un serveur WISP a ensuite été implémenté, mais le temps a manqué pour le mettre en production ; la sortie s’est donc faite avec la configuration réseau relay par défaut de copy.sh/v86
- L’image disque intégrant Tailscale et Plan 9 faisait 16 Mo, et le binaire Tailscale 23 Mo après décompression
- C’est la raison pour laquelle l’étape « gunzip… » apparaît au démarrage
- L’image d’exemple est incluse dans le profil 9legacy de
copy.sh/v86
Travaux restants et résultats concrets
- Le portage actuel de Tailscale sur Plan 9 n’a été testé que sur 9legacy
- Les principaux forks de Plan 9 incluent 9legacy, minimal, et 9front, plus fortement modifié
- Certains correctifs écrits par Russ pour 9legacy devront peut-être être portés vers 9front
- La prise en charge 64 bits
GOARCH=amd64doit encore être vérifiée - La prise en charge des exit nodes et du paquet Go
net/netnsn’est pas implémentée- Cela pourrait nécessiter de repenser, par exemple, la manière dont Tailscale s’expose sur Plan 9 comme un
/netséparé
- Cela pourrait nécessiter de repenser, par exemple, la manière dont Tailscale s’expose sur Plan 9 comme un
- Ce travail a aussi amélioré la prise en charge de Plan 9 dans Go
- cmd/compile: use FMA on plan9, and drop UseFMA
- runtime: remove nextSampleNoFP from plan9
- cmd/compile, runtime: remove plan9 special case avoiding SSE
- net: fix parsing of interfaces on plan9 without associated devices
- os: guarantee min buffer size for ReadFile reads on /proc-like files
- net: unblock UDP Reads upon Close on plan9, add test
- runtime: fix plan9 monotonic time, crypto randomness
- En particulier, la suppression des traitements spéciaux pour Plan 9 dans le compilateur Go a rendu celui-ci plus simple et plus facile à modifier
- Au moment de la publication de la démo v86, une blague du 1er avril de l’auteur de v86 faisait même apparaître la sortie texte VGA comme du faux néerlandais, mais il était possible de la contourner avec l’argument de requête
&nojoke
1 commentaires
Avis sur Hacker News
Si vous avez des questions, je peux y répondre.
Quelques personnes en discutent en ce moment sur https://meet.google.com/qre-gydb-mkv
Édit : au bout d’une heure, tout le monde était parti.
Le précédent billet de blog du 1er avril était https://tailscale.com/blog/tailscale-enterprise-plan-9-suppo...
Le fait que Russ Cox soit allé jusqu’au bout de cette blague est vraiment légendaire.
Sur la liste 9fans, il y a eu ceci pour le poisson d’avril :
les coûts de maintenance d’architectures informatiques immatures comme mips, 386, arm, arm64 et amd64 étant trop élevés, il a été décidé de se concentrer sur des architectures plus mûres et plus stables.
Les architectures visées seraient power64 et itanium ; par conséquent, toutes les architectures sauf power64 et itanium seraient gelées, archivées et promues en fin de vie.
Blague à part, j’aimerais vraiment qu’il existe une version Enterprise de Plan 9.
Ces temps-ci, j’écris la plupart de mes scripts en
rc, et comme nous utilisons nix et pouvons les récupérer automatiquement avec dirnev, mes collègues prennent sur eux ; c’est plutôt agréable.rcque de savoir s’ils peuvent les lire et les modifier.rc, c’est ceci [1] :« Le principe le plus important dans la conception de rc est qu’il ne s’agit pas d’un processeur de macros. L’entrée n’est jamais scannée plus d’une fois par le code d’analyse lexicale et syntaxique. »
Dans une entreprise Unix où je travaillais autrefois, un script shell en cours d’exécution avait été modifié, ce qui avait effacé la majeure partie du disque de travail. Heureusement, nous avions des sauvegardes quotidiennes sur bande ; c’était il y a environ 17 ans.
[1] https://www.scs.stanford.edu/nyu/04fa/sched/readings/rc.pdf
Si vous avez raté le premier billet et que vous voulez simplement essayer par vous-même, ça fonctionne dans cette image v86 :
https://copy.sh/v86/?profile=custom&m=768&vram=16&hda.url=ht...
Dans la VM, vous pouvez démarrer
tailscaledettailscale. La disponibilité du proxy étant limitée, il peut falloir un peu de temps avant qu’elle passe en ligne.Édit : alt fait office de troisième bouton. Pour ouvrir un terminal, maintenez alt enfoncée et faites un clic droit, choisissez new, relâchez alt puis redimensionnez la fenêtre du terminal en faisant glisser avec le clic droit.
Un webinaire est en cours (Google Meet) https://ftp.plan9.ts.net/webinar
J’aimais bien le postulat de la blague, mais plus l’explication s’allongeait, plus c’est devenu soudainement déprimant.
Il y a trop de choses cassées et trop de complexité. Tout ça pour quoi, au final, créer un tunnel réseau ? Si ce travail supplémentaire avait lui-même fait partie de la blague, ça aurait été drôle.
Je pourrais sûrement retenir rsc, Rob Pike et bradfitz pendant des heures pour parler de Plan 9, en particulier. Bien sûr, ce serait un gaspillage complet de leur temps.
Ce système d’exploitation est vraiment fascinant.
Je me souviens, au début de ma carrière, d’un expert avec qui je travaillais, assis à côté de moi, qui me montrait patiemment comment faire et répondait à mes questions jusqu’à ce que je comprenne suffisamment. C’était une façon de vous apprendre à nager même jeté en eau profonde, et en trois heures j’avais l’impression d’avoir obtenu une licence dans ce domaine précis : l’une des progressions les plus rapides de ma carrière.
Je ne connais pas le C et je n’en sais pas assez sur Plan 9 pour l’utiliser de façon productive, mais il y a des fonctionnalités élégantes et utiles que j’aimerais mieux connaître et apprendre, ne serait-ce que pour regretter leur absence des trois grands systèmes d’exploitation actuels.
Si j’avais de l’argent, j’achèterais du temps avec tous les trois pour élargir mes connaissances de Go, et aussi du temps avec rsc et Rob Pike pour acquérir la compréhension de Plan 9 que j’ai toujours voulue sans réussir à l’obtenir par moi-même.
J’adore Plan 9. Mon projet de retraite et objectif de vie, c’est de reprendre beaucoup de ses principes pour créer mon propre système d’exploitation.
Édit : j’ai réservé le nom « chaos10 » pour ce projet. Comme SerenityOS, il n’y aura sans doute pas de plan.
Je ne m’attendais absolument pas à ce qu’ils aillent jusqu’à patcher le noyau Plan 9 pour que ça fonctionne.