Finally, notes on an actual topic! Something I’m interested in learning. FUSE allows a program to provide a virtual file system. A virtual file system looks like a file system on the outside. But when a file is saved in the virtual file system, the program providing the file system can do whatever it wants.


I’ve got a use case – my hometemp system!

Virtual file system powered hometemp


Today: zsh function to cd into temp folder.

hometemp () {
    mkcd ${HOME}/tmp/temp-$(date "+%Y-%m-%d")

Works very well, I like it a lot.

Better: mount “today” into a folder!

  1. Mount ~/tmp/temp-$(date "+%Y-%m-%d") into ~/tmp/temp-$(date "+%Y-%m-%d")
  2. Auto-run this when I start the computer.
    1. Or … trigger a service start on the first time I call hometemp. Hmm.


The first exploration


I decided to start out the “right place” - man fuse. I got redirected to man 8 fuse. Curious about what man 8 stuff is, I haven’t seen that before. But no distractions now.

I’ll start by simply reading and annotating the manual.

Exploring man fuse

  1. Definitions

    What? DEFINITIONS contains the terminology in use in the FUSE manual. Understanding those terms is nice.

    Source: man 8 fuse, section DEFINITIONS.

    My definitions:

    MyProgram my program providing the virtual filesystem

    Manual definitions:

    FUSE kernel thing. Responds to “create file”, forwards requests to MyProgram
    filesystem MyProgram
    libfuse shared library. Makes writing MyProgram easy (or just possible)
    filesystem owner The Unix user running MyProgram, and later mounting it with fusermount3
    client A program that writes files, reads files, etc, from the virtual file system

    More details: man 1 fusermount3 explains how to mount a virtual filesystem.

  2. Configuration

    What? This manual is written for me. It is my system — I control the system. Therefore, I choose. The CONFIGURATION section explains to me how I choose.

    Two options are present. mount_max controls the number of filesystems a user can create.

  3. Options

    What? There’s lots of options.

    There are options related to caching: kernel_cache and auto_cache. So … it looks like there’s some way of speeding up recurring actions built in. Network file systems are mentioned.

    There’s two mount commands mentioned - both mount.fuse and mount.fuse3.

  4. See also

Exploring libfuse

Source. https://github.com/libfuse/libfuse

  1. libfuse is using pytest for testing


    Pytest is lightweight. Very lightweight. There’s no runtime dependency on it to get started testing code. Name your tests test_..., and it just works. Put asserts in the tests. Pytest can inject dependencies into tests with “fixtures”. capfd is such a fixture. If your test takes a capfd argument, it will capture “file descriptors” for stdin and stdout. You can then assert that stdout printed something. Read from capfd with captured = capfd.readouterr(). Assert with assert caputred.out = “on stdout”= or assert captured.err = “on stderr”=.

    Reading the Pytest documentation impresses me. It provides value without introducing coupling or dependencies. This is awesome.

  2. Exploring http://libfuse.github.io/doxygen/

    Libfuse provides a low-level async API and a high-level synchronous API.

    From the documentation:

    libfuse offers two APIs: a “high-level”, synchronous API, and a “low-level” asynchronous API. In both cases, incoming requests from the kernel are passed to the main program using callbacks. When using the high-level API, the callbacks may work with file names and paths instead of inodes, and processing of a request finishes when the callback function returns. When using the low-level API, the callbacks must work with inodes and responses must be sent explicitly using a separate set of API functions.

    The high-level API that is primarily specified in fuse.h. The low-level API that is primarily documented in fuselowlevel.h.

    Smells hourglassy to me.

Perhaps I just need to learn C.


Realizing that I don’t have a good design

  1. I don’t really know which problem I want to solve right now
  2. Which means it’s even harder to find a solution

Then, what is the right first step? I dunno.