1 Punkte von GN⁺ 2024-10-13 | 1 Kommentare | Auf WhatsApp teilen
  • 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

Aufbau des GitLab-Leitfadens

Vortragstermine und veröffentlichte Materialien

1 Kommentare

 
GN⁺ 2024-10-13
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

    • [2] kann zwar ein gutes Codebeispiel sein, aber diese Funktion ist bereits in ZFS eingebaut
      Am Mount-Punkt jedes Datasets gibt es einen versteckten Ordner .zfs, der selbst bei ls -A nicht angezeigt wird; man kann einfach davon ausgehen, dass er existiert, und direkt per cd hineingehen
      Darunter liegt der Ordner snapshot, darin wiederum je ein Ordner für jeden Snapshot dieses Datasets, mit den Dateien des Snapshots
      Zum Beispiel liegt /etc/hosts aus dem Snapshot zrepl_20241011_010143_000 unter /.zfs/snapshot/zrepl_20241011_010143_000/etc/hosts
      Wenn man dieses magische Versteckspiel nicht mag, kann man es mit zfs set snapdir=visible auch so einstellen, dass es wie ein normaler Ordner sichtbar ist
    • Vor einiger Zeit dachte ich über FUSE nach, um unter Linux Case-Sensitivity umgehen zu können
      Die 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

    • 9p ist wirklich ein großartiges kleines Protokoll, und diod[0] enthält auch einiges an Dokumentation zum Protokoll selbst; der Inhalt ist simpel
      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
    • Vor etwa 18 Monaten habe ich damit experimentiert, FUSE vor HTTPS-URLs zu setzen
      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
    • In qemu kann fuse (virtiofs) bessere Performance liefern als 9p (virtio-9p)
      Die FAQ findet man unter https://virtio-fs.gitlab.io
    • Das letzte Release von py9p ist von 2013, und es scheint immer noch als „beta“ markiert zu sein
      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 ls sieht man nur einen Haufen schwer verständlicher IDs, was die Navigation für Menschen erschwert. Deshalb habe ich einen parallelen Verzeichnistyp -with-summary hinzugefügt, bei dem hinter der Issue-ID eine slugifizierte Zusammenfassung steht.

    • Ich will nicht sagen, dass das eine gute Idee ist, aber wie wäre es mit einem Daemon, der eine Symlink-Version der gesamten Jira-Umgebung aktuell hält?
      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.
    • In Unix-Dateisystemen ist es üblich, dasselbe Ziel auf zwei Arten zu referenzieren.
      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.
    • Auf GitHub gibt es ziemlich viele jirafs-Verwandte.
      Beispiel: https://github.com/coddingtonbear/jirafs
    • Könnte man es nicht einfach wie 1234-human-sense machen?
      Das enthält beide Arten von Informationen und scheint leicht zu parsen zu sein.
    • Besteht die Möglichkeit, die gebaute Lösung als Open Source zu veröffentlichen?
  • 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?

    • Interessante Tatsache: In neueren macOS-Versionen muss man Sicherheitsfunktionen deaktivieren, um macFUSE zu installieren, aber es gibt das hervorragende fuse-t.
      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.
    • Rust-Beispiel: https://github.com/xetdata/nfsserve
  • 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

    • Mich würde interessieren, welcher Use Case hinter einem FUSE für dokuwiki stand.
      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.