def testManyClaims(t, env): """REBOOT test FLAGS: reboot DEPEND: MKDIR MKFILE CODE: REBT2 """ c = env.c1 clientcount = 5 pid = str(os.getpid()) basedir = c.homedir + [t.code] res = c.create_obj(basedir) check(res, msg="Creating test directory %s" % t.code) # Make lots of client ids fhdict = {} idlist = ["pynfs%s%06i" % (pid, x) for x in range(clientcount)] badids = ["badpynfs%s%06i" % (pid, x) for x in range(clientcount)] for id in idlist: c.init_connection(id) fh, stateid = c.create_confirm(t.code, basedir + [id]) fhdict[id] = fh sleeptime = _waitForReboot(c, env) try: # Lots of reclaims badfh = fhdict[idlist[-1]] for goodid, badid in zip(idlist, badids): c.init_connection(goodid) res = c.open_file(t.code, fhdict[goodid], claim_type=CLAIM_PREVIOUS, deleg_type=OPEN_DELEGATE_NONE) check(res, msg="Reclaim with valid clientid %s" % goodid) c.init_connection(badid) res = c.open_file(t.code, badfh, claim_type=CLAIM_PREVIOUS, deleg_type=OPEN_DELEGATE_NONE) checklist(res, [NFS4ERR_NO_GRACE, NFS4ERR_RECLAIM_BAD], "Reclaim with bad clientid %s" % badid) finally: env.sleep(sleeptime, "Waiting for grace period to end")
def testRemove(t, env): """DELEGATION test Get read delegation, then ensure REMOVE recalls it. Respond properly and send DELEGRETURN. FLAGS: delegations CODE: DELEG15 """ c = env.c1 count = c.cb_server.opcounts[OP_CB_RECALL] c.init_connection('pynfs%i_%s' % (os.getpid(), t.code), cb_ident=0) _get_deleg(t, c, c.homedir + [t.code], _recall, NFS4_OK) sleeptime = 5 while 1: ops = c.use_obj(c.homedir) + [c.remove_op(t.code)] _lock.acquire() res = c.compound(ops) _lock.release() if res.status == NFS4_OK: break checklist(res, [NFS4_OK, NFS4ERR_DELAY], "Remove which causes recall") env.sleep(sleeptime, 'Got NFS4ERR_DELAY on remove') sleeptime += 5 if sleeptime > 20: sleeptime = 20 _verify_cb_occurred(t, c, count)
def testRenew(t, env, funct=None, response=NFS4_OK): """Get and recall a read delegation The cb_server will first call funct, then respond with response FLAGS: delegations CODE: DELEG6 """ c = env.c1 c.init_connection('pynfs%i_%s' % (os.getpid(), t.code), cb_ident=0) lease = c.getLeaseTime() _get_deleg(t, c, c.homedir + [t.code], funct, response) try: c.cb_command(0) # Shut off callback server noticed = False for i in range(4): res = c.open_file('newowner', c.homedir + [t.code], access=OPEN4_SHARE_ACCESS_WRITE) env.sleep(lease // 2 + 5, "Waiting to send RENEW") res = c.compound([c.renew_op(c.clientid)]) checklist(res, [NFS4_OK, NFS4ERR_CB_PATH_DOWN], "RENEW") if res.status != NFS4_OK: noticed = True break finally: c.cb_command(1) # Turn on callback server if not noticed: t.fail("RENEWs should not have all returned OK")
def testUnlockFile(t, env): """LOCKU a regular file, testing with LOCK instead of LOCKT FLAGS: multiconn locku all DEPEND: MKFILE MULTICONN CODE: LKUNOLOCKT """ c1 = env.c1 c1.init_connection() c2 = env.get_and_init_secondconn(c1) # Lock file on c1 fh, stateid = c1.create_confirm(t.code, deny=OPEN4_SHARE_DENY_NONE) res1 = c1.lock_file(t.code, fh, stateid) check(res1, msg="Locking file %s" % t.code) # Try to lock file on c2 fh2, stateid2 = c2.open_confirm(t.code, access=OPEN4_SHARE_ACCESS_BOTH, deny=OPEN4_SHARE_DENY_NONE) res2 = c2.lock_file(t.code, fh2, stateid2) # XXX Isilon was returning NFS4ERR_SERVERFAULT instead of DENIED, but this # test is really to test the unlock below, so allow SERVERFAULT. checklist(res2, [NFS4ERR_DENIED, NFS4ERR_SERVERFAULT], "Testing file %s is locked" % t.code) # Unlock file on c1 res3 = c1.unlock_file(1, fh, res1.lockid) check(res3, msg="Unlocking locked file %s" % t.code) # Try to lock file on c2 res2 = c2.lock_file(t.code, fh2, stateid2) check(res2, msg="Testing file %s was unlocked" % t.code)
def testClaimCur(t, env): """DELEGATION test Get read delegation, then have it recalled. In the process of returning, send some OPENs with CLAIM_DELEGATE_CUR FLAGS: delegations CODE: DELEG14 """ c = env.c1 c.init_connection('pynfs%i_%s' % (os.getpid(), t.code), cb_ident=0) deleg_info, fh, stateid = _get_deleg(t, c, c.homedir + [t.code], None, NFS4_OK) # Cause it to be recalled, and wait for cb_recall to finish # FRED - this is problematic if server doesn't reply until # it gets the DELEGRETURN res = c.open_file('newowner', c.homedir + [t.code], access=OPEN4_SHARE_ACCESS_WRITE, deny=OPEN4_SHARE_DENY_NONE) checklist(res, [NFS4_OK, NFS4ERR_DELAY], "Open which causes recall") env.sleep(2, "Waiting for recall") # Now send some opens path = c.homedir + [t.code] res = c.open_file('owner1', path, access=OPEN4_SHARE_ACCESS_READ, claim_type=CLAIM_DELEGATE_CUR, deleg_stateid=deleg_info.read.stateid) check(res) ops = c.use_obj(path) + [c.delegreturn_op(deleg_info.read.stateid)] res = c.compound(ops) check(res)
def testChangeDeleg(t, env, funct=_recall): """Get a read delegation, change to a different callback server, then recall the delegation FLAGS: delegations CODE: DELEG9 """ from nfs4lib import CBServer c = env.c1 id = 'pynfs%i_%s' % (os.getpid(), t.code) c.init_connection(id, cb_ident=0) deleg_info, fh, stateid = _get_deleg(t, c, c.homedir + [t.code], funct, NFS4_OK) # Create new callback server new_server = CBServer(c) new_server.set_cb_recall(c.cbid, funct, NFS4_OK); cb_thread = threading.Thread(target=new_server.run) cb_thread.setDaemon(1) cb_thread.start() c.cb_server = new_server env.sleep(3) # Switch to using new server res = c.compound([_set_clientid(c, id, new_server)]) check(res, msg="Switch to new callback server") c.clientid = res.resarray[0].switch.switch.clientid confirm = res.resarray[0].switch.switch.setclientid_confirm confirmop = c.setclientid_confirm_op(c.clientid, confirm) res = c.compound([confirmop]) checklist(res, [NFS4_OK, NFS4ERR_RESOURCE]) if res.status == NFS4ERR_RESOURCE: # ibm workaround res = c.compound([confirmop]) check(res) count = new_server.opcounts[OP_CB_RECALL] fh2, stateid2 = _cause_recall(t, env) _verify_cb_occurred(t, c, count)
def testTimedoutGrabLock(t, env): """LOCK: server should release locks of timed out client FLAGS: lock timed all DEPEND: MKFILE CODE: LOCK13 """ c1 = env.c1 c1.init_connection() # Client 1: create a file and get its fh fh1, stateid1 = c1.create_confirm(t.code) c2 = env.c2 c2.init_connection() # Client 2: open the file fh2, stateid2 = c2.open_confirm(t.code, deny=OPEN4_SHARE_DENY_NONE) # Client 1: lock file res1 = c1.lock_file(t.code, fh1, stateid1) check(res1) # Now wait, let client1 expire while client2 sends RENEWs sleeptime = c2.getLeaseTime() // 2 for i in range(3): env.sleep(sleeptime) res = c2.compound([c2.renew_op(c2.clientid)]) checklist(res, [NFS4_OK, NFS4ERR_CB_PATH_DOWN]) # Client 2: Lock file, should work since Client 1's lock has expired res2 = c2.lock_file(t.code, fh2, stateid2, type=READ_LT) check(res2, msg="Locking file after another client's lock expires")
def testUnaccessibleDirAttrs(t, env): """READDIR with (cfh) in unaccessible directory requesting attrs FLAGS: readdir all mode000 DEPEND: MKDIR MODE CODE: RDDR12 """ c = env.c1 path = c.homedir + [t.code] c.maketree([t.code, ['hidden']]) ops = c.use_obj(path) + [c.setattr({FATTR4_MODE:0})] res = c.compound(ops) check(res, msg="Setting mode=0 on directory %s" % t.code) ops = c.use_obj(path) + \ [c.readdir(attr_request=[FATTR4_RDATTR_ERROR, FATTR4_TYPE])] res = c.compound(ops) if env.opts.uid == 0: checklist(res, [NFS4_OK, NFS4ERR_ACCESS], "READDIR of directory with mode=000") else: check(res, NFS4ERR_ACCESS, "READDIR of directory with mode=000") ########################################### def testStrangeNames(t, env): """READDIR should obey OPEN naming policy Extra test Comments: Verifying that readdir obeys the same naming policy as OPEN. """ self.init_connection() try: (accepted_names, rejected_names) = self.try_file_names(remove_files=0) except SkipException, e: self.skip(e) fh = self.do_rpc(self.ncl.do_getfh, self.tmp_dir) entries = self.do_rpc(self.ncl.do_readdir, fh) readdir_names = [entry.name for entry in entries] # Verify that READDIR returned all accepted_names missing_names = [] for name in accepted_names: if name not in readdir_names: missing_names.append(name) self.failIf(missing_names, "Missing names in READDIR results: %s" \ % missing_names) # ... and nothing more extra_names = [] for name in readdir_names: if not name in accepted_names: extra_names.append(name) self.failIf(extra_names, "Extra names in READDIR results: %s" \ % extra_names)
def testCreatExclusiveFile(t, env): """OPEN normal file with create and exclusive flags FLAGS: open all DEPEND: INIT CODE: OPEN4 """ c = env.c1 c.init_connection() # Create the file res = c.create_file(t.code, mode=EXCLUSIVE4, verifier='12345678', deny=OPEN4_SHARE_DENY_NONE) checklist(res, [NFS4_OK, NFS4ERR_NOTSUPP], "Trying to do exclusive create of file %s" % t.code) if res.status == NFS4ERR_NOTSUPP: c.fail_support("Exclusive OPEN not supported") fh, stateid = c.confirm(t.code, res) # Create the file again, should return an error res = c.create_file(t.code, mode=EXCLUSIVE4, verifier='87654321', deny=OPEN4_SHARE_DENY_NONE) check(res, NFS4ERR_EXIST, "Trying to do exclusive recreate of file %s" % t.code) # Create with same verifier should return same object res = c.create_file(t.code, mode=EXCLUSIVE4, verifier='12345678', deny=OPEN4_SHARE_DENY_NONE) check(res, msg="Trying to do exclusive recreate of file %s" % t.code) newfh, stateid = c.confirm(t.code, res) if fh != newfh: c.fail("Filehandle changed on duplicate exclusive create")
def _testDeleg(t, env, openaccess, want, breakaccess, sec = None, sec2 = None): recall = threading.Event() def pre_hook(arg, env): recall.stateid = arg.stateid # NOTE this must be done before set() recall.cred = env.cred.raw_cred env.notify = recall.set # This is called after compound sent to queue def post_hook(arg, env, res): return res sess1 = env.c1.new_client_session("%s_1" % env.testname(t), sec = sec) sess1.client.cb_pre_hook(OP_CB_RECALL, pre_hook) sess1.client.cb_post_hook(OP_CB_RECALL, post_hook) if sec2: sess1.compound([op.backchannel_ctl(env.c1.prog, sec2)]) fh = _create_file_with_deleg(sess1, env.testname(t), openaccess | want) sess2 = env.c1.new_client_session("%s_2" % env.testname(t)) claim = open_claim4(CLAIM_NULL, env.testname(t)) owner = open_owner4(0, "My Open Owner 2") how = openflag4(OPEN4_NOCREATE) open_op = op.open(0, breakaccess, OPEN4_SHARE_DENY_NONE, owner, how, claim) slot = sess2.compound_async(env.home + [open_op]) # Wait for recall, and return delegation recall.wait() # STUB - deal with timeout # Getting here means CB_RECALL reply is in the send queue. # Give it a moment to actually be sent env.sleep(.1) res = sess1.compound([op.putfh(fh), op.delegreturn(recall.stateid)]) check(res) # Now get OPEN reply res = sess2.listen(slot) checklist(res, [NFS4_OK, NFS4ERR_DELAY]) return recall
def testUnlockFile2(t, env): """Take a couple of locks, then LOCKU a regular file, testing with LOCK instead of LOCKT FLAGS: multiconn locku all DEPEND: MKFILE MULTICONN CODE: LKUNOLOCKT2 """ c1 = env.c1 c1.init_connection() c2 = env.get_and_init_secondconn(c1) # Lock two ranges on c1 fh, stateid = c1.create_confirm(t.code, deny=OPEN4_SHARE_DENY_NONE) res1 = c1.lock_file(t.code, fh, stateid, 0, 10, READ_LT) check(res1, msg="(1) Locking bytes 0-10 on file %s" % t.code) res2 = c1.lock_file(t.code, fh, stateid, 0, 5, READ_LT) check(res2, msg="(2) Locking bytes 0-5 on file %s" % t.code) # Try to lock exclusive on c2 and fail fh2, stateid2 = c2.open_confirm(t.code, access=OPEN4_SHARE_ACCESS_BOTH, deny=OPEN4_SHARE_DENY_NONE) res3 = c2.lock_file(t.code, fh2, stateid2, 0, 10, WRITE_LT) # XXX Isilon was returning NFS4ERR_SERVERFAULT instead of DENIED, but this # test is really to test the unlock below, so allow SERVERFAULT. checklist(res3, [NFS4ERR_DENIED, NFS4ERR_SERVERFAULT], "Testing file %s is locked" % t.code) # Unlock bigger range on c1 res3 = c1.unlock_file(1, fh, res1.lockid, 0, 10) check(res3, msg="Unlocking locked file %s" % t.code) # Try to lock small range on c2 res3 = c2.lock_file(t.code, fh2, stateid2, 9, 10, WRITE_LT) check(res3, msg="Testing file %s was unlocked" % t.code)
def testOwnerName(t, env): """GETATTR on owner FLAGS: getattr all DEPEND: LOOKFILE CODE: GATT10 """ c = env.c1 ops = c.use_obj(env.opts.usefile) ops += [c.getattr([FATTR4_OWNER])] res = c.compound(ops) checklist(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(owner)") if res.status == NFS4ERR_ATTRNOTSUPP: t.fail_support("owner not a supported attribute") # print res.resarray[-1].obj_attributes #################################################### def xxxtestMountedOnFileid(self): """GETATTR(FATTR4_MOUNTED_ON_FILEID) This DOES NOT work on standard test tree. It assumes that pseudofs root / and pseudo fs node /unix exist, and that /unix is a mountpoint of an exported file system. The fsid of "/" should differ from the fsid of "/unix", and the mounted_on_fileid should != the filed with both the Getattr of "/unix" and the Readdir of "/". """ request = [FATTR4_MOUNTED_ON_FILEID, FATTR4_FILEID, FATTR4_FSID] lookupops = [self.ncl.lookup_op("unix")] ops = [self.ncl.putrootfh_op()] ops.append(self.ncl.getattr(request)) ops += lookupops ops.append(self.ncl.getattr(request)) res = self.ncl.do_ops(ops) self.assert_OK(res) print print "From Getattr / - ", res.resarray[-3].obj_attributes print print "From Getattr /unix - ", res.resarray[-1].obj_attributes ops = [self.ncl.putrootfh_op()] attrmask = nfs4lib.list2bitmap(request) ops.append(self.ncl.readdir(attr_request=attrmask)) res = self.ncl.do_ops(ops) self.assert_OK(res) # Find 'user' (note this assumes dir listing is small enough that # the whole listing was returned) reply = res.resarray[-1].switch.switch.reply entry = reply.entries[0] while 1: if entry.name=="unix": break if not entry.nextentry: self.fail("Could not find mountpoint /unix") entry = entry.nextentry[0] print "From Readdir / - ", entry.attrs
def _retry_conflicting_op(env, c, op, opname): while 1: _lock.acquire() res = c.compound(op) _lock.release() if res.status == NFS4_OK: break checklist(res, [NFS4_OK, NFS4ERR_DELAY], "%s which causes recall" % opname) env.sleep(1, 'Got NFS4ERR_DELAY on %s' % opname)
def testLink(t, env): """COMMIT FLAGS: commit symlink all DEPEND: LOOKLINK CODE: CMT2a """ c = env.c1 res = c.commit_file(env.opts.uselink) checklist(res, [NFS4ERR_INVAL, NFS4ERR_SYMLINK], "COMMIT with non-file object")
def testDirOffLink(t, env): """CREATE a dir off a symbolic link FLAGS: create symlink all DEPEND: LOOKLINK CODE: CR2 """ c = env.c1 res = c.create_obj(env.opts.uselink + [t.code]) checklist(res, [NFS4ERR_NOTDIR, NFS4ERR_SYMLINK])
def testSfhLink(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR FLAGS: rename symlink all CODE: RNM2a """ name = env.testname(t) sess = env.c1.new_client_session(name) res = rename_obj(sess, env.opts.uselink + [name], env.c1.homedir + [name]) checklist(res, [NFS4ERR_SYMLINK, NFS4ERR_NOTDIR], "RENAME with non-dir <sfh>")
def testSfhLink(t, env): """RENAME with non-dir (sfh) should return NFS4ERR_NOTDIR FLAGS: rename symlink all DEPEND: LOOKLINK CODE: RNM2a """ c = env.c1 res = c.rename_obj(env.opts.uselink + [t.code], c.homedir + [t.code]) checklist(res, [NFS4ERR_NOTDIR, NFS4ERR_SYMLINK], "RENAME with non-dir <sfh>")
def testCfhLink(t, env): """LINK should fail with NFS4ERR_NOTDIR if cfh is not dir FLAGS: link symlink all DEPEND: LINKS LOOKFILE LOOKLINK CODE: LINK4a """ res = env.c1.link(env.opts.usefile, env.opts.uselink + [t.code]) checklist(res, [NFS4ERR_NOTDIR, NFS4ERR_SYMLINK], "LINK with <cfh> not a directory")
def testLink(t, env): """READ with non-file objects FLAGS: read symlink all DEPEND: LOOKLINK CODE: RD7a """ c = env.c1 res = c.read_file(env.opts.uselink) checklist(res, [NFS4ERR_INVAL, NFS4ERR_SYMLINK], "Read of a non-file object")
def testCfhLink(t, env): """REMOVE with non-dir (cfh) should give NFS4ERR_NOTDIR FLAGS: remove symlink all DEPEND: LOOKLINK CODE: RM2a """ c = env.c1 ops = c.use_obj(env.opts.uselink) + [c.remove_op(t.code)] res = c.compound(ops) checklist(res, [NFS4ERR_NOTDIR, NFS4ERR_SYMLINK], "REMOVE with non-dir cfh")
def testLink(t, env): """LOCKT on non-file objects) FLAGS: lockt symlink all DEPEND: LOOKLINK CODE: LKT2a """ c = env.c1 c.init_connection() res = c.lock_test(env.opts.uselink) checklist(res, [NFS4ERR_INVAL, NFS4ERR_SYMLINK], "LOCKT on non-file object")
def testDirToFullDir(t, env): """RENAME dir into existing, nonempty dir should return NFS4ERR_EXIST FLAGS: rename all CODE: RNM16 """ name = env.testname(t) sess = env.c1.new_client_session(name) basedir = env.c1.homedir + [name] maketree(sess, [name, ['dir1'], ['dir2', ['foo']]]) res = rename_obj(sess, basedir + ['dir1'], basedir + ['dir2']) checklist(res, [NFS4ERR_EXIST, NFS4ERR_NOTEMPTY], "RENAME dir1 into existing, nonempty dir2")
def _try_unsupported(env, path): c = env.c1 baseops = c.use_obj(path) supp_mask = c.supportedAttrs(path) unsupp = [attr for attr in env.attr_info if not (attr.mask & supp_mask)] for attr in unsupp: ops = baseops + [c.verify_op({attr.bitnum: attr.sample})] res = c.compound(ops) if attr.writeonly: checklist(res, [NFS4ERR_ATTRNOTSUPP, NFS4ERR_INVAL], "VERIFY with unsupported attr %s" % attr.name) else: check(res, NFS4ERR_ATTRNOTSUPP, "VERIFY with unsupported attr %s" % attr.name)
def testDirToFullDir(t, env): """RENAME dir into existing, nonempty dir should return NFS4ERR_EXIST FLAGS: rename all DEPEND: MKDIR CODE: RNM16 """ c = env.c1 basedir = c.homedir + [t.code] c.maketree([t.code, ['dir1'], ['dir2', ['foo']]]) res = c.rename_obj(basedir + ['dir1'], basedir + ['dir2']) checklist(res, [NFS4ERR_EXIST, NFS4ERR_NOTEMPTY], "RENAME dir1 into existing, nonempty dir2")
def testCfhLink(t, env): """RENAME with non-dir (cfh) should return NFS4ERR_NOTDIR FLAGS: rename symlink all DEPEND: MKDIR LOOKLINK CODE: RNM3a """ c = env.c1 res = c.create_obj(t.code) check(res) res = c.rename_obj(c.homedir + [t.code], env.opts.uselink + [t.code]) checklist(res, [NFS4ERR_NOTDIR, NFS4ERR_SYMLINK], "RENAME with non-dir <cfh>")
def testFhLink(t, env): """READDIR with non-dir (cfh) should give NFS4ERR_NOTDIR FLAGS: readdir symlink all DEPEND: LOOKLINK CODE: RDDR5a """ c = env.c1 ops = c.use_obj(env.opts.uselink) ops += [c.readdir()] res = c.compound(ops) checklist(res, [NFS4ERR_NOTDIR, NFS4ERR_SYMLINK], "READDIR with non-dir <cfh>")
def testOpenPutrootfhClose(t, env): """test current state id processing by having OPEN, PUTROOTFH and CLOSE in a single compound FLAGS: currentstateid all CODE: CSID5 """ sess1 = env.c1.new_client_session(env.testname(t)) open_op = open_create_file_op(sess1, env.testname(t), open_create=OPEN4_CREATE) res = sess1.compound(open_op + [op.putrootfh(), op.close(0, current_stateid)]) checklist(res, [NFS4ERR_STALE_STATEID, NFS4ERR_BAD_STATEID])
def testLink(t, env): """LOOKUPP with non-dir (cfh) FLAGS: lookupp symlink all DEPEND: LOOKLINK CODE: LOOKP2a """ c = env.c1 ops = c.use_obj(env.opts.uselink) + [c.lookupp_op()] res = c.compound(ops) checklist(res, [NFS4ERR_NOTDIR, NFS4ERR_SYMLINK], "LOOKUPP with non-dir <cfh>")
def testDelegRevocation(t, env): """Allow a delegation to be revoked, check that TEST_STATEID and FREE_STATEID have the required effect. FLAGS: deleg CODE: DELEG8 """ sess1 = env.c1.new_client_session("%s_1" % env.testname(t)) fh, deleg = __create_file_with_deleg(sess1, env.testname(t), OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WANT_READ_DELEG) delegstateid = deleg.read.stateid sess2 = env.c1.new_client_session("%s_2" % env.testname(t)) claim = open_claim4(CLAIM_NULL, env.testname(t)) owner = open_owner4(0, "My Open Owner 2") how = openflag4(OPEN4_NOCREATE) open_op = op.open(0, OPEN4_SHARE_ACCESS_WRITE, OPEN4_SHARE_DENY_NONE, owner, how, claim) while 1: res = sess2.compound(env.home + [open_op]) if res.status == NFS4_OK: break; checklist(res, [NFS4_OK, NFS4ERR_DELAY]) # just to keep sess1 renewed. This is a bit fragile, as we # depend on the above compound waiting no longer than the # server's lease period: res = sess1.compound([]) slot, seq_op = sess1._prepare_compound({}) res = sess1.c.compound([seq_op]) flags = res.resarray[0].sr_status_flags; if not(flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED): fail("SEQ4_STATUS_RECALLABLE_STATE_REVOKED should be set after" " sucess of open conflicting with delegation") flags &= ~SEQ4_STATUS_RECALLABLE_STATE_REVOKED if flags: print("WARNING: unexpected status flag(s) 0x%x set" % flags); res = sess1.update_seq_state(res, slot) res = sess1.compound([op.test_stateid([delegstateid])]) stateid_stat = res.resarray[0].tsr_status_codes[0] if stateid_stat != NFS4ERR_DELEG_REVOKED: fail("TEST_STATEID on revoked stateid should report status" " NFS4ERR_DELEG_REVOKED, instead got %s" % nfsstat4[stateid_stat]); res = sess1.compound([op.free_stateid(delegstateid)]) check(res) slot, seq_op = sess1._prepare_compound({}) res = sess1.c.compound([seq_op]) flags = res.resarray[0].sr_status_flags if flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED: fail("SEQ4_STATUS_RECALLABLE_STATE_REVOKED should be cleared after" " FREE_STATEID") if flags & ~SEQ4_STATUS_RECALLABLE_STATE_REVOKED: print("WARNING: unexpected status flag(s) 0x%x set" % flags)
def testZeroLengthForLNK(t, env): """CREATE with zero length name should return NFS4ERR_INVAL FLAGS: create symlink all CODE: CR9a """ c = env.c1 ops = c.go_home() objtype = createtype4(NF4LNK, **{'linkdata':''}) ops += [c.create_op(objtype, t.code, getDefaultAttr(c))] res = c.compound(ops) checklist(res, [NFS4ERR_INVAL, NFS4ERR_NOENT], "CREATE with zero-length name for SYMLINK")
def testChangeDeleg(t, env, funct=_recall): """Get a read delegation, change to a different callback server, then recall the delegation FLAGS: delegations CODE: DELEG9 """ from nfs4lib import CBServer c = env.c1 id = 'pynfs%i_%s' % (os.getpid(), t.code) c.init_connection(id, cb_ident=0) deleg_info, fh, stateid = _get_deleg(t, c, c.homedir + [t.code], funct, NFS4_OK) # Create new callback server new_server = CBServer(c) new_server.set_cb_recall(c.cbid, funct, NFS4_OK) cb_thread = threading.Thread(target=new_server.run) cb_thread.setDaemon(1) cb_thread.start() c.cb_server = new_server env.sleep(3) # Switch to using new server res = c.compound([_set_clientid(c, id, new_server)]) check(res, msg="Switch to new callback server") c.clientid = res.resarray[0].switch.switch.clientid confirm = res.resarray[0].switch.switch.setclientid_confirm confirmop = c.setclientid_confirm_op(c.clientid, confirm) res = c.compound([confirmop]) checklist(res, [NFS4_OK, NFS4ERR_RESOURCE]) if res.status == NFS4ERR_RESOURCE: # ibm workaround res = c.compound([confirmop]) check(res) count = new_server.opcounts[OP_CB_RECALL] fh2, stateid2 = _cause_recall(t, env) _verify_cb_occurred(t, c, count)
def testUnaccessibleDirAttrs(t, env): """READDIR with (cfh) in unaccessible directory requesting attrs FLAGS: readdir all mode000 DEPEND: MKDIR MODE CODE: RDDR12 """ c = env.c1 path = c.homedir + [t.code] c.maketree([t.code, ['hidden']]) ops = c.use_obj(path) + [c.setattr({FATTR4_MODE: 0})] res = c.compound(ops) check(res, msg="Setting mode=0 on directory %s" % t.code) ops = c.use_obj(path) + \ [c.readdir(attr_request=[FATTR4_RDATTR_ERROR, FATTR4_TYPE])] res = c.compound(ops) if env.opts.uid == 0: checklist(res, [NFS4_OK, NFS4ERR_ACCESS], "READDIR of directory with mode=000") else: check(res, NFS4ERR_ACCESS, "READDIR of directory with mode=000") ########################################### def testStrangeNames(t, env): """READDIR should obey OPEN naming policy Extra test Comments: Verifying that readdir obeys the same naming policy as OPEN. """ self.init_connection() try: (accepted_names, rejected_names) = self.try_file_names(remove_files=0) except SkipException, e: self.skip(e) fh = self.do_rpc(self.ncl.do_getfh, self.tmp_dir) entries = self.do_rpc(self.ncl.do_readdir, fh) readdir_names = [entry.name for entry in entries] # Verify that READDIR returned all accepted_names missing_names = [] for name in accepted_names: if name not in readdir_names: missing_names.append(name) self.failIf(missing_names, "Missing names in READDIR results: %s" \ % missing_names) # ... and nothing more extra_names = [] for name in readdir_names: if not name in accepted_names: extra_names.append(name) self.failIf(extra_names, "Extra names in READDIR results: %s" \ % extra_names)
def testFSLocations(t, env): """GETATTR on FSLocations FLAGS: getattr fslocations all DEPEND: LOOKFILE CODE: GATT8 """ c = env.c1 ops = c.use_obj(env.opts.usefile) ops += [c.getattr([FATTR4_FS_LOCATIONS])] res = c.compound(ops) checklist(res, [NFS4_OK, NFS4ERR_ATTRNOTSUPP], "GETATTR(fs_locations)") if res.status == NFS4ERR_ATTRNOTSUPP: t.fail_support("fs_locations not a supported attribute") raw_attrs = res.resarray[-1].arm.arm.obj_attributes d = fattr2dict(raw_attrs) print d #################################################### def xxxtestMountedOnFileid(self): """GETATTR(FATTR4_MOUNTED_ON_FILEID) This DOES NOT work on standard test tree. It assumes that pseudofs root / and pseudo fs node /unix exist, and that /unix is a mountpoint of an exported file system. The fsid of "/" should differ from the fsid of "/unix", and the mounted_on_fileid should != the filed with both the Getattr of "/unix" and the Readdir of "/". """ request = [FATTR4_MOUNTED_ON_FILEID, FATTR4_FILEID, FATTR4_FSID] lookupops = [self.ncl.lookup_op("unix")] ops = [self.ncl.putrootfh_op()] ops.append(self.ncl.getattr(request)) ops += lookupops ops.append(self.ncl.getattr(request)) res = self.ncl.do_ops(ops) self.assert_OK(res) obj = res.resarray[-3].arm.arm.obj_attributes d = nfs4lib.fattr2dict(obj) print print "From Getattr / - ", d obj = res.resarray[-1].arm.arm.obj_attributes d = nfs4lib.fattr2dict(obj) print print "From Getattr /unix - ", d ops = [self.ncl.putrootfh_op()] attrmask = nfs4lib.list2attrmask(request) ops.append(self.ncl.readdir(attr_request=attrmask)) res = self.ncl.do_ops(ops) self.assert_OK(res) # Find 'user' (note this assumes dir listing is small enough that # the whole listing was returned) reply = res.resarray[-1].arm.arm.reply entry = reply.entries[0] while 1: if entry.name == "unix": break if not entry.nextentry: self.fail("Could not find mountpoint /unix") entry = entry.nextentry[0] d2 = nfs4lib.fattr2dict(entry.attrs) print "From Readdir / - ", d2