def testLockWriteLocku(t, env): """test current state id processing by having LOCK, WRITE and LOCKU in a single compound FLAGS: currentstateid all CODE: CSID4 """ sess1 = env.c1.new_client_session(env.testname(t)) res = create_file(sess1, env.testname(t)) check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid data = "write test data" open_to_lock_owner = open_to_lock_owner4(0, stateid, 0, lock_owner4(0, "lock1")) lock_owner = locker4(open_owner=open_to_lock_owner, new_lock_owner=True) lock_ops = [ op.lock(WRITE_LT, False, 0, NFS4_UINT64_MAX, lock_owner), op.write(current_stateid, 5, FILE_SYNC4, data), op.locku(WRITE_LT, 0, current_stateid, 0, NFS4_UINT64_MAX), op.close(0, stateid), ] res = sess1.compound([op.putfh(fh)] + lock_ops) check(res, NFS4_OK)
def testReplayCache002(t, env): """Send two successful non-idempotent compounds with same seqid FLAGS: sequence all CODE: SEQ9b """ sess1 = env.c1.new_client_session(env.testname(t)) res = create_file(sess1, "%s_1" % env.testname(t)) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid check(res) ops = env.home + [op.savefh(),\ op.rename("%s_1" % env.testname(t), "%s_2" % env.testname(t))] res1 = sess1.compound(ops, cache_this=True) check(res1) res2 = sess1.compound(ops, seq_delta=0) check(res2) res1.tag = res2.tag = "" if not nfs4lib.test_equal(res1, res2): fail("Replay results not equal") # Cleanup res = sess1.compound([op.putfh(fh), op.close(0, stateid)]) check(res)
def testEmptyCommit(t, env): """Check for proper handling of empty LAYOUTCOMMIT. FLAGS: block CODE: BLOCK3 """ sess = env.c1.new_pnfs_client_session(env.testname(t)) # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout 1 fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid print open_stateid ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW, 0, 8192, 8192, open_stateid, 0xffff)] res = sess.compound(ops) check(res) # Get layout 2 lo_stateid1 = res.resarray[-1].logr_stateid print lo_stateid1 ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW, 8192, 8192, 8192, lo_stateid1, 0xffff)] res = sess.compound(ops) check(res) lo_stateid2 = res.resarray[-1].logr_stateid print lo_stateid2 # Parse opaque to get info for commit # STUB not very general layout = res.resarray[-1].logr_layout[-1] p = BlockUnpacker(layout.loc_body) opaque = p.unpack_pnfs_block_layout4() p.done() extent = opaque.blo_extents[-1] extent.bex_state = PNFS_BLOCK_READWRITE_DATA p = BlockPacker() p.pack_pnfs_block_layoutupdate4(pnfs_block_layoutupdate4([extent])) time = newtime4(True, get_nfstime()) ops = [op.putfh(fh), op.layoutcommit(extent.bex_file_offset, extent.bex_length, False, lo_stateid2, newoffset4(True, 2 * 8192 - 1), time, layoutupdate4(LAYOUT4_BLOCK_VOLUME, p.get_buffer()))] res = sess.compound(ops) check(res) # Send another LAYOUTCOMMIT, with an empty opaque time = newtime4(True, get_nfstime()) ops = [op.putfh(fh), op.layoutcommit(extent.bex_file_offset, extent.bex_length, False, lo_stateid2, newoffset4(True, 2 * 8192 - 1), time, layoutupdate4(LAYOUT4_BLOCK_VOLUME, ""))] res = sess.compound(ops) check(res)
def testLayoutReturnAll(t, env): """ Return all of a client's layouts FLAGS: pnfs DEPEND: GETLAYOUT1 CODE: LAYOUTRET3 """ # Make sure E_ID returns MDS capabilities c1 = env.c1.new_client(env.testname(t), flags=EXCHGID4_FLAG_USE_PNFS_MDS) if not c1.flags & EXCHGID4_FLAG_USE_PNFS_MDS: fail("Server can not be used as pnfs metadata server") sess = c1.create_session() print sess.c.homedir # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_READ, 0, 0xffffffffffffffff, 0, open_stateid, 0xffff)] res = sess.compound(ops) check(res) # Return layout ops = [op.layoutreturn(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_ANY, layoutreturn4(LAYOUTRETURN4_ALL))] res = sess.compound(ops) check(res)
def testOPENClaimFH(t, env): """OPEN file with claim_type is CLAIM_FH FLAGS: open all CODE: OPEN7 """ sess1 = env.c1.new_client_session(env.testname(t)) res = create_file(sess1, env.testname(t)) check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid res = close_file(sess1, fh, stateid=stateid) check(res) claim = open_claim4(CLAIM_FH) how = openflag4(OPEN4_NOCREATE) oowner = open_owner4(0, "My Open Owner 2") open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH, OPEN4_SHARE_DENY_NONE, oowner, how, claim) res = sess1.compound([op.putfh(fh), open_op]) check(res) stateid = res.resarray[-1].stateid stateid.seqid = 0 data = "write test data" res = sess1.compound([op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, data)]) check(res) res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 1000)]) check(res) if not res.resarray[-1].eof: fail("EOF not set on read") desired = "\0"*5 + data if res.resarray[-1].data != desired: fail("Expected %r, got %r" % (desired, res.resarray[-1].data))
def testFlexLayoutStress(t, env): """Alternate LAYOUTIOMODE4_RW/LAYOUTIOMODE4_READ layout segments in the file FLAGS: flex CODE: FFLG2 """ seqid_next = 1 sess = env.c1.new_pnfs_client_session(env.testname(t)) # Create the file res = create_file(sess, env.testname(t)) check(res) fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid lo_stateid = open_stateid for i in range(1000): ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_READ if i%2 else LAYOUTIOMODE4_RW, 0, 0xffffffffffffffff, 8192, lo_stateid, 0xffff)] res = sess.compound(ops) check(res) lo_stateid = res.resarray[-1].logr_stateid check_seqid(lo_stateid, seqid_next) seqid_next += 1 ops = [op.putfh(fh), op.layoutreturn(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_ANY, layoutreturn4(LAYOUTRETURN4_FILE, layoutreturn_file4(0, 0xffffffffffffffff, lo_stateid, "")))] res = sess.compound(ops) check(res) res = close_file(sess, fh, stateid=open_stateid) check(res)
def testAnonReadWrite(t, env): """Do a simple READ and WRITE using anonymous stateid FLAGS: open all CODE: OPEN31 """ sess1 = env.c1.new_client_session(env.testname(t)) owner = open_owner4(0, "My Open Owner") res = create_file(sess1, env.testname(t)) check(res) expect(res, seqid=1) fh = res.resarray[-1].object data = "write test data" stateid = res.resarray[-2].stateid res = close_file(sess1, fh, stateid=stateid) check(res) res = sess1.compound([op.putfh(fh), op.write(nfs4lib.state00, 5, FILE_SYNC4, data)]) check(res) res = sess1.compound([op.putfh(fh), op.read(nfs4lib.state00, 0, 1000)]) check(res) if not res.resarray[-1].eof: fail("EOF not set on read") desired = "\0"*5 + data if res.resarray[-1].data != desired: fail("Expected %r, got %r" % (desired, res.resarray[-1].data))
def testSupported2(t, env): """Check OPEN delegation handling FLAGS: open all CODE: OPEN200 """ # c1 - OPEN - READ with delegation c1 = env.c1.new_client("%s_1" % env.testname(t)) sess1 = c1.create_session() res = create_file(sess1, env.testname(t), access=OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WANT_READ_DELEG) check(res) # STUB Should check delegation was granted fh1 = res.resarray[-1].object stateid1 = res.resarray[-2].stateid # c2 - OPEN - WRITE c2 = env.c1.new_client("%s_2" % env.testname(t)) sess2 = c2.create_session() owner = open_owner4(0, "My Open Owner 2") claim = open_claim4(CLAIM_NULL, env.testname(t)) how = openflag4(OPEN4_NOCREATE) open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH, OPEN4_SHARE_DENY_NONE, owner, how, claim) res = sess2.compound(env.home + [open_op]) # STUB - since we are not handling callback, deleg_return never gets done print res check(res) fh2 = res.resarray[-1].object stateid2 = res.resarray[-2].stateid res = close_file(sess1, fh1, stateid=stateid1) check(res) res = close_file(sess2, fh2, stateid=stateid2) check(res)
def testFlexLayoutReturnFile(t, env): """ Return a file's layout FLAGS: flex DEPEND: FFGLO1 CODE: FFLOR1 """ sess = env.c1.new_pnfs_client_session(env.testname(t)) # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_READ, 0, 0xffffffffffffffff, 4196, open_stateid, 0xffff)] res = sess.compound(ops) check(res) # Return layout layout_stateid = res.resarray[-1].logr_stateid ops = [op.putfh(fh), op.layoutreturn(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_ANY, layoutreturn4(LAYOUTRETURN4_FILE, layoutreturn_file4(0, 0xffffffffffffffff, layout_stateid, "")))] res = sess.compound(ops) check(res) res = close_file(sess, fh, stateid=open_stateid) check(res)
def testRepTooBig(t, env): """If requester sends a request for which the size of the reply would exceed ca_maxresponsesize, the replier will return NFS4ERR_REP_TOO_BIG FLAGS: create_session all CODE: CSESS26 """ name = env.testname(t) c1 = env.c1.new_client(name) # create session with a small ca_maxresponsesize chan_attrs = channel_attrs4(0,8192,500,8192,128,8,[]) sess1 = c1.create_session(fore_attrs=chan_attrs) sess1.compound([op.reclaim_complete(FALSE)]) owner = "owner_%s" % name path = sess1.c.homedir + [name] res = create_file(sess1, owner, path, access=OPEN4_SHARE_ACCESS_BOTH) check(res) # write some data to file fh = res.resarray[-1].object stateid = res.resarray[-2].stateid res = sess1.compound([op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, "write test data " * 10)]) check(res) # read data rather than ca_maxresponsesize res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 500)]) check(res, NFS4ERR_REP_TOO_BIG)
def testAsyncRead(t, env): """Do a simple ASYNCREAD FLAGS: asyncread all CODE: ASYNC1 """ sess1 = env.c1.new_client_session(env.testname(t)) owner = open_owner4(0, "My Open Owner") res = create_file(sess1, env.testname(t)) check(res) expect(res, seqid=1) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid stateid.seqid = 0 #f = open("/home/sujan/Documents/pynfs/nfs4.1/data.txt","r") data = "Testing testAsyncRead Test Case" res = sess1.compound([op.putfh(fh), op.write(stateid, 0, FILE_SYNC4,data)]) check(res) asyre = threading.Event() def pre_hook(arg, env): print "received callback for testAsyncRead with reqId",arg.opcbasync_read.argok4.reqid env.notify = asyre.set sess1.client.cb_pre_hook(OP_CB_ASYNC_READ, pre_hook) reqId = getReqId() async_res = sess1.compound([op.putfh(fh), op.async_read(reqId,stateid,0,10,0)]) check(async_res) asyre.wait()
def testSupported2(t, env): """GETFH after do a SECINFO_NO_NAME or SECINFO result in a NOFILEHANDLE error, See rfc 5661 section 2.6.3.1.1.8 FLAGS: all CODE: SEC2 """ name = env.testname(t) sess = env.c1.new_client_session(env.testname(t)) # Create a tmpfile for testing owner = "owner_%s" % name path = sess.c.homedir + [name] res = create_file(sess, owner, path, access=OPEN4_SHARE_ACCESS_WRITE) check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid # Get the filehandle of the tmpfile's parent dir res = sess.compound(use_obj(sess.c.homedir) + [op.getfh()]) check(res) fh_p = res.resarray[-1].object # GETFH after do a SECINFO should get error NFS4ERR_NOFILEHANDLE res = sess.compound([op.putfh(fh_p), op.secinfo(name), op.getfh()]) check(res, NFS4ERR_NOFILEHANDLE) # Cleanup res = sess.compound([op.putfh(fh), op.close(0, stateid)]) check(res)
def testSupported(t, env): """Do a simple SECINFO FLAGS: all CODE: SEC1 """ name = env.testname(t) sess = env.c1.new_client_session(env.testname(t)) # Create a tmpfile for testing owner = "owner_%s" % name path = sess.c.homedir + [name] res = create_file(sess, owner, path, access=OPEN4_SHARE_ACCESS_WRITE) check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid # Get the filehandle of the tmpfile's parent dir res = sess.compound(use_obj(sess.c.homedir) + [op.getfh()]) check(res) fh_p = res.resarray[-1].object # Just do a simple SECINFO res = sess.compound([op.putfh(fh_p), op.secinfo(name)]) check(res) # Cleanup res = sess.compound([op.putfh(fh), op.close(0, stateid)]) check(res)
def testGetLayout(t, env): """Verify layout handling FLAGS: pnfs CODE: GETLAYOUT1 """ sess = env.c1.new_pnfs_client_session(env.testname(t)) blocksize = get_blocksize(sess, use_obj(env.opts.path)) # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_READ, 0, 0xffffffffffffffff, 4*blocksize, open_stateid, 0xffff)] res = sess.compound(ops) check(res) # Parse opaque for layout in res.resarray[-1].logr_layout: if layout.loc_type == LAYOUT4_BLOCK_VOLUME: p = BlockUnpacker(layout.loc_body) opaque = p.unpack_pnfs_block_layout4() p.done() print opaque
def testFlexLayoutOldSeqid(t, env): """Check that we do not get NFS4ERR_OLD_STATEID if we send two LAYOUTGETS in a row without bumping the seqid FLAGS: flex CODE: FFLOOS """ seqid_next = 1 sess = env.c1.new_pnfs_client_session(env.testname(t)) # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout 1 fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_RW, 0, 0xffffffffffffffff, 8192, open_stateid, 0xffff)] res = sess.compound(ops) check(res) lo_stateid = res.resarray[-1].logr_stateid check_seqid(lo_stateid, seqid_next) seqid_next += 1 # Get the first with the lo_stateid ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_RW, 0, 0xffffffffffffffff, 8192, lo_stateid, 0xffff)] res = sess.compound(ops) check(res) lo_stateid2 = res.resarray[-1].logr_stateid check_seqid(lo_stateid2, seqid_next) seqid_next += 1 # Get the second with the original lo_stateid ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_RW, 0, 0xffffffffffffffff, 8192, lo_stateid, 0xffff)] res = sess.compound(ops) check(res) lo_stateid3 = res.resarray[-1].logr_stateid check_seqid(lo_stateid3, seqid_next) seqid_next += 1 ops = [op.putfh(fh), op.layoutreturn(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_ANY, layoutreturn4(LAYOUTRETURN4_FILE, layoutreturn_file4(0, 0xffffffffffffffff, lo_stateid, "")))] res = sess.compound(ops) check(res) res = close_file(sess, fh, stateid=open_stateid) check(res)
def testLayoutReturnAll(t, env): """ Return all of a client's layouts FLAGS: pnfs DEPEND: GETLAYOUT1 CODE: LAYOUTRET3 """ sess = env.c1.new_pnfs_client_session(env.testname(t)) blocksize = get_blocksize(sess, use_obj(env.opts.path)) # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_READ, 0, 0xffffffffffffffff, 4*blocksize, open_stateid, 0xffff)] res = sess.compound(ops) check(res) # Return layout ops = [op.layoutreturn(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_ANY, layoutreturn4(LAYOUTRETURN4_ALL))] res = sess.compound(ops) check(res)
def testEXCLUSIVE4AtNameAttribute(t, env): """If the file does exist,but the stored verifier does not match, then an error of NFS4ERR_EXIST is returned from server. rfc5661 18.16.3 FLAGS: open all CODE: OPEN6 """ sess1 = env.c1.new_client_session(env.testname(t)) res = create_file(sess1, env.testname(t), mode=EXCLUSIVE4_1) check(res) res = create_file(sess1, env.testname(t), mode=EXCLUSIVE4_1, verifier = "Justtest") check(res, NFS4ERR_EXIST)
def testFlexGetLayout(t, env): """Verify layout handling FLAGS: flex CODE: FFGLO1 """ sess = env.c1.new_pnfs_client_session(env.testname(t)) # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_READ, 0, 0xffffffffffffffff, 4196, open_stateid, 0xffff)] res = sess.compound(ops) check(res) # Parse opaque for layout in res.resarray[-1].logr_layout: if layout.loc_type == LAYOUT4_FLEX_FILES: p = FlexUnpacker(layout.loc_body) opaque = p.unpack_ff_layout4() p.done() res = close_file(sess, fh, stateid=open_stateid) check(res)
def testStateid2(t, env): """Check for proper sequence handling in layout stateids. FLAGS: block CODE: BLOCK2 """ c1 = env.c1.new_client_session(env.testname(t), flags=EXCHGID4_FLAG_USE_PNFS_MDS) # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout 1 fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid print open_stateid ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW, 0, 8192, 8192, open_stateid, 0xffff)] res = sess.compound(ops) check(res) # Get layout 2 lo_stateid1 = res.resarray[-1].logr_stateid print lo_stateid1 ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW, 8192, 8192, 8192, lo_stateid1, 0xffff)] res = sess.compound(ops) check(res) # Get layout 3 (merge of prior two) lo_stateid2 = res.resarray[-1].logr_stateid print lo_stateid2 ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW, 0, 2*8192, 2*8192, lo_stateid2, 0xffff)] res = sess.compound(ops) check(res) lo_stateid3 = res.resarray[-1].logr_stateid print lo_stateid3 # lo_stateid3.seqid = 3 # BUG - work around emc problem # Parse opaque to get info for commit # STUB not very general layout = res.resarray[-1].logr_layout[-1] p = BlockUnpacker(layout.loc_body) opaque = p.unpack_pnfs_block_layout4() p.done() extent = opaque.blo_extents[-1] extent.bex_state = PNFS_BLOCK_READWRITE_DATA p = BlockPacker() p.pack_pnfs_block_layoutupdate4(pnfs_block_layoutupdate4([extent])) time = newtime4(True, get_nfstime()) ops = [op.putfh(fh), op.layoutcommit(extent.bex_file_offset, extent.bex_length, False, lo_stateid3, newoffset4(True, 2 * 8192 - 1), time, layoutupdate4(LAYOUT4_BLOCK_VOLUME, p.get_buffer()))] res = sess.compound(ops) check(res)
def testDestroy3(t, env): """ - create client (exchangeid) - create session - trigger callback; check that it arrives, but don't answer it. - destroy session - create new session - check that a new callback is sent over the new session. Some servers will do this very quickly, some might take longer. FLAGS: destroy_session CODE: DSESS9003 """ recall = threading.Event() def pre_hook(arg, env): recall.stateid = arg.stateid # NOTE this must be done before set() recall.happened = True env.notify = recall.set # This is called after compound sent to queue def bad_post_hook(arg, env, res): return None; def good_post_hook(arg, env, res): return res c = env.c1.new_client(env.testname(t)) sess1 = c.create_session() sess1.compound([op.reclaim_complete(FALSE)]) res = create_file(sess1, env.testname(t), access=OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WANT_READ_DELEG) check(res) fh = res.resarray[-1].object deleg = res.resarray[-2].delegation print "OPEN fh =", repr(fh) if deleg.delegation_type == OPEN_DELEGATE_NONE: fail("Could not get delegation") recall.happened = False c2 = env.c1.new_client("%s_2" % env.testname(t)) sess2 = c2.create_session() sess2.compound([op.reclaim_complete(FALSE)]) 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_BOTH, OPEN4_SHARE_DENY_NONE, owner, how, claim) slot = sess2.compound_async(env.home + [open_op]) c.cb_pre_hook(OP_CB_RECALL, pre_hook) c.cb_post_hook(OP_CB_RECALL, bad_post_hook) recall.wait(1) # STUB - deal with timeout if not recall.happened: fail("Did not get callback") recall.happened = False # since we did not reply to callback, robust server should retry when # we give it a new backchannel to use: res = c.c.compound([op.destroy_session(sess1.sessionid)]) c.cb_pre_hook(OP_CB_RECALL, pre_hook) c.cb_post_hook(OP_CB_RECALL, good_post_hook) sess3 = c.create_session() recall.wait(100) # STUB - deal with timeout if not recall.happened: fail("Did not get callback")
def __create_file_with_deleg(sess, name, access): res = create_file(sess, name, access = access) check(res) fh = res.resarray[-1].object deleg = res.resarray[-2].delegation if (not _got_deleg(deleg)): res = open_file(sess, name, access = access) fh = res.resarray[-1].object deleg = res.resarray[-2].delegation if (not _got_deleg(deleg)): fail("Could not get delegation") return (fh, deleg)
def testSupported(t, env): """Do a simple OPEN create FLAGS: open all CODE: OPEN1 """ sess1 = env.c1.new_client_session(env.testname(t)) res = create_file(sess1, env.testname(t)) check(res) # See 8.1.3.1 of draft-10: # the server MUST provide an "seqid" value starting at one... expect(res, seqid=1)
def testAllocateStateidOne(t, env): """Do a simple ALLOCATE with all-one stateid FLAGS: all sparse CODE: ALLOC3 VERS: 2- """ sess = env.c1.new_client_session(env.testname(t)) res = create_file(sess, env.testname(t), access=OPEN4_SHARE_ACCESS_WRITE) fh = res.resarray[-1].object res = sess.compound([op.putfh(fh), op.allocate(env.stateid1, 0, 1)]) check(res)
def testCloseWithZeroSeqid(t, env): """OPEN followed by CLOSE with stateid.seq = 0 FLAGS: open all CODE: OPEN8 """ sess1 = env.c1.new_client_session(env.testname(t)) res = create_file(sess1, env.testname(t)) check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid stateid.seqid = 0 res = close_file(sess1, fh, stateid=stateid) check(res)
def test_async_read(): sess1 = env.c1.new_client_session(env.testname(t)) owner = open_owner4(0, "My Open Owner") res = create_file(sess1, env.testname(t)) check(res) expect(res, seqid=1) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid stateid.seqid = 0 data = "write test data" res = sess1.compound([op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, data)]) check(res) res = sess1.compound([op.putfh(fh), op.async_read(1, 0, 5)]) check(res)
def testReplayCache007(t, env): """Send two successful non-idempotent compounds with same seqid and False cache_this FLAGS: sequence all CODE: SEQ10b """ sess1 = env.c1.new_client_session(env.testname(t)) res = create_file(sess1, "%s_1" % env.testname(t)) check(res) ops = env.home + [op.savefh(),\ op.rename("%s_1" % env.testname(t), "%s_2" % env.testname(t))] res1 = sess1.compound(ops, cache_this=False) check(res1, NFS4_OK) res2 = sess1.compound(ops, seq_delta=0, cache_this=False) check(res2, NFS4ERR_RETRY_UNCACHED_REP)
def testAllocateSupported(t, env): """Do a simple ALLOCATE send PUTROOTFH+ALLOCATE, check for legal result FLAGS: all sparse CODE: ALLOC1 VERS: 2- """ sess = env.c1.new_client_session(env.testname(t)) res = create_file(sess, env.testname(t), access=OPEN4_SHARE_ACCESS_WRITE) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid res = sess.compound([op.putfh(fh), op.allocate(stateid, 0, 1)]) check(res)
def testLayoutCommit(t, env): """ Do some commits FLAGS: pnfs CODE: LAYOUTCOMMIT1 """ sess = env.c1.new_pnfs_client_session(env.testname(t)) blocksize = get_blocksize(sess, use_obj(env.opts.path)) # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW, 0, 4*blocksize, 4*blocksize, open_stateid, 0xffff)] res = sess.compound(ops) check(res) layout_stateid = res.resarray[-1].logr_stateid # Parse opaque for layout in res.resarray[-1].logr_layout: if layout.loc_type != LAYOUT4_BLOCK_VOLUME: fail("Did not get Block layout") p = BlockUnpacker(layout.loc_body) opaque = p.unpack_pnfs_block_layout4() p.done() print opaque final_extent = opaque.blo_extents[-1] print final_extent if final_extent.bex_state != PNFS_BLOCK_INVALID_DATA: fail("Expected INVALID_DATA in extent") # LAYOUTCOMMIT final_extent.bex_state = PNFS_BLOCK_READWRITE_DATA p = BlockPacker() p.pack_pnfs_block_layoutupdate4(pnfs_block_layoutupdate4([final_extent])) notime = newtime4(False) ops = [op.putfh(fh), op.layoutcommit(final_extent.bex_file_offset, final_extent.bex_length, False, layout_stateid, newoffset4(True, 4 * blocksize - 1), notime, layoutupdate4(LAYOUT4_BLOCK_VOLUME, p.get_buffer()))] res = sess.compound(ops) check(res) print res
def testDestroy2(t, env): """ - create client (exchangeid) - create session - destroy session - create a new session for the same client - do something that triggers a callback (look at the delegation tests for example) - check that we get the callback FLAGS: destroy_session CODE: DSESS9002 """ recall = threading.Event() def pre_hook(arg, env): recall.stateid = arg.stateid # NOTE this must be done before set() recall.happened = True env.notify = recall.set # This is called after compound sent to queue def post_hook(arg, env, res): return res c = env.c1.new_client(env.testname(t)) sess1 = c.create_session() sess1.compound([op.reclaim_complete(FALSE)]) res = c.c.compound([op.destroy_session(sess1.sessionid)]) sess2 = c.create_session() res = create_file(sess2, env.testname(t), access=OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WANT_READ_DELEG) check(res) fh = res.resarray[-1].object deleg = res.resarray[-2].delegation if deleg.delegation_type == OPEN_DELEGATE_NONE: fail("Could not get delegation") c2 = env.c1.new_client("%s_2" % env.testname(t)) sess3 = c2.create_session() sess3.compound([op.reclaim_complete(FALSE)]) 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_BOTH, OPEN4_SHARE_DENY_NONE, owner, how, claim) c.cb_pre_hook(OP_CB_RECALL, pre_hook) c.cb_post_hook(OP_CB_RECALL, post_hook) slot = sess3.compound_async(env.home + [open_op]) recall.happened = False recall.wait(100) # STUB - deal with timeout if not recall.happened: fail("Did not get callback")
def testCloseNoStateid(t, env): """test current state id processing by having CLOSE without operation which provides stateid FLAGS: currentstateid all CODE: CSID6 """ sess1 = env.c1.new_client_session(env.testname(t)) res = create_file(sess1, env.testname(t)) check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid res = sess1.compound([op.putfh(fh), op.close(0, current_stateid)]) checklist(res, [NFS4ERR_STALE_STATEID, NFS4ERR_BAD_STATEID])
def testOPENClaimFH(t, env): """OPEN file with claim_type is CLAIM_FH FLAGS: open all CODE: OPEN7 """ sess1 = env.c1.new_client_session(env.testname(t)) res = create_file(sess1, env.testname(t), want_deleg=False) check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid res = close_file(sess1, fh, stateid=stateid) check(res) claim = open_claim4(CLAIM_FH) how = openflag4(OPEN4_NOCREATE) oowner = open_owner4(0, "My Open Owner 2") access = OPEN4_SHARE_ACCESS_BOTH | OPEN4_SHARE_ACCESS_WANT_NO_DELEG open_op = op.open(0, access, OPEN4_SHARE_DENY_NONE, oowner, how, claim) res = sess1.compound([op.putfh(fh), open_op]) check(res) stateid = res.resarray[-1].stateid stateid.seqid = 0 data = "write test data" res = sess1.compound( [op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, data)]) check(res) res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 1000)]) check(res) if not res.resarray[-1].eof: fail("EOF not set on read") desired = "\0" * 5 + data if res.resarray[-1].data != desired: fail("Expected %r, got %r" % (desired, res.resarray[-1].data)) res = close_file(sess1, fh, stateid=stateid) check(res)
def testSupported(t, env): """Do a simple OPEN create FLAGS: open all CODE: OPEN1 """ sess1 = env.c1.new_client_session(env.testname(t)) res = create_file(sess1, env.testname(t)) check(res) # See 8.1.3.1 of draft-10: # the server MUST provide an "seqid" value starting at one... expect(res, seqid=1) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid # STUB - need to check open_res.delegation.delegation_type # see draft-10 line 19445 # QUESTION - what does "If the server supports the new _WANT_ flags" mean? # will the server return INVAL? NOTSUPP? or just silently ignore? res = close_file(sess1, fh, stateid=stateid) check(res)
def xtestOpenSeqid(t, env): """Verify server enforces seqid==0 See 8.13(draft-10): Such vestigial fields in existing operations should be set by the client to zero FLAGS: open all CODE: OPEN4 """ name = env.testname(t) sess1 = env.c1.new_client_session(name) owner = "owner_%s" % name path = sess1.c.homedir + [name] res = create_file(sess1, owner, path, access=OPEN4_SHARE_ACCESS_WRITE) check(res) expect(res, seqid=1) res = open_file(sess1, owner, path, access=OPEN4_SHARE_ACCESS_READ, seqid=1) check(res, NFS4ERR_INVAL, msg="Using non-zero seqid in OPEN")
def testNoDeleg(t, env): """Test no delegation handout FLAGS: open deleg CODE: DELEG4 """ sess1 = env.c1.new_client_session("%s_1" % env.testname(t)) res = create_file(sess1, env.testname(t), access=OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WANT_NO_DELEG) check(res) fh = res.resarray[-1].object deleg = res.resarray[-2].delegation if deleg.delegation_type == OPEN_DELEGATE_NONE: fail("Got no delegation, expected OPEN_DELEGATE_NONE_EXT") if deleg.delegation_type != OPEN_DELEGATE_NONE_EXT: fail("Got a delegation (type " + str(deleg.delegation_type) + ") despite asking for none") if deleg.ond_why != WND4_NOT_WANTED: fail("Wrong reason (" + str(deleg.ond_why) + ") for giving no delegation")
def testLayoutReturnFile(t, env): """ Return a file's layout FLAGS: layoutreturn all DEPEND: GETLAYOUT1 CODE: LAYOUTRET1 """ # Make sure E_ID returns MDS capabilities c1 = env.c1.new_client(env.testname(t), flags=EXCHGID4_FLAG_USE_PNFS_MDS) if not c1.flags & EXCHGID4_FLAG_USE_PNFS_MDS: fail("Server can not be used as pnfs metadata server") sess = c1.create_session() # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_READ, 0, 0xffffffffffffffff, 0, open_stateid, 0xffff) ] res = sess.compound(ops) check(res) # Return layout layout_stateid = res.resarray[-1].logr_stateid ops = [ op.putfh(fh), op.layoutreturn( False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_ANY, layoutreturn4( LAYOUTRETURN4_FILE, layoutreturn_file4(0, 0xffffffffffffffff, layout_stateid, ""))) ] res = sess.compound(ops) check(res)
def testLockLockU(t, env): """test current state id processing by having LOCK and LOCKU in a single compound FLAGS: currentstateid all CODE: CSID2 """ sess1 = env.c1.new_client_session(env.testname(t)) res = create_file(sess1, env.testname(t)) check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid open_to_lock_owner = open_to_lock_owner4(0, stateid, 0, lock_owner4(0, "lock1")) lock_owner = locker4(open_owner=open_to_lock_owner, new_lock_owner=True) lock_ops = [ op.lock(WRITE_LT, False, 0, NFS4_UINT64_MAX, lock_owner), op.locku(WRITE_LT, 0, current_stateid, 0, NFS4_UINT64_MAX) ] res = sess1.compound([op.putfh(fh)] + lock_ops) check(res, NFS4_OK)
def testServerStateSeqid(t, env): """Do multiple OPENs of a file, check that server bumps stateid.seqid FLAGS: open all CODE: OPEN2 """ name = env.testname(t) sess1 = env.c1.new_client_session(name) owner = "owner_%s" % name path = sess1.c.homedir + [name] res = create_file(sess1, owner, path, access=OPEN4_SHARE_ACCESS_WRITE) check(res) expect(res, seqid=1) res = open_file(sess1, owner, path, access=OPEN4_SHARE_ACCESS_READ) check(res) expect(res, seqid=2) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid # STUB - need to check no delegation return res = close_file(sess1, fh, stateid=stateid) check(res)
def testSupported(t, env): """Do a simple SECINFO FLAGS: all CODE: SEC1 """ name = env.testname(t) sess = env.c1.new_client_session(env.testname(t)) # Create a tmpfile for testing owner = "owner_%s" % name path = sess.c.homedir + [name] res = create_file(sess, owner, path, access=OPEN4_SHARE_ACCESS_WRITE) check(res) # Get the filehandle of the tmpfile's parent dir res = sess.compound(use_obj(sess.c.homedir) + [op.getfh()]) check(res) fh = res.resarray[-1].object # Just do a simple SECINFO res = sess.compound([op.putfh(fh), op.secinfo(name)]) check(res)
def testGetLayout(t, env): """Verify layout handling FLAGS: pnfs CODE: GETLAYOUT1 """ # Make sure E_ID returns MDS capabilities c1 = env.c1.new_client(env.testname(t), flags=EXCHGID4_FLAG_USE_PNFS_MDS) if not c1.flags & EXCHGID4_FLAG_USE_PNFS_MDS: fail("Server can not be used as pnfs metadata server") sess = c1.create_session() # Test that fs handles block layouts ops = use_obj(env.opts.path) + [op.getattr(1<<FATTR4_FS_LAYOUT_TYPES)] res = sess.compound(ops) check(res) if FATTR4_FS_LAYOUT_TYPES not in res.resarray[-1].obj_attributes: fail("fs_layout_type not available") if LAYOUT4_BLOCK_VOLUME not in res.resarray[-1].obj_attributes[FATTR4_FS_LAYOUT_TYPES]: fail("layout_type does not contain BLOCK") # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid ops = [op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_READ, 0, 0xffffffffffffffff, 0, open_stateid, 0xffff)] res = sess.compound(ops) check(res) # Parse opaque for layout in res.resarray[-1].logr_layout: if layout.loc_type == LAYOUT4_BLOCK_VOLUME: p = BlockUnpacker(layout.loc_body) opaque = p.unpack_pnfs_block_layout4() p.done() print opaque
def xtestClientStateSeqid(t, env): """Verify server enforce that client stateid.seqid==0 See 8.1.3.1(draft-10): The client must...set the sequence value to zero. FLAGS: open all CODE: OPEN3 """ name = env.testname(t) sess1 = env.c1.new_client_session(name) owner = "owner_%s" % name path = sess1.c.homedir + [name] res = create_file(sess1, owner, path, access=OPEN4_SHARE_ACCESS_WRITE) check(res) expect(res, seqid=1) # Now use returned stateid (w/o zeroing seqid) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid res = sess1.compound( [op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, "write test data")]) check(res, NFS4ERR_BAD_STATEID, "Using an open_stateid w/o zeroing the seqid")
def testFlexLayoutReturnFile(t, env): """ Return a file's layout FLAGS: flex DEPEND: FFGLO1 CODE: FFLOR1 """ sess = env.c1.new_pnfs_client_session(env.testname(t)) # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_READ, 0, 0xffffffffffffffff, 4196, open_stateid, 0xffff) ] res = sess.compound(ops) check(res) # Return layout layout_stateid = res.resarray[-1].logr_stateid ops = [ op.putfh(fh), op.layoutreturn( False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_ANY, layoutreturn4( LAYOUTRETURN4_FILE, layoutreturn_file4(0, 0xffffffffffffffff, layout_stateid, ""))) ] res = sess.compound(ops) check(res) res = close_file(sess, fh, stateid=open_stateid) check(res)
def testReadWrite(t, env): """Do a simple READ and WRITE FLAGS: open all CODE: OPEN30 """ sess1 = env.c1.new_client_session(env.testname(t)) owner = open_owner4(0, "My Open Owner") res = create_file(sess1, env.testname(t)) check(res) expect(res, seqid=1) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid stateid.seqid = 0 data = "write test data" res = sess1.compound([op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, data)]) check(res) res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 1000)]) check(res) if not res.resarray[-1].eof: fail("EOF not set on read") desired = "\0"*5 + data if res.resarray[-1].data != desired: fail("Expected %r, got %r" % (desired, res.resarray[-1].data))
def testSupported2(t, env): """GETFH after do a SECINFO_NO_NAME or SECINFO result in a NOFILEHANDLE error, See rfc 5661 section 2.6.3.1.1.8 FLAGS: all CODE: SEC2 """ name = env.testname(t) sess = env.c1.new_client_session(env.testname(t)) # Create a tmpfile for testing owner = "owner_%s" % name path = sess.c.homedir + [name] res = create_file(sess, owner, path, access=OPEN4_SHARE_ACCESS_WRITE) check(res) # Get the filehandle of the tmpfile's parent dir res = sess.compound(use_obj(sess.c.homedir) + [op.getfh()]) check(res) fh = res.resarray[-1].object # GETFH after do a SECINFO should get error NFS4ERR_NOFILEHANDLE res = sess.compound([op.putfh(fh), op.secinfo(name), op.getfh()]) check(res, NFS4ERR_NOFILEHANDLE)
def testEmptyCommit(t, env): """Check for proper handling of empty LAYOUTCOMMIT. FLAGS: block CODE: BLOCK3 """ c1 = env.c1.new_client(env.testname(t), flags=EXCHGID4_FLAG_USE_PNFS_MDS) sess = c1.create_session() # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout 1 fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid print open_stateid ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW, 0, 8192, 8192, open_stateid, 0xffff) ] res = sess.compound(ops) check(res) # Get layout 2 lo_stateid1 = res.resarray[-1].logr_stateid print lo_stateid1 ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW, 8192, 8192, 8192, lo_stateid1, 0xffff) ] res = sess.compound(ops) check(res) lo_stateid2 = res.resarray[-1].logr_stateid print lo_stateid2 # Parse opaque to get info for commit # STUB not very general layout = res.resarray[-1].logr_layout[-1] p = BlockUnpacker(layout.loc_body) opaque = p.unpack_pnfs_block_layout4() p.done() extent = opaque.blo_extents[-1] extent.bex_state = PNFS_BLOCK_READWRITE_DATA p = BlockPacker() p.pack_pnfs_block_layoutupdate4(pnfs_block_layoutupdate4([extent])) time = newtime4(True, get_nfstime()) ops = [ op.putfh(fh), op.layoutcommit(extent.bex_file_offset, extent.bex_length, False, lo_stateid2, newoffset4(True, 2 * 8192 - 1), time, layoutupdate4(LAYOUT4_BLOCK_VOLUME, p.get_buffer())) ] res = sess.compound(ops) check(res) # Send another LAYOUTCOMMIT, with an empty opaque time = newtime4(True, get_nfstime()) ops = [ op.putfh(fh), op.layoutcommit(extent.bex_file_offset, extent.bex_length, False, lo_stateid2, newoffset4(True, 2 * 8192 - 1), time, layoutupdate4(LAYOUT4_BLOCK_VOLUME, "")) ] res = sess.compound(ops) check(res)
def testDestroy3(t, env): """ - create client (exchangeid) - create session - trigger callback; check that it arrives, but don't answer it. - destroy session - create new session - check that a new callback is sent over the new session. Some servers will do this very quickly, some might take longer. FLAGS: destroy_session CODE: DSESS9003 """ recall = threading.Event() def pre_hook(arg, env): recall.stateid = arg.stateid # NOTE this must be done before set() recall.happened = True env.notify = recall.set # This is called after compound sent to queue def bad_post_hook(arg, env, res): return None def good_post_hook(arg, env, res): return res c = env.c1.new_client(env.testname(t)) sess1 = c.create_session() sess1.compound([op.reclaim_complete(FALSE)]) res = create_file(sess1, env.testname(t), access=OPEN4_SHARE_ACCESS_READ | OPEN4_SHARE_ACCESS_WANT_READ_DELEG) check(res) fh = res.resarray[-1].object deleg = res.resarray[-2].delegation print "OPEN fh =", repr(fh) if deleg.delegation_type == OPEN_DELEGATE_NONE: fail("Could not get delegation") recall.happened = False c2 = env.c1.new_client("%s_2" % env.testname(t)) sess2 = c2.create_session() sess2.compound([op.reclaim_complete(FALSE)]) 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_BOTH, OPEN4_SHARE_DENY_NONE, owner, how, claim) slot = sess2.compound_async(env.home + [open_op]) c.cb_pre_hook(OP_CB_RECALL, pre_hook) c.cb_post_hook(OP_CB_RECALL, bad_post_hook) recall.wait(1) # STUB - deal with timeout if not recall.happened: fail("Did not get callback") recall.happened = False # since we did not reply to callback, robust server should retry when # we give it a new backchannel to use: res = c.c.compound([op.destroy_session(sess1.sessionid)]) c.cb_pre_hook(OP_CB_RECALL, pre_hook) c.cb_post_hook(OP_CB_RECALL, good_post_hook) sess3 = c.create_session() recall.wait(100) # STUB - deal with timeout if not recall.happened: fail("Did not get callback")
def testStateid2(t, env): """Check for proper sequence handling in layout stateids. FLAGS: block CODE: BLOCK2 """ c1 = env.c1.new_client_session(env.testname(t), flags=EXCHGID4_FLAG_USE_PNFS_MDS) # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout 1 fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid print open_stateid ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW, 0, 8192, 8192, open_stateid, 0xffff) ] res = sess.compound(ops) check(res) # Get layout 2 lo_stateid1 = res.resarray[-1].logr_stateid print lo_stateid1 ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW, 8192, 8192, 8192, lo_stateid1, 0xffff) ] res = sess.compound(ops) check(res) # Get layout 3 (merge of prior two) lo_stateid2 = res.resarray[-1].logr_stateid print lo_stateid2 ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW, 0, 2 * 8192, 2 * 8192, lo_stateid2, 0xffff) ] res = sess.compound(ops) check(res) lo_stateid3 = res.resarray[-1].logr_stateid print lo_stateid3 # lo_stateid3.seqid = 3 # BUG - work around emc problem # Parse opaque to get info for commit # STUB not very general layout = res.resarray[-1].logr_layout[-1] p = BlockUnpacker(layout.loc_body) opaque = p.unpack_pnfs_block_layout4() p.done() extent = opaque.blo_extents[-1] extent.bex_state = PNFS_BLOCK_READWRITE_DATA p = BlockPacker() p.pack_pnfs_block_layoutupdate4(pnfs_block_layoutupdate4([extent])) time = newtime4(True, get_nfstime()) ops = [ op.putfh(fh), op.layoutcommit(extent.bex_file_offset, extent.bex_length, False, lo_stateid3, newoffset4(True, 2 * 8192 - 1), time, layoutupdate4(LAYOUT4_BLOCK_VOLUME, p.get_buffer())) ] res = sess.compound(ops) check(res)
def testFlexLayoutOldSeqid(t, env): """Check that we do not get NFS4ERR_OLD_STATEID if we send two LAYOUTGETS in a row without bumping the seqid FLAGS: flex CODE: FFLOOS """ seqid_next = 1 sess = env.c1.new_pnfs_client_session(env.testname(t)) # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout 1 fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_RW, 0, 0xffffffffffffffff, 8192, open_stateid, 0xffff) ] res = sess.compound(ops) check(res) lo_stateid = res.resarray[-1].logr_stateid check_seqid(lo_stateid, seqid_next) seqid_next += 1 # Get the first with the lo_stateid ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_RW, 0, 0xffffffffffffffff, 8192, lo_stateid, 0xffff) ] res = sess.compound(ops) check(res) lo_stateid2 = res.resarray[-1].logr_stateid check_seqid(lo_stateid2, seqid_next) seqid_next += 1 # Get the second with the original lo_stateid ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_RW, 0, 0xffffffffffffffff, 8192, lo_stateid, 0xffff) ] res = sess.compound(ops) check(res) lo_stateid3 = res.resarray[-1].logr_stateid check_seqid(lo_stateid3, seqid_next) seqid_next += 1 ops = [ op.putfh(fh), op.layoutreturn( False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_ANY, layoutreturn4( LAYOUTRETURN4_FILE, layoutreturn_file4(0, 0xffffffffffffffff, lo_stateid, ""))) ] res = sess.compound(ops) check(res) res = close_file(sess, fh, stateid=open_stateid) check(res)
def testLayoutCommit(t, env): """ Do some commits FLAGS: layoutcommit all CODE: LAYOUTCOMMIT1 """ # Make sure E_ID returns MDS capabilities c1 = env.c1.new_client(env.testname(t), flags=EXCHGID4_FLAG_USE_PNFS_MDS) if not c1.flags & EXCHGID4_FLAG_USE_PNFS_MDS: fail("Server can not be used as pnfs metadata server") sess = c1.create_session() # Test that fs handles block layouts ops = use_obj(env.opts.path) + [ op.getattr(1 << FATTR4_FS_LAYOUT_TYPE | 1 << FATTR4_LAYOUT_BLKSIZE) ] res = sess.compound(ops) check(res) attrdict = res.resarray[-1].obj_attributes if FATTR4_FS_LAYOUT_TYPE not in attrdict: fail("fs_layout_type not available") if LAYOUT4_BLOCK_VOLUME not in attrdict[FATTR4_FS_LAYOUT_TYPE]: fail("layout_type does not contain BLOCK") blocksize = attrdict[FATTR4_LAYOUT_BLKSIZE] # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW, 0, 4 * blocksize, 4 * blocksize, open_stateid, 0xffff) ] res = sess.compound(ops) check(res) layout_stateid = res.resarray[-1].logr_stateid # Parse opaque for layout in res.resarray[-1].logr_layout: if layout.loc_type != LAYOUT4_BLOCK_VOLUME: fail("Did not get Block layout") p = BlockUnpacker(layout.loc_body) opaque = p.unpack_pnfs_block_layout4() p.done() print opaque final_extent = opaque.blo_extents[-1] print final_extent if final_extent.bex_state != PNFS_BLOCK_INVALID_DATA: fail("Expected INVALID_DATA in extent") # LAYOUTCOMMIT final_extent.bex_state = PNFS_BLOCK_READWRITE_DATA p = BlockPacker() p.pack_pnfs_block_layoutupdate4(pnfs_block_layoutupdate4([final_extent])) notime = newtime4(False) ops = [ op.putfh(fh), op.layoutcommit(final_extent.bex_file_offset, final_extent.bex_length, False, layout_stateid, newoffset4(True, 4 * blocksize - 1), notime, layoutupdate4(LAYOUT4_BLOCK_VOLUME, p.get_buffer())) ] res = sess.compound(ops) check(res) print res
def testFlexLayoutTestAccess(t, env): """Get both a LAYOUTIOMODE4_RW and LAYOUTIOMODE4_READ segment making sure that they have the same gid, but a different uid. FLAGS: flex CODE: FFLA1 """ sess = env.c1.new_pnfs_client_session(env.testname(t)) # Create the file res = create_file(sess, env.testname(t)) check(res) # Get layout 1 fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_RW, 0, 0xffffffffffffffff, 8192, open_stateid, 0xffff) ] res = sess.compound(ops) check(res) lo_stateid = res.resarray[-1].logr_stateid check_seqid(lo_stateid, 1) layout = res.resarray[-1].logr_layout[-1] p = FlexUnpacker(layout.loc_body) opaque = p.unpack_ff_layout4() p.done() # Assume one mirror/storage device ds = opaque.ffl_mirrors[-1].ffm_data_servers[-1] uid_rw = ds.ffds_user gid_rw = ds.ffds_group ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_READ, 0, 0xffffffffffffffff, 8192, lo_stateid, 0xffff) ] res = sess.compound(ops) check(res) lo_stateid = res.resarray[-1].logr_stateid check_seqid(lo_stateid, 2) layout = res.resarray[-1].logr_layout[-1] p = FlexUnpacker(layout.loc_body) opaque = p.unpack_ff_layout4() p.done() # Assume one mirror/storage device ds = opaque.ffl_mirrors[-1].ffm_data_servers[-1] uid_rd = ds.ffds_user gid_rd = ds.ffds_group if uid_rw == uid_rd: fail("Expected uid_rd != %i, got %i" % (uid_rd, uid_rw)) if gid_rw != gid_rd: fail("Expected gid_rd == %i, got %i" % (gid_rd, gid_rw)) res = close_file(sess, fh, stateid=open_stateid) check(res)
def _LayoutStats(t, env, stats): '''Loop over the provided layoutstats, sending them on in time ''' sess = env.c1.new_pnfs_client_session(env.testname(t)) # Create the file res = create_file(sess, env.testname(t)) check(res) fh = res.resarray[-1].object open_stateid = res.resarray[-2].stateid lo_stateid = open_stateid ops = [ op.putfh(fh), op.layoutget(False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_RW, 0, 0xffffffffffffffff, 8192, lo_stateid, 0xffff) ] res = sess.compound(ops) check(res) lo_stateid = res.resarray[-1].logr_stateid check_seqid(lo_stateid, 1) layout = res.resarray[-1].logr_layout[-1] p = FlexUnpacker(layout.loc_body) opaque = p.unpack_ff_layout4() p.done() stats_hint = opaque.ffl_stats_collect_hint # Assume one mirror/storage device ds = opaque.ffl_mirrors[-1].ffm_data_servers[-1] deviceid = ds.ffds_deviceid ops = [ op.putfh(fh), op.getdeviceinfo(deviceid, LAYOUT4_FLEX_FILES, 0xffffffff, 0) ] res = sess.compound(ops) check(res) gda = res.resarray[-1].gdir_device_addr p = FlexUnpacker(gda.da_addr_body) da = p.unpack_ff_device_addr4() p.done() rd_io = io_info4() wr_io = io_info4() rd_lat = ff_io_latency4() wr_lat = ff_io_latency4() for s in stats: dur = get_nfstime(s[1]) # Did not capture these in the gathered traces offset = 0 file_length = 0xffffffffffffffff rd_io.ii_count = 0 rd_io.ii_bytes = 0 wr_io.ii_count = 0 wr_io.ii_bytes = 0 rd_lat.ffil_ops_requested = s[5] rd_lat.ffil_bytes_requested = s[4] rd_lat.ffil_ops_completed = s[6] rd_lat.ffil_bytes_completed = s[2] rd_lat.ffil_bytes_not_delivered = s[3] rd_lat.ffil_total_busy_time = get_nfstime(s[7]) rd_lat.ffil_aggregate_completion_time = get_nfstime(s[8]) wr_lat.ffil_ops_requested = s[12] wr_lat.ffil_bytes_requested = s[11] wr_lat.ffil_ops_completed = s[13] wr_lat.ffil_bytes_completed = s[9] wr_lat.ffil_bytes_not_delivered = s[10] wr_lat.ffil_total_busy_time = get_nfstime(s[14]) wr_lat.ffil_aggregate_completion_time = get_nfstime(s[15]) sleeper = s[0] env.sleep(sleeper) fflu = ff_layoutupdate4(da.ffda_netaddrs[-1], ds.ffds_fh_vers[-1], rd_lat, wr_lat, dur, True) p = FlexPacker() p.pack_ff_layoutupdate4(fflu) lu4 = layoutupdate4(LAYOUT4_FLEX_FILES, p.get_buffer()) ops = [ op.putfh(fh), op.layoutstats(offset, file_length, lo_stateid, rd_io, wr_io, deviceid, lu4) ] res = sess.compound(ops) check(res) ops = [ op.putfh(fh), op.layoutreturn( False, LAYOUT4_FLEX_FILES, LAYOUTIOMODE4_ANY, layoutreturn4( LAYOUTRETURN4_FILE, layoutreturn_file4(0, 0xffffffffffffffff, lo_stateid, ""))) ] res = sess.compound(ops) check(res) res = close_file(sess, fh, stateid=open_stateid) check(res)