- Im Zuge eines Dateisystem-Projekts für den Unterricht und der Vorbereitung eines ChiPy-Vortrags wurde ein GitLab-Leitfaden gestartet, der Schritt für Schritt zeigt, wie man ein FUSE-basiertes Dateisystem in Python erstellt
- Das im Unterricht verwendete FIUnamFS ist ein Spielzeug-Dateisystem mit zusammenhängender Dateiallokation, ohne Unterstützung für Unterverzeichnisse und mit einer Größenbeschränkung auf 1,44-MB-Disketten
- Sechs Semester lang wurde die Aufgabe pro Semester an 30 bis 40 Studierende gestellt, aber nur eine Person reichte eine FUSE-Implementierung ein, wodurch der Bedarf an leicht nachvollziehbarem Python-FUSE-Material stieg
- Der neue Leitfaden ist als schrittweise Aufgabenreihe aufgebaut, die mit einem leeren Dateisystem beginnt und nach und nach Systemaufrufe und Funktionen ergänzt; behandelt werden auch RAM-basierte Lese-/Schreibimplementierungen und eine schreibgeschützte Passthrough-Implementierung
- Dazu kommen kurze Beispiele wie DNS, spontane Markdown-Kompilierung, unzip und ein Dateisystem zum Entfernen von Kommentaren, sodass Studierende FUSE an praktischen Beispielen lernen können
Python-FUSE-Leitfaden aus einem Unterrichtsprojekt heraus
- Nach einem Vortragsvorschlag der Chicago Python User Group auf der DebConf22 kam das Thema auf der DebConf24 erneut zur Sprache, wodurch nach einem Python-Vortragsthema gesucht wurde
- Python gilt zwar nicht als bevorzugte Hauptsprache, wird im Unterricht aber verwendet, weil die Studierenden ihr am besten folgen können
- Das Unterrichtsprojekt FIUnamFS ist die Abkürzung für „Facultad de Ingeniería, Universidad Nacional Autónoma de México“ und ein Dateisystem, das in Lehrveranstaltungen der Ingenieurfakultät der Nationalen Autonomen Universität von Mexiko verwendet wird
- Es basiert auf zusammenhängender Dateiallokation
- Es unterstützt keine Unterverzeichnisse
- Es ist in der Regel auf die Größe einer 1,44-MB-Diskette beschränkt
- Es dient als leicht spezifizierbares und leicht umsetzbares Spielzeug-Dateisystem
- Von den Studierenden wurde verlangt, eine ausgefeiltere Oberfläche als ein simples Menü zu bauen, und FUSE erschien passend, damit Nutzende FIUnamFS verwenden können, ohne sich dessen bewusst zu sein
- Dieses Projekt wurde über sechs Semester hinweg jeweils 30 bis 40 Studierenden gegeben, aber nur eine einzige Person reichte tatsächlich eine FUSE-Implementierung ein
Grenzen vorhandener Materialien und Auswahlmöglichkeiten
- Es gab bereits Python-FUSE-Beispiele und Artikel, viele davon waren aber zum eigenständigen Nachvollziehen unzureichend oder veraltet
- Auch die in Python nutzbaren FUSE-Schnittstellen sind nicht auf eine einzige Lösung vereinheitlicht, was die Wahl eines Startpunkts erschwert
Aufbau des GitLab-Leitfadens
- Das neue GitLab-Projekt a hand-holding guide to writing FUSE-based filesystems in Python zeigt mehrere funktionierende Implementierungen von FUSE-Dateisystemen Schritt für Schritt
- Einige arbeiten RAM-basiert
- Einige sind Passthrough-basiert umgesetzt
- Für Implementierungen wie FIUnamFS soll außerdem ein Dateisystem auf Basis eines Pseudo-Blockgeräts ergänzt werden
- Derzeit enthält es fünf schrittweise aufgebaute Dateien, beginnend mit dem einfachsten leeren Dateisystem, zu dem Systemaufrufe und Funktionen nach und nach hinzugefügt werden
- Dazu kommen kurze und nützliche Beispiele, die für Studierende interessant sein könnten
- Die Beispiele umfassen nur einige Dutzend Zeilen und lassen sich daher gut im Unterricht behandeln;
uncommentfsentfernt Kommentare und Leerraum automatisch
Vortragstermine und veröffentlichte Materialien
- Der ChiPy-Vortrag findet am 10. Oktober 2024 um 18:30 GMT-6 online statt
- Dasselbe Thema soll auch bei den Jornadas Regionales de Software Libre und auf nerdear.la vorgestellt werden
- Nach den Vorträgen wurden auch Videos veröffentlicht
- ChiPy-Vortragsvideo: A hand-holding guide to writing FUSE-based filesystems in Python
- Spanischsprachiges Vortragsvideo: Aprendiendo y enseñando a escribir sistemas de archivo en espacio de usuario con FUSE y Python
1 Kommentare
Meinungen auf Hacker News
Auf dem libfuse-GitHub [0] sind Beispiele für C/C++ gut nach Komplexität geordnet
passthrough.c spiegelt ein bestehendes Dateisystem, wird aber als „performance is terrible“ beschrieben; passthrough_fh.c sei „not quite as bad“
passthrough_ll.c ist mit der Low-Level-API implementiert und „the least bad of the three“, während passthrough_hp.cc eine in C++ geschriebene High-Performance-Version ist
Interessante FUSE-Projekte, die ich mir notiert habe, sind Aufteilen großer Dateien [1], ZFS-Incremental-Snapshots als Dateien anzeigen [2], transparente Dateisystem-Kompression [3] sowie Optionen, Archive als Dateisystem zu mounten [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
Am Mount-Punkt jedes Datasets gibt es einen versteckten Ordner
.zfs, der selbst beils -Anicht angezeigt wird; man kann einfach davon ausgehen, dass er existiert, und direkt percdhineingehenDarunter liegt der Ordner
snapshot, darin wiederum je ein Ordner für jeden Snapshot dieses Datasets, mit den Dateien des SnapshotsZum Beispiel liegt
/etc/hostsaus dem Snapshot zrepl_20241011_010143_000 unter/.zfs/snapshot/zrepl_20241011_010143_000/etc/hostsWenn man dieses magische Versteckspiel nicht mag, kann man es mit
zfs set snapdir=visibleauch so einstellen, dass es wie ein normaler Ordner sichtbar istDie Links dazu sind willkommen; mein Gefühl dafür ist etwas eingerostet, daher würde ich mich über FUSE-Tutorials oder -Guides freuen, die euch geholfen haben
Ich mag FUSE, aber es ist nicht die einzige Option; vor einiger Zeit habe ich ein virtuelles Dateisystem mit dem 9p-Protokoll implementiert, und das hat ziemlich Spaß gemacht
Soweit ich mich erinnere, habe ich py9p verwendet, und die Python-Erfahrung war deutlich besser als mit fuse-python
Wenn man möchte, kann man einen 9p-Service mit 9pfuse über FUSE mounten, ich habe aber den Kernel-v9fs-Client benutzt
Wenn es einfach darum geht, ein Dateisystem über das Netzwerk bereitzustellen, habe ich, glaube ich, den diod-9p-Server verwendet; insgesamt ein kleines Ökosystem, das einen Blick wert ist
Meine Notizen sind unter [1], aber größtenteils ist das eine Sammlung von Links zu Originalmaterial
FUSE ist auch gut, aber 9P ist allgemeiner einsetzbar, und es gibt hochwertige Implementierungen an vielen Stellen, einschließlich Windows
Allerdings bin ich mir bei den Performance-Eigenschaften von 9p nicht sicher; ich habe zwar gelesen, dass es langsam sei, aber keine belastbaren Daten gesehen
Ich frage mich, ob es Benchmarks oder Informationen dazu gibt
[0]: https://github.com/chaos/diod/blob/master/protocol.md
[1]: https://athenaeum.wiki/Zettelkasten/9p
Ich wollte große Dateien beliebig wie lokale Dateien lesen können, ohne sie zuerst herunterzuladen
Einer der Schmerzen dabei war, dass die Blockgröße von FUSE zu klein ist, wodurch die Latenz und der Churn der HTTP-Aufrufe zum Backend groß wurden und ziemlich komplexe Caching-/Read-ahead-Logik nötig war
Die Read-ahead-Logik des Kernels schien überhaupt nicht zu funktionieren, und damals habe ich nicht weiter nachgeforscht, außer dass ich keinen Weg fand, sie dazu zu bringen
Die FAQ findet man unter https://virtio-fs.gitlab.io
Trotzdem ein schönes Projekt
Hätte ich das doch gekannt, als ich vor einem Monat genau denselben Prozess durchlaufen musste.
In einem verzweifelten Versuch, Jira weniger nervig zu machen, kam mir das Projekt jira-as-filesystem in den Sinn, das aus der internen Issue-Klassifizierung einen Baum erzeugt.
Verzeichnisse sollten Issues darstellen, Dateien Issue-Felder und Unterverzeichnisse verknüpfte Issues; am Ende entschied ich mich für fuse-python.
Ich konnte eine Weile nicht daran arbeiten, aber schon jetzt gibt es Probleme mit der Abstraktion.
Wenn man als Verzeichnisnamen nur die Issue-ID verwendet, ist Automatisierung einfach, aber bei
lssieht man nur einen Haufen schwer verständlicher IDs, was die Navigation für Menschen erschwert. Deshalb habe ich einen parallelen Verzeichnistyp-with-summaryhinzugefügt, bei dem hinter der Issue-ID eine slugifizierte Zusammenfassung steht.Man hätte ein jira-as-filesystem für die Originaldateien und für menschliche Navigation und Interaktion einen Symlink-Baum, der dieselben Dateien an mehreren relevanten Stellen als mehrere Links platziert.
Es kann sein, dass ich aus mangelndem Verständnis mehr Schichten einziehe als nötig, aber technisch scheint das das gerade beschriebene Abstraktionsproblem lösen zu können.
Auf modernen Linux-Systemen werden Datenträger sowohl als Block Devices als auch per UUID referenziert; daher halte ich diesen Ansatz für in Ordnung und erwartungsgemäß.
Persönlich würde ich es allerdings wohl nicht nutzen, weil JIRA selbst schon komplex genug ist.
Beispiel: https://github.com/coddingtonbear/jirafs
1234-human-sensemachen?Das enthält beide Arten von Informationen und scheint leicht zu parsen zu sein.
Es gibt wirklich viele FUSE-Mount-Optionen, jeweils mit unterschiedlichen Kompromissen, unterschiedlicher Performance und unterschiedlichen Features.
Es gibt auch s3fs, goofys, seaweed, minio, Google Drive usw.; JuiceFS ist ziemlich interessant, wenn man Object Storage mounten und dann POSIX-artig mit den Metadaten darauf zugreifen will, die man von einem traditionellen Dateisystem erwartet.
https://juicefs.com
Gut.
Als angrenzende Frage: In letzter Zeit sehe ich Fälle, in denen NFS-basierte Dateisysteme implementiert werden, weil das ein breiter unterstütztes Protokoll ist.
rclone scheint das auf dem Mac so zu machen; gibt es zu diesem Ansatz Guides oder Vergleichsmaterial?
Es funktioniert fast wie ein Ersatz, braucht keine Kernel-Erweiterung, startet im Hintergrund einen NFS-Server und mountet ihn mit macOS-Funktionen.
Auch die Performance ist ziemlich gut.
Wenn man sehen möchte, wie ein fertiges Produkt aussieht, lohnt sich ein Blick auf den Musikmanager azuline/rosé mit virtuellem Dateisystem.
Es ist eine hervorragende Codebase mit vielen Kommentaren, Erklärungen, Typen und Tests, also dürfte sie gut zum Lernen geeignet sein.
https://github.com/azuline/rose
Wenn du dich für FUSE interessierst, könnte auch das Schwesterprojekt CUSE spannend sein.
CUSE ist eine Emulation für Character-Device-Treiber im Userspace und ermöglicht es, Hardware nachzuahmen, ohne ein neues Kernel-Modul zu kompilieren.
Ich habe es kürzlich verwendet, um in Python ein Hardwaregerät mit IOCTL-Unterstützung zu schreiben.
Ich konnte weder eine gute Python-Bibliothek finden, die einfach funktioniert, noch war die Dokumentation ausreichend, aber am Ende ließ es sich allein mit der ctypes-FFI-Bibliothek gut genug schreiben.
Der einzige Teil, der für jemanden ohne Erfahrung mit Kernel-Treibern nicht sofort intuitiv war, war, dass IOCTL für jeden Lese-/Schreibvorgang die Puffergröße neu anpassen muss und die Aufrufe daher paarweise kommen.
Zum Glück hat CUSE einen Debug-Modus, der alle Ein- und Ausgabe-Bytes anzeigt.
CUSE wurde ursprünglich implementiert, um Soundgeräte im Userspace zu bauen¹, wurde aber auch für Dinge wie Custom-TTYs genutzt; ich habe es zum Bau eines virtuellen SPI-Geräts verwendet.
Ich hoffe, dass es jemandem nützt und dieses Projekt mehr Aufmerksamkeit bekommt.
¹ https://lwn.net/Articles/308445/
Vor ziemlich langer Zeit habe ich ein Python-FUSE-Dateisystem[1] gebaut, um mit einem Wiki-System namens dokuwiki zu interagieren.
Es basierte auf hde llfuse[2], und ich musste ziemlich viele Low-Level-APIs implementieren, die nicht direkt mit dokuwiki zu tun hatten.
Deshalb habe ich easyfuse[3][4] als Wrapper gebaut, der die von der dokuwiki-Implementierung unabhängigen Teile kapselt; wenn man ein FUSE-System bauen will, ist es einen Blick wert.
[1]: https://github.com/JelteF/dokuwikifuse
[2]: https://pypi.org/project/llfuse/
[3]: https://pypi.org/project/easyfuse/
[4]: https://github.com/JelteF/easyfuse
Im Grunde ist dokuwiki doch ein Bündel von Textdateien; wäre es nicht einfacher und effizienter, es per NFS zu mounten oder über Dropbox/Syncthing zu teilen?
Man kann sich FUSE gut als eine Methode vorstellen, mit der ein Makefile einen gerichteten azyklischen Graphen über beliebige Ressourcen festlegen kann.
Wenn es zum Beispiel ein FUSE-Dateisystem gäbe, das den Zustand eines k8s-Clusters offenlegt, könnte es selbst für jemanden mit einem einfachen Kopf wie mich leichter werden, einen zugänglichen Operator zu schreiben.
Ähnlich bei E-Mails: Wenn man IMAP als Dateisystem offenlegt, könnten RAG-Apps wie gpt4all dann nicht direkt auf alles zugreifen?
Abseits des Themas: Wenn ich Blogs im Stil der 90er/2000er sehe, gehe ich immer zur Seite mit dem ersten Beitrag.
Auch bei gwolf.org enttäuscht der Blick in solche Zeitkapseln nie.