Un musée de ZFS, lu dans son code source

Uberblok

Le stockage a toujours eu les mêmes ennemis : des disques qui mentent, des écritures interrompues, une panne au milieu d’une mise à jour. ZFS leur répond avec une poignée d’idées. Ce musée les montre une salle après l’autre, à partir du code qui les met en œuvre.

Chaque animation renvoie à des lignes d’OpenZFS zfs-2.4.4, figé au commit 71a9f9578616, et chaque extrait pointe vers elles. Rien n’est cité de mémoire.

Pourquoi ce musée ?

Rendu d’une bande de papier listing à pliage paravent, imprimée avec le fichier d’OpenZFS include/sys/uberblock_impl.h, dont l’extrémité lointaine s’efface. Une loupe ronde à monture et manche noirs, tenue au-dessus, agrandit la déclaration surlignée de struct uberblock : uint64_t ub_magic, ub_version, ub_txg, ub_guid_sum, ub_timestamp et blkptr_t ub_rootbp ressortent, plus grands que les lignes autour. La loupe projette sur le papier une ombre douce, avec une tache de lumière.

Fig. 1. L’objet du hall sous la loupe : struct uberblock, lignes 122 à 128 de include/sys/uberblock_impl.h à zfs-2.4.4, imprimées avec les lignes 36 à 150 du fichier.

  1. struct uberblock : l’enregistrement qui désigne tout le pool
  2. ub_txg : le groupe de transactions de la dernière synchronisation
  3. ub_rootbp : le pointeur de bloc vers la racine de l’arbre, le MOS
  4. Le listing : les lignes 36 à 150 du fichier, numérotées comme dans la source

L’objet du hall : l’uberblock

Un pool, ce sont des millions de blocs répartis sur plusieurs disques. Après une panne, le système doit retrouver son état courant et cohérent sans en parcourir aucun. Un petit enregistrement désigne donc la racine de tout : l’uberblock. Il contient un numéro de groupe de transactions, ub_txg, et un pointeur de bloc, ub_rootbp ; tous les autres blocs du pool sont atteignables depuis ce pointeur.

Chaque disque porte quatre labels, deux au début et deux à la fin, et chaque label garde un anneau de 128 Kio d’uberblocks. Un nouvel uberblock n’écrase jamais le précédent : celui du txg N va dans la case N modulo le nombre de cases (avec multihost=on, la dernière case est réservée au MMP, et l’anneau tourne sur une case de moins). À l’import, ZFS lit toutes les cases de tous les labels et garde l’uberblock valide au txg le plus élevé.

On dit souvent que l’anneau contient 128 uberblocks. Il fait 128 Kio : une case occupe un secteur, arrondie à 1 Kio au moins et plafonnée à 8 Kio, soit 128 cases sur des secteurs de 512 octets, 64 avec un ashift de 11, 32 sur les disques actuels à secteurs de 4 Kio, 16 au-delà. Changez la taille de secteur et regardez les txg suivants prendre leur case tour à tour.

txg 4211
ub_magic
0x00bab10c
ub_txg
4211
ub_rootbp
→ MOS

Anneau de 32 cases de 4 Kio (ashift 12). L’uberblock du txg 4211 est le plus récent : case 19, car 4211 mod 32 = 19. L’uberblock du txg 4210 reste intact dans la case 18.

Tout uberblock commence par le même nombre magique, 0x00bab10c : « oo-ba-bloc ».

Plan de la visite

Les salles suivent les données : la racine et l’arbre, la façon dont l’arbre change, l’endroit où les blocs atterrissent, ce que l’arbre rend possible, puis les fonctions bâties dessus, et la salle des machines, où le musée dit comment il a été fait.

  1. Hall : l’uberblock L’enregistrement qui désigne tout le pool, et l’anneau qui le garde.
  2. Aile de l’histoire Des premières lignes de code à OpenZFS, chaque fait sourcé.
  3. L’arbre et l’uberblock Des pointeurs de bloc jusqu’en bas, et l’écriture qui fait d’un nouvel arbre l’arbre courant.
  4. Copie sur écriture, sommes de contrôle et autoréparation Pourquoi un pool reste cohérent sans fsck, et comment il démasque un disque qui ment.
  5. Groupes de transactions Ouvert, en clôture, en synchronisation : comment des milliers d’écritures deviennent une seule validation.
  6. Les vdevs Miroir, raidz, draid, log, cache, special : l’arbre des périphériques sous un pool.
  7. RAID-Z Des bandes de largeur variable, et pourquoi il n’y a pas de trou d’écriture.
  8. Instantanés et clones Dates de naissance et deadlists : à quel instantané appartient ce bloc ?
  9. L’ARC Un cache qui apprend de ce qu’il a oublié.
  10. Metaslabs et space maps Trouver vite de l’espace libre, avec un journal d’allocations en ajout seul.
  11. ZIL et SLOG Le chemin d’une écriture synchrone.
  12. send / receive Un dataset en flux, et l’incrément entre deux instantanés.
  13. Compression, déduplication, chiffrement Trois transformations dans le pipeline d’écriture, et le vrai coût de la déduplication.
  14. Salle des machines Comment ce musée a été construit, et à partir de quel commit.

Dédicace

Pourquoi ce musée ?

Garder les données intactes est un travail critique, et qui se voit rarement. Un système de fichiers reçoit tout ce que l’on conserve, et il doit rester exact malgré les pannes, les disques défaillants et les écritures interrompues. L’un des principes de conception de ZFS, selon les mots de Bill Moore : never, ever trust the underlying hardware. (ne jamais, au grand jamais, faire confiance au matériel sous-jacent ; notre traduction)1

Ce musée rend hommage à cette pièce d’ingénierie, et à ceux qui l’ont bâtie. Jeff Bonwick a dirigé le développement de ZFS, avec Bill Moore pour codirecteur ;1 Matt Ahrens en fut l’un des deux auteurs originels.2 Les travaux ont commencé en 2001 avec deux ingénieurs de Sun Microsystems3 et ZFS a été intégré à Solaris le 31 octobre 2005,4 étape que Bonwick résume ainsi : 584 files, 92,000 lines of change, 56 patents, 5 years (584 fichiers, 92 000 lignes modifiées, 56 brevets, 5 ans ; notre traduction).4 Le 17 novembre, il écrivait : I’m incredibly proud of the ZFS team, and deeply grateful: no one person can do something on this scale. (je suis immensément fier de l’équipe ZFS, et profondément reconnaissant : personne ne peut, seul, faire quelque chose à cette échelle ; notre traduction)5

Il rend hommage, aussi, à l’ingénierie de Sun en ces années-là, où les ingénieurs publiaient le fonctionnement de leurs systèmes : l’allocateur slab, présenté par Jeff Bonwick à USENIX en 1994 ;6 DTrace, de Bryan Cantrill, Michael Shapiro et Adam Leventhal, en 2004 ;7 et le code source de ZFS lui-même, publié sous licence CDDL dans le cadre d’OpenSolaris.3

Et à ceux qui le font vivre : OpenZFS, annoncé en 20132 et fondé par des membres des communautés Linux, FreeBSD, Mac OS X et illumos.2 La version que ce musée lit compte plus de 700 personnes dans son fichier AUTHORS.

Rendu d’un disque dur démonté le long de son axe : le châssis, le moteur, trois plateaux bruns et brillants, la bride et, tout en haut, le capot dessiné au trait ; les bras du bloc de têtes s’avancent au-dessus des plateaux.

Fig. 2. Le matériel sous-jacent : un disque dur de 3,5 pouces, éclaté le long de son axe.

  1. Capot
  2. Bride de serrage
  3. Plateaux
  4. Bloc de têtes : bras et têtes
  5. Bobine mobile et son aimant
  6. Moteur de broche
  7. Châssis

Sources

  1. 1 “A Conversation with Jeff Bonwick and Bill Moore”, ACM Queue 5(6), November 2007 (archived 2011-07-16)
  2. 2 OpenZFS launch announcement, open-zfs.org (archived 2013-09-20)
  3. 3 openzfs.org wiki, “History” (archived 2020-05-14)
  4. 4 Jeff Bonwick, “ZFS: The Last Word in Filesystems”, blog post of 31 October 2005 (archived 2007-02-07)
  5. 5 Jeff Bonwick, blog, posts of November 2005, “Thank You” of 17 November 2005 (archived 2006-12-19)
  6. 6 USENIX, abstract of “The Slab Allocator: An Object-Caching Kernel Memory Allocator”, Summer 1994 Technical Conference (archived 2001-02-21)
  7. 7 USENIX, abstract of “Dynamic Instrumentation of Production Systems”, 2004 Annual Technical Conference (archived 2006-01-07)