- Com a coincidência entre um projeto de sistema de arquivos para a disciplina e a preparação de uma apresentação na ChiPy, foi iniciado um guia no GitLab para criar passo a passo um sistema de arquivos baseado em FUSE com Python
- O FIUnamFS usado na disciplina é um sistema de arquivos de brinquedo com alocação contígua de arquivos, sem suporte a subdiretórios e limitado ao tamanho de um disquete de 1,44 MB
- Ao longo de seis semestres, a tarefa foi passada para 30 a 40 alunos por semestre, mas apenas um entregou uma implementação com FUSE, o que aumentou a necessidade de material de Python FUSE fácil de acompanhar
- O novo guia segue o formato de tarefas progressivas, começando de um sistema de arquivos vazio e adicionando chamadas de sistema e funcionalidades, cobrindo até implementações de leitura/escrita em RAM e passthrough somente leitura
- Há também exemplos curtos como sistemas de arquivos de DNS, compilação instantânea de Markdown, unzip e remoção de comentários, para que os alunos aprendam FUSE com exemplos práticos
Um guia de Python FUSE que nasceu de um projeto de disciplina
- Depois de receber uma proposta de apresentação no Chicago Python User Group durante a DebConf22, o tema voltou à tona na DebConf24, levando à busca por um assunto de apresentação em Python
- Embora Python não seja considerado sua linguagem principal, ele é a linguagem que os alunos acompanham melhor, por isso é usado na disciplina
- O projeto da disciplina, FIUnamFS, significa “Facultad de Ingeniería, Universidad Nacional Autónoma de México” e é um sistema de arquivos usado nas aulas da Escola de Engenharia da Universidade Nacional Autônoma do México
- É baseado em alocação contígua de arquivos
- Não oferece suporte a subdiretórios
- Normalmente é limitado ao tamanho de um disquete de 1,44 MB
- É usado como um sistema de arquivos de brinquedo, com especificação e implementação simples
- Há tempos os alunos são incentivados a criar uma interface mais refinada do que um menu simples, e o autor considera o FUSE a opção adequada para que o usuário use o FIUnamFS sem precisar percebê-lo conscientemente
- Esse projeto foi proposto a 30 a 40 alunos por semestre durante seis semestres, mas apenas um aluno entregou de fato uma implementação com FUSE
Limitações do material existente e opções disponíveis
- Já existiam exemplos e textos sobre Python FUSE, mas muitos eram insuficientes para seguir de forma autônoma ou estavam desatualizados
- As interfaces de FUSE que podem ser usadas em Python também não estão padronizadas em uma única opção, o que dificulta escolher por onde começar
Como o guia no GitLab é estruturado
- O novo projeto no GitLab a hand-holding guide to writing FUSE-based filesystems in Python mostra passo a passo várias implementações funcionais de sistemas de arquivos FUSE
- Algumas funcionam em RAM
- Algumas são implementadas com base em passthrough
- Também há planos para adicionar um sistema de arquivos baseado em pseudodispositivo de blocos para implementações como o FIUnamFS
- Atualmente há cinco arquivos progressivos, começando pelo sistema de arquivos vazio mais simples e adicionando chamadas de sistema e funcionalidades uma a uma
- Também há exemplos curtos e úteis que podem despertar o interesse dos alunos
- Os exemplos têm só algumas dezenas de linhas, o que facilita o uso em aula, e o
uncommentfsremove automaticamente comentários e espaços em branco
Agenda das apresentações e material publicado
- A apresentação na ChiPy ocorreu online em 10 de outubro de 2024, às 18:30 GMT-6
- O mesmo tema também seria apresentado no Jornadas Regionales de Software Libre e no nerdear.la
- Os vídeos das apresentações também foram publicados
- Vídeo da apresentação na ChiPy: A hand-holding guide to writing FUSE-based filesystems in Python
- Vídeo da apresentação em espanhol: Aprendiendo y enseñando a escribir sistemas de archivo en espacio de usuario con FUSE y Python
1 comentários
Comentários do Hacker News
No GitHub do libfuse [0], há exemplos para C/C++ bem organizados por nível de complexidade
passthrough.cespelha um sistema de arquivos existente, mas é descrito como tendo “desempenho terrível”, enquantopassthrough_fh.cé “não tão ruim assim”passthrough_ll.cé implementado com a API de baixo nível e é descrito como “o menos ruim dos três”, epassthrough_hp.ccé uma versão de alto desempenho escrita em C++Entre os projetos FUSE interessantes que anotei estão divisão de arquivos grandes [1], exibição de snapshots incrementais do ZFS como arquivos [2], compressão transparente de sistema de arquivos [3] e opções para montar arquivos compactados como sistemas de arquivos [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
No ponto de montagem de todo dataset há uma pasta oculta
.zfs, que nem aparece emls -A; basta acreditar que ela existe e darcddiretamente nelaDentro dela há uma pasta
snapshot, e nela há uma pasta para cada snapshot daquele dataset, contendo os arquivos do snapshotPor exemplo, o
/etc/hostsdo snapshotzrepl_20241011_010143_000fica em/.zfs/snapshot/zrepl_20241011_010143_000/etc/hostsSe você não gosta desse comportamento mágico de ocultação, também pode configurá-la para aparecer como uma pasta normal com
zfs set snapdir=visibleFico feliz com esses links relacionados e, como minha intuição está meio enferrujada, gostaria de receber tutoriais ou guias de FUSE que tenham sido úteis
Gosto de FUSE, mas ele não é a única opção; há algum tempo implementei um sistema de arquivos virtual com o protocolo 9p e foi bem divertido
Pelo que lembro, usei py9p, e a experiência com Python foi muito melhor do que com fuse-python
Se quiser, dá para montar um serviço 9p via FUSE usando 9pfuse, mas eu usei o cliente v9fs do kernel
Se o objetivo for simplesmente transportar um sistema de arquivos pela rede, acho que usei o servidor 9p diod; no geral, é um pequeno ecossistema que vale a pena conhecer
Minhas anotações estão em [1], mas são principalmente uma coleção de links para os materiais originais
FUSE também é bom, mas 9P é mais genérico, e há implementações de boa qualidade em vários lugares, incluindo Windows
Porém não tenho certeza sobre as características de desempenho do 9p; já vi comentários dizendo que ele é lento, mas não encontrei material definitivo
Gostaria de saber se há benchmarks ou informações
[0]: https://github.com/chaos/diod/blob/master/protocol.md
[1]: https://athenaeum.wiki/Zettelkasten/9p
Eu queria fazer leituras aleatórias como se fossem arquivos locais, sem precisar baixar primeiro arquivos grandes
Uma das dores que enfrentei foi que o tamanho de bloco do FUSE era pequeno demais, o que aumentava a latência e o churn das chamadas HTTP para o backend e exigia uma lógica de cache/pré-leitura bastante complexa
A lógica de pré-leitura do kernel parecia simplesmente não funcionar, e na época não investiguei a fundo além de não ter encontrado um jeito de induzi-la
O FAQ pode ser visto em https://virtio-fs.gitlab.io
Ainda assim, é um projeto bacana
Eu queria ter sabido disso um mês atrás, quando precisei passar exatamente pelo mesmo processo.
Numa tentativa desesperada de tornar o Jira menos irritante de usar, pensei no projeto jira-as-filesystem, que cria uma árvore usando a classificação interna de issues.
Fiz diretórios representarem issues, arquivos representarem campos das issues e subdiretórios representarem issues vinculadas, e acabei escolhendo fuse-python.
Faz um tempo que não consigo trabalhar nisso, mas já esbarrei em problemas de abstração.
Se eu usar apenas o ID da issue como nome de diretório, a automação fica fácil, mas, ao rodar
ls, aparecem só IDs difíceis de reconhecer, o que torna a navegação humana difícil; então adicionei um tipo paralelo de diretório-with-summary, anexando ao ID da issue um resumo em formato de slug.A ideia seria ter um jira-as-filesystem para os arquivos originais e, para navegação e interação humanas, uma árvore de links simbólicos colocando links para os mesmos arquivos em várias posições relevantes.
Talvez eu esteja acrescentando camadas demais por não entender bem o problema, mas tecnicamente isso parece resolver o problema de abstração que você descreveu.
No Linux moderno, discos são referenciados tanto como dispositivos de bloco quanto por UUID; então acho essa abordagem aceitável e alinhada às expectativas.
Dito isso, pessoalmente eu provavelmente não usaria, porque o próprio JIRA já é complexo o bastante.
Ex.: https://github.com/coddingtonbear/jirafs
1234-human-sense?Contém os dois tipos de informação e parece fácil de fazer parsing.
Há muitas opções de montagem FUSE, cada uma com compromissos, desempenho e recursos diferentes.
Existem s3fs, goofys, seaweed, minio, Google Drive etc., e o JuiceFS é bem interessante para montar armazenamento de objetos e acessá-lo de forma POSIX, com os metadados esperados de um sistema de arquivos tradicional.
https://juicefs.com
Legal.
Como pergunta relacionada, ultimamente tenho visto casos de implementação de sistemas de arquivos baseados em NFS, por ser um protocolo com suporte mais amplo.
Parece que o rclone faz isso no Mac; existe algum guia ou comparação sobre essa abordagem?
Ele funciona quase como um substituto, não precisa de extensão de kernel, abre um servidor NFS em segundo plano e monta usando recursos do macOS.
O desempenho também é bem bom.
Se quiser ver como fica um produto completo, vale olhar o gerenciador de música azuline/rosé, que tem um sistema de arquivos virtual.
É uma ótima base de código, com muitos comentários, explicações, tipos e testes, então deve ser fácil aprender com ela.
https://github.com/azuline/rose
Se você se interessa por FUSE, o projeto irmão CUSE também pode ser interessante.
CUSE é uma emulação de driver de dispositivo de caractere em espaço de usuário, que permite simular hardware sem compilar um novo módulo de kernel.
Usei recentemente para escrever, em Python, um dispositivo de hardware com suporte a IOCTL.
Não encontrei uma boa biblioteca Python que funcionasse facilmente, e a documentação era escassa, mas no fim consegui escrever tudo só com a biblioteca FFI ctypes.
Como alguém que nunca tinha escrito um driver de kernel, a única parte que não foi intuitiva de imediato foi que IOCTL exige reajustar o tamanho do buffer a cada leitura/escrita, então as chamadas vêm em pares.
Felizmente, o CUSE tem um modo de depuração que mostra todos os bytes de entrada e saída.
O CUSE foi originalmente implementado para criar dispositivos de som em espaço de usuário¹, mas também já foi usado para coisas como TTYs customizados, e eu o usei para criar um dispositivo SPI virtual.
Espero que seja útil para alguém e que esse projeto receba mais atenção.
¹ https://lwn.net/Articles/308445/
Há bastante tempo criei um sistema de arquivos FUSE em Python[1] para interagir com um sistema wiki chamado dokuwiki.
Construí em cima do hde llfuse[2], mas precisei implementar uma boa quantidade de APIs de baixo nível que não tinham relação direta com o dokuwiki.
Por isso criei o easyfuse[3][4], um wrapper que encapsula as partes independentes da implementação do dokuwiki; vale dar uma olhada se você está pensando em criar um 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
Basicamente, o dokuwiki é um conjunto de arquivos de texto; então não seria mais simples e eficiente montá-lo via NFS ou compartilhá-lo com Dropbox/Syncthing?
Uma boa forma de pensar no FUSE é como algo que permite a um Makefile especificar um grafo acíclico direcionado sobre recursos arbitrários.
Por exemplo, se houvesse um sistema de arquivos FUSE expondo o estado de um cluster k8s, talvez fosse mais fácil escrever operadores acessíveis até para uma cabeça simples como a minha.
O mesmo vale para e-mail: se o IMAP fosse exposto como um sistema de arquivos, um app de RAG (como o gpt4all) não poderia acessar tudo diretamente?
Fugindo do assunto, mas sempre que vejo um blog com vibe anos 90/2000, vou até a página do primeiro post.
Incluindo gwolf.org, olhar para essas cápsulas do tempo nunca decepciona.