예제 #1
0
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)
예제 #2
0
def testLayoutReturnFile(t, env):
    """
    Return a file's layout
    
    FLAGS: pnfs
    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)
예제 #3
0
파일: st_debug.py 프로젝트: bongiojp/pynfs
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)
예제 #4
0
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)
예제 #5
0
파일: st_open.py 프로젝트: bongiojp/pynfs
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))
예제 #6
0
def testReadWrite(t, env):
    """Do a simple READ and WRITE

    FLAGS: open all
    CODE: OPEN30
    """
    c1 = env.c1.new_client(env.testname(t))
    sess1 = c1.create_session()
    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))
예제 #7
0
def rename_obj(sess, oldpath, newpath):
    olddir = lookup_obj(sess, oldpath[:-1])
    newdir = lookup_obj(sess, newpath[:-1])
    ops =  [op.putfh(olddir), op.savefh()]
    ops += [op.putfh(newdir)]
    ops += [op.rename(oldpath[-1], newpath[-1])]
    return sess.compound(ops)
예제 #8
0
def testLayoutReturnFile(t, env):
    """
    Return a file's layout
    
    FLAGS: pnfs
    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)
예제 #9
0
파일: st_block.py 프로젝트: bongiojp/pynfs
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)
예제 #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
예제 #11
0
def testLayout(t, env):
    """Verify layout handling

    FLAGS: layout all
    CODE: LAYOUT1
    """
    # 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)]
    res = sess.compound(ops)
    check(res)
    if FATTR4_FS_LAYOUT_TYPE 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_TYPE]:
        fail("layout_type does not contain BLOCK")
    # Open the file
    owner = "owner for %s" % env.testname(t)
    # openres = open_file(sess, owner, env.opts.path + ["simple_extent"])
    openres = open_file(sess, owner, env.opts.path + ["hole_between_extents"])
    check(openres)
    # Get a layout
    fh = openres.resarray[-1].object
    ops = [
        op.putfh(fh),
        op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_READ, 0,
                     0xffffffff, 0, 0xffff)
    ]
    res = sess.compound(ops)
    check(res)
예제 #12
0
 def ops(i):
     return [
         op.putfh(fh),
         op.write(stateid, i * 1000, UNSTABLE4,
                  chr(97 + i) * 100),
         op.getattr(42950721818L)
     ]
예제 #13
0
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()])
예제 #14
0
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)
예제 #15
0
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)
예제 #16
0
def testLayoutReturnFsid(t, env):
    """
    Return all of a filesystem's layouts
    
    FLAGS: layoutreturn all
    DEPEND: GETLAYOUT1
    CODE: LAYOUTRET2
    """
    # 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 = use_obj(env.opts.path) + \
          [op.layoutreturn(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_ANY,
                           layoutreturn4(LAYOUTRETURN4_FSID))]
    res = sess.compound(ops)
    check(res)
예제 #17
0
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)
    c1 = env.c1.new_client(name)
    sess1 = c1.create_session()
    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")
예제 #18
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
예제 #19
0
파일: st_debug.py 프로젝트: bongiojp/pynfs
def testLayout(t, env):
    """Verify layout handling

    FLAGS: layout all
    CODE: LAYOUT1
    """
    # 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)]
    res = sess.compound(ops)
    check(res)
    if FATTR4_FS_LAYOUT_TYPE 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_TYPE]:
        fail("layout_type does not contain BLOCK")
    # Open the file
    owner = "owner for %s" % env.testname(t)
    # openres = open_file(sess, owner, env.opts.path + ["simple_extent"])
    openres = open_file(sess, owner, env.opts.path + ["hole_between_extents"])
    check(openres)
    # Get a layout
    fh = openres.resarray[-1].object
    ops = [op.putfh(fh),
           op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_READ,
                        0, 0xffffffff, 0, 0xffff)]
    res = sess.compound(ops)
    check(res)
예제 #20
0
def testSplitCommit(t, env):
    """Check for proper handling of disjoint LAYOUTCOMMIT.opaque

    FLAGS: block
    CODE: BLOCK4
    """
    sess = 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,
                     2 * 8192, 2 * 8192, open_stateid, 0xffff)
    ]
    res = sess.compound(ops)
    check(res)

    lo_stateid1 = res.resarray[-1].logr_stateid
    print lo_stateid1
    # 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()
    dev = opaque.blo_extents[-1].bex_vol_id
    extent1 = pnfs_block_extent4(dev, 0, 8192, 0, PNFS_BLOCK_READWRITE_DATA)
    extent2 = pnfs_block_extent4(dev, 8192, 8192, 0, PNFS_BLOCK_READWRITE_DATA)

    p = BlockPacker()
    p.pack_pnfs_block_layoutupdate4(
        pnfs_block_layoutupdate4([extent1, extent2]))
    time = newtime4(True, get_nfstime())
    ops = [
        op.putfh(fh),
        op.layoutcommit(0, 2 * 8192, False, lo_stateid1,
                        newoffset4(True, 2 * 8192 - 1), time,
                        layoutupdate4(LAYOUT4_BLOCK_VOLUME, p.get_buffer()))
    ]
    res = sess.compound(ops)
    check(res)
예제 #21
0
def use_obj(file):
    """File is either None, a fh, or a list of path components"""
    if file is None or file == [None]:
        return []
    elif type(file) is str:
        return [op.putfh(file)]
    else:
        return [op.putrootfh()] + [op.lookup(comp) for comp in file]
예제 #22
0
파일: nfs4lib.py 프로젝트: mauser/pynfs
def use_obj(file):
    """File is either None, a fh, or a list of path components"""
    if file is None or file == [None]:
        return []
    elif type(file) is str:
        return [op.putfh(file)]
    else:
        return [op.putrootfh()] + [op.lookup(comp) for comp in file]
예제 #23
0
 def close_file(self, mds_fh):
     """close the given file"""
     seqid=0 #FIXME: seqid must be !=0
     fh, stateid = self.filehandles[mds_fh]
     ops = [op.putfh(fh)] + [op.close(seqid, stateid)]
     res = self.execute(ops)
     # ignoring return
     del self.filehandles[mds_fh]
예제 #24
0
def testStateid1(t, env):
    """Check for proper sequence handling in layout stateids.

    FLAGS: block
    CODE: BLOCK1
    """
    sess = 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)
    lo_stateid = res.resarray[-1].logr_stateid
    print lo_stateid
    if lo_stateid.seqid != 1:
        # From draft23 12.5.2 "The first successful LAYOUTGET processed by
        # the server using a non-layout stateid as an argument MUST have the
        # "seqid" field of the layout stateid in the response set to one."
        fail("Expected stateid.seqid==1, got %i" % lo_stateid.seqid)
    for i in range(6):
        # Get subsequent layouts
        ops = [
            op.putfh(fh),
            op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW,
                         (i + 1) * 8192, 8192, 8192, lo_stateid, 0xffff)
        ]
        res = sess.compound(ops)
        check(res)
        lo_stateid = res.resarray[-1].logr_stateid
        print lo_stateid
        if lo_stateid.seqid != i + 2:
            # From draft23 12.5.3 "After the layout stateid is established,
            # the server increments by one the value of the "seqid" in each
            # subsequent LAYOUTGET and LAYOUTRETURN response,
            fail("Expected stateid.seqid==%i, got %i" %
                 (i + 2, lo_stateid.seqid))
예제 #25
0
 def close_file(self, mds_fh):
     """close the given file"""
     seqid = 0  #FIXME: seqid must be !=0
     fh, stateid = self.filehandles[mds_fh]
     ops = [op.putfh(fh)] + [op.close(seqid, stateid)]
     res = self.execute(ops)
     # ignoring return
     del self.filehandles[mds_fh]
예제 #26
0
파일: st_block.py 프로젝트: bongiojp/pynfs
def testSplitCommit(t, env):
    """Check for proper handling of disjoint LAYOUTCOMMIT.opaque

    FLAGS: block
    CODE: BLOCK4
    """
    sess = 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, 2*8192, 2*8192, open_stateid, 0xffff)]
    res = sess.compound(ops)
    check(res)

    lo_stateid1 = res.resarray[-1].logr_stateid
    print lo_stateid1
    # 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()
    dev = opaque.blo_extents[-1].bex_vol_id
    extent1 = pnfs_block_extent4(dev, 0, 8192, 0, PNFS_BLOCK_READWRITE_DATA)
    extent2 = pnfs_block_extent4(dev, 8192, 8192, 0, PNFS_BLOCK_READWRITE_DATA)

    p = BlockPacker()
    p.pack_pnfs_block_layoutupdate4(pnfs_block_layoutupdate4([extent1,
                                                              extent2]))
    time = newtime4(True, get_nfstime())
    ops = [op.putfh(fh),
           op.layoutcommit(0,
                           2*8192,
                           False, lo_stateid1,
                           newoffset4(True, 2 * 8192 - 1),
                           time,
                           layoutupdate4(LAYOUT4_BLOCK_VOLUME, p.get_buffer()))]
    res = sess.compound(ops)
    check(res)
예제 #27
0
def close_file(sess, fh, stateid, seqid=0):
    """close the given file"""
    if fh is None:
        ops = []
    else:
        ops = [op.putfh(fh)]
    ops += [op.close(seqid, stateid)]
    res = sess.compound(ops)
    return res
예제 #28
0
def testBadHandle(t, env):
    """PUTFH with bad filehandle should return NFS4ERR_BADHANDLE

    FLAGS: putfh all
    CODE: PUTFH2
    """
    c = env.c1.new_client(env.testname(t))
    sess = c.create_session()
    res = sess.compound([op.putfh('abc')])
    check(res, NFS4ERR_BADHANDLE, "PUTFH with bad filehandle='abc'")
예제 #29
0
파일: st_putfh.py 프로젝트: bongiojp/pynfs
def testBadHandle(t, env):
    """PUTFH with bad filehandle should return NFS4ERR_BADHANDLE

    FLAGS: putfh all
    CODE: PUTFH2
    """
    c = env.c1.new_client(env.testname(t))
    sess = c.create_session()
    res = sess.compound([op.putfh('abc')])
    check(res, NFS4ERR_BADHANDLE, "PUTFH with bad filehandle='abc'")
예제 #30
0
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))
예제 #31
0
파일: st_putfh.py 프로젝트: bongiojp/pynfs
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))
예제 #32
0
파일: st_block.py 프로젝트: bongiojp/pynfs
def testStateid1(t, env):
    """Check for proper sequence handling in layout stateids.

    FLAGS: block
    CODE: BLOCK1
    """
    sess = 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)
    lo_stateid = res.resarray[-1].logr_stateid
    print lo_stateid
    if lo_stateid.seqid != 1:
        # From draft23 12.5.2 "The first successful LAYOUTGET processed by
        # the server using a non-layout stateid as an argument MUST have the
        # "seqid" field of the layout stateid in the response set to one."
        fail("Expected stateid.seqid==1, got %i" % lo_stateid.seqid)
    for i in range(6):
        # Get subsequent layouts
        ops = [op.putfh(fh),
               op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_RW,
                            (i+1)*8192, 8192, 8192, lo_stateid, 0xffff)]
        res = sess.compound(ops)
        check(res)
        lo_stateid = res.resarray[-1].logr_stateid
        print lo_stateid
        if lo_stateid.seqid != i + 2:
            # From draft23 12.5.3 "After the layout stateid is established,
            # the server increments by one the value of the "seqid" in each
            # subsequent LAYOUTGET and LAYOUTRETURN response,
            fail("Expected stateid.seqid==%i, got %i" % (i+2, lo_stateid.seqid))
예제 #33
0
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)
예제 #34
0
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)
예제 #35
0
파일: st_open.py 프로젝트: bongiojp/pynfs
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))
예제 #36
0
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))
예제 #37
0
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()]
예제 #38
0
def testReadDeleg(t, env):
    """Test read delgation handout and return

    FLAGS: open all
    CODE: OPEN20
    """
    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 - READ
    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()
    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
    if deleg.delegation_type == OPEN_DELEGATE_NONE:
        fail("Could not get delegation")
    # c2 - OPEN - WRITE
    c2 = env.c1.new_client("%s_2" % env.testname(t))
    sess2 = c2.create_session()
    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])
    # 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])
예제 #39
0
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])
예제 #40
0
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])
예제 #41
0
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)
예제 #42
0
def testEMCGetLayout(t, env):
    """Verify layout handling

    Debugging test that looks for pre-existing file (server2fs1/dump.eth)
    so we don't have to worry about creating a file.

    FLAGS: 
    CODE: GETLAYOUT100
    """
    # 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)]
    res = sess.compound(ops)
    check(res)
    if FATTR4_FS_LAYOUT_TYPE 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_TYPE]:
        fail("layout_type does not contain BLOCK")
    # Create the file
    file = ["server2fs1", "dump.eth"]
    res = open_file(sess, env.testname(t), file)
    check(res)
    # Get layout
    fh = res.resarray[-1].object
    stateid = res.resarray[-2].stateid
    stateid.seqid = 0
    ops = [
        op.putfh(fh),
        op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_READ, 0,
                     0xffffffffffffffff, 0, 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
예제 #43
0
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])
예제 #44
0
    def _maketree(self, sess):
        """Make test tree"""
        # ensure /tmp (and path leading up) exists
        path = []
        for comp in self.opts.home:
            path.append(comp)
            res = sess.compound(use_obj(path))
            checklist(res, [NFS4_OK, NFS4ERR_NOENT],
                      "LOOKUP /%s," % '/'.join(path))
            if res.status == NFS4ERR_NOENT:
                res = create_obj(sess, path, NF4DIR)
                check(res, msg="Trying to create /%s," % '/'.join(path))
        # ensure /tree exists and is empty
        tree = self.opts.path + ['tree']
        res = sess.compound(use_obj(tree))
        checklist(res, [NFS4_OK, NFS4ERR_NOENT])
        if res.status == NFS4ERR_NOENT:
            res = create_obj(sess, tree, NF4DIR)
            check(res, msg="Trying to create /%s," % '/'.join(tree))
        else:
            clean_dir(sess, tree)

        # make non-file objects in /tree
        d = {
            'dir': NF4DIR,
            'socket': NF4SOCK,
            'fifo': NF4FIFO,
            'link': createtype4(NF4LNK, linkdata=self.linkdata),
            'block': createtype4(NF4BLK, devdata=specdata4(1, 2)),
            'char': createtype4(NF4CHR, devdata=specdata4(1, 2)),
        }
        for name, kind in d.items():
            path = tree + [name]
            res = create_obj(sess, path, kind)
            if res.status != NFS4_OK:
                log.warning("could not create /%s" % '/'.join(path))
        # Make file-object in /tree
        fh, stateid = create_confirm(sess, 'maketree', tree + ['file'])
        stateid.seqid = 0
        ops = [op.putfh(fh), op.write(stateid, 0, FILE_SYNC4, self.filedata)]
        res = sess.compound(ops)
        check(res, msg="Writing data to /%s/file" % '/'.join(tree))
        res = close_file(sess, fh, stateid)
        check(res)
예제 #45
0
    def _maketree(self, sess):
        """Make test tree"""
        # ensure /tmp (and path leading up) exists
        path = []
        for comp in self.opts.home:
            path.append(comp)
            res = sess.compound(use_obj(path))
            checklist(res, [NFS4_OK, NFS4ERR_NOENT],
                      "LOOKUP /%s," % '/'.join(path))
            if res.status == NFS4ERR_NOENT:
                res = create_obj(sess, path, NF4DIR)
                check(res, msg="Trying to create /%s," % '/'.join(path))
        # ensure /tree exists and is empty
        tree = self.opts.path + ['tree']
        res = sess.compound(use_obj(tree))
        checklist(res, [NFS4_OK, NFS4ERR_NOENT])
        if res.status == NFS4ERR_NOENT:
            res = create_obj(sess, tree, NF4DIR)
            check(res, msg="Trying to create /%s," % '/'.join(tree))
        else:
            clean_dir(sess, tree)

        # make non-file objects in /tree
        d = {'dir': NF4DIR,
             'socket': NF4SOCK,
             'fifo':  NF4FIFO,
             'link':  createtype4(NF4LNK, linkdata=self.linkdata),
             'block': createtype4(NF4BLK, devdata=specdata4(1, 2)),
             'char': createtype4(NF4CHR, devdata=specdata4(1, 2)),
             }
        for name, kind in d.items():
            path = tree + [name]
            res = create_obj(sess, path, kind)
            if res.status != NFS4_OK:
                log.warning("could not create /%s" % '/'.join(path))
        # Make file-object in /tree
        fh, stateid = create_confirm(sess, 'maketree', tree + ['file'])
        ops = [op.putfh(fh),
               op.write(stateid, 0, FILE_SYNC4, self.filedata)]
        res = sess.compound(ops)
        check(res, msg="Writing data to /%s/file" % '/'.join(tree))
        res = close_file(sess, fh, stateid)
        check(res)
예제 #46
0
def testEMCGetLayout(t, env):
    """Verify layout handling

    Debugging test that looks for pre-existing file (server2fs1/dump.eth)
    so we don't have to worry about creating a file.

    FLAGS: 
    CODE: GETLAYOUT100
    """
    # 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)]
    res = sess.compound(ops)
    check(res)
    if FATTR4_FS_LAYOUT_TYPE 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_TYPE]:
        fail("layout_type does not contain BLOCK")
    # Create the file
    file = ["server2fs1", "dump.eth"]
    res = open_file(sess, env.testname(t), file)
    check(res)
    # Get layout
    fh = res.resarray[-1].object
    stateid = res.resarray[-2].stateid
    stateid.seqid = 0
    ops = [op.putfh(fh),
           op.layoutget(False, LAYOUT4_BLOCK_VOLUME, LAYOUTIOMODE4_READ,
                        0, 0xffffffffffffffff, 0, 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
예제 #47
0
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()]
예제 #48
0
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)
예제 #49
0
파일: st_open.py 프로젝트: bongiojp/pynfs
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")
예제 #50
0
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)
예제 #51
0
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)
예제 #52
0
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)
예제 #53
0
def testLayoutCommit(t, env):
    """
    Do some commits

    FLAGS: pnfs
    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
예제 #54
0
파일: st_debug.py 프로젝트: bongiojp/pynfs
 def ops(i):
     return [op.putfh(fh),
             op.write(stateid, i*1000, UNSTABLE4, chr(97+i)*100),
             op.getattr(42950721818L)
             ]
예제 #55
0
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