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 _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) check(res, [NFS4_OK, NFS4ERR_DELAY]) return recall
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; check(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([]) res = sess1.compound([op.putfh(fh), op.read(delegstateid, 0, 1000)]) check(res, NFS4ERR_DELEG_REVOKED, "Read with a revoked delegation") 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 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 check(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([]) res = sess1.compound([op.putfh(fh), op.read(delegstateid, 0, 1000)]) check(res, NFS4ERR_DELEG_REVOKED, "Read with a revoked delegation") 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 testWriteDeleg(t, env): """Test write delgation handout and return FLAGS: open deleg all CODE: DELEG2 """ recall = threading.Event() def pre_hook(arg, env): recall.stateid = arg.stateid # NOTE this must be done before set() env.notify = recall.set # This is called after compound sent to queue def post_hook(arg, env, res): return res # c1 - OPEN - WRITE c1 = env.c1.new_client("%s_1" % env.testname(t)) c1.cb_pre_hook(OP_CB_RECALL, pre_hook) c1.cb_post_hook(OP_CB_RECALL, post_hook) sess1 = c1.create_session() sess1.compound([op.reclaim_complete(FALSE)]) res = create_file(sess1, env.testname(t), access=OPEN4_SHARE_ACCESS_BOTH | OPEN4_SHARE_ACCESS_WANT_WRITE_DELEG) check(res) fh = res.resarray[-1].object deleg = res.resarray[-2].delegation if deleg.delegation_type == OPEN_DELEGATE_NONE or deleg.delegation_type == OPEN_DELEGATE_NONE_EXT: fail("Could not get delegation") # c2 - OPEN - READ 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_READ, 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])