- Coincidiendo con un proyecto de sistema de archivos para una clase y la preparación de una charla para ChiPy, se inició una guía en GitLab para crear paso a paso un sistema de archivos basado en FUSE con Python
- El FIUnamFS usado en clase es un sistema de archivos de juguete con asignación contigua de archivos, sin soporte para subdirectorios y con una limitación de tamaño de 1.44 MB de disquete
- Durante seis semestres se dejó la tarea a 30~40 estudiantes por semestre, pero solo una persona entregó una implementación con FUSE, por lo que creció la necesidad de contar con material de Python FUSE fácil de seguir
- La nueva guía tiene formato de ejercicios progresivos que parten de un sistema de archivos vacío y van agregando llamadas al sistema y funciones, incluyendo implementaciones de lectura/escritura en RAM y passthrough de solo lectura
- También incluye ejemplos breves como un sistema de archivos DNS, compilación instantánea de Markdown, unzip y eliminación de comentarios, para que los estudiantes aprendan FUSE con casos prácticos
Una guía de Python FUSE nacida de un proyecto de clase
- Después de recibir en DebConf22 una propuesta para dar una charla al Chicago Python User Group, y de que el tema volviera a surgir en DebConf24, comenzó la búsqueda de un tema de presentación sobre Python
- Aunque no considera Python como su lenguaje principal, en clase usa Python porque es el lenguaje que mejor siguen sus estudiantes
- El proyecto de clase FIUnamFS es el acrónimo de “Facultad de Ingeniería, Universidad Nacional Autónoma de México”, y es un sistema de archivos usado en clases de la Facultad de Ingeniería de la UNAM
- Está basado en asignación contigua de archivos
- No soporta subdirectorios
- Normalmente está limitado al tamaño de un disquete de 1.44 MB
- Se usa como sistema de archivos de juguete por lo fácil que resulta especificarlo e implementarlo
- Desde hace tiempo se pide a los estudiantes crear una interfaz más pulida que un menú simple, y para usar FIUnamFS sin que el usuario tenga que pensar en ello, FUSE parecía una opción adecuada
- Este proyecto se asignó durante seis semestres a grupos de 30~40 estudiantes por semestre, pero solo un estudiante llegó a entregar una implementación real con FUSE
Límites del material existente y opciones disponibles
- Ya existían ejemplos y artículos sobre Python FUSE, pero muchos eran insuficientes para seguirlos por cuenta propia o estaban desactualizados
- Tampoco existe una sola interfaz FUSE unificada para usar desde Python, así que elegir por dónde empezar también es complicado
Cómo está organizada la guía de GitLab
- El nuevo proyecto de GitLab a hand-holding guide to writing FUSE-based filesystems in Python muestra varias implementaciones funcionales de sistemas de archivos FUSE paso a paso
- Algunas funcionan sobre RAM
- Algunas están implementadas con passthrough
- También planea agregar un sistema de archivos basado en pseudodispositivo de bloques para implementaciones como FIUnamFS
- Actualmente incluye cinco archivos progresivos, empezando por el sistema de archivos vacío más simple y agregando una a una llamadas al sistema y funcionalidades
- También incluye ejemplos breves y útiles que podrían resultar interesantes para estudiantes
- Los ejemplos tienen apenas unas decenas de líneas, así que son fáciles de usar en clase, y
uncommentfselimina automáticamente comentarios y espacios en blanco
Calendario de charlas y material publicado
- La charla de ChiPy se realizará en línea el 10 de octubre de 2024 a las 18:30 GMT-6
- El mismo tema también será presentado en Jornadas Regionales de Software Libre y en nerdear.la
- Después de la presentación también se publicaron videos
- Video de la charla de ChiPy: A hand-holding guide to writing FUSE-based filesystems in Python
- Video de la charla en español: Aprendiendo y enseñando a escribir sistemas de archivo en espacio de usuario con FUSE y Python
1 comentarios
Comentarios de Hacker News
En el GitHub de libfuse, [0] tiene ejemplos para C/C++ bien organizados por nivel de complejidad
passthrough.crefleja un sistema de archivos existente, pero dice que “el rendimiento es terrible”;passthrough_fh.c“no es tan malo”;passthrough_ll.cestá implementado con la API de bajo nivel y “es el menos malo de los tres”; ypassthrough_hp.cces una versión de alto rendimiento escrita en C++Algunos proyectos FUSE interesantes que tenía anotados son dividir archivos grandes [1], mostrar snapshots incrementales de ZFS como archivos [2], compresión transparente del sistema de archivos [3], y opciones para montar archivos comprimidos como sistemas de archivos [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
El punto de montaje de cada dataset tiene una carpeta oculta
.zfsque ni siquiera aparece conls -A, pero puedes hacercddirectamente si asumes que existeDebajo hay una carpeta
snapshot, y dentro una carpeta por cada snapshot de ese dataset, con los archivos del snapshotPor ejemplo,
/etc/hostsdel snapshotzrepl_20241011_010143_000está en/.zfs/snapshot/zrepl_20241011_010143_000/etc/hostsSi no te gusta ese comportamiento oculto medio mágico, también puedes hacer que se vea como una carpeta normal con
zfs set snapdir=visibleMe da gusto ver enlaces relacionados, y como ya estoy algo oxidado, agradecería cualquier tutorial o guía de FUSE que les haya servido
Me gusta FUSE, pero no es la única opción; hace poco implementé un sistema de archivos virtual con el protocolo 9p y fue bastante divertido
Si no recuerdo mal, usé py9p, y la experiencia en Python fue mucho mejor que con fuse-python
Si quieres, puedes montar un servicio 9p a través de FUSE con 9pfuse, pero yo usé el cliente v9fs del kernel
Si tu objetivo es simplemente exponer un sistema de archivos a través de la red, creo que usé el servidor 9p diod; en general es un ecosistema pequeño que vale la pena revisar
Mis notas están en [1], pero en su mayoría son una recopilación de enlaces a material original
FUSE también está bien, pero 9P es más general y tiene implementaciones de buena calidad en varios lugares, incluyendo Windows
Eso sí, no tengo claras las características de rendimiento de 9p; he visto que dicen que es lento, pero no he encontrado material concluyente
Me pregunto si alguien tiene benchmarks o información
[0]: https://github.com/chaos/diod/blob/master/protocol.md
[1]: https://athenaeum.wiki/Zettelkasten/9p
Quería poder hacer lecturas aleatorias como si fuera un archivo local, sin descargar primero el archivo grande completo
Uno de los dolores que encontré fue que el tamaño de bloque de FUSE era demasiado pequeño, así que la latencia y el churn de las llamadas HTTP al backend aumentaban, y terminé necesitando una lógica bastante compleja de caché y prefetch
La lógica de prefetch del kernel no parecía funcionar en absoluto, y en ese momento no investigué mucho más aparte de no encontrar cómo inducirla
El FAQ se puede ver en https://virtio-fs.gitlab.io
Aun así, es un proyecto genial
Ojalá hubiera sabido esto cuando exactamente tuve que pasar por el mismo proceso hace un mes
En un intento desesperado por hacer que Jira fuera menos irritante de usar, se me ocurrió el proyecto jira-as-filesystem, que usa la clasificación interna de issues para construir un árbol
Hice que los directorios representaran issues, los archivos representaran campos del issue y los subdirectorios representaran issues enlazados, y al final elegí fuse-python
No pude trabajar en ello por un tiempo, pero ya me había topado con problemas en la abstracción
Si usas solo el ID del issue como nombre del directorio, la automatización se facilita, pero cuando haces
lssolo ves un montón de IDs difíciles de reconocer, así que para que a las personas les resulte más fácil navegar agregué un tipo de directorio paralelo-with-summaryque añade un resumen convertido en slug después del ID del issueLa idea sería tener un jira-as-filesystem para los archivos originales y, para que las personas naveguen e interactúen, un árbol de enlaces simbólicos que coloque esos mismos archivos con varios enlaces en múltiples ubicaciones relacionadas
Puede que esté agregando más capas de las necesarias por falta de comprensión, pero técnicamente parece que sí podría resolver el problema de abstracción que se menciona aquí
En Linux moderno los discos se referencian tanto por dispositivo de bloques como por UUID, así que me parece que este enfoque está bien y coincide con lo esperado
Aun así, personalmente no creo que lo usaría porque JIRA ya es lo suficientemente complejo por sí solo
Ej.: https://github.com/coddingtonbear/jirafs
1234-human-sense?Parece contener ambos tipos de información y también sería fácil de parsear
Hay muchísimas opciones de montaje de FUSE, todas con distintos compromisos, rendimiento y funciones
También están s3fs, goofys, seaweed, minio, Google Drive, etc., y JuiceFS es bastante interesante para montar almacenamiento de objetos y luego acceder a él de forma tipo POSIX con los metadatos que uno espera de un sistema de archivos tradicional
https://juicefs.com
Está bueno
Una pregunta relacionada: últimamente veo casos donde se implementa un sistema de archivos basado en NFS porque es un protocolo con soporte más amplio
Creo que rclone hace esto en Mac; ¿hay alguna guía o comparación sobre este enfoque?
Funciona casi como un reemplazo, no requiere extensiones de kernel y monta usando funciones de macOS mientras abre un servidor NFS en segundo plano
El rendimiento también es bastante bueno
Si quieres ver cómo luce un producto terminado, vale la pena mirar azuline/rosé, un gestor de música con un sistema de archivos virtual
Tiene una base de código excelente, con muchos comentarios, explicaciones, tipos y pruebas, así que debería ser fácil aprender de ahí
https://github.com/azuline/rose
Si te interesa FUSE, también podría parecerte interesante su proyecto hermano, CUSE
CUSE es una emulación de controladores de dispositivos de caracteres en espacio de usuario, que permite imitar hardware sin compilar nuevos módulos del kernel
Hace poco lo usé para crear un dispositivo de hardware con soporte IOCTL en Python
No encontré una buena biblioteca de Python que funcionara fácilmente y la documentación era escasa, pero al final se pudo hacer solo con la biblioteca FFI de ctypes
La única parte que no me resultó inmediatamente intuitiva, viniendo de alguien que nunca había escrito un driver de kernel, fue que IOCTL entra en pares de llamadas porque hay que volver a ajustar el tamaño del búfer en cada lectura/escritura
Por suerte, CUSE tiene un modo de depuración que muestra todos los bytes de entrada y salida
CUSE se implementó originalmente para crear dispositivos de sonido en espacio de usuario¹, pero también se ha usado para cosas como TTYs personalizados, y yo lo usé para crear un dispositivo SPI virtual
Ojalá le sirva a alguien y este proyecto reciba más atención
¹ https://lwn.net/Articles/308445/
Hace bastante tiempo hice un sistema de archivos FUSE en Python[1] para interactuar con un sistema wiki llamado dokuwiki
Lo construí sobre hde llfuse[2], pero tuve que implementar bastante API de bajo nivel que no tenía relación directa con dokuwiki
Por eso hice easyfuse[3][4] como un wrapper que envuelve las partes no relacionadas con la implementación de dokuwiki, y podría valer la pena revisarlo si estás pensando en crear un sistema FUSE
[1]: https://github.com/JelteF/dokuwikifuse
[2]: https://pypi.org/project/llfuse/
[3]: https://pypi.org/project/easyfuse/
[4]: https://github.com/JelteF/easyfuse
Al final, dokuwiki básicamente es un conjunto de archivos de texto, así que ¿no sería más simple y eficiente montarlo por NFS o compartirlo por Dropbox/Syncthing?
Me gusta pensar en FUSE como una forma de permitir que un Makefile especifique un grafo acíclico dirigido sobre recursos arbitrarios
Por ejemplo, si hubiera un sistema de archivos FUSE que expusiera el estado de un clúster de k8s, podría ser más fácil escribir un operador al que hasta alguien de mente simple como yo pudiera acceder
Lo mismo con el correo electrónico: si expones IMAP como sistema de archivos, ¿no podría una app de RAG (como gpt4all) acceder directamente a todo?
Ya sé que me salgo del tema, pero cuando veo un blog con vibra de los 90/2000 siempre voy a la página del primer post
Incluyendo gwolf.org, mirar ese tipo de cápsulas del tiempo nunca decepciona