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