Search code examples
gofuse

Named pipe in form of a directory using FUSE


I would like to create a FUSE file system which accepts any kind of write operation to any path inside the file system. Kind of like a named pipe, but in form of a directory.

echo test > bar         # consumes "test"
echo test > bar/foo     # consumes "test", even though the directory "bar" hasn't been created
echo test > x/y/z/test  # consumes "test", even though the directories "x/y/z" haven't been created

I'm using bazil.org/fuse for the implementation. The problem that I'm facing is that when an application wants to write to foo/bar inside my file system, it checks whether foo is a directory, then whether bar is a file. Unfortunately, I can't know upfront whether foo should be a file or a directory.

My Attr function looks as follows:

func (d *Dir) Attr(ctx context.Context, a *fuse.Attr) error {
        a.Inode = 1
        a.Mode = os.ModeDir | 0755
}

This code is specific for a directory node type, due to os.ModeDir. I want this to work for directories or files.

Is there a way to achieve what I want?


Solution

  • The problem that I'm facing is that when an application wants to write to foo/bar inside my file system, it checks whether foo is a directory, then whether bar is a file. Unfortunately, I can't know upfront whether foo should be a file or a directory.

    Given these constraints, solving your problem is impossible.

    A file system node can be either a file or a directory; sometimes neither, but never both at the same time. Because your FUSE driver cannot know in advance whether an application performing the getattr request means to recurse inside the node until it actually tries to, you cannot know whether it should pretend to be a file or a directory.

    Your best options seem to be:

    • hardcode application-specific virtual directory structure into your FUSE driver
    • implement application-specific heuristics in your FUSE driver
    • make your FUSE driver memorise getattr requests and construct a virtual directory tree by trial and error (and keep re-running the application until it works)