import sys, os, random import md5 import py from nfs2server import Filesystem, MountServer, NFSServer from nfscommon import NFSError, NFSStat from time import time from cStringIO import StringIO class TestFS (Filesystem): def __init__(self): self.handles = {} self.cache = {} self.root = py.path.svnurl('http://codespeak.net/svn') def getHandleOf(self, file): ''' Returns an opaque string. ''' h = md5.new(str(file)).hexdigest() self.handles.setdefault(h, file) return h def getFileByHandle(self, handle): ''' Returns an opaque file. ''' handles = self.handles if handles.has_key(handle): return handles[handle] else: return None def getRoot(self): ''' Returns an opaque file. ''' return self.root def getFileFrom(self, container, name): ''' Returns an opaque file. ''' p = container.join(name) if p.check(exists=1): return self.handles[self.getHandleOf(p)] # normalize object else: #print '********', container, name return None def isDirectory(self, file): ''' Returns a flag. ''' return file.check(dir=1) def getAttributesOf(self, file, attrsClass): ''' Returns an instance of attrsClass. ''' #print 'attr:', file, dir = file.check(dir=1) if file is not self.root: mtime = file.mtime() else: mtime = time() if not dir: size = file.size() else: size = 0 #print dir, mtime, size return attrsClass( dir, dir and 0775 or 0664, # Note the octal notation. 500, 100, size, 2374, id(file), mtime, mtime, mtime, ) def remember(self, file, value): if len(self.cache) >= 32: del self.cache[random.choice(self.cache.keys())] self.cache[file] = value def readFrom(self, file, offset, count): ''' Returns a string. ''' try: data = self.cache[file] except KeyError: #print 'open:', file data = file.read() self.remember(file, data) return data[offset:offset+count] def err_ro(self, *args): raise NFSError(NFSStat.NFSERR_ROFS) setAttributesOf = err_ro writeTo = err_ro createIn = err_ro removeFrom = err_ro rename = err_ro createLink = err_ro createDirectoryIn = err_ro def getDirectoryEntriesFrom(self, dir, cookie, count, entryClass): ''' Returns (entries, eof), entries being a list of instances of entryClass. ''' try: lst = self.cache[dir] except KeyError: #print 'list:', dir lst = [('.', dir)] if dir is self.root: lst.append(('..', dir)) else: lst.append(('..', dir.dirpath())) for p in dir.listdir(): lst.append((p.get('basename'), p)) self.remember(dir, lst) assign_cookie = cookie + 1 rval = [] for name, ob in lst[cookie:cookie + count]: rval.append(entryClass(fileid=id(ob), name=name, cookie=assign_cookie)) assign_cookie = assign_cookie + 1 eof = (cookie + count >= len(lst)) return rval, eof def getFilesystemStatus(self, root_file, resClass): ''' Returns an instance of resClass. ''' return resClass(tsize=0, bsize=0, blocks=0, bfree=0, bavail=0) # ____________________________________________________________ import sys import asyncore class KeyboardKiller(asyncore.dispatcher): def __init__(self): self.set_socket(sys.stdin) self.connected = 1 def handle_read_event (self): asyncore.close_all() def writable (self): return 0 if __name__ == '__main__': from rpcserver import exportService, UDP_RPCServer, _stopwatch from mount1 import Mount_V1_Program from nfs2 import NFS_V2_Program fs = TestFS() ms = MountServer(fs, {'/':('127.0.0.1',)}) exportService(Mount_V1_Program(), ms) nfss = NFSServer(fs) exportService(NFS_V2_Program(), nfss) # mount -t nfs -o namlen=127 -o noac -o mountport=2049 127.0.0.1:/ /mnt server = UDP_RPCServer(2049) #5489) KeyboardKiller() #import profile #profile.run('asyncore.loop()') asyncore.loop() print _stopwatch.report()