Creating a file system can seem to be an intimidating task but with FUSE it's very easy and it gets even easier with python bindings. Any decent Linux distribution should include support for FUSE and be configured such that regular users (or a group) can mount file systems written with FUSE without having root access.
If you are running Ubuntu you need to install the python-fuse package which contains the Python bindings for FUSE.
- Enough, show me the code
#!/usr/bin/env python # -*- coding: utf-8 -*- import errno import fuse import stat import time fuse.fuse_python_api = (0, 2) class MyFS(fuse.Fuse): def __init__(self, *args, **kw): fuse.Fuse.__init__(self, *args, **kw) def getattr(self, path): st = fuse.Stat() st.st_mode = stat.S_IFDIR | 0755 st.st_nlink = 2 st.st_atime = int(time.time()) st.st_mtime = st.st_atime st.st_ctime = st.st_atime if path == '/': pass else: return - errno.ENOENT return st if __name__ == '__main__': fs = MyFS() fs.parse(errex=1) fs.main()The example above shows how easy it is to create a mountable file system, it does nothing but is still a valid file system. The MyFS class implements a file system with no entries, it will always return ENOENT (No such file or directory) except for the root path. You should take a look at the FUSE Python Reference page which contains details about FusePython and, among other things, describes the stat object returned from the getattr method.
Paste the example to a file, MyFS.py, and make the file executable:
$ chmod 755 MyFS.pyNow create a directory which will be used as mount point and mount the file system:
$ mkdir myfs $ ls -l totalt 4 drwxr-xr-x 2 mario mario 4096 2009-11-15 15:59 myfs -rwxr-xr-x 1 mario mario 648 2009-11-15 15:59 MyFS.py $ # This will mount the file system, try ./MyFS.py --help $ ./MyFS.py myfs $ ls -l totalt 0 drwxr-xr-x 2 root root 0 2009-11-15 16:10 myfs -rwxr-xr-x 1 mario mario 648 2009-11-15 15:59 MyFS.pyHere we can see that the owner, size and time stamp changed on myfs after we mounted the file system. You can cd into myfs, but if you try to list the directory (file system root) you'll get an error:
$ cd myfs $ ls ls: reading directory .: Function not implementedYou got this error because we haven't implemented the readdir method which is invoked when listing a directory. To make this work we need to add a readdir method which returns (at least) the '.' and '..' entries. Add the following snippet to the class:
def readdir(self, path, offset): for e in '.', '..': yield fuse.Direntry(e)Before you continue you should unmount the file system:
$ fusermount -u myfsThis will unmount your FUSE file system as a regular user and doesn't require root access.
Retry to mount and cd into the myfs directory:
$ ./MyFS.py myfs $ cd myfs $ ls -a . ..Alright, I think I'll stop for today. Oh, just one more thing... You won't get any print outputs nor tracebacks from your code if you don't start the file system in foreground mode. This is done by adding '-f' as argument when starting the file system.
$ ./MyFS.py -f myfsIt can be hard to tell why something doesn't work if you can't see tracebacks and print outputs.