- À la croisée d’un projet de système de fichiers pour un cours et de la préparation d’une présentation à ChiPy, un guide GitLab démarre pour créer étape par étape un système de fichiers basé sur FUSE en Python
- FIUnamFS, utilisé dans le cours, est un système de fichiers jouet avec allocation contiguë des fichiers, sans prise en charge des sous-répertoires, et limité à la taille d’une disquette de 1,44 Mo
- Sur six semestres, le devoir a été donné à 30 à 40 étudiants par semestre, mais un seul a rendu une implémentation FUSE, ce qui a renforcé le besoin de ressources Python FUSE faciles à suivre
- Le nouveau guide prend la forme de travaux progressifs, partant d’un système de fichiers vide puis ajoutant appels système et fonctionnalités ; il couvre aussi la lecture/écriture en RAM et une implémentation passthrough en lecture seule
- De courts exemples comme DNS, compilation Markdown à la volée, unzip ou système de fichiers supprimant les commentaires sont également inclus pour permettre aux étudiants d’apprendre FUSE à partir d’exemples pratiques
Un guide Python FUSE né d’un projet de cours
- Après avoir reçu à DebConf22 une proposition d’intervention pour le Chicago Python User Group, puis avoir reparlé du sujet à DebConf24, l’auteur a cherché un thème de présentation autour de Python
- Même s’il ne considère pas Python comme son langage principal, il l’utilise en cours car c’est celui que les étudiants suivent le plus facilement
- Le projet de cours FIUnamFS est l’acronyme de « Facultad de Ingeniería, Universidad Nacional Autónoma de México » ; c’est un système de fichiers utilisé dans un cours de la faculté d’ingénierie de l’Université nationale autonome du Mexique
- Il repose sur une allocation contiguë des fichiers
- Il ne prend pas en charge les sous-répertoires
- Il est généralement limité à la taille d’une disquette de 1,44 Mo
- Il sert de système de fichiers jouet, facile à spécifier et à implémenter
- Les étudiants ont été encouragés à créer une interface plus aboutie qu’un simple menu, et FUSE a été jugé adapté pour permettre aux utilisateurs d’utiliser FIUnamFS sans y penser explicitement
- Ce projet a été donné pendant six semestres à 30 à 40 étudiants par semestre, mais un seul étudiant a effectivement rendu une implémentation FUSE
Limites des ressources existantes et choix possibles
- Il existait déjà des exemples et articles sur FUSE en Python, mais beaucoup étaient insuffisants pour être suivis seuls, ou datés
- Les interfaces FUSE utilisables en Python ne sont pas non plus unifiées, ce qui rend difficile le choix du point de départ
Structure du guide GitLab
- Le nouveau projet GitLab a hand-holding guide to writing FUSE-based filesystems in Python présente étape par étape plusieurs implémentations fonctionnelles de systèmes de fichiers FUSE
- Certaines fonctionnent en RAM
- Certaines sont implémentées en mode passthrough
- Il est prévu d’ajouter aussi un système de fichiers basé sur un pseudo-périphérique bloc pour des implémentations comme FIUnamFS
- Il contient actuellement cinq fichiers progressifs, qui partent du système de fichiers vide le plus simple puis ajoutent un à un des appels système et des fonctionnalités
- Le guide inclut aussi de courts exemples utiles susceptibles d’intéresser les étudiants
- Les exemples ne font que quelques dizaines de lignes, ce qui les rend faciles à traiter en cours, et
uncommentfssupprime automatiquement commentaires et espaces
Calendrier des présentations et ressources publiques
- La présentation ChiPy a eu lieu en ligne le 10 octobre 2024 à 18:30 GMT-6
- Le même sujet devait également être présenté aux Jornadas Regionales de Software Libre et à nerdear.la
- Les vidéos ont aussi été publiées après les présentations
- Vidéo de la présentation ChiPy : A hand-holding guide to writing FUSE-based filesystems in Python
- Vidéo de la présentation en espagnol : Aprendiendo y enseñando a escribir sistemas de archivo en espacio de usuario con FUSE y Python
1 commentaires
Avis de Hacker News
Sur le GitHub de libfuse [0], les exemples pour C/C++ sont bien classés par niveau de complexité
passthrough.c miroir un système de fichiers existant, mais il est indiqué que « les performances sont horribles », tandis que passthrough_fh.c serait « pas aussi mauvais »
passthrough_ll.c est implémenté avec l’API bas niveau et serait « le moins mauvais des trois », et passthrough_hp.cc est une version haute performance écrite en C++
Parmi les projets FUSE intéressants que j’avais notés, il y a la division de gros fichiers [1], l’affichage des snapshots incrémentaux ZFS sous forme de fichiers [2], la compression transparente du système de fichiers [3], ainsi que des options pour monter des archives comme systèmes de fichiers [4], [5]
[0] https://github.com/libfuse/libfuse/tree/master/example
[1] https://github.com/seiferma/splitviewfuse
[2] https://github.com/UNFmontreal/zfs_fuse_snapshot
[3] https://github.com/FS-make-simple/fusecompress
[4] https://github.com/google/fuse-archive
[5] https://github.com/mxmlnkn/ratarmount
Au point de montage de chaque dataset, il existe un dossier caché
.zfsqui n’apparaît même pas avecls -A; il suffit d’y faire directementcden partant du principe qu’il existeEn dessous se trouve un dossier
snapshot, qui contient un dossier pour chaque snapshot de ce dataset, avec les fichiers du snapshotPar exemple, le fichier
/etc/hostsdu snapshot zrepl_20241011_010143_000 se trouve dans/.zfs/snapshot/zrepl_20241011_010143_000/etc/hostsSi ce comportement caché un peu magique ne vous plaît pas, vous pouvez aussi le rendre visible comme un dossier normal avec
zfs set snapdir=visibleCes liens sont les bienvenus ; je suis un peu rouillé, donc je serais preneur de tutoriels ou guides FUSE qui vous ont aidé
J’aime bien FUSE, mais ce n’est pas la seule option ; récemment, j’ai essayé d’implémenter un système de fichiers virtuel avec le protocole 9p, et c’était plutôt amusant
De mémoire, j’ai utilisé py9p, et l’expérience en Python était nettement meilleure qu’avec fuse-python
Si on veut, on peut monter un service 9p via FUSE avec 9pfuse, mais j’ai utilisé le client v9fs du noyau
Si le but est simplement de faire passer un système de fichiers par-dessus le réseau, il me semble que j’avais utilisé le serveur 9p diod ; dans l’ensemble, c’est un petit écosystème qui vaut le détour
Mes notes sont en [1], mais ce sont surtout des liens vers les documents d’origine
FUSE est bien aussi, mais 9P est plus généraliste, avec de bonnes implémentations sur de nombreuses plateformes, y compris Windows
En revanche, je ne suis pas sûr des caractéristiques de performance de 9p ; j’ai déjà lu qu’il était lent, mais je n’ai rien vu de définitif
Je me demande s’il existe des benchmarks ou des informations à ce sujet
[0]: https://github.com/chaos/diod/blob/master/protocol.md
[1]: https://athenaeum.wiki/Zettelkasten/9p
Je voulais pouvoir faire des lectures aléatoires comme sur un fichier local, sans télécharger d’abord les gros fichiers
L’une des douleurs rencontrées était que la taille de bloc de FUSE était trop petite, ce qui augmentait la latence et le churn des appels HTTP vers le backend, et nécessitait une logique de cache/prélecture assez complexe
La logique de prélecture du noyau ne semblait pas fonctionner du tout, et à l’époque je n’ai pas poussé l’enquête au-delà du fait que je n’avais pas trouvé comment l’y inciter
La FAQ est disponible sur https://virtio-fs.gitlab.io
Cela reste néanmoins un chouette projet
J’aurais aimé connaître ça il y a un mois, quand j’ai dû suivre exactement le même parcours.
Dans une tentative désespérée de rendre Jira moins pénible à utiliser, j’ai imaginé un projet jira-as-filesystem qui construit une arborescence à partir de notre classification interne des tickets.
Les répertoires représentaient les tickets, les fichiers les champs des tickets, et les sous-répertoires les tickets liés ; j’ai fini par choisir fuse-python.
Je n’ai pas pu avancer dessus pendant un moment, mais je me suis déjà heurté à des problèmes d’abstraction.
Si les noms de répertoire ne contiennent que l’ID du ticket, l’automatisation est simple, mais un
lsn’affiche qu’une masse d’ID difficiles à reconnaître, ce qui rend l’exploration pénible pour un humain ; j’ai donc ajouté un type de répertoire parallèle-with-summary, qui ajoute après l’ID du ticket un résumé transformé en slug.L’idée serait d’avoir un jira-as-filesystem pour les fichiers originaux, et, pour la navigation et l’interaction humaines, une arborescence de liens symboliques plaçant les mêmes fichiers à plusieurs emplacements pertinents.
C’est peut-être que je comprends mal le problème et que j’ajoute une couche de trop, mais techniquement cela semble pouvoir résoudre le problème d’abstraction évoqué.
Sous Linux moderne, les disques sont référencés à la fois comme périphériques bloc et par UUID ; cette approche me paraît donc correcte et conforme aux attentes.
Cela dit, personnellement, je ne l’utiliserais probablement pas, JIRA étant déjà assez complexe comme ça.
Exemple : https://github.com/coddingtonbear/jirafs
1234-human-sense?Ça contient les deux types d’information et ça semble facile à parser.
Il existe vraiment beaucoup d’options de montage FUSE, avec des compromis, des performances et des fonctionnalités très variables.
Il y a aussi s3fs, goofys, seaweed, minio, Google Drive, etc., et JuiceFS est assez intéressant pour monter un stockage objet puis y accéder façon POSIX, avec les métadonnées qu’on attend d’un système de fichiers traditionnel.
https://juicefs.com
Sympa.
Question voisine : récemment, j’ai vu des implémentations de systèmes de fichiers basés sur NFS, parce que c’est un protocole plus largement pris en charge.
Il me semble que rclone procède ainsi sur Mac ; existe-t-il des guides ou comparatifs sur cette approche ?
Il fonctionne presque comme un substitut, ne nécessite pas d’extension noyau, lance un serveur NFS en arrière-plan et le monte via les fonctions de macOS.
Les performances sont aussi plutôt bonnes.
Si vous voulez voir à quoi ressemble un produit abouti, regardez azuline/rosé, un gestionnaire de musique doté d’un système de fichiers virtuel.
C’est une excellente base de code, avec beaucoup de commentaires, de documentation, de types et de tests ; elle devrait être facile à apprendre.
https://github.com/azuline/rose
Si FUSE vous intéresse, son projet compagnon CUSE pourrait aussi vous intéresser.
CUSE émule des pilotes de périphériques caractère en espace utilisateur, ce qui permet de simuler du matériel sans compiler de nouveau module noyau.
Je l’ai utilisé récemment pour écrire en Python un périphérique matériel prenant en charge IOCTL.
Je n’ai pas trouvé de bonne bibliothèque Python fonctionnant facilement, et la documentation était maigre, mais au final la bibliothèque FFI ctypes a suffi.
N’ayant jamais écrit de pilote noyau, le seul point qui ne m’a pas paru immédiatement intuitif est qu’IOCTL doit réajuster la taille du tampon à chaque lecture/écriture, ce qui fait que les appels arrivent par paires.
Heureusement, CUSE dispose d’un mode debug qui affiche tous les octets en entrée et en sortie.
CUSE a été implémenté à l’origine pour créer des périphériques audio en espace utilisateur¹, mais il a aussi servi à des usages comme des TTY personnalisés ; de mon côté, je l’ai utilisé pour créer un périphérique SPI virtuel.
J’espère que cela sera utile à quelqu’un et que ce projet gagnera en visibilité.
¹ https://lwn.net/Articles/308445/
Il y a assez longtemps, j’ai créé un système de fichiers FUSE en Python[1] pour interagir avec un système de wiki appelé dokuwiki.
Je l’ai construit par-dessus llfuse[2] de hde, mais j’ai dû implémenter pas mal d’API bas niveau sans rapport direct avec dokuwiki.
J’ai donc créé easyfuse[3][4], un wrapper pour encapsuler les parties indépendantes de l’implémentation dokuwiki ; si vous envisagez de créer un système FUSE, ça peut valoir le coup d’y jeter un œil.
[1]: https://github.com/JelteF/dokuwikifuse
[2]: https://pypi.org/project/llfuse/
[3]: https://pypi.org/project/easyfuse/
[4]: https://github.com/JelteF/easyfuse
Fondamentalement, dokuwiki est un ensemble de fichiers texte ; ne serait-il pas plus simple et plus efficace de le monter via NFS ou de le partager avec Dropbox/Syncthing ?
On peut voir FUSE comme un moyen de permettre à un Makefile de définir un graphe orienté acyclique au-dessus de ressources arbitraires.
Par exemple, avec un système de fichiers FUSE exposant l’état d’un cluster k8s, même un esprit simple comme le mien pourrait écrire plus facilement des opérateurs accessibles.
Même chose pour les e-mails : si l’on expose IMAP comme un système de fichiers, une appli de RAG (comme gpt4all) ne pourrait-elle pas accéder directement à tout ?
Hors sujet, mais quand je tombe sur un blog à l’ambiance années 90/2000, je vais toujours voir la page du premier billet.
Y compris sur gwolf.org : regarder dans ce genre de capsule temporelle ne déçoit jamais.