I made a test script with FusePython, referencing a couple of existing scripts (this one and this one). You can make a file e.g. www.google.co.jp and get the contents of the page from it. Internally it uses urllib2 module. Once it downloads the HTML it caches it in the memory.
To mount it,
python hohefs.py mountpoint
To unmount it,
fusermount -u mountpoint
It is not at all a good example. I just made it to see what it would be like to make a file system with FUSE. I didn't implement permission, I omitted lots of error checkings, and unlink equals to deleting a file, etc.etc.etc....
import fuse from fuse import Fuse from time import time import sys import urllib2 import stat # for file properties import os # for filesystem modes (O_RDONLY, etc) import errno # for error number codes (ENOENT, etc) # - note: these must be returned as negatives fuse.fuse_python_api = (0, 2) class Mystdout(): def __init__(self, filename): self.f = open(filename, 'w') def write(self, text): self.f.write(text) self.f.flush() class HoheStat(fuse.Stat): def __init__(self): self.st_mode = 0 self.st_ino = 0 self.st_dev = 0 self.st_nlink = 0 self.st_uid = 0 self.st_gid = 0 self.st_size = 0 self.st_atime = 0 self.st_mtime = 0 self.st_ctime = 0 def setStat(self, path): st =os.stat(path) self.st_mode = st[0] self.st_ino = st[1] self.st_dev = st[2] self.st_nlink = st[3] self.st_uid = st[4] self.st_gid = st[5] self.st_size = st[6] self.st_atime = st[7] self.st_mtime = st[8] self.st_ctime = st[9] class NullFS(Fuse): def __init__(self, logfilename, mountpoint, *args, **kw): Fuse.__init__(self, *args, **kw) sys.stdout = Mystdout(logfilename) self.__filestats = {} s = self.__filestats['/'] = HoheStat() s.setStat(mountpoint) self.__docs ={} print 'Init complete.' def getattr(self, path): print '*** getattr', path return self.__filestats.get(path, -errno.ENOENT) def readdir(self, path, offset): print '*** readdir', path, offset for r in self.__getFileNames(path) + ['.', '..']: yield fuse.Direntry(r) def getdir(self, path): print '*** getdir', path return map(lambda x: (x, 0), self.__getFileNames(path)) def mknod(self, path, mode, dev): print '*** mknod', path, oct(mode), dev st = HoheStat() st.st_mode = stat.S_IFREG | mode st.st_dev = dev st.st_nlink = 1 st.st_size = 0 st.st_uid = os.getuid() st.st_gid = os.getgid() st.st_utime = time() self.__filestats[path] = st def utime (self, path, times): print '*** utime', path, times st = self.__filestats.get(path) if st: st.st_atime = times[0] st.st_utime = times[1] def read(self, path, length, offset): print '*** read', path, length, offset st = self.__filestats[path] st.st_atime = time() return self.__docs[path][offset:offset +length] def open(self, path, flags): print '*** open', path, flags st = self.__filestats.get(path) if not st: return -errno.ENOENT accmode = os.O_RDONLY | os.O_WRONLY | os.O_RDWR if not (flags & accmode) in [os.O_RDONLY, os.O_WRONLY, os.O_RDWR]: return -errno.EACCES docs = self.__docs if path in docs: doc = docs[path] else: f = urllib2.urlopen("http:/" + path) doc = f.read() st.st_size = len(doc) docs[path] = doc #Oops I need to close f def mkdir(self, path, mode): print '*** mkdir', path, oct(mode) st =self.__filestats.get(path) if st: return -errno.EEXIST parentpath = os.path.dirname(path) parentst = self.__filestats.get(parentpath) if not parentst: return -errno.ENOENT if not parentst.st_mode & stat.S_IFDIR: return -errno.ENOTDIR st = HoheStat() st.st_mode = stat.S_IFDIR | mode st.st_dev = 0 st.st_nlink = 1 st.st_size = 0 st.st_uid = os.getuid() st.st_gid = os.getgid() st.st_utime = time() self.__filestats[path] = st def unlink(self, path): print '*** unlink', path if path in self.__filestats: del self.__filestats[path] docs =self.__docs if path in docs: del docs[path] else: return -errno.ENOENT def rmdir(self, path): print '*** rmdir', path if self.__getFileNames(path): return -errno.EEXIST if path in self.__filestats: del self.__filestats[path] else: return -errno.ENOENT def rename(self, oldPath, newPath): print '*** rename', oldPath, newPath return -errno.ENOENT def mythread(self): print '*** mythread' return -errno.ENOSYS def chmod(self, path, mode): print '*** chmod', path, oct(mode) return -errno.ENOSYS def chown(self, path, uid, gid): print '*** chown', path, uid, gid return -errno.ENOSYS def fsync(self, path, isFsyncFile): print '*** fsync', path, isFsyncFile return -errno.ENOSYS def link(self, targetPath, linkPath): print '*** link', targetPath, linkPath return -errno.ENOSYS def readlink(self, path): print '*** readlink', path return -errno.ENOSYS def release(self, path, flags): print '*** release', path, flags return 0 return -errno.ENOSYS def statfs(self): print '*** statfs' return -errno.ENOSYS def symlink(self, targetPath, linkPath): print '*** symlink', targetPath, linkPath return -errno.ENOSYS def truncate(self, path, size): print '*** truncate', path, size return -errno.ENOSYS def write(self, path, buf, offset): print '*** write', path, buf, offset return -errno.ENOSYS def __getFileNames(self, currentpath): filt = lambda(x): os.path.dirname(x) == currentpath filesincurrent = filter(filt, self.__filestats) if currentpath in filesincurrent: filesincurrent.remove(currentpath) return map(os.path.basename, filesincurrent) if __name__ == '__main__': usage=""" Userspace hello example """ + Fuse.fusage fs = NullFS( "hohefs.log", sys.argv[1], version="%prog " + fuse.__version__, usage=usage, dash_s_do='setsingle') fs.parse(values=fs, errex=1) fs.main()
No comments:
Post a Comment