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) c = env.c1.new_client(env.testname(t)) sess = c.create_session() # 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 _try_put(t, sess, path): # Get fh via LOOKUP res = sess.compound(use_obj(path) + [op.getfh()]) check(res) oldfh = res.resarray[-1].object # Now try PUTFH and GETFH, see if it agrees res = sess.compound([op.putfh(oldfh), op.getfh()]) check(res) newfh = res.resarray[-1].object if oldfh != newfh: t.fail("GETFH did not return input of PUTFH for /%s" % '/'.join(path))
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 lookup_obj(sess, path): compound = [op.putrootfh()] compound += [op.lookup(comp) for comp in path] compound += [op.getfh()] res = sess.compound(compound) check(res) return res.resarray[-1].object
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): # Set defaults if path is None: dir = sess.c.homedir name = owner else: dir = path[:-1] name = path[-1] if (mode == EXCLUSIVE4) 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( 0, access, deny, open_owner4(0, owner), openflag4(OPEN4_CREATE, createhow4(mode, attrs, verifier)), open_claim4(CLAIM_NULL, name)) return sess.compound(use_obj(dir) + [open_op, op.getfh()])
def open_file(self, mds_fh, seqid=0, access=OPEN4_SHARE_ACCESS_BOTH, deny=OPEN4_SHARE_DENY_NONE, attrs={FATTR4_MODE: 0777}, owner="mds", mode=GUARDED4): verifier = self.sess.c.verifier openflag = openflag4(OPEN4_CREATE, createhow4(mode, attrs, verifier)) name = self.fh_to_name(mds_fh) while True: if mds_fh in self.filehandles: return open_op = op.open(seqid, access, deny, open_owner4(self.sess.client.clientid, owner), openflag, open_claim4(CLAIM_NULL, name)) res = self.execute(nfs4lib.use_obj(self.path_fh) + [open_op, op.getfh()], exceptions=[NFS4ERR_EXIST]) if res.status == NFS4_OK: ds_fh = res.resarray[-1].opgetfh.resok4.object ds_openstateid = stateid4(0, res.resarray[-2].stateid.other) self.filehandles[mds_fh] = (ds_fh, ds_openstateid) return elif res.status == NFS4ERR_EXIST: openflag = openflag4(OPEN4_NOCREATE) else: raise RuntimeError
def testReadWrite(t, env): """Do a simple READ and WRITE FLAGS: open all CODE: OPEN400 """ c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session() owner = open_owner4(0, "My Open Owner") how = openflag4(OPEN4_CREATE, createhow4(GUARDED4, {FATTR4_SIZE:0})) claim = open_claim4(CLAIM_NULL, env.testname(t)) open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH , OPEN4_SHARE_DENY_NONE, owner, how, claim) fh_op = op.putrootfh() res = sess1.compound([fh_op, open_op, op.getfh()]) # OPEN print res check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid stateid.seqid = 0 res = sess1.compound([op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, "write test data")]) print res check(res) res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 1000)]) print res check(res)
def testDeadlock(t, env): """Trigger deadlock bug FLAGS: debug all CODE: DEBUG1 """ c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session() owner = open_owner4(0, "My Open Owner") how = openflag4(OPEN4_CREATE, createhow4(GUARDED4, {FATTR4_SIZE:0})) claim = open_claim4(CLAIM_NULL, env.testname(t)) open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH , OPEN4_SHARE_DENY_NONE, owner, how, claim) res = sess1.compound(env.home + [open_op, op.getfh()]) # OPEN fh = res.resarray[-1].object stateid = res.resarray[-2].stateid #### def ops(i): return [op.putfh(fh), op.write(stateid, i*1000, UNSTABLE4, chr(97+i)*100), op.getattr(42950721818L) ] xids = [sess1.compound_async(ops(i), slot=i) for i in range(4)] for xid in xids: res = sess1.listen(xid) check(res) print res
def testDeadlock(t, env): """Trigger deadlock bug FLAGS: debug all CODE: DEBUG1 """ c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session() owner = open_owner4(0, "My Open Owner") how = openflag4(OPEN4_CREATE, createhow4(GUARDED4, {FATTR4_SIZE: 0})) claim = open_claim4(CLAIM_NULL, env.testname(t)) open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH, OPEN4_SHARE_DENY_NONE, owner, how, claim) res = sess1.compound(env.home + [open_op, op.getfh()]) # OPEN fh = res.resarray[-1].object stateid = res.resarray[-2].stateid #### def ops(i): return [ op.putfh(fh), op.write(stateid, i * 1000, UNSTABLE4, chr(97 + i) * 100), op.getattr(42950721818L) ] xids = [sess1.compound_async(ops(i), slot=i) for i in range(4)] for xid in xids: res = sess1.listen(xid) check(res) print res
def testReadWrite(t, env): """Do a simple READ and WRITE FLAGS: open all CODE: OPEN400 """ c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session() owner = open_owner4(0, "My Open Owner") how = openflag4(OPEN4_CREATE, createhow4(GUARDED4, {FATTR4_SIZE: 0})) claim = open_claim4(CLAIM_NULL, env.testname(t)) open_op = op.open(0, OPEN4_SHARE_ACCESS_BOTH, OPEN4_SHARE_DENY_NONE, owner, how, claim) fh_op = op.putrootfh() res = sess1.compound([fh_op, open_op, op.getfh()]) # OPEN print res check(res) fh = res.resarray[-1].object stateid = res.resarray[-2].stateid stateid.seqid = 0 res = sess1.compound( [op.putfh(fh), op.write(stateid, 5, FILE_SYNC4, "write test data")]) print res check(res) res = sess1.compound([op.putfh(fh), op.read(stateid, 0, 1000)]) print res check(res)
def testXdev(t, env): """LOOKUPP with dir on different fs FLAGS: special CODE: LKPP4 """ c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session() ops = [op.putrootfh(), op.getfh()] op_pairs = [(op.lookup(component), op.getfh()) for component in env.opts.usespecial] ops += [op_pair[i] for op_pair in op_pairs for i in range(2)] ops += [op.lookupp(), op.getfh()] res = sess1.compound(ops) check(res) fh1 = res.resarray[-5].object fh2 = res.resarray[-1].object if fh1 != fh2: t.fail("file handles not equal")
def testHome(t, env): """LOOKUP home directory FLAGS: lookup all CODE: HOME """ c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session() res = sess1.compound(env.home + [op.getfh()]) check(res)
def testLookupp(t, env): """Basic Lookupp test FLAGS: lookupp all CODE: LKPP1d """ c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session() ops = [] op_pairs = [(component, op.getfh()) for component in env.home] ops += [op_pair[i] for op_pair in op_pairs for i in range(2)] op_pairs = [op.lookupp(), op.getfh()] ops += [op_pairs[i] for component in env.home[:-1] for i in range(2)] res = sess1.compound(ops) check(res) for i in range(len(env.home)): if res.resarray[2 * i + 1].object != res.resarray[-(2 * i + 1)].object: t.fail('LOOKUPP returned %r, expected %r' % (res.resarray[-(2 * i + 1)].object, res.resarray[2 * i + 1].object))
def testLookupp(t, env): """Basic Lookupp test FLAGS: lookupp all CODE: LKPP1d """ c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session() ops = [] op_pairs = [(component, op.getfh()) for component in env.home] ops += [op_pair[i] for op_pair in op_pairs for i in range(2)] op_pairs = [op.lookupp(), op.getfh()] ops += [op_pairs[i] for component in env.home[:-1] for i in range(2)] res = sess1.compound(ops) check(res) for i in range(len(env.home)): if res.resarray[2 * i + 1].object != res.resarray[-(2 * i + 1)].object: t.fail( "LOOKUPP returned %r, expected %r" % (res.resarray[-(2 * i + 1)].object, res.resarray[2 * i + 1].object) )
def testLookuppRoot(t, env): """Lookupp from root should return NFS4ERR_NOENT FLAGS: lookupp all CODE: LKPP2 """ c1 = env.c1.new_client(env.testname(t)) sess1 = c1.create_session() res = sess1.compound([op.putrootfh(), op.getfh()]) check(res) fh = res.resarray[-1].object res = sess1.compound([op.putfh(fh), op.lookupp()]) check(res, NFS4ERR_NOENT)
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 secinfo_no_name CODE: SECNN2 """ c = env.c1.new_client(env.testname(t)) sess = c.create_session() # GETFH after do a SECINFO_NO_NAME should get error NFS4ERR_NOFILEHANDLE res = sess.compound([op.putrootfh(), op.secinfo_no_name(0), op.getfh()]) print res check(res, NFS4ERR_NOFILEHANDLE)
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: SECNN2 """ c = env.c1.new_client(env.testname(t)) sess = c.create_session() # GETFH after do a SECINFO_NO_NAME should get error NFS4ERR_NOFILEHANDLE res = sess.compound([op.putrootfh(), op.secinfo_no_name(0), op.getfh()]) print res check(res, NFS4ERR_NOFILEHANDLE)
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 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()]
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 testOpenSaveFHLookupRestoreFHClose(t, env): """test current state id processing by having OPEN, SAVEFH, LOOKUP, RESTOREFH and CLOSE in a single compound FLAGS: currentstateid all CODE: CSID10 """ sess1 = env.c1.new_client_session(env.testname(t)) fname = env.testname(t) open_op = open_create_file_op(sess1, fname, open_create=OPEN4_CREATE) lookup_op = env.home res = sess1.compound(lookup_op + [op.getfh()]) check(res) fh = res.resarray[-1].object res = sess1.compound(open_op + [op.savefh(), op.putfh(fh), op.restorefh(), op.close(0, current_stateid)]) check(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 testTooManyOps(t, env): """Send a request with more ops than the session can handle FLAGS: sequence all CODE: SEQ7 """ c1 = env.c1.new_client(env.testname(t)) # Create session asking for 4 ops max per request attrs = channel_attrs4(0, 8192, 8192, 8192, 4, 8, []) sess1 = c1.create_session(fore_attrs = attrs) # Send the max number of ops allowed by the server lots_of_ops = [op.putrootfh(), op.getfh()] lots_of_ops += [op.getattr(0) for num in xrange(sess1.fore_channel.maxoperations-3)] res = sess1.compound(lots_of_ops) check(res) # Add one more op to exceed the maximum lots_of_ops += [op.getattr(0)] res = sess1.compound(lots_of_ops) check(res, NFS4ERR_TOO_MANY_OPS)
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()]
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): # Set defaults if path is None: dir = sess.c.homedir name = owner else: dir = path[:-1] name = path[-1] if (mode==EXCLUSIVE4) 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(0, access, deny, open_owner4(0, owner), openflag4(OPEN4_CREATE, createhow4(mode, attrs, verifier)), open_claim4(CLAIM_NULL, name)) return sess.compound(use_obj(dir) + [open_op, op.getfh()])
def open_file(self, mds_fh, seqid=0, access=OPEN4_SHARE_ACCESS_BOTH, deny=OPEN4_SHARE_DENY_NONE, attrs={FATTR4_MODE: 0777}, owner = "mds", mode=GUARDED4): verifier = self.sess.c.verifier openflag = openflag4(OPEN4_CREATE, createhow4(mode, attrs, verifier)) name = self.fh_to_name(mds_fh) while True: if mds_fh in self.filehandles: return open_op = op.open(seqid, access, deny, open_owner4(self.sess.client.clientid, owner), openflag, open_claim4(CLAIM_NULL, name)) res = self.execute(nfs4lib.use_obj(self.path_fh) + [open_op, op.getfh()], exceptions=[NFS4ERR_EXIST]) if res.status == NFS4_OK: ds_fh = res.resarray[-1].opgetfh.resok4.object ds_openstateid = stateid4(0, res.resarray[-2].stateid.other) self.filehandles[mds_fh] = (ds_fh, ds_openstateid) return elif res.status == NFS4ERR_EXIST: openflag = openflag4(OPEN4_NOCREATE) else: raise RuntimeError
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)