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