Exemple #1
0
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")
Exemple #2
0
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)
Exemple #3
0
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")
Exemple #4
0
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)
Exemple #5
0
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)
Exemple #6
0
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)
Exemple #7
0
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")
Exemple #8
0
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)
Exemple #9
0
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")
Exemple #10
0
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
Exemple #11
0
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)
Exemple #12
0
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
Exemple #13
0
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)
Exemple #14
0
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")
Exemple #15
0
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])
Exemple #16
0
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>")
Exemple #17
0
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>")
Exemple #18
0
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")
Exemple #19
0
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")
Exemple #20
0
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")
Exemple #21
0
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")
Exemple #22
0
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")
Exemple #23
0
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)
Exemple #24
0
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")
Exemple #25
0
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>")
Exemple #26
0
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])
Exemple #28
0
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>")
Exemple #29
0
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)
Exemple #30
0
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")
Exemple #31
0
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)
Exemple #32
0
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)
Exemple #33
0
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)
Exemple #34
0
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