Skip to content

vkazanov/elfuse

Repository files navigation

Elfuse

Elfuse is a little experiment in implementing a dynamic Emacs module. The idea is to expose some of the libfuse possibilities to Emacs Lisp code.

In other words, it should now be possible to implement file systems in Emacs lisp!

Compile

Because Elfuse is a dynamic module, Emacs compiled with dynamic module support is required. Currently (Emacs 25.1) this requires supplying a special flag at configure time (--with-modules).

Additionally, Elfuse was developed and tested on Linux only (Ubuntu 16.04) using libfuse 2.9.4, no guaranties on other platforms or libfuse versions.

Compilation should be trivial on Linux with a recent GCC:

> cd elfuse/directory/
> make

Running Examples

To run one of the Elfuse examples in the examples directory using a config-less separated Emacs instance do something like the following:

> cd elfuse/directory/
> mkdir mount
> make hello.el
> # an emacs window will open
> # do M-x elfuse-start "mount/" to mount an Elfuse instance to the mount/ path
> ls mount/ # a few fake files should appear here
> # do M-x elfuse-stop to unmount Elfuse

This will start Emacs with Elfuse loaded and load an example Elfuse project. In fact, this is the recommended way to run Elfuse instances (i.e., emacs -Q --load elfuse.el).

Notice that elfuse-start / elfuse-stop functions are main user-visible entry points.

Examples included:

  • hello.el - a static list of files with dummy content
  • hello-2.el - a dynamic list of files, i.e. it’s possible to create a file in the mount path
  • list-buffers.el - expose a list of emacs buffers as a list of files. Only buffers having names compatible with POSIX portable filename definition will be listed. Buffer content will also be mirrored. Is is possible to create an Emacs buffer using touch.
  • write-buffer.el - edit an emacs buffer (*Elfuse buffer*) from the terminal.

Additional Notes

Elfuse currently doesn’t have much documentation apart from the source code and examples/*.el. To play with the library the user will have to consult the examples.

Also, it is strictly not recommended to try to list the mounted Elfuse directory using the same Emacs instance that runs Elfuse. This will definitely block Emacs.

Elfuse runs a libfuse loop using a dedicated (Pthread) thread. When syscalls arrive the thread signals (sends a SIGUSR1 signal) the main Emacs thread and blocks until the main thread finds time to respond to the request.

Elfuse currently does not support mounting multiple FUSE paths. Actually, it uses a single set of predefined callback names (i.e. elfuse--readir-op).

In case things go wrong fusermount -u path/to/a/mount should help.

In case things go HORRIBLY wrong umount -f path/to/a/mount/ should do the trick.

Background

Some time ago I wrote quick Python script that allows to mount org-mode files as FUSE filesystems. The obvious problem with the script was that it needed a custom Org-mode file parser, which would always lag behind the mainstream Org-mode and would miss important features. I was wondering if using the native parser was possible.

As some point Chris Wellons jumped in and mentioned that it might be possible to implement a dynamic Emacs module doing just that: Emacs Lisp bindings to FUSE. Which I did! Later on Chris came up with a blog post about the way Elfuse works. Elfuse uses a few interesting tricks so if you’re interested in details - just follow the link.