def testReuseSlotID(t, env): """ If client reuses a slot ID and sequence ID for a completely different request, server MAY treat the request as if it is a retry of what it has already executed. rfc5661 18.46.3 FLAGS: sequence all CODE: SEQ14 """ c = env.c1.new_client(env.testname(t)) # CREATE_SESSION sess1 = c.create_session() name = "%s_1" % env.testname(t) res = create_file(sess1, name) check(res) sid = sess1.sessionid seqid = nfs4lib.inc_u32(sess1.seqid) dir = sess1.c.homedir res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE)] + nfs4lib.use_obj(dir) + [op.remove(name)]) check(res) # Reuses slot ID and sequence ID for different request res = c.c.compound([op.sequence(sid, seqid, 0, 0, TRUE)] + nfs4lib.use_obj(dir) + [op.rename(name, "test")]) check(res)
def rename_obj(sess, oldpath, newpath): # Set (sfh) to olddir ops = use_obj(oldpath[:-1]) + [op.savefh()] # Set (cfh) to newdir ops += use_obj(newpath[:-1]) # Call rename ops += [op.rename(oldpath[-1], newpath[-1])] return sess.compound(ops)
def create_obj(sess, path, kind=NF4DIR, attrs={FATTR4_MODE:0755}): """Return ops needed to create given non-file object""" # Ensure using createtype4 if not hasattr(kind, "type"): kind = createtype4(kind) ops = use_obj(path[:-1]) + [op.create(kind, path[-1], attrs)] return sess.compound(ops)
def do_readdir(sess, file, cookie=0, cookieverf='', attrs=0, dircount=4096, maxcount=4096): # Since we may not get whole directory listing in one readdir request, # loop until we do. For each request result, create a flat list # with <entry4> objects. log.info("Called do_readdir()") entries = [] baseops = use_obj(file) while True: readdir_op = op.readdir(cookie, cookieverf, dircount, maxcount, attrs) res = sess.compound(baseops + [readdir_op]) check(res, msg="READDIR with cookie=%i, maxcount=%i" % (cookie, maxcount)) reply = res.resarray[-1].reply if not reply.entries and not reply.eof: raise UnexpectedCompoundRes("READDIR had no entries") entries.extend(reply.entries) if reply.eof: break cookie = entries[-1].cookie cookieverf = res.resarray[-1].cookieverf log.info("do_readdir() = %r" % entries) return entries
def open_file(self, mds_fh): seqid=0 access = const4.OPEN4_SHARE_ACCESS_BOTH deny = const4.OPEN4_SHARE_DENY_NONE attrs = {const4.FATTR4_MODE: 0777} owner = "mds" mode = const4.GUARDED4 verifier = self.sess.c.verifier openflag = type4.openflag4(const4.OPEN4_CREATE, type4.createhow4(mode, attrs, verifier)) name = self.fh_to_name(mds_fh) while True: if mds_fh in self.filehandles: return open_op = op4.open(seqid, access, deny, type4.open_owner4(self.sess.client.clientid, owner), openflag, type4.open_claim4(const4.CLAIM_NULL, name)) res = self._execute(nfs4lib.use_obj(self.path_fh) + [open_op, op4.getfh()], exceptions=[const4.NFS4ERR_EXIST]) if res.status == const4.NFS4_OK: ds_fh = res.resarray[-1].opgetfh.resok4.object ds_openstateid = type4.stateid4(0, res.resarray[-2].stateid.other) self.filehandles[mds_fh] = (ds_fh, ds_openstateid) return elif res.status == const4.NFS4ERR_EXIST: openflag = type4.openflag4(const4.OPEN4_NOCREATE) else: raise RuntimeError
def open_file(self, mds_fh): seqid = 0 access = const4.OPEN4_SHARE_ACCESS_BOTH deny = const4.OPEN4_SHARE_DENY_NONE attrs = {const4.FATTR4_MODE: 0777} owner = "mds" mode = const4.GUARDED4 verifier = self.sess.c.verifier openflag = type4.openflag4(const4.OPEN4_CREATE, type4.createhow4(mode, attrs, verifier)) name = self.fh_to_name(mds_fh) while True: if mds_fh in self.filehandles: return open_op = op4.open( seqid, access, deny, type4.open_owner4(self.sess.client.clientid, owner), openflag, type4.open_claim4(const4.CLAIM_NULL, name)) res = self._execute(nfs4lib.use_obj(self.path_fh) + [open_op, op4.getfh()], exceptions=[const4.NFS4ERR_EXIST]) if res.status == const4.NFS4_OK: ds_fh = res.resarray[-1].opgetfh.resok4.object ds_openstateid = type4.stateid4(0, res.resarray[-2].stateid.other) self.filehandles[mds_fh] = (ds_fh, ds_openstateid) return elif res.status == const4.NFS4ERR_EXIST: openflag = type4.openflag4(const4.OPEN4_NOCREATE) else: raise RuntimeError
def open_file( sess, owner, path=None, access=OPEN4_SHARE_ACCESS_READ, deny=OPEN4_SHARE_DENY_NONE, claim_type=CLAIM_NULL, want_deleg=False, deleg_type=None, # Setting the following should induce server errors seqid=0, clientid=0): # Set defaults if path is None: dir = sess.c.homedir name = owner else: dir = path[:-1] name = path[-1] if not want_deleg and access & OPEN4_SHARE_ACCESS_WANT_DELEG_MASK == 0: access |= OPEN4_SHARE_ACCESS_WANT_NO_DELEG # Open the file if claim_type == CLAIM_NULL: fh_op = use_obj(dir) elif claim_type == CLAIM_PREVIOUS: fh_op = [op.putfh(path)] name = None if not want_deleg and access & OPEN4_SHARE_ACCESS_WANT_DELEG_MASK == 0: access |= OPEN4_SHARE_ACCESS_WANT_NO_DELEG open_op = op.open(seqid, access, deny, open_owner4(clientid, owner), openflag4(OPEN4_NOCREATE), open_claim4(claim_type, name, deleg_type)) return sess.compound(fh_op + [open_op, op.getfh()])
def do_getattrdict(sess, file, attrlist): """file can be either a fh or a path""" ops = use_obj(file) ops += [op.getattr(nfs4lib.list2bitmap(attrlist))] res = sess.compound(ops) check(res) return res.resarray[-1].obj_attributes
def create_file( sess, owner, path=None, attrs={FATTR4_MODE: 0644}, access=OPEN4_SHARE_ACCESS_BOTH, deny=OPEN4_SHARE_DENY_NONE, mode=GUARDED4, verifier=None, want_deleg=False, # Setting the following should induce server errors seqid=0, clientid=0): # Set defaults if path is None: dir = sess.c.homedir name = owner else: dir = path[:-1] name = path[-1] if ((mode == EXCLUSIVE4) or (mode == EXCLUSIVE4_1)) and (verifier == None): verifier = sess.c.verifier if not want_deleg and access & OPEN4_SHARE_ACCESS_WANT_DELEG_MASK == 0: access |= OPEN4_SHARE_ACCESS_WANT_NO_DELEG # Create the file open_op = op.open( seqid, access, deny, open_owner4(clientid, owner), openflag4( OPEN4_CREATE, createhow4(mode, attrs, verifier, creatverfattr(verifier, attrs))), open_claim4(CLAIM_NULL, name)) return sess.compound(use_obj(dir) + [open_op, op.getfh()])
def create_obj(sess, path, kind=NF4DIR, attrs={FATTR4_MODE: 0o755}): """Return ops needed to create given non-file object""" # Ensure using createtype4 if not hasattr(kind, "type"): kind = createtype4(kind) ops = use_obj(path[:-1]) + [op.create(kind, path[-1], attrs)] return sess.compound(ops)
def make_root(self, attrs={FATTR4_MODE:0777}): existing_path = [] kind = createtype4(NF4DIR) for comp in self.path: existing_path.append(comp) res = self.execute(nfs4lib.use_obj(existing_path), exceptions=[NFS4ERR_NOENT]) if res.status == NFS4ERR_NOENT: cr_ops = nfs4lib.use_obj(existing_path[:-1]) + \ [op.create(kind, comp, attrs)] self.execute(cr_ops) res = self.execute(nfs4lib.use_obj(self.path) + [op.getfh()]) self.path_fh = res.resarray[-1].object need = ACCESS4_READ | ACCESS4_LOOKUP | ACCESS4_MODIFY | ACCESS4_EXTEND res = self.execute(nfs4lib.use_obj(self.path_fh) + [op.access(need)]) if res.resarray[-1].access != need: raise RuntimeError
def read_file(sess, file, offset=0, count=2048, stateid=stateid4(0, b'')): ops = use_obj(file) ops += [op.read(stateid, offset, count)] res = sess.compound(ops) if res.status == NFS4_OK: res.eof = res.resarray[-1].switch.switch.eof res.data = res.resarray[-1].switch.switch.data return res
def make_root(self, attrs={FATTR4_MODE: 0777}): existing_path = [] kind = createtype4(NF4DIR) for comp in self.path: existing_path.append(comp) res = self.execute(nfs4lib.use_obj(existing_path), exceptions=[NFS4ERR_NOENT]) if res.status == NFS4ERR_NOENT: cr_ops = nfs4lib.use_obj(existing_path[:-1]) + \ [op.create(kind, comp, attrs)] self.execute(cr_ops) res = self.execute(nfs4lib.use_obj(self.path) + [op.getfh()]) self.path_fh = res.resarray[-1].object need = ACCESS4_READ | ACCESS4_LOOKUP | ACCESS4_MODIFY | ACCESS4_EXTEND res = self.execute(nfs4lib.use_obj(self.path_fh) + [op.access(need)]) if res.resarray[-1].access != need: raise RuntimeError
def clean_dir(sess, path): stateid = nfs4lib.state00 # fh = self.do_getfh(path) entries = do_readdir(sess, path) for e in entries: # We separate setattr and remove to avoid an inode locking bug ops = use_obj(path + [e.name]) ops += [op.setattr(stateid, {FATTR4_MODE: 0o755})] res = sess.compound(ops) check(res, msg="Setting mode on %s" % repr(e.name)) ops = use_obj(path) ops += [op.remove(e.name)] res = sess.compound(ops) if res.status == NFS4ERR_NOTEMPTY: clean_dir(sess, path + [e.name]) res = sess.compound(ops) check(res, msg="Trying to remove %s" % repr(e.name))
def clean_dir(sess, path): stateid = nfs4lib.state00 # fh = self.do_getfh(path) entries = do_readdir(sess, path) for e in entries: # We separate setattr and remove to avoid an inode locking bug ops = use_obj(path + [e.name]) ops += [op.setattr(stateid, {FATTR4_MODE:0755})] res = sess.compound(ops) check(res, msg="Setting mode on %s" % repr(e.name)) ops = use_obj(path) ops += [op.remove(e.name)] res = sess.compound(ops) if res.status == NFS4ERR_NOTEMPTY: clean_dir(sess, path + [e.name]) res = sess.compound(ops) check(res, msg="Trying to remove %s" % repr(e.name))
def _maketree(self, sess): """Make test tree""" # ensure /tmp (and path leading up) exists path = [] for comp in self.opts.home: path.append(comp) res = sess.compound(use_obj(path)) checklist(res, [NFS4_OK, NFS4ERR_NOENT], "LOOKUP /%s," % '/'.join(path)) if res.status == NFS4ERR_NOENT: res = create_obj(sess, path, NF4DIR) check(res, msg="Trying to create /%s," % '/'.join(path)) # ensure /tree exists and is empty tree = self.opts.path + ['tree'] res = sess.compound(use_obj(tree)) checklist(res, [NFS4_OK, NFS4ERR_NOENT]) if res.status == NFS4ERR_NOENT: res = create_obj(sess, tree, NF4DIR) check(res, msg="Trying to create /%s," % '/'.join(tree)) else: clean_dir(sess, tree) # make non-file objects in /tree d = { 'dir': NF4DIR, 'socket': NF4SOCK, 'fifo': NF4FIFO, 'link': createtype4(NF4LNK, linkdata=self.linkdata), 'block': createtype4(NF4BLK, devdata=specdata4(1, 2)), 'char': createtype4(NF4CHR, devdata=specdata4(1, 2)), } for name, kind in d.items(): path = tree + [name] res = create_obj(sess, path, kind) if res.status != NFS4_OK: log.warning("could not create /%s" % '/'.join(path)) # Make file-object in /tree fh, stateid = create_confirm(sess, 'maketree', tree + ['file']) stateid.seqid = 0 ops = [op.putfh(fh), op.write(stateid, 0, FILE_SYNC4, self.filedata)] res = sess.compound(ops) check(res, msg="Writing data to /%s/file" % '/'.join(tree)) res = close_file(sess, fh, stateid) check(res)
def _maketree(self, sess): """Make test tree""" # ensure /tmp (and path leading up) exists path = [] for comp in self.opts.home: path.append(comp) res = sess.compound(use_obj(path)) check(res, [NFS4_OK, NFS4ERR_NOENT], "LOOKUP /%s," % '/'.join(path)) if res.status == NFS4ERR_NOENT: res = create_obj(sess, path, NF4DIR) check(res, msg="Trying to create /%s," % '/'.join(path)) # ensure /tree exists and is empty tree = self.opts.path + ['tree'] res = sess.compound(use_obj(tree)) check(res, [NFS4_OK, NFS4ERR_NOENT]) if res.status == NFS4ERR_NOENT: res = create_obj(sess, tree, NF4DIR) check(res, msg="Trying to create /%s," % '/'.join(tree)) else: clean_dir(sess, tree) # make non-file objects in /tree d = {'dir': NF4DIR, 'socket': NF4SOCK, 'fifo': NF4FIFO, 'link': createtype4(NF4LNK, linkdata=self.linkdata), 'block': createtype4(NF4BLK, devdata=specdata4(1, 2)), 'char': createtype4(NF4CHR, devdata=specdata4(1, 2)), } for name, kind in d.items(): path = tree + [name] res = create_obj(sess, path, kind) if res.status != NFS4_OK: log.warning("could not create /%s" % '/'.join(path)) # Make file-object in /tree fh, stateid = create_confirm(sess, 'maketree', tree + ['file']) ops = [op.putfh(fh), op.write(stateid, 0, FILE_SYNC4, self.filedata)] res = sess.compound(ops) check(res, msg="Writing data to /%s/file" % '/'.join(tree)) res = close_file(sess, fh, stateid) check(res)
def init(self): """Run once before any test is run""" if self.opts.noinit: return sess = self.c1.new_client_session("Environment.init_%i" % self.timestamp) if self.opts.maketree: self._maketree(sess) # Make sure opts.home exists res = sess.compound(use_obj(self.opts.home)) check(res, msg="Could not LOOKUP /%s," % '/'.join(self.opts.home)) # Make sure it is empty clean_dir(sess, self.opts.home) sess.c.null()
def write_file(sess, file, data, offset=0, stateid=stateid4(0, b''), how=FILE_SYNC4): ops = use_obj(file) ops += [op.write(stateid, offset, how, data)] res = sess.compound(ops) if res.status == NFS4_OK: res.count = res.resarray[-1].switch.switch.count res.committed = res.resarray[-1].switch.switch.committed return res
def open_create_file_op(sess, owner, path=None, attrs={FATTR4_MODE: 0o644}, access=OPEN4_SHARE_ACCESS_BOTH, deny=OPEN4_SHARE_DENY_NONE, mode=GUARDED4, verifier=None, claim_type=CLAIM_NULL, want_deleg=False, deleg_type=None, open_create=OPEN4_NOCREATE, seqid=0, clientid=0): # Set defaults if path is None: dir = sess.c.homedir name = owner else: dir = path[:-1] name = path[-1] if ((mode == EXCLUSIVE4) or (mode == EXCLUSIVE4_1)) and (verifier == None): verifier = sess.c.verifier if not want_deleg and access & OPEN4_SHARE_ACCESS_WANT_DELEG_MASK == 0: access |= OPEN4_SHARE_ACCESS_WANT_NO_DELEG # Open the file if claim_type == CLAIM_NULL: fh_op = use_obj(dir) elif claim_type == CLAIM_PREVIOUS: fh_op = [op.putfh(path)] name = None if open_create == OPEN4_CREATE: openflag = openflag4( OPEN4_CREATE, createhow4(mode, attrs, verifier, creatverfattr(verifier, attrs))) openclaim = open_claim4(CLAIM_NULL, name) else: openflag = openflag4(OPEN4_NOCREATE) openclaim = open_claim4(claim_type, name, deleg_type) open_op = op.open(seqid, access, deny, open_owner4(clientid, owner), openflag, openclaim) return fh_op + [open_op, op.getfh()]
def open_create_file_op(sess, owner, path=None, attrs={FATTR4_MODE: 0644}, access=OPEN4_SHARE_ACCESS_BOTH, deny=OPEN4_SHARE_DENY_NONE, mode=GUARDED4, verifier=None, claim_type=CLAIM_NULL, want_deleg=False, deleg_type=None, open_create=OPEN4_NOCREATE, seqid=0, clientid=0): # Set defaults if path is None: dir = sess.c.homedir name = owner else: dir = path[:-1] name = path[-1] if ((mode==EXCLUSIVE4) or (mode==EXCLUSIVE4_1)) and (verifier==None): verifier = sess.c.verifier if not want_deleg and access & OPEN4_SHARE_ACCESS_WANT_DELEG_MASK == 0: access |= OPEN4_SHARE_ACCESS_WANT_NO_DELEG # Open the file if claim_type==CLAIM_NULL: fh_op = use_obj(dir) elif claim_type==CLAIM_PREVIOUS: fh_op = [op.putfh(path)] name = None if open_create==OPEN4_CREATE: openflag=openflag4(OPEN4_CREATE, createhow4(mode, attrs, verifier, creatverfattr(verifier, attrs))) openclaim=open_claim4(CLAIM_NULL, name) else: openflag=openflag4(OPEN4_NOCREATE) openclaim=open_claim4(claim_type, name, deleg_type) open_op = op.open(seqid, access, deny, open_owner4(clientid, owner), openflag, openclaim) return fh_op + [open_op, op.getfh()]
class Environment(testmod.Environment): # STUB attr_info = [ \ AttrInfo('supported_attrs', 'rm', []), AttrInfo('type', 'rm', 1), AttrInfo('fh_expire_type', 'rm', 0), AttrInfo('change', 'rm', 0), AttrInfo('size', 'rwm', 0), AttrInfo('link_support', 'rm', False), AttrInfo('symlink_support', 'rm', False), AttrInfo('named_attr', 'rm', False), AttrInfo('fsid', 'rm', fsid4(0, 0)), AttrInfo('unique_handles', 'rm', False), AttrInfo('lease_time', 'rm', 0), AttrInfo('rdattr_error', 'rm', 0), AttrInfo('filehandle', 'rm', 'nonsense'), AttrInfo('acl', 'rw', [nfsace4(0,0,0,'EVERYONE@')]), AttrInfo('aclsupport', 'r', 0), AttrInfo('archive', 'rw', False), AttrInfo('cansettime', 'r', False), AttrInfo('case_insensitive', 'r', False), AttrInfo('case_preserving', 'r', False), AttrInfo('chown_restricted', 'r', False), AttrInfo('fileid', 'r', 0), AttrInfo('files_avail', 'r', 0), AttrInfo('files_free', 'r', 0), AttrInfo('files_total', 'r', 0), # FRED - packer did not complain about missing [] about server AttrInfo('fs_locations', 'r', fs_locations4('root',[fs_location4(['server'],'path')])), AttrInfo('hidden', 'rw', False), AttrInfo('homogeneous', 'r', False), AttrInfo('maxfilesize', 'r', 0), AttrInfo('maxlink', 'r', 0), AttrInfo('maxname', 'r', 0), AttrInfo('maxread', 'r', 0), AttrInfo('maxwrite', 'r', 0), AttrInfo('mimetype', 'rw', 'nonsense'), AttrInfo('mode', 'rw', 0), AttrInfo('no_trunc', 'r', False), AttrInfo('numlinks', 'r', 0), AttrInfo('owner', 'rw', 'nonsense'), AttrInfo('owner_group', 'rw', 'nonsense'), AttrInfo('quota_avail_hard', 'r', 0), AttrInfo('quota_avail_soft', 'r', 0), AttrInfo('quota_used', 'r', 0), AttrInfo('rawdev', 'r', specdata4(0, 0)), AttrInfo('space_avail', 'r', 0), AttrInfo('space_free', 'r', 0), AttrInfo('space_total', 'r', 0), AttrInfo('space_used', 'r', 0), AttrInfo('system', 'rw', False), AttrInfo('time_access', 'r', nfstime4(0, 0)), AttrInfo('time_access_set', 'w', settime4(0)), AttrInfo('time_backup', 'rw', nfstime4(0, 0)), AttrInfo('time_create', 'rw', nfstime4(0, 0)), AttrInfo('time_delta', 'r', nfstime4(0, 0)), AttrInfo('time_metadata', 'r', nfstime4(0, 0)), AttrInfo('time_modify', 'r', nfstime4(0, 0)), AttrInfo('time_modify_set', 'w', settime4(0)), AttrInfo('mounted_on_fileid', 'r', 0), ] home = property(lambda s: use_obj(s.opts.home)) def __init__(self, opts): self._lock = Lock() self.opts = opts self.c1 = nfs4client.NFS4Client(opts.server, opts.port) s1 = rpc.security.instance(opts.flavor) if opts.flavor == rpc.AUTH_NONE: self.cred1 = s1.init_cred() elif opts.flavor == rpc.AUTH_SYS: self.cred1 = s1.init_cred(uid=opts.uid, gid=opts.gid, name=opts.machinename) elif opts.flavor == rpc.RPCSEC_GSS: call = self.c1.make_call_function(self.c1.c1, 0, self.c1.default_prog, self.c1.default_vers) krb5_cred = AuthGss().init_cred(call, target="nfs@%s" % opts.server) krb5_cred.service = opts.service self.cred1 = krb5_cred self.c1.set_cred(self.cred1) self.cred2 = AuthSys().init_cred(uid=1111, gid=37, name="shampoo") opts.home = opts.path + ['tmp'] self.c1.homedir = opts.home # Put this after client creation, to ensure _last_verf bigger than # any natural client verifiers self.timestamp = int(time.time()) self._last_verf = self.timestamp + 1 self.filedata = "This is the file test data." self.linkdata = "/etc/X11" log.info("Created client to %s, %i" % (opts.server, opts.port)) def init(self): """Run once before any test is run""" if self.opts.noinit: return c = self.c1.new_client("Environment.init_%i" % self.timestamp) sess = c.create_session() if self.opts.maketree: self._maketree(sess) # Make sure opts.home exists res = sess.compound(use_obj(self.opts.home)) check(res, msg="Could not LOOKUP /%s," % '/'.join(self.opts.home)) # Make sure it is empty clean_dir(sess, self.opts.home) sess.c.null() def _maketree(self, sess): """Make test tree""" # ensure /tmp (and path leading up) exists path = [] for comp in self.opts.home: path.append(comp) res = sess.compound(use_obj(path)) checklist(res, [NFS4_OK, NFS4ERR_NOENT], "LOOKUP /%s," % '/'.join(path)) if res.status == NFS4ERR_NOENT: res = create_obj(sess, path, NF4DIR) check(res, msg="Trying to create /%s," % '/'.join(path)) # ensure /tree exists and is empty tree = self.opts.path + ['tree'] res = sess.compound(use_obj(tree)) checklist(res, [NFS4_OK, NFS4ERR_NOENT]) if res.status == NFS4ERR_NOENT: res = create_obj(sess, tree, NF4DIR) check(res, msg="Trying to create /%s," % '/'.join(tree)) else: clean_dir(sess, tree) # make non-file objects in /tree d = { 'dir': NF4DIR, 'socket': NF4SOCK, 'fifo': NF4FIFO, 'link': createtype4(NF4LNK, linkdata=self.linkdata), 'block': createtype4(NF4BLK, devdata=specdata4(1, 2)), 'char': createtype4(NF4CHR, devdata=specdata4(1, 2)), } for name, kind in d.items(): path = tree + [name] res = create_obj(sess, path, kind) if res.status != NFS4_OK: log.warning("could not create /%s" % '/'.join(path)) # Make file-object in /tree fh, stateid = create_confirm(sess, 'maketree', tree + ['file']) stateid.seqid = 0 ops = [op.putfh(fh), op.write(stateid, 0, FILE_SYNC4, self.filedata)] res = sess.compound(ops) check(res, msg="Writing data to /%s/file" % '/'.join(tree)) res = close_file(sess, fh, stateid) check(res) def finish(self): """Run once after all tests are run""" pass def startUp(self): """Run before each test""" log.debug("Sending pretest NULL") self.c1.null() log.debug("Got pretest NULL response") def sleep(self, sec, msg=''): """Sleep for given seconds""" log.info("Sleeping for %i seconds: %s" % (sec, msg)) time.sleep(sec) log.info("Woke up") def new_verifier(self): """Returns a never before used verifier""" candidate = int(time.time()) self._lock.acquire() try: if candidate <= self._last_verf: candidate = self._last_verf + 1 self._last_verf = candidate finally: self._lock.release() return struct.pack('>d', candidate) def testname(self, t): """Returns a name for the test that is unique between runs""" return "%s_%i" % (t.code, self.timestamp)
class Environment(testmod.Environment): # STUB attr_info = [ \ AttrInfo('supported_attrs', 'rm', []), AttrInfo('type', 'rm', 1), AttrInfo('fh_expire_type', 'rm', 0), AttrInfo('change', 'rm', 0), AttrInfo('size', 'rwm', 0), AttrInfo('link_support', 'rm', False), AttrInfo('symlink_support', 'rm', False), AttrInfo('named_attr', 'rm', False), AttrInfo('fsid', 'rm', fsid4(0, 0)), AttrInfo('unique_handles', 'rm', False), AttrInfo('lease_time', 'rm', 0), AttrInfo('rdattr_error', 'rm', 0), AttrInfo('filehandle', 'rm', 'nonsense'), AttrInfo('acl', 'rw', [nfsace4(0,0,0,'EVERYONE@')]), AttrInfo('aclsupport', 'r', 0), AttrInfo('archive', 'rw', False), AttrInfo('cansettime', 'r', False), AttrInfo('case_insensitive', 'r', False), AttrInfo('case_preserving', 'r', False), AttrInfo('chown_restricted', 'r', False), AttrInfo('fileid', 'r', 0), AttrInfo('files_avail', 'r', 0), AttrInfo('files_free', 'r', 0), AttrInfo('files_total', 'r', 0), # FRED - packer did not complain about missing [] about server AttrInfo('fs_locations', 'r', fs_locations4('root',[fs_location4(['server'],'path')])), AttrInfo('hidden', 'rw', False), AttrInfo('homogeneous', 'r', False), AttrInfo('maxfilesize', 'r', 0), AttrInfo('maxlink', 'r', 0), AttrInfo('maxname', 'r', 0), AttrInfo('maxread', 'r', 0), AttrInfo('maxwrite', 'r', 0), AttrInfo('mimetype', 'rw', 'nonsense'), AttrInfo('mode', 'rw', 0), AttrInfo('no_trunc', 'r', False), AttrInfo('numlinks', 'r', 0), AttrInfo('owner', 'rw', 'nonsense'), AttrInfo('owner_group', 'rw', 'nonsense'), AttrInfo('quota_avail_hard', 'r', 0), AttrInfo('quota_avail_soft', 'r', 0), AttrInfo('quota_used', 'r', 0), AttrInfo('rawdev', 'r', specdata4(0, 0)), AttrInfo('space_avail', 'r', 0), AttrInfo('space_free', 'r', 0), AttrInfo('space_total', 'r', 0), AttrInfo('space_used', 'r', 0), AttrInfo('system', 'rw', False), AttrInfo('time_access', 'r', nfstime4(0, 0)), AttrInfo('time_access_set', 'w', settime4(0)), AttrInfo('time_backup', 'rw', nfstime4(0, 0)), AttrInfo('time_create', 'rw', nfstime4(0, 0)), AttrInfo('time_delta', 'r', nfstime4(0, 0)), AttrInfo('time_metadata', 'r', nfstime4(0, 0)), AttrInfo('time_modify', 'r', nfstime4(0, 0)), AttrInfo('time_modify_set', 'w', settime4(0)), AttrInfo('mounted_on_fileid', 'r', 0), ] home = property(lambda s: use_obj(s.opts.home)) def __init__(self, opts): self._lock = Lock() self.opts = opts self.c1 = nfs4client.NFS4Client(opts.server, opts.port, opts.minorversion) s1 = rpc.security.instance(opts.flavor) if opts.flavor == rpc.AUTH_NONE: self.cred1 = s1.init_cred() elif opts.flavor == rpc.AUTH_SYS: self.cred1 = s1.init_cred(uid=opts.uid, gid=opts.gid, name=opts.machinename) elif opts.flavor == rpc.RPCSEC_GSS: call = self.c1.make_call_function(self.c1.c1, 0, self.c1.default_prog, self.c1.default_vers) krb5_cred = AuthGss().init_cred(call, target="nfs@%s" % opts.server) krb5_cred.service = opts.service self.cred1 = krb5_cred self.c1.set_cred(self.cred1) self.cred2 = AuthSys().init_cred(uid=1111, gid=37, name="shampoo") opts.home = opts.path + ['tmp'] self.c1.homedir = opts.home # Put this after client creation, to ensure _last_verf bigger than # any natural client verifiers self.timestamp = int(time.time()) self._last_verf = self.timestamp + 1 self.filedata = "This is the file test data." self.linkdata = "/etc/X11" self.stateid0 = stateid4(0, '') self.stateid1 = stateid4(0xffffffff, '\xff' * 12) log.info("Created client to %s, %i" % (opts.server, opts.port)) def init(self, name): """Run once before any test is run""" if self.opts.noinit: return # sess = self.c1.new_client_session("Environment.init_%i" % self.timestamp) c = self.c1.new_client("Linux NFSv4.1 %s" % str(name + str(random.randint(0, 100)))) sess = c.create_session() res = sess.compound([op.reclaim_complete(FALSE)]) res = sess.compound([op.putrootfh(), op.secinfo_no_name(0)]) res = sess.compound([ op.putrootfh(), op.getfh(), op.getattr( nfs4lib.list2bitmap( [1, 3, 4, 8, 20, 33, 35, 36, 37, 41, 45, 47, 52, 53, 55])) ]) fh = res.resarray[1].object print("-1-----------------") print(fh) res = sess.compound([ op.putfh(fh), op.getattr(nfs4lib.list2bitmap([0, 2, 5, 6, 13, 75])) ]) res = sess.compound([ op.putfh(fh), op.getattr(nfs4lib.list2bitmap([10, 27, 30, 31, 51, 62, 65])) ]) res = sess.compound([ op.putfh(fh), op.getattr(nfs4lib.list2bitmap([0, 2, 5, 6, 13, 75])) ]) res = sess.compound([ op.putfh(fh), op.getattr(nfs4lib.list2bitmap([10, 27, 30, 31, 51, 62, 65])) ]) res = sess.compound( [op.putfh(fh), op.getattr(nfs4lib.list2bitmap([28, 29]))]) res = sess.compound([ op.putfh(fh), op.getattr(nfs4lib.list2bitmap([0, 2, 5, 6, 13, 75])) ]) res = sess.compound([ op.putfh(fh), op.getattr( nfs4lib.list2bitmap( [1, 3, 4, 8, 20, 33, 35, 36, 37, 41, 45, 47, 52, 53, 55])) ]) res = sess.compound([ op.putfh(fh), op.access(0x1f), op.getattr(nfs4lib.list2bitmap([3, 4, 52, 53])) ]) res = sess.compound([ op.putfh(fh), op.lookup("nfs"), op.getfh(), op.getattr( nfs4lib.list2bitmap( [1, 3, 4, 8, 20, 33, 35, 36, 37, 41, 45, 47, 52, 53, 55])) ]) print("0-----------------") # oldfh = res.resarray[1].resok4 # un = NFS4Unpacker(oldfh) # fh = un.unpack_GETFH4resok() #print (fh) # print(sess.sessionid, sess.seqid, sess.client, sess.c) # print(c) time.sleep(100) if self.opts.maketree: self._maketree(sess) # Make sure opts.home exists res = sess.compound(use_obj(self.opts.home)) check(res, msg="Could not LOOKUP /%s," % '/'.join(self.opts.home)) # Make sure it is empty clean_dir(sess, self.opts.home) sess.c.null() print("chenggongle") self.c1 self.clean_sessions() self.clean_clients() def _maketree(self, sess): """Make test tree""" # ensure /tmp (and path leading up) exists path = [] for comp in self.opts.home: path.append(comp) res = sess.compound(use_obj(path)) check(res, [NFS4_OK, NFS4ERR_NOENT], "LOOKUP /%s," % '/'.join(path)) if res.status == NFS4ERR_NOENT: res = create_obj(sess, path, NF4DIR) check(res, msg="Trying to create /%s," % '/'.join(path)) # ensure /tree exists and is empty tree = self.opts.path + ['tree'] res = sess.compound(use_obj(tree)) check(res, [NFS4_OK, NFS4ERR_NOENT]) if res.status == NFS4ERR_NOENT: res = create_obj(sess, tree, NF4DIR) check(res, msg="Trying to create /%s," % '/'.join(tree)) else: clean_dir(sess, tree) # make non-file objects in /tree d = { 'dir': NF4DIR, 'socket': NF4SOCK, 'fifo': NF4FIFO, 'link': createtype4(NF4LNK, linkdata=self.linkdata), 'block': createtype4(NF4BLK, devdata=specdata4(1, 2)), 'char': createtype4(NF4CHR, devdata=specdata4(1, 2)), } for name, kind in d.items(): path = tree + [name] res = create_obj(sess, path, kind) if res.status != NFS4_OK: log.warning("could not create /%s" % '/'.join(path)) # Make file-object in /tree fh, stateid = create_confirm(sess, 'maketree', tree + ['file']) ops = [op.putfh(fh), op.write(stateid, 0, FILE_SYNC4, self.filedata)] res = sess.compound(ops) check(res, msg="Writing data to /%s/file" % '/'.join(tree)) res = close_file(sess, fh, stateid) check(res) def finish(self): """Run once after all tests are run""" if self.opts.nocleanup: return sess = self.c1.new_client_session("Environment.init_%i" % self.timestamp) clean_dir(sess, self.opts.home) sess.c.null() self.clean_sessions() self.clean_clients() def startUp(self): """Run before each test""" log.debug("Sending pretest NULL") self.c1.null() log.debug("Got pretest NULL response") def sleep(self, sec, msg=''): """Sleep for given seconds""" log.info("Sleeping for %i seconds: %s" % (sec, msg)) time.sleep(sec) log.info("Woke up") def serverhelper(self, args): """Perform a special operation on the server side (such as rebooting the server)""" if self.opts.serverhelper is None: print("Manual operation required on server:") print(args + " and hit ENTER when done") sys.stdin.readline() print("Continuing with test") else: cmd = self.opts.serverhelper if self.opts.serverhelperarg: cmd += ' ' + self.opts.serverhelperarg cmd += ' ' + args os.system(cmd) def new_verifier(self): """Returns a never before used verifier""" candidate = int(time.time()) self._lock.acquire() try: if candidate <= self._last_verf: candidate = self._last_verf + 1 self._last_verf = candidate finally: self._lock.release() return struct.pack('>d', candidate) def testname(self, t): """Returns a name for the test that is unique between runs""" return "%s_%i" % (t.code, self.timestamp) def clean_sessions(self): """Destroy client name env.c1""" for sessionid in self.c1.sessions.keys(): self.c1.compound([op.destroy_session(sessionid)]) del (self.c1.sessions[sessionid]) def clean_clients(self): """Destroy client name env.c1""" for clientid in self.c1.clients.keys(): self.c1.compound([op.destroy_clientid(clientid)]) del (self.c1.clients[clientid])
def init(self, name): """Run once before any test is run""" if self.opts.noinit: return # sess = self.c1.new_client_session("Environment.init_%i" % self.timestamp) c = self.c1.new_client("Linux NFSv4.1 %s" % str(name + str(random.randint(0, 100)))) sess = c.create_session() res = sess.compound([op.reclaim_complete(FALSE)]) res = sess.compound([op.putrootfh(), op.secinfo_no_name(0)]) res = sess.compound([ op.putrootfh(), op.getfh(), op.getattr( nfs4lib.list2bitmap( [1, 3, 4, 8, 20, 33, 35, 36, 37, 41, 45, 47, 52, 53, 55])) ]) fh = res.resarray[1].object print("-1-----------------") print(fh) res = sess.compound([ op.putfh(fh), op.getattr(nfs4lib.list2bitmap([0, 2, 5, 6, 13, 75])) ]) res = sess.compound([ op.putfh(fh), op.getattr(nfs4lib.list2bitmap([10, 27, 30, 31, 51, 62, 65])) ]) res = sess.compound([ op.putfh(fh), op.getattr(nfs4lib.list2bitmap([0, 2, 5, 6, 13, 75])) ]) res = sess.compound([ op.putfh(fh), op.getattr(nfs4lib.list2bitmap([10, 27, 30, 31, 51, 62, 65])) ]) res = sess.compound( [op.putfh(fh), op.getattr(nfs4lib.list2bitmap([28, 29]))]) res = sess.compound([ op.putfh(fh), op.getattr(nfs4lib.list2bitmap([0, 2, 5, 6, 13, 75])) ]) res = sess.compound([ op.putfh(fh), op.getattr( nfs4lib.list2bitmap( [1, 3, 4, 8, 20, 33, 35, 36, 37, 41, 45, 47, 52, 53, 55])) ]) res = sess.compound([ op.putfh(fh), op.access(0x1f), op.getattr(nfs4lib.list2bitmap([3, 4, 52, 53])) ]) res = sess.compound([ op.putfh(fh), op.lookup("nfs"), op.getfh(), op.getattr( nfs4lib.list2bitmap( [1, 3, 4, 8, 20, 33, 35, 36, 37, 41, 45, 47, 52, 53, 55])) ]) print("0-----------------") # oldfh = res.resarray[1].resok4 # un = NFS4Unpacker(oldfh) # fh = un.unpack_GETFH4resok() #print (fh) # print(sess.sessionid, sess.seqid, sess.client, sess.c) # print(c) time.sleep(100) if self.opts.maketree: self._maketree(sess) # Make sure opts.home exists res = sess.compound(use_obj(self.opts.home)) check(res, msg="Could not LOOKUP /%s," % '/'.join(self.opts.home)) # Make sure it is empty clean_dir(sess, self.opts.home) sess.c.null() print("chenggongle") self.c1 self.clean_sessions() self.clean_clients()
def link(sess, old, new): ops = use_obj(old) + [op.savefh()] ops += use_obj(new[:-1]) ops += [op.link(new[-1])] return sess.compound(ops)
check(res, msg="Trying to remove %s" % repr(e.name)) def do_readdir(sess, file, cookie=0, cookieverf='', attrs=0L, dircount=4096, maxcount=4096): # Since we may not get whole directory listing in one readdir request, # loop until we do. For each request result, create a flat list # with <entry4> objects. log.info("Called do_readdir()") entries = [] baseops = use_obj(file) while True: readdir_op = op.readdir(cookie, cookieverf, dircount, maxcount, attrs) res = sess.compound(baseops + [readdir_op]) check(res, msg="READDIR with cookie=%i, maxcount=%i" % (cookie, maxcount)) reply = res.resarray[-1].reply if not reply.entries and not reply.eof: raise UnexpectedCompoundRes("READDIR had no entries") entries.extend(reply.entries) if reply.eof: break cookie = entries[-1].cookie cookieverf = res.resarray[-1].cookieverf log.info("do_readdir() = %r" % entries) return entries
ops = use_obj(path) ops += [op.remove(e.name)] res = sess.compound(ops) if res.status == NFS4ERR_NOTEMPTY: clean_dir(sess, path + [e.name]) res = sess.compound(ops) check(res, msg="Trying to remove %s" % repr(e.name)) def do_readdir(sess, file, cookie=0, cookieverf='', attrs=0L, dircount=4096, maxcount=4096): # Since we may not get whole directory listing in one readdir request, # loop until we do. For each request result, create a flat list # with <entry4> objects. log.info("Called do_readdir()") entries = [] baseops = use_obj(file) while True: readdir_op = op.readdir(cookie, cookieverf, dircount, maxcount, attrs) res = sess.compound(baseops + [readdir_op]) check(res, msg="READDIR with cookie=%i, maxcount=%i" % (cookie, maxcount)) reply = res.resarray[-1].reply if not reply.entries and not reply.eof: raise UnexpectedCompoundRes("READDIR had no entries") entries.extend(reply.entries) if reply.eof: break cookie = entries[-1].cookie cookieverf = res.resarray[-1].cookieverf log.info("do_readdir() = %r" % entries) return entries