fusetoys

various hacky fuse filesystem utilities
git clone https://a3nm.net/git/fusetoys/
Log | Files | Refs | README

loopfs.py (3473B)


      1 #!/usr/bin/python
      2 
      3 """Dummy loopback FUSE filesystem"""
      4 
      5 import fuse
      6 import errno
      7 import os
      8 import sys
      9 import threading
     10 
     11 fuse.fuse_python_api = (0, 2)
     12 
     13 class LoopFS(fuse.Fuse):
     14     def __init__(self, *args, **kw):
     15         fuse.Fuse.__init__(self, *args, **kw)
     16 
     17         self.rwlock = threading.Lock()
     18 
     19     def fsinit(self):
     20         self.source = self.cmdline[1][0]
     21 
     22     def sourcePath(self, path):
     23         return os.path.join(self.source, path[1:])
     24 
     25     def access(self, path, mode):
     26         if not os.access(self.sourcePath(path), mode):
     27             return -errno.EACCES
     28 
     29     def chmod(self, path, mode):
     30         return os.chmod(self.sourcePath(path), mode)
     31 
     32     def chown(self, path, mode):
     33         return os.chown(self.sourcePath(path), mode)
     34 
     35     def create(self, path, flags, mode):
     36         return os.open(self.sourcePath(path), os.O_WRONLY | os.O_CREAT, mode)
     37 
     38     def getattr(self, path):
     39         return os.lstat(self.sourcePath(path))
     40 
     41     def link(self, target, source):
     42         os.link(self.sourcePath(source), self.sourcePath(target))
     43 
     44     def mkdir(self, path, mode):
     45         return os.mkdir(self.sourcePath(path), mode)
     46 
     47     def mknod(self, path, mode, rdev):
     48         return os.mknod(self.sourcePath(path), mode, rdev)
     49 
     50     def open(self, path, flags):
     51         return 0
     52 
     53     def read(self, path, size, offset):
     54         with self.rwlock:
     55             fh = os.open(self.sourcePath(path), os.O_RDONLY)
     56             os.lseek(fh, offset, 0)
     57             x = os.read(fh, size)
     58             os.close(fh)
     59             return x
     60 
     61     def readdir(self, path, offset):
     62         path = self.sourcePath(path)
     63         myIno = os.lstat(path).st_ino
     64         print ("will yield dot")
     65         yield fuse.Direntry('.', ino=myIno)
     66         print ("will yield parent")
     67         try:
     68             parentIno = os.lstat(os.path.join(path, "..")).st_ino
     69             print ("yielded parent")
     70         except OSError as e:
     71             parentIno = myIno # root
     72             print ("faked parent")
     73         yield fuse.Direntry('..', ino=parentIno)
     74         print ("will yield children")
     75         for name in os.listdir(path):
     76             print ("yield %s" % os.path.join(path, name))
     77             ino = os.lstat(os.path.join(path, name)).st_ino
     78             yield fuse.Direntry(name, ino=ino)
     79         print ("alldone")
     80 
     81     def readlink(self, path):
     82         return os.readlink(self.sourcePath(path))
     83 
     84     def rename(self, old, new):
     85         return os.rename(self.sourcePath(old), self.sourcePath(new))
     86 
     87     def rmdir(self, path):
     88         return os.rmdir(self.sourcePath(path))
     89 
     90     def statfs(self):
     91         return os.statvfs(self.sourceRoot)
     92 
     93     def symlink(self, target, source):
     94         return os.symlink(self.sourcePath(source), self.sourcePath(target))
     95 
     96     def truncate(self, path, length, fh=None):
     97         with open(self.sourcePath(path), 'r+') as f:
     98             return f.truncate(length)
     99 
    100     def unlink(self, path):
    101         return os.unlink(self.sourcePath(path))
    102 
    103     def utimens(self, path, ts_acc, ts_mod):
    104         times = (ts_acc.tv_sec, ts_mod.tv_sec)
    105         return os.utime(self.sourcePath(path), times)
    106 
    107     def write(self, path, data, offset):
    108         with self.rwlock:
    109             fh = os.open(self.sourcePath(path), os.O_WRONLY)
    110             os.lseek(fh, offset, 0)
    111             x = os.write(fh, data)
    112             os.close(fh)
    113             return x
    114 
    115 
    116 if __name__ == "__main__":
    117     loopfs = LoopFS()
    118     fuse_opts = loopfs.parse(['-o', 'fsname=loopfs'] + sys.argv[1:])
    119     loopfs.main()
    120