linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH pynfs v2 00/16] prep for flex file layout server
@ 2014-06-05 13:55 Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 01/16] dataserver: reclaim_complete after create_session Weston Andros Adamson
                   ` (17 more replies)
  0 siblings, 18 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

Changes in v2:

 - moved "4.1 client: reclaim_complete after create_session" to
   "dataserver: reclaim_complete after create_session" as the implicit
   reclaim complete is needed in DS path, but not in all server tests.

 - dropped "4.1 server: service RECLAIM_COMPLETE operations" as it's
   unneeded.

 - formatted these patches with -M flag so we can see moved files

.. and I pushed the changes to my ff_prep branch.

Thanks!
 -dros


These patches are in preparation for the pynfs implementation of a flex
file layout server.

I already have patches for a working flex file server, but I figure those
should wait until the spec is complete ;)

I pushed these patches to my linux-nfs.org tree on branch 'ff_prep':

 git://git.linux-nfs.org/projects/dros/pynfs.git

The prep includes:

 - patches that enable pynfs mds using real v4.1 DSes (on the backend,
   not usable from clients as there is no stateid sharing between mds and ds)

 - fix several bugs in pnfs path

 - move .x files to subdir 'xdrdef' - the nfs4.1 directory was getting crowded
   and we're going to add several more .x files along with all of the
   autogenerated files.  Note this change touches server tests too.

 - clean up the nfs4server's output - no longer print out EVERY part of EVERY
   operation which was very efficient at hiding tracebacks and made pynfs
   even slower. Old functionality is now switched on with -v flag. Also
   added an in-between mode "-s" that prints a summary of whats going on.

 - support for NFSv3 backend communication - this is not actually used yet,
   but can be tested with file layout by always returning
   NFS4ERR_LAYOUTUNAVAILABLE in layoutget and using DataServer3 class instead
   of DataServer41


Weston Andros Adamson (16):
  dataserver: reclaim_complete after create_session
  dataserver: only catch connection error
  4.1 server: avoid traceback in DS disconnect()
  move .x files to subdir 'xdrdef'
  4.1 client: remove unused imports
  4.1 server: add -v flag & silence random output
  4.1 server: add -s option to print summary of ops
  dataserver: make generic interface to ops
  dataserver: don't import * from nfs4 specific mods
  4.1 server: move nfs4_ops.py to nfs_ops.py
  add mntv3, portmapv2 and nfsv3 .x files
  dataserver: separate generic and 4.1 code
  4.1 server: add support for NFSv3 data servers
  4.1 server: get rid of old op_getdeviceinfo
  rpc: on socket error, close and mark pipe inactive
  nfs3clnt: reconnect when sending on inactive pipe

 nfs4.1/block.py                             |   8 +-
 nfs4.1/client41tests/environment.py         |   4 +-
 nfs4.1/config.py                            |   8 +-
 nfs4.1/dataserver.py                        | 308 ++++++++---
 nfs4.1/fs.py                                |  38 +-
 nfs4.1/nfs3client.py                        | 185 +++++++
 nfs4.1/nfs4_ops.py                          |  61 ---
 nfs4.1/nfs4client.py                        |  47 +-
 nfs4.1/nfs4commoncode.py                    |  10 +-
 nfs4.1/nfs4lib.py                           |  62 ++-
 nfs4.1/nfs4server.py                        | 163 +++---
 nfs4.1/nfs4state.py                         |  15 +-
 nfs4.1/nfs_ops.py                           |  89 +++
 nfs4.1/server41tests/environment.py         |   4 +-
 nfs4.1/server41tests/st_block.py            |   4 +-
 nfs4.1/server41tests/st_compound.py         |   4 +-
 nfs4.1/server41tests/st_create_session.py   |   4 +-
 nfs4.1/server41tests/st_current_stateid.py  |   8 +-
 nfs4.1/server41tests/st_debug.py            |   4 +-
 nfs4.1/server41tests/st_delegation.py       |   4 +-
 nfs4.1/server41tests/st_destroy_clientid.py |   2 +-
 nfs4.1/server41tests/st_destroy_session.py  |   4 +-
 nfs4.1/server41tests/st_exchange_id.py      |   4 +-
 nfs4.1/server41tests/st_getdevicelist.py    |   4 +-
 nfs4.1/server41tests/st_lookup.py           |   2 +-
 nfs4.1/server41tests/st_lookupp.py          |   2 +-
 nfs4.1/server41tests/st_open.py             |   8 +-
 nfs4.1/server41tests/st_putfh.py            |   2 +-
 nfs4.1/server41tests/st_reboot.py           |   4 +-
 nfs4.1/server41tests/st_reclaim_complete.py |   2 +-
 nfs4.1/server41tests/st_rename.py           |   4 +-
 nfs4.1/server41tests/st_secinfo.py          |   4 +-
 nfs4.1/server41tests/st_secinfo_no_name.py  |   4 +-
 nfs4.1/server41tests/st_sequence.py         |   4 +-
 nfs4.1/server41tests/st_trunking.py         |   4 +-
 nfs4.1/server41tests/st_verify.py           |   2 +-
 nfs4.1/server_exports.py                    |   7 +-
 nfs4.1/setup.py                             |  33 +-
 nfs4.1/testclient.py                        |   2 +-
 nfs4.1/testserver.py                        |   2 +-
 nfs4.1/xdrdef/__init__.py                   |   0
 nfs4.1/xdrdef/mnt3.x                        |  68 +++
 nfs4.1/xdrdef/nfs3.x                        | 818 ++++++++++++++++++++++++++++
 nfs4.1/{ => xdrdef}/nfs4.x                  |   0
 nfs4.1/{ => xdrdef}/nfs4.x.diff             |   0
 nfs4.1/{ => xdrdef}/pnfs_block.x            |   0
 nfs4.1/xdrdef/portmap.x                     |  51 ++
 nfs4.1/{ => xdrdef}/sctrl.x                 |   0
 rpc/rpc.py                                  |  26 +-
 49 files changed, 1704 insertions(+), 389 deletions(-)
 create mode 100644 nfs4.1/nfs3client.py
 delete mode 100644 nfs4.1/nfs4_ops.py
 create mode 100644 nfs4.1/nfs_ops.py
 create mode 100644 nfs4.1/xdrdef/__init__.py
 create mode 100644 nfs4.1/xdrdef/mnt3.x
 create mode 100644 nfs4.1/xdrdef/nfs3.x
 rename nfs4.1/{ => xdrdef}/nfs4.x (100%)
 rename nfs4.1/{ => xdrdef}/nfs4.x.diff (100%)
 rename nfs4.1/{ => xdrdef}/pnfs_block.x (100%)
 create mode 100644 nfs4.1/xdrdef/portmap.x
 rename nfs4.1/{ => xdrdef}/sctrl.x (100%)

-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 01/16] dataserver: reclaim_complete after create_session
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 02/16] dataserver: only catch connection error Weston Andros Adamson
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

Send RECLAIM_COMPLETE after CREATE_SESSION. This enables backend
communication to v4.1 linux nfsd servers (i/o through MDS only).

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/dataserver.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/nfs4.1/dataserver.py b/nfs4.1/dataserver.py
index 65e4f55..ade55e1 100644
--- a/nfs4.1/dataserver.py
+++ b/nfs4.1/dataserver.py
@@ -54,6 +54,7 @@ class DataServer(object):
         # as wide as the client/MDS channel (at least for linux client)
         fore_attrs = channel_attrs4(0, 16384, 16384, 2868, 8, 8, [])
         self.sess = c.create_session(fore_attrs=fore_attrs)
+        sess.compound([op.reclaim_complete(FALSE)])
         self.make_root()
 
     def disconnect(self):
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 02/16] dataserver: only catch connection error
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 01/16] dataserver: reclaim_complete after create_session Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 03/16] 4.1 server: avoid traceback in DS disconnect() Weston Andros Adamson
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

This specifically checks for the error being reported, otherwise a
other exceptions like a programming error  will be caught and treated
as connection errors.

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/dataserver.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/nfs4.1/dataserver.py b/nfs4.1/dataserver.py
index ade55e1..aca07ee 100644
--- a/nfs4.1/dataserver.py
+++ b/nfs4.1/dataserver.py
@@ -9,6 +9,7 @@ import nfs4client
 import hashlib
 import sys
 import nfs4_ops as op
+import socket
 
 log = logging.getLogger("Dataserver Manager")
 
@@ -198,7 +199,7 @@ class DSDevice(object):
                     ds = DataServer(server, port, path, mdsds=self.mdsds,
                                     multipath_servers=server_list)
                     self.list.append(ds)
-                except:
+                except socket.error:
                     log.critical("cannot access %s:%i/%s" %
                                  (server, port, '/'.join(path)))
                     sys.exit(1)
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 03/16] 4.1 server: avoid traceback in DS disconnect()
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 01/16] dataserver: reclaim_complete after create_session Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 02/16] dataserver: only catch connection error Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 04/16] move .x files to subdir 'xdrdef' Weston Andros Adamson
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

Session objects have no destroy method.

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/dataserver.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nfs4.1/dataserver.py b/nfs4.1/dataserver.py
index aca07ee..435ddd2 100644
--- a/nfs4.1/dataserver.py
+++ b/nfs4.1/dataserver.py
@@ -59,7 +59,7 @@ class DataServer(object):
         self.make_root()
 
     def disconnect(self):
-        self.sess.destroy()
+        pass
 
     def execute(self, ops, exceptions=[], delay=5, maxretries=3):
         """ execute the NFS call
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 04/16] move .x files to subdir 'xdrdef'
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (2 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 03/16] 4.1 server: avoid traceback in DS disconnect() Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 05/16] 4.1 client: remove unused imports Weston Andros Adamson
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

In preparation for adding more .x files, clean up the main nfs4.1 dir
by moving these files (and autogenerated files) to a subdirectory.

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/block.py                             |  8 ++---
 nfs4.1/client41tests/environment.py         |  4 +--
 nfs4.1/config.py                            |  8 ++---
 nfs4.1/dataserver.py                        |  6 ++--
 nfs4.1/fs.py                                |  8 ++---
 nfs4.1/nfs4_ops.py                          |  4 +--
 nfs4.1/nfs4client.py                        | 11 +++---
 nfs4.1/nfs4commoncode.py                    | 10 +++---
 nfs4.1/nfs4lib.py                           | 54 ++++++++++++++---------------
 nfs4.1/nfs4server.py                        | 36 +++++++++----------
 nfs4.1/nfs4state.py                         |  6 ++--
 nfs4.1/server41tests/environment.py         |  4 +--
 nfs4.1/server41tests/st_block.py            |  4 +--
 nfs4.1/server41tests/st_compound.py         |  4 +--
 nfs4.1/server41tests/st_create_session.py   |  4 +--
 nfs4.1/server41tests/st_current_stateid.py  |  8 ++---
 nfs4.1/server41tests/st_debug.py            |  4 +--
 nfs4.1/server41tests/st_delegation.py       |  4 +--
 nfs4.1/server41tests/st_destroy_clientid.py |  2 +-
 nfs4.1/server41tests/st_destroy_session.py  |  4 +--
 nfs4.1/server41tests/st_exchange_id.py      |  4 +--
 nfs4.1/server41tests/st_getdevicelist.py    |  4 +--
 nfs4.1/server41tests/st_lookup.py           |  2 +-
 nfs4.1/server41tests/st_lookupp.py          |  2 +-
 nfs4.1/server41tests/st_open.py             |  8 ++---
 nfs4.1/server41tests/st_putfh.py            |  2 +-
 nfs4.1/server41tests/st_reboot.py           |  4 +--
 nfs4.1/server41tests/st_reclaim_complete.py |  2 +-
 nfs4.1/server41tests/st_rename.py           |  4 +--
 nfs4.1/server41tests/st_secinfo.py          |  4 +--
 nfs4.1/server41tests/st_secinfo_no_name.py  |  4 +--
 nfs4.1/server41tests/st_sequence.py         |  4 +--
 nfs4.1/server41tests/st_trunking.py         |  4 +--
 nfs4.1/server41tests/st_verify.py           |  2 +-
 nfs4.1/setup.py                             | 33 ++++++++++--------
 nfs4.1/testclient.py                        |  2 +-
 nfs4.1/testserver.py                        |  2 +-
 nfs4.1/xdrdef/__init__.py                   |  0
 nfs4.1/{ => xdrdef}/nfs4.x                  |  0
 nfs4.1/{ => xdrdef}/nfs4.x.diff             |  0
 nfs4.1/{ => xdrdef}/pnfs_block.x            |  0
 nfs4.1/{ => xdrdef}/sctrl.x                 |  0
 42 files changed, 141 insertions(+), 139 deletions(-)
 create mode 100644 nfs4.1/xdrdef/__init__.py
 rename nfs4.1/{ => xdrdef}/nfs4.x (100%)
 rename nfs4.1/{ => xdrdef}/nfs4.x.diff (100%)
 rename nfs4.1/{ => xdrdef}/pnfs_block.x (100%)
 rename nfs4.1/{ => xdrdef}/sctrl.x (100%)

diff --git a/nfs4.1/block.py b/nfs4.1/block.py
index 2201550..f37bd9b 100644
--- a/nfs4.1/block.py
+++ b/nfs4.1/block.py
@@ -1,8 +1,8 @@
 from __future__ import with_statement
-from pnfs_block_pack import PNFS_BLOCKPacker as Packer
-from pnfs_block_pack import PNFS_BLOCKUnpacker as Unpacker
-from pnfs_block_type import *
-from pnfs_block_const import *
+from xdrdef.pnfs_block_pack import PNFS_BLOCKPacker as Packer
+from xdrdef.pnfs_block_pack import PNFS_BLOCKUnpacker as Unpacker
+from xdrdef.pnfs_block_type import *
+from xdrdef.pnfs_block_const import *
 
 import fs_base
 from threading import Lock
diff --git a/nfs4.1/client41tests/environment.py b/nfs4.1/client41tests/environment.py
index 84b7d38..225197f 100644
--- a/nfs4.1/client41tests/environment.py
+++ b/nfs4.1/client41tests/environment.py
@@ -10,8 +10,8 @@
 
 import time
 import testmod
-from nfs4_const import *
-from nfs4_type import *
+from xdrdef.nfs4_const import *
+from xdrdef.nfs4_type import *
 import rpc
 import nfs4client
 import os
diff --git a/nfs4.1/config.py b/nfs4.1/config.py
index 2238aee..4747f73 100644
--- a/nfs4.1/config.py
+++ b/nfs4.1/config.py
@@ -1,6 +1,6 @@
-from nfs4_type import server_owner4, nfs_impl_id4
-from nfs4_const import *
-import nfs4_const
+from xdrdef.nfs4_type import server_owner4, nfs_impl_id4
+from xdrdef.nfs4_const import *
+import xdrdef.nfs4_const
 import nfs4lib
 from copy import deepcopy
 import os
@@ -37,7 +37,7 @@ def _statcode(value):
     try:
         return int(value)
     except ValueError:
-        rv = getattr(nfs4_const, value, None)
+        rv = getattr(xdr.nfs4_const, value, None)
         if rv is None or nfsstat4.get(rv, None) != value:
             raise
         else:
diff --git a/nfs4.1/dataserver.py b/nfs4.1/dataserver.py
index 435ddd2..acca210 100644
--- a/nfs4.1/dataserver.py
+++ b/nfs4.1/dataserver.py
@@ -1,8 +1,8 @@
 import rpc
 import nfs4lib
-from nfs4_type import *
-from nfs4_pack import NFS4Packer
-from nfs4_const import *
+from xdrdef.nfs4_type import *
+from xdrdef.nfs4_pack import NFS4Packer
+from xdrdef.nfs4_const import *
 import time
 import logging
 import nfs4client
diff --git a/nfs4.1/fs.py b/nfs4.1/fs.py
index a63c5bf..3d63ce5 100644
--- a/nfs4.1/fs.py
+++ b/nfs4.1/fs.py
@@ -1,6 +1,6 @@
 from nfs4state import FileState
-from nfs4_const import *
-from nfs4_type import fsid4, layout4, layout_content4, nfsv4_1_file_layout4
+from xdrdef.nfs4_const import *
+from xdrdef.nfs4_type import fsid4, layout4, layout_content4, nfsv4_1_file_layout4
 import nfs4lib
 from nfs4lib import NFS4Error
 import struct
@@ -8,7 +8,7 @@ import logging
 from locking import Lock, RWLock
 from cStringIO import StringIO
 import time
-from nfs4_pack import NFS4Packer
+from xdrdef.nfs4_pack import NFS4Packer
 
 log_o = logging.getLogger("fs.obj")
 log_fs = logging.getLogger("fs")
@@ -1070,7 +1070,7 @@ class StubFS_Disk(FileSystem):
 
 ###################################################
 
-from pnfs_block_type import pnfs_block_extent4, pnfs_block_layout4
+from xdrdef.pnfs_block_type import pnfs_block_extent4, pnfs_block_layout4
 import block
 
 class my_ro_extent(object):
diff --git a/nfs4.1/nfs4_ops.py b/nfs4.1/nfs4_ops.py
index 75381b6..35a10ca 100644
--- a/nfs4.1/nfs4_ops.py
+++ b/nfs4.1/nfs4_ops.py
@@ -2,8 +2,8 @@
 <name>() that returns the appropriate *_argop4 structure, hiding
 this routine packing from the user.
 """
-import nfs4_type as _type
-import nfs4_const as _const
+import xdrdef.nfs4_type as _type
+import xdrdef.nfs4_const as _const
 
 # This string is our general function template
 code = """\
diff --git a/nfs4.1/nfs4client.py b/nfs4.1/nfs4client.py
index e750728..2aa0a2c 100644
--- a/nfs4.1/nfs4client.py
+++ b/nfs4.1/nfs4client.py
@@ -2,10 +2,9 @@ import use_local # HACK so don't have to rebuild constantly
 import rpc
 import nfs4lib
 from nfs4lib import NFS4Error, NFS4Replay, inc_u32
-import nfs4_type, nfs4_const
-from nfs4_type import *
-from nfs4_const import *
-from sctrl_pack import SCTRLPacker, SCTRLUnpacker
+from xdrdef.nfs4_type import *
+from xdrdef.nfs4_const import *
+from xdrdef.sctrl_pack import SCTRLPacker, SCTRLUnpacker
 import nfs4_ops as op
 import time, struct
 import threading
@@ -545,8 +544,8 @@ sec.init_cred(call)
 
 """ EXCHANGE_ID
 import nfs4client
-from nfs4_type import *
-from nfs4_const import *
+from xdrdef.nfs4_type import *
+from xdrdef.nfs4_const import *
 import nfs4_ops as op
 owner = client_owner4("12345678","MyClientName")
 protect = state_protect4_a(SP4_NONE)
diff --git a/nfs4.1/nfs4commoncode.py b/nfs4.1/nfs4commoncode.py
index 317f04c..cadd237 100644
--- a/nfs4.1/nfs4commoncode.py
+++ b/nfs4.1/nfs4commoncode.py
@@ -4,10 +4,10 @@
 """
 
 import nfs4lib
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 import sys
-import nfs4_type, nfs4_const
-from nfs4_type import *
+import xdrdef.nfs4_type, xdrdef.nfs4_const
+from xdrdef.nfs4_type import *
 
 _d = {"CompoundState" : "CompoundState",
       "PairedResults" : "PairedResults",
@@ -34,8 +34,8 @@ def %(encode_status)s_by_name(name, status, *args, **kwargs):
     name_l = name.lower()
     name_u = name.upper()
     try:
-        res4 = getattr(nfs4_type, name_u + "4res")(status, *args, **kwargs)
-        result = %(nfs_resop4)s(getattr(nfs4_const, "OP_" + name_u))
+        res4 = getattr(xdrdef.nfs4_type, name_u + "4res")(status, *args, **kwargs)
+        result = %(nfs_resop4)s(getattr(xdrdef.nfs4_const, "OP_" + name_u))
         setattr(result, %(mangle)s, res4)
         # STUB XXX 4.1 has messed with the naming conventions,
         #      and added prefixes to the "status" variable. Grrr.
diff --git a/nfs4.1/nfs4lib.py b/nfs4.1/nfs4lib.py
index d1edc10..116324a 100644
--- a/nfs4.1/nfs4lib.py
+++ b/nfs4.1/nfs4lib.py
@@ -1,8 +1,8 @@
 from __future__ import with_statement
 import rpc
-import nfs4_const
-import nfs4_pack
-import nfs4_type
+import xdrdef.nfs4_const
+from xdrdef.nfs4_pack import NFS4Packer, NFS4Unpacker
+import xdrdef.nfs4_type
 import nfs4_ops as op
 import time
 import collections
@@ -24,9 +24,9 @@ except ImportError:
             raise NotImplementedError("could not import Crypto.Cipher")
 
 # Special stateids
-state00 = nfs4_type.stateid4(0, "\0" * 12)
-state11 = nfs4_type.stateid4(0xffffffff, "\xff" * 12)
-state01 = nfs4_type.stateid4(1, "\0" * 12)
+state00 = xdrdef.nfs4_type.stateid4(0, "\0" * 12)
+state11 = xdrdef.nfs4_type.stateid4(0xffffffff, "\xff" * 12)
+state01 = xdrdef.nfs4_type.stateid4(1, "\0" * 12)
 
 import hashlib # Note this requires 2.5 or higher
 
@@ -105,9 +105,9 @@ def set_attrbit_dicts():
             { 1: "unpack_fattr4_type", 2: "unpack_fattr4_fh_expire_type", ...}
     """
     global attr2bitnum, bitnum2attr, bitnum2packer, bitnum2unpacker
-    for name in dir(nfs4_const):
+    for name in dir(xdrdef.nfs4_const):
         if name.startswith("FATTR4_"):
-            value = getattr(nfs4_const, name)
+            value = getattr(xdrdef.nfs4_const, name)
             # Sanity checking. Must be integer. 
             assert(type(value) is int)
             attrname = name[7:].lower()
@@ -130,9 +130,9 @@ def set_flags(name, search_string=None):
     mask = 0
     if search_string is None:
         search_string = "%s4_FLAG_" % name.upper()
-    for var in dir(nfs4_const):
+    for var in dir(xdrdef.nfs4_const):
         if var.startswith(search_string):
-            value = getattr(nfs4_const, var)
+            value = getattr(xdrdef.nfs4_const, var)
             flag_dict[value] = var
             mask |= value
     # Now we need to set the appropriate module level variable
@@ -187,7 +187,7 @@ class InvalidCompoundRes(NFSException):
         else:
             return "Invalid COMPOUND result"
 
-class FancyNFS4Packer(nfs4_pack.NFS4Packer):
+class FancyNFS4Packer(NFS4Packer):
     """Handle fattr4 and dirlist4 more cleanly than auto-generated methods"""
     def filter_bitmap4(self, data):
         out = []
@@ -208,11 +208,11 @@ class FancyNFS4Packer(nfs4_pack.NFS4Packer):
         for e in data.entries[::-1]:
             # print "handle", e
             # This reverses the direction of the list, so start with reversed
-            out = [nfs4_type.entry4(e.cookie, e.name, e.attrs, out)]
+            out = [xdrdef.nfs4_type.entry4(e.cookie, e.name, e.attrs, out)]
         # Must not modify original data structure
-        return nfs4_type.dirlist4(out, data.eof)
+        return xdrdef.nfs4_type.dirlist4(out, data.eof)
 
-class FancyNFS4Unpacker(nfs4_pack.NFS4Unpacker):
+class FancyNFS4Unpacker(NFS4Unpacker):
     def filter_bitmap4(self, data):
         """Put bitmap into single long, instead of array of 32bit chunks"""
         out = 0L
@@ -257,7 +257,7 @@ def dict2fattr(dict):
         getattr(packer, bitnum2packer[bitnum])(value)
         attr_vals += packer.get_buffer()
     attrmask = list2bitmap(attrs)
-    return nfs4_type.fattr4(attrmask, attr_vals); 
+    return xdrdef.nfs4_type.fattr4(attrmask, attr_vals); 
 
 def fattr2dict(obj):
     """Convert a fattr4 object to a dictionary with attribute name and values.
@@ -360,10 +360,10 @@ class SSVContext(object):
         """Compute getMIC token from given data"""
         # See draft26 2.10.9
         p = FancyNFS4Packer()
-        p.pack_ssv_mic_plain_tkn4(nfs4_type.ssv_mic_plain_tkn4(seqnum, data))
+        p.pack_ssv_mic_plain_tkn4(xdrdef.nfs4_type.ssv_mic_plain_tkn4(seqnum, data))
         hash = hmac.new(key, p.get_buffer(), self.hash).digest()
         p.reset()
-        p.pack_ssv_mic_tkn4(nfs4_type.ssv_mic_tkn4(seqnum, hash))
+        p.pack_ssv_mic_tkn4(xdrdef.nfs4_type.ssv_mic_tkn4(seqnum, hash))
         return p.get_buffer()
 
     def getMIC(self, data):
@@ -405,13 +405,13 @@ class SSVContext(object):
         p = FancyNFS4Packer()
         # We need to compute pad.  Easiest (though not fastest) way
         # is to pack w/o padding, determine padding needed, then repack.
-        input = nfs4_type.ssv_seal_plain_tkn4(cofounder, seqnum, data, "")
+        input = xdrdef.nfs4_type.ssv_seal_plain_tkn4(cofounder, seqnum, data, "")
         p.pack_ssv_seal_plain_tkn4(input)
         offset = len(p.get_buffer()) % blocksize
         if offset:
             pad = '\0' * (blocksize - offset)
             p.reset()
-            input = nfs4_type.ssv_seal_plain_tkn4(cofounder, seqnum, data, pad)
+            input = xdrdef.nfs4_type.ssv_seal_plain_tkn4(cofounder, seqnum, data, pad)
             p.pack_ssv_seal_plain_tkn4(input)
         plain_xdr = p.get_buffer()
         p.reset()
@@ -421,7 +421,7 @@ class SSVContext(object):
         encrypted = obj.encrypt(plain_xdr)
         dir = (SSV4_SUBKEY_MIC_I2T if self.local else SSV4_SUBKEY_MIC_T2I)
         hash = hmac.new(keys[dir], plain_xdr, self.hash).digest()
-        token = nfs4_type.ssv_seal_cipher_tkn4(seqnum, iv, encrypted, hash)
+        token = xdrdef.nfs4_type.ssv_seal_cipher_tkn4(seqnum, iv, encrypted, hash)
         p.pack_ssv_seal_cipher_tkn4(token)
         return p.get_buffer()
 
@@ -491,7 +491,7 @@ def get_nfstime(t=None):
         t = time.time()
     sec = int(t)
     nsec = int((t - sec) * 1000000000)
-    return nfs4_type.nfstime4(sec, nsec)
+    return xdrdef.nfs4_type.nfstime4(sec, nsec)
 
 def parse_nfs_url(url):
     """Parse [nfs://]host:port/path, format taken from rfc 2224
@@ -565,7 +565,7 @@ def attr_name(bitnum):
 class NFS4Error(Exception):
     def __init__(self, status, attrs=0L, lock_denied=None, tag=None, check_msg=None):
         self.status = status
-        self.name = nfs4_const.nfsstat4[status]
+        self.name = xdrdef.nfs4_const.nfsstat4[status]
         if check_msg is None:
             self.msg = "NFS4 error code: %s" % self.name
         else:
@@ -602,19 +602,19 @@ class NFS4Principal(object):
     def __ne__(self, other):
         return not self.__eq__(other)
 
-def check(res, expect=nfs4_const.NFS4_OK, msg=None):
+def check(res, expect=xdrdef.nfs4_const.NFS4_OK, msg=None):
     if res.status == expect:
         return
     if type(expect) is str:
         raise RuntimeError("You forgot to put 'msg=' in front "
                            "of check()'s string arg")
     # Get text representations
-    desired = nfs4_const.nfsstat4[expect]
-    received = nfs4_const.nfsstat4[res.status]
+    desired = xdrdef.nfs4_const.nfsstat4[expect]
+    received = xdrdef.nfs4_const.nfsstat4[res.status]
     if msg:
         failedop_name = msg
     elif res.resarray:
-        failedop_name = nfs4_const.nfs_opnum4[res.resarray[-1].resop]
+        failedop_name = xdrdef.nfs4_const.nfs_opnum4[res.resarray[-1].resop]
     else:
         failedop_name = 'Compound'
     msg = "%s should return %s, instead got %s" % \
@@ -647,7 +647,7 @@ class AttrConfig(object):
         self._s = (kind=="serv")
         self._fs = (kind=="fs")
     
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 
 A = AttrConfig
 attr_info = { FATTR4_SUPPORTED_ATTRS : A("r", "fs"),
diff --git a/nfs4.1/nfs4server.py b/nfs4.1/nfs4server.py
index 65fb9af..2ae99fe 100755
--- a/nfs4.1/nfs4server.py
+++ b/nfs4.1/nfs4server.py
@@ -4,10 +4,10 @@ import use_local # HACK so don't have to rebuild constantly
 import nfs4lib
 from nfs4lib import inc_u32, NFS4Error, NFS4Replay
 import rpc
-from nfs4_const import *
-from nfs4_type import *
-from sctrl_pack import SCTRLPacker, SCTRLUnpacker
-import sctrl_type, sctrl_const
+from xdrdef.nfs4_const import *
+from xdrdef.nfs4_type import *
+from xdrdef.sctrl_pack import SCTRLPacker, SCTRLUnpacker
+import xdrdef.sctrl_type, xdrdef.sctrl_const
 import traceback, threading
 from locking import Lock, Counter
 import time
@@ -620,7 +620,7 @@ class NFS4Server(rpc.Server):
             return rpc.GARBAGE_ARGS, None
         log_cfg.info(repr(args))
         # Handle the given control operation
-        opname = sctrl_const.ctrl_opnum.get(args.ctrlop, 'ctrl_illegal')
+        opname = xdrdef.sctrl_const.ctrl_opnum.get(args.ctrlop, 'ctrl_illegal')
         funct = getattr(self, opname.lower(), None)
         if funct is None:
             # This shouldn't happen
@@ -633,8 +633,8 @@ class NFS4Server(rpc.Server):
             raise
         # Now pack and return the result
         p = SCTRLPacker()
-        # res = sctrl_type.CTRLres(status, sctrl_type.resdata_t(args.ctrlop))
-        res = sctrl_type.CTRLres(status, result)
+        # res = xdrdef.sctrl_type.CTRLres(status, xdrdef.sctrl_type.resdata_t(args.ctrlop))
+        res = xdrdef.sctrl_type.CTRLres(status, result)
         p.pack_CTRLres(res)
         return rpc.SUCCESS, p.get_buffer()
 
@@ -1926,22 +1926,22 @@ class NFS4Server(rpc.Server):
 
     def ctrl_reset(self, arg):
         self.recording.reset()
-        return sctrl_const.CTRLSTAT_OK, sctrl_type.resdata_t(arg.ctrlop)
+        return xdrdef.sctrl_const.CTRLSTAT_OK, xdrdef.sctrl_type.resdata_t(arg.ctrlop)
 
     def ctrl_record(self, arg):
         self.recording.set_stamp(arg.stamp)
         self.recording.on = True
-        return sctrl_const.CTRLSTAT_OK, sctrl_type.resdata_t(arg.ctrlop)
+        return xdrdef.sctrl_const.CTRLSTAT_OK, xdrdef.sctrl_type.resdata_t(arg.ctrlop)
 
     def ctrl_pause(self, arg):
         self.recording.on = False
-        return sctrl_const.CTRLSTAT_OK, sctrl_type.resdata_t(arg.ctrlop)
+        return xdrdef.sctrl_const.CTRLSTAT_OK, xdrdef.sctrl_type.resdata_t(arg.ctrlop)
 
     def ctrl_grab(self, arg):
         queue = self.recording.queues.get(arg.stamp, None)
         if queue is None:
-            return sctrl_const.CTRLSTAT_NOT_AVAIL, \
-                   sctrl_type.resdata_t(arg.ctrlop, sctrl_type.GRABres([],[]))
+            return xdrdef.sctrl_const.CTRLSTAT_NOT_AVAIL, \
+                   xdrdef.sctrl_type.resdata_t(arg.ctrlop, xdrdef.sctrl_type.GRABres([],[]))
         max = arg.number
         if max == 0:
             max = len(queue)
@@ -1949,19 +1949,19 @@ class NFS4Server(rpc.Server):
         replies = []
         for i in range(max):
             call, reply = queue.pop()
-            if arg.dir & sctrl_const.DIR_CALL:
+            if arg.dir & xdrdef.sctrl_const.DIR_CALL:
                 calls.append(call)
-            if arg.dir & sctrl_const.DIR_REPLY:
+            if arg.dir & xdrdef.sctrl_const.DIR_REPLY:
                 replies.append(reply)
         print calls
         print replies
-        grabres = sctrl_type.GRABres(calls, replies)
-        return sctrl_const.CTRLSTAT_OK, \
-               sctrl_type.resdata_t(arg.ctrlop, grab = grabres)
+        grabres = xdrdef.sctrl_type.GRABres(calls, replies)
+        return xdrdef.sctrl_const.CTRLSTAT_OK, \
+               xdrdef.sctrl_type.resdata_t(arg.ctrlop, grab = grabres)
 
     def ctrl_illegal(self, arg):
         print "ILLEGAL"
-        return sctrl_const.CTRLSTAT_ILLEGAL, sctrl_type.resdata_t(arg.ctrlop)
+        return xdrdef.sctrl_const.CTRLSTAT_ILLEGAL, xdrdef.sctrl_type.resdata_t(arg.ctrlop)
         
     def op_setclientid(self, arg, env):
         return encode_status(NFS4ERR_NOTSUPP)
diff --git a/nfs4.1/nfs4state.py b/nfs4.1/nfs4state.py
index e8445e3..1294083 100644
--- a/nfs4.1/nfs4state.py
+++ b/nfs4.1/nfs4state.py
@@ -5,9 +5,9 @@ from locking import Lock
 import struct
 import nfs4lib
 from nfs4lib import NFS4Error
-#from nfs4_type import stateid4
-from nfs4_type import *
-from nfs4_const import *
+#from xdrdef.nfs4_type import stateid4
+from xdrdef.nfs4_type import *
+from xdrdef.nfs4_const import *
 import nfs4_ops as op
 import rpc
 import logging
diff --git a/nfs4.1/server41tests/environment.py b/nfs4.1/server41tests/environment.py
index b2df732..b8b05cf 100644
--- a/nfs4.1/server41tests/environment.py
+++ b/nfs4.1/server41tests/environment.py
@@ -10,8 +10,8 @@
 
 import time
 import testmod
-from nfs4_const import *
-from nfs4_type import *
+from xdrdef.nfs4_const import *
+from xdrdef.nfs4_type import *
 import rpc
 import nfs4client
 import sys
diff --git a/nfs4.1/server41tests/st_block.py b/nfs4.1/server41tests/st_block.py
index f62968e..432dbbf 100644
--- a/nfs4.1/server41tests/st_block.py
+++ b/nfs4.1/server41tests/st_block.py
@@ -1,5 +1,5 @@
-from nfs4_const import *
-from nfs4_type import *
+from xdrdef.nfs4_const import *
+from xdrdef.nfs4_type import *
 import nfs4_ops as op
 from environment import check, fail, create_file
 from block import Packer as BlockPacker, Unpacker as BlockUnpacker, \
diff --git a/nfs4.1/server41tests/st_compound.py b/nfs4.1/server41tests/st_compound.py
index c6a5ea9..0443a29 100644
--- a/nfs4.1/server41tests/st_compound.py
+++ b/nfs4.1/server41tests/st_compound.py
@@ -1,7 +1,7 @@
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 import nfs4_ops as op
 from environment import check, fail, get_invalid_utf8strings
-from nfs4_type import *
+from xdrdef.nfs4_type import *
 from rpc import RPCAcceptError, GARBAGE_ARGS, RPCTimeout
 from nfs4lib import NFS4Error, hash_oids, encrypt_oids, FancyNFS4Packer
 
diff --git a/nfs4.1/server41tests/st_create_session.py b/nfs4.1/server41tests/st_create_session.py
index ae5ca27..4685eb0 100644
--- a/nfs4.1/server41tests/st_create_session.py
+++ b/nfs4.1/server41tests/st_create_session.py
@@ -1,7 +1,7 @@
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 import nfs4_ops as op
 from environment import check, fail, create_file, open_file
-from nfs4_type import *
+from xdrdef.nfs4_type import *
 import random
 import nfs4lib
 import threading
diff --git a/nfs4.1/server41tests/st_current_stateid.py b/nfs4.1/server41tests/st_current_stateid.py
index 9a1adc4..b2e69c5 100644
--- a/nfs4.1/server41tests/st_current_stateid.py
+++ b/nfs4.1/server41tests/st_current_stateid.py
@@ -1,11 +1,11 @@
 from st_create_session import create_session
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 
 from environment import check, checklist, fail, create_file, open_file, close_file
 from environment import open_create_file_op, use_obj
-from nfs4_type import open_owner4, openflag4, createhow4, open_claim4
-from nfs4_type import creatverfattr, fattr4, stateid4, locker4, lock_owner4
-from nfs4_type import open_to_lock_owner4
+from xdrdef.nfs4_type import open_owner4, openflag4, createhow4, open_claim4
+from xdrdef.nfs4_type import creatverfattr, fattr4, stateid4, locker4, lock_owner4
+from xdrdef.nfs4_type import open_to_lock_owner4
 import nfs4_ops as op
 import threading
 
diff --git a/nfs4.1/server41tests/st_debug.py b/nfs4.1/server41tests/st_debug.py
index aff6842..7bf6b5b 100644
--- a/nfs4.1/server41tests/st_debug.py
+++ b/nfs4.1/server41tests/st_debug.py
@@ -1,7 +1,7 @@
 from st_create_session import create_session
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 from environment import check, fail, create_file
-from nfs4_type import open_owner4, openflag4, createhow4, open_claim4
+from xdrdef.nfs4_type import open_owner4, openflag4, createhow4, open_claim4
 import nfs4_ops as op
 import threading
 
diff --git a/nfs4.1/server41tests/st_delegation.py b/nfs4.1/server41tests/st_delegation.py
index 02ce719..5abc904 100644
--- a/nfs4.1/server41tests/st_delegation.py
+++ b/nfs4.1/server41tests/st_delegation.py
@@ -1,9 +1,9 @@
 from st_create_session import create_session
 from st_open import open_claim4
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 
 from environment import check, checklist, fail, create_file, open_file, close_file
-from nfs4_type import *
+from xdrdef.nfs4_type import *
 import nfs4_ops as op
 import nfs4lib
 import threading
diff --git a/nfs4.1/server41tests/st_destroy_clientid.py b/nfs4.1/server41tests/st_destroy_clientid.py
index 1b193cf..6b7042f 100644
--- a/nfs4.1/server41tests/st_destroy_clientid.py
+++ b/nfs4.1/server41tests/st_destroy_clientid.py
@@ -1,5 +1,5 @@
 from st_create_session import create_session
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 from environment import check, fail
 import nfs4_ops as op
 import nfs4lib
diff --git a/nfs4.1/server41tests/st_destroy_session.py b/nfs4.1/server41tests/st_destroy_session.py
index f4f0762..e3c3424 100644
--- a/nfs4.1/server41tests/st_destroy_session.py
+++ b/nfs4.1/server41tests/st_destroy_session.py
@@ -1,7 +1,7 @@
 from st_create_session import create_session
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 from environment import check, checklist, fail, create_file, open_file
-from nfs4_type import open_owner4, openflag4, createhow4, open_claim4
+from xdrdef.nfs4_type import open_owner4, openflag4, createhow4, open_claim4
 import nfs4_ops as op
 import threading
 import rpc
diff --git a/nfs4.1/server41tests/st_exchange_id.py b/nfs4.1/server41tests/st_exchange_id.py
index 956090f..39b8b0c 100644
--- a/nfs4.1/server41tests/st_exchange_id.py
+++ b/nfs4.1/server41tests/st_exchange_id.py
@@ -1,8 +1,8 @@
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 import nfs4_ops as op
 import time
 from environment import check, checklist, fail
-from nfs4_type import *
+from xdrdef.nfs4_type import *
 from rpc import RPCAcceptError, GARBAGE_ARGS, RPCTimeout
 from nfs4lib import NFS4Error, hash_oids, encrypt_oids
 
diff --git a/nfs4.1/server41tests/st_getdevicelist.py b/nfs4.1/server41tests/st_getdevicelist.py
index 7a10c6c..df0107d 100644
--- a/nfs4.1/server41tests/st_getdevicelist.py
+++ b/nfs4.1/server41tests/st_getdevicelist.py
@@ -1,5 +1,5 @@
-from nfs4_const import *
-from nfs4_type import *
+from xdrdef.nfs4_const import *
+from xdrdef.nfs4_type import *
 from environment import check, fail, use_obj, open_file, create_file
 import nfs4_ops as op
 from block import Packer as BlockPacker, Unpacker as BlockUnpacker, \
diff --git a/nfs4.1/server41tests/st_lookup.py b/nfs4.1/server41tests/st_lookup.py
index 33e06b9..85ddcfe 100644
--- a/nfs4.1/server41tests/st_lookup.py
+++ b/nfs4.1/server41tests/st_lookup.py
@@ -1,4 +1,4 @@
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 from environment import check, fail
 import nfs4_ops as op
 
diff --git a/nfs4.1/server41tests/st_lookupp.py b/nfs4.1/server41tests/st_lookupp.py
index 512ea6b..7aa7406 100644
--- a/nfs4.1/server41tests/st_lookupp.py
+++ b/nfs4.1/server41tests/st_lookupp.py
@@ -1,4 +1,4 @@
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 from environment import check, fail, use_obj
 import nfs4_ops as op
 
diff --git a/nfs4.1/server41tests/st_open.py b/nfs4.1/server41tests/st_open.py
index 2ec646f..71e01fb 100644
--- a/nfs4.1/server41tests/st_open.py
+++ b/nfs4.1/server41tests/st_open.py
@@ -1,11 +1,11 @@
 from st_create_session import create_session
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 
 from environment import check, checklist, fail, create_file, open_file, close_file
 from environment import open_create_file_op
-from nfs4_type import open_owner4, openflag4, createhow4, open_claim4
-from nfs4_type import creatverfattr, fattr4, stateid4, locker4, lock_owner4
-from nfs4_type import open_to_lock_owner4
+from xdrdef.nfs4_type import open_owner4, openflag4, createhow4, open_claim4
+from xdrdef.nfs4_type import creatverfattr, fattr4, stateid4, locker4, lock_owner4
+from xdrdef.nfs4_type import open_to_lock_owner4
 import nfs4_ops as op
 import threading
 
diff --git a/nfs4.1/server41tests/st_putfh.py b/nfs4.1/server41tests/st_putfh.py
index d7bc0be..6d96048 100644
--- a/nfs4.1/server41tests/st_putfh.py
+++ b/nfs4.1/server41tests/st_putfh.py
@@ -1,4 +1,4 @@
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 from environment import check, fail, use_obj, create_confirm, close_file
 import nfs4_ops as op
 
diff --git a/nfs4.1/server41tests/st_reboot.py b/nfs4.1/server41tests/st_reboot.py
index bbfc40e..b778fd7 100644
--- a/nfs4.1/server41tests/st_reboot.py
+++ b/nfs4.1/server41tests/st_reboot.py
@@ -1,5 +1,5 @@
-from nfs4_const import *
-from nfs4_type import *
+from xdrdef.nfs4_const import *
+from xdrdef.nfs4_type import *
 from environment import check, checklist, fail, create_file, open_file, create_confirm
 import sys
 import os
diff --git a/nfs4.1/server41tests/st_reclaim_complete.py b/nfs4.1/server41tests/st_reclaim_complete.py
index f6baf09..1d9270f 100644
--- a/nfs4.1/server41tests/st_reclaim_complete.py
+++ b/nfs4.1/server41tests/st_reclaim_complete.py
@@ -1,5 +1,5 @@
 from st_create_session import create_session
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 from environment import check, fail, open_file, create_file, create_confirm
 import nfs4_ops as op
 import nfs4lib
diff --git a/nfs4.1/server41tests/st_rename.py b/nfs4.1/server41tests/st_rename.py
index 943587c..51b6cd6 100644
--- a/nfs4.1/server41tests/st_rename.py
+++ b/nfs4.1/server41tests/st_rename.py
@@ -1,7 +1,7 @@
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 from environment import check, checklist, fail, maketree, rename_obj, get_invalid_utf8strings, create_obj, create_confirm, link, use_obj, create_file
 import nfs4_ops as op
-from nfs4_type import *
+from xdrdef.nfs4_type import *
 
 def testValidDir(t, env):
     """RENAME : normal operation
diff --git a/nfs4.1/server41tests/st_secinfo.py b/nfs4.1/server41tests/st_secinfo.py
index d9a1e98..b676edc 100644
--- a/nfs4.1/server41tests/st_secinfo.py
+++ b/nfs4.1/server41tests/st_secinfo.py
@@ -1,7 +1,7 @@
 from st_create_session import create_session
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 from environment import check, fail, use_obj, bad_sessionid, create_file
-from nfs4_type import channel_attrs4
+from xdrdef.nfs4_type import channel_attrs4
 import nfs4_ops as op
 import nfs4lib
 
diff --git a/nfs4.1/server41tests/st_secinfo_no_name.py b/nfs4.1/server41tests/st_secinfo_no_name.py
index ada4853..2f8ee1b 100644
--- a/nfs4.1/server41tests/st_secinfo_no_name.py
+++ b/nfs4.1/server41tests/st_secinfo_no_name.py
@@ -1,7 +1,7 @@
 from st_create_session import create_session
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 from environment import check, fail, bad_sessionid, create_file
-from nfs4_type import channel_attrs4
+from xdrdef.nfs4_type import channel_attrs4
 import nfs4_ops as op
 import nfs4lib
 
diff --git a/nfs4.1/server41tests/st_sequence.py b/nfs4.1/server41tests/st_sequence.py
index 96f5e42..e21bf7d 100644
--- a/nfs4.1/server41tests/st_sequence.py
+++ b/nfs4.1/server41tests/st_sequence.py
@@ -1,7 +1,7 @@
 from st_create_session import create_session
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 from environment import check, fail, bad_sessionid, create_file
-from nfs4_type import channel_attrs4
+from xdrdef.nfs4_type import channel_attrs4
 import nfs4_ops as op
 import nfs4lib
 
diff --git a/nfs4.1/server41tests/st_trunking.py b/nfs4.1/server41tests/st_trunking.py
index b984425..142b924 100644
--- a/nfs4.1/server41tests/st_trunking.py
+++ b/nfs4.1/server41tests/st_trunking.py
@@ -1,7 +1,7 @@
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 import nfs4_ops as op
 from environment import check, fail
-from nfs4_type import *
+from xdrdef.nfs4_type import *
 import random
 import nfs4lib
 import threading
diff --git a/nfs4.1/server41tests/st_verify.py b/nfs4.1/server41tests/st_verify.py
index a1bc5ca..cfb3809 100644
--- a/nfs4.1/server41tests/st_verify.py
+++ b/nfs4.1/server41tests/st_verify.py
@@ -1,4 +1,4 @@
-from nfs4_const import *
+from xdrdef.nfs4_const import *
 import nfs4_ops as op
 from environment import check, checklist, get_invalid_clientid, makeStaleId, \
     do_getattrdict, use_obj
diff --git a/nfs4.1/setup.py b/nfs4.1/setup.py
index e73a1d0..5c3a0df 100644
--- a/nfs4.1/setup.py
+++ b/nfs4.1/setup.py
@@ -31,22 +31,25 @@ class build_py(_build_py):
                 self.build_module(module, module_file, package)
 
     def expand_xdr(self, dir):
+        print "expand = %r" % dir
         cwd = os.getcwd()
-        try:
-            if dir:
-                os.chdir(dir)
-            xdr_files = glob(os.path.join(dir, "*.x"))
-            for f in xdr_files:
-                # Can conditionalize this
-                # XXX need some way to pass options here
-                xdrgen.run(f)
-                try:
-                    os.remove("parser.out")
-                    os.remove("parsetab.py")
-                except:
-                    print "Remove parse* failed"
-        finally:
-            os.chdir(cwd)
+        xdrdir = os.path.join(cwd, dir, 'xdrdef')
+        print "xdrdir = %r" % xdrdir
+        if os.path.exists(xdrdir):
+            try:
+                os.chdir(xdrdir)
+                xdr_files = glob(os.path.join(xdrdir, "*.x"))
+                for f in xdr_files:
+                    # Can conditionalize this
+                    # XXX need some way to pass options here
+                    xdrgen.run(f)
+                    try:
+                        os.remove("parser.out")
+                        os.remove("parsetab.py")
+                    except:
+                        print "Remove parse* failed"
+            finally:
+                os.chdir(cwd)
 
 setup(name = "nfs4",
       version = "0.0.0", # import this?
diff --git a/nfs4.1/testclient.py b/nfs4.1/testclient.py
index 9189c60..95e90e1 100755
--- a/nfs4.1/testclient.py
+++ b/nfs4.1/testclient.py
@@ -193,7 +193,7 @@ def run_filter(test, options):
 
 def printflags(list):
     """Print all legal flag names, which are given in list"""
-    from nfs4_const import nfs_opnum4
+    from xdrdef.nfs4_const import nfs_opnum4
     command_names = [s.lower()[3:].replace('_', '') \
                      for s in nfs_opnum4.values()]
     list.sort()
diff --git a/nfs4.1/testserver.py b/nfs4.1/testserver.py
index 61e308c..7c10fe6 100755
--- a/nfs4.1/testserver.py
+++ b/nfs4.1/testserver.py
@@ -190,7 +190,7 @@ def run_filter(test, options):
 
 def printflags(list):
     """Print all legal flag names, which are given in list"""
-    from nfs4_const import nfs_opnum4
+    from xdrdef.nfs4_const import nfs_opnum4
     command_names = [s.lower()[3:].replace('_', '') \
                      for s in nfs_opnum4.values()]
     list.sort()
diff --git a/nfs4.1/xdrdef/__init__.py b/nfs4.1/xdrdef/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/nfs4.1/nfs4.x b/nfs4.1/xdrdef/nfs4.x
similarity index 100%
rename from nfs4.1/nfs4.x
rename to nfs4.1/xdrdef/nfs4.x
diff --git a/nfs4.1/nfs4.x.diff b/nfs4.1/xdrdef/nfs4.x.diff
similarity index 100%
rename from nfs4.1/nfs4.x.diff
rename to nfs4.1/xdrdef/nfs4.x.diff
diff --git a/nfs4.1/pnfs_block.x b/nfs4.1/xdrdef/pnfs_block.x
similarity index 100%
rename from nfs4.1/pnfs_block.x
rename to nfs4.1/xdrdef/pnfs_block.x
diff --git a/nfs4.1/sctrl.x b/nfs4.1/xdrdef/sctrl.x
similarity index 100%
rename from nfs4.1/sctrl.x
rename to nfs4.1/xdrdef/sctrl.x
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 05/16] 4.1 client: remove unused imports
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (3 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 04/16] move .x files to subdir 'xdrdef' Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 06/16] 4.1 server: add -v flag & silence random output Weston Andros Adamson
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/nfs4client.py | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/nfs4.1/nfs4client.py b/nfs4.1/nfs4client.py
index 2aa0a2c..7a07ab7 100644
--- a/nfs4.1/nfs4client.py
+++ b/nfs4.1/nfs4client.py
@@ -8,15 +8,13 @@ from xdrdef.sctrl_pack import SCTRLPacker, SCTRLUnpacker
 import nfs4_ops as op
 import time, struct
 import threading
-import collections
 import hmac
-from locking import Lock
 from nfs4commoncode import CBCompoundState as CompoundState, \
      cb_encode_status as encode_status, \
      cb_encode_status_by_name as encode_status_by_name
 
 
-import sys, traceback
+import traceback
 import logging
 logging.basicConfig(level=logging.INFO,
                     format="%(levelname)-7s:%(name)s:%(message)s")
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 06/16] 4.1 server: add -v flag & silence random output
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (4 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 05/16] 4.1 client: remove unused imports Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 07/16] 4.1 server: add -s option to print summary of ops Weston Andros Adamson
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

By default the nfs4server spews so much information to stdout/stderr
that it's almost useless.  Add the -v flag (aka --verbose) to enable
the old output.

Also remove some random prints and change some to log.info().

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/dataserver.py |  3 +--
 nfs4.1/fs.py         |  4 ----
 nfs4.1/nfs4client.py | 11 ++--------
 nfs4.1/nfs4server.py | 61 +++++++++++++++++++++++-----------------------------
 nfs4.1/nfs4state.py  |  1 -
 5 files changed, 30 insertions(+), 50 deletions(-)

diff --git a/nfs4.1/dataserver.py b/nfs4.1/dataserver.py
index acca210..c400d22 100644
--- a/nfs4.1/dataserver.py
+++ b/nfs4.1/dataserver.py
@@ -182,7 +182,7 @@ class DSDevice(object):
                 line = line.strip()
                 if not line or line.startswith('#'):
                     continue
-                print "Analyzing: %r" % line
+                log.info("Analyzing: %r" % line)
                 try:
                     server_list, path = nfs4lib.parse_nfs_url(line)
                 except:
@@ -192,7 +192,6 @@ class DSDevice(object):
                 # for now, just use the last path for local connections
                 server, port = server_list[-1]
                 server_list = server_list[:-1]
-                print server, port, path
                 try:
                     log.info("Adding dataserver ip:%s port:%s path:%s" %
                              (server, port, '/'.join(path)))
diff --git a/nfs4.1/fs.py b/nfs4.1/fs.py
index 3d63ce5..6ef283b 100644
--- a/nfs4.1/fs.py
+++ b/nfs4.1/fs.py
@@ -13,7 +13,6 @@ from xdrdef.nfs4_pack import NFS4Packer
 log_o = logging.getLogger("fs.obj")
 log_fs = logging.getLogger("fs")
 logging.addLevelName(5, "FUNCT")
-log_fs.setLevel(20)
 
 class MetaData(object):
     """Contains everything that needs to be stored
@@ -743,7 +742,6 @@ class ConfigObj(FSObject):
             line = line.strip()
             if line and not line.startswith("#"):
                 lines.append(line)
-        print lines
         if len(lines) != 1:
             self._reset()
             return
@@ -1154,7 +1152,6 @@ class LayoutFSObj(FSObject):
                                             disk_offset,
                                             e.state))
         block_layout = pnfs_block_layout4(elist)
-        print block_layout
         p = block.Packer()
         p.pack_pnfs_block_layout4(block_layout)
 ##         if self.id <= 4:
@@ -1194,7 +1191,6 @@ class LayoutFSObj(FSObject):
                 log_o.exception("Problem decoding opaque")
                 raise NFS4Error(NFS4ERR_BADLAYOUT, tag="Error decoding opaque")
             upd_list = update.blu_commit_list
-            print upd_list
         # Error check
         for e in upd_list:
             if e.bex_state != block.PNFS_BLOCK_READWRITE_DATA:
diff --git a/nfs4.1/nfs4client.py b/nfs4.1/nfs4client.py
index 7a07ab7..0ba84bd 100644
--- a/nfs4.1/nfs4client.py
+++ b/nfs4.1/nfs4client.py
@@ -19,9 +19,7 @@ import logging
 logging.basicConfig(level=logging.INFO,
                     format="%(levelname)-7s:%(name)s:%(message)s")
 log_cb = logging.getLogger("nfs.client.cb")
-log_cb.setLevel(logging.DEBUG)
 
-SHOW_TRAFFIC = True # Debugging aid, prints out client traffic
 class NFS4Client(rpc.Client, rpc.Server):
     def __init__(self, host='localhost', port=2049, minorversion=1, ctrl_proc=16):
         rpc.Client.__init__(self, 100003, 4)
@@ -76,9 +74,7 @@ class NFS4Client(rpc.Client, rpc.Server):
             pipe = self.c1
         p = packer(check_enum=checks, check_array=checks)
         c4 = COMPOUND4args(tag, version, ops)
-        if SHOW_TRAFFIC:
-            print
-            print c4
+        log_cb.info("compound args = %r" % (c4,))
         p.pack_COMPOUND4args(c4)
         return self.send_call(pipe, 1, p.get_buffer(), credinfo)
 
@@ -86,19 +82,16 @@ class NFS4Client(rpc.Client, rpc.Server):
         xid = self.compound_async(*args, **kwargs)
         pipe = kwargs.get("pipe", None)
         res = self.listen(xid, pipe=pipe)
-        if SHOW_TRAFFIC:
-            print res
+        log_cb.info("compound result = %r" % (res,))
         return res
     
     def listen(self, xid, pipe=None, timeout=10.0):
         if pipe is None:
             pipe = self.c1
         header, data = pipe.listen(xid, timeout)
-        #print "HEADER", header
         if data:
             p = nfs4lib.FancyNFS4Unpacker(data)
             data = p.unpack_COMPOUND4res()
-        #print "DATA", repr(data)
         return data
 
     def handle_0(self, data, cred):
diff --git a/nfs4.1/nfs4server.py b/nfs4.1/nfs4server.py
index 2ae99fe..a495d3c 100755
--- a/nfs4.1/nfs4server.py
+++ b/nfs4.1/nfs4server.py
@@ -21,14 +21,11 @@ from nfs4commoncode import CompoundState, encode_status, encode_status_by_name
 from fs import RootFS, ConfigFS
 from config import ServerConfig, ServerPerClientConfig, OpsConfigServer, Actions
 
-logging.basicConfig(level=logging.INFO,
+logging.basicConfig(level=logging.WARN,
                     format="%(levelname)-7s:%(name)s:%(message)s")
 log_41 = logging.getLogger("nfs.server")
-log_41.setLevel(logging.DEBUG)
-log_41.setLevel(9)
 
 log_cfg = logging.getLogger("nfs.server.opconfig")
-log_cfg.setLevel(20)
 
 ##################################################
 # Set various global constants and magic numbers #
@@ -116,9 +113,6 @@ class Recording(object):
     def add(self, call, reply):
         """Add call and reply strings to records"""
         if self.on:
-            print "Adding"
-            print repr(call)
-            print repr(reply)
             self.queue.appendleft((call, reply))
 
     def set_stamp(self, stamp):
@@ -269,13 +263,13 @@ class VerboseDict(dict):
         self.config = config
 
     def __setitem__(self, key, value):
-        if 0 or self.config.debug_state:
-            print "+++ Adding client.state[%r]" % key
+        if self.config.debug_state:
+            log_41.info("+++ Adding client.state[%r]" % key)
         dict.__setitem__(self, key, value)
 
     def __delitem__(self, key):
-        if 0 or self.config.debug_state:
-            print "+++ Removing client.state[%r]" % key
+        if self.config.debug_state:
+            log_41.info("+++ Removing client.state[%r]" % key)
         dict.__delitem__(self, key)
         
 class ClientRecord(object):
@@ -526,6 +520,13 @@ class NFS4Server(rpc.Server):
         port = kwargs.pop("port", NFS4_PORT)
         self.is_mds = kwargs.pop("is_mds", False)
         self.is_ds = kwargs.pop("is_ds", False)
+
+        self.verbose = kwargs.pop('verbose', False)
+        if self.verbose:
+            log_41.setLevel(logging.DEBUG) # XXX redundant?
+            log_41.setLevel(9)
+            log_cfg.setLevel(20)
+
         rpc.Server.__init__(self, prog=NFS4_PROGRAM, versions=[4], port=port,
                             **kwargs)
         self.root = RootFS().root # Root of exported filesystem tree
@@ -552,7 +553,7 @@ class NFS4Server(rpc.Server):
             rpc.Server.start(self)
         except KeyboardInterrupt:
             # Put user into console where can look at state of server
-            if not self.config.catch_ctrlc:
+            if not self.config.catch_ctrlc or not self.verbose:
                 raise
             import code
             import readline
@@ -1330,9 +1331,9 @@ class NFS4Server(rpc.Server):
         sid, deleg, flags = self.open_file(existing, arg.owner,
                                     arg.share_access, arg.share_deny)
         env.set_cfh(existing, sid)
-        if 0 or env.session.client.config.debug_state:
-            print "+++ client(id=%i).state =" %  env.session.client.clientid
-            print env.session.client.state
+        if env.session.client.config.debug_state:
+            log_41.info("+++ client(id=%i).state = %r" %
+                        (env.session.client.clientid, env.session.client.state))
         res = OPEN4resok(sid, cinfo, flags, bitmask, deleg)
         return encode_status(NFS4_OK, res)
 
@@ -1452,14 +1453,13 @@ class NFS4Server(rpc.Server):
         ret_dict = {}
         info = nfs4lib.attr_info
         for attr in attrs:
-            print "handling fattr4_%s : " % nfs4lib.attr_name(attr),
             if attr not in info:
                 # Ignore unknown attributes
-                print "Unknown"
+                log_41.info("Skipping unknown attr: %s" % (attr,))
                 continue
             if not info[attr].readable:
                 # XXX How deal with write-only attrs?
-                print "Write only"
+                log_41.info("Skipping write only attr: %s" % (attr,))
                 continue
             # Attributes hide in different places, call the place 'base'
             if info[attr].from_fs:
@@ -1471,24 +1471,14 @@ class NFS4Server(rpc.Server):
             name = "fattr4_%s" % nfs4lib.attr_name(attr)
             if hasattr(base, name) and (obj.fs.fattr4_supported_attrs & 1<<attr): # STUB we should be able to remove hasattr
                 ret_dict[attr] = getattr(base, name)
-                print ret_dict[attr]
             else:
                 if ignore:
                     # Must ignore for GETATTR (and READDIR) per 15.1
-                    print "ignored"
-                    if name == "fattr4_mounted_on_fileid":
-                        print base == obj
-                        print base.fattr4_mounted_on_fileid
-                    if name == "fattr4_layout_blksize":
-                        print base == obj
-                        print hasattr(base, name)
-                        print obj.fs.fattr4_supported_attrs
-                        print 1<<attr
-                        print obj.fs.fattr4_supported_attrs & 1<<attr
+                    log_41.info("ignored attr %s" % (name,))
                     continue
                 else:
                     # This is for VERIFY/NVERIFY
-                    print "NOT SUPP"
+                    log_41.info("attr NOT SUPP %s" % (name,))
                     raise NFS4Error(NFS4ERR_ATTRNOTSUPP)
         obj.fattr4_rdattr_error = NFS4_OK # XXX STUB Handle correctly
         return ret_dict
@@ -1953,14 +1943,14 @@ class NFS4Server(rpc.Server):
                 calls.append(call)
             if arg.dir & xdrdef.sctrl_const.DIR_REPLY:
                 replies.append(reply)
-        print calls
-        print replies
+        #print calls
+        #print replies
         grabres = xdrdef.sctrl_type.GRABres(calls, replies)
         return xdrdef.sctrl_const.CTRLSTAT_OK, \
                xdrdef.sctrl_type.resdata_t(arg.ctrlop, grab = grabres)
 
     def ctrl_illegal(self, arg):
-        print "ILLEGAL"
+        #print "ILLEGAL"
         return xdrdef.sctrl_const.CTRLSTAT_ILLEGAL, xdrdef.sctrl_type.resdata_t(arg.ctrlop)
         
     def op_setclientid(self, arg, env):
@@ -2067,6 +2057,8 @@ def scan_options():
                     )
     p.add_option("-r", "--reset", action="store_true", default=False,
                  help="Reset and clear any disk-based filesystems")
+    p.add_option("-v", "--verbose", action="store_true", default=False,
+                 help="Print debug info to screen and enter interpreter on ^C")
     p.add_option("--use_block", action="store_true", default=False,
                  help="Mount a block-pnfs fs")
     p.add_option("--use_files", action="store_true", default=False,
@@ -2099,7 +2091,8 @@ if __name__ == "__main__":
         locking.DEBUG = True
     S = NFS4Server(port=opts.port,
                    is_mds=opts.use_block or opts.use_files,
-                   is_ds = opts.is_ds)
+                   is_ds = opts.is_ds,
+                   verbose = opts.verbose)
     read_exports(S, opts)
     if True:
         S.start()
diff --git a/nfs4.1/nfs4state.py b/nfs4.1/nfs4state.py
index 1294083..2f3cd59 100644
--- a/nfs4.1/nfs4state.py
+++ b/nfs4.1/nfs4state.py
@@ -13,7 +13,6 @@ import rpc
 import logging
 
 log = logging.getLogger("nfs.server.state")
-log.setLevel(10)
 
 POSIXLOCK = False
 
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 07/16] 4.1 server: add -s option to print summary of ops
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (5 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 06/16] 4.1 server: add -v flag & silence random output Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 08/16] dataserver: make generic interface to ops Weston Andros Adamson
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

As a middle ground between verbose (-v) mode and silent mode, add
"-s" (aka "--show_summary") to print one line per operation.

The summary mode will print a "role" header whenever the role changes.

Example output - mds starts, talks to v3 ds (.200), client (.11) mounts,
touches an existing file:

call v3 172.16.200.200:2049
  access
Mounting (2, 6) on '/files'

handle v4.1 ::ffff:172.16.200.11:758
  exchange_id
  create_session
  sequence, reclaim_complete
  sequence, putrootfh, secinfo_no_name
  sequence, putrootfh, getfh, getattr
  sequence, putfh, getattr
  (repeated 6 times)
  sequence, putfh, access, getattr
  sequence, putfh, lookup, getfh, getattr
  (repeated 1 times)
  sequence, putfh, secinfo -> NFS4ERR_NOTSUPP
  sequence, putfh, getattr
  (repeated 4 times)
  sequence, putfh, access, getattr

call v3 172.16.200.200:2049
  create -> NFS3ERR_EXIST
  lookup
  getattr
  (repeated 1 times)

handle v4.1 ::ffff:172.16.200.11:758
  sequence, putfh, open, getfh, access, getattr

call v3 172.16.200.200:2049
  getattr
  (repeated 1 times)

handle v4.1 ::ffff:172.16.200.11:758
  sequence, putfh, setattr, getattr
  sequence, putfh, close, getattr

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/dataserver.py     | 16 ++++++++++------
 nfs4.1/nfs4client.py     |  7 ++++++-
 nfs4.1/nfs4server.py     | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
 nfs4.1/server_exports.py |  7 ++++---
 4 files changed, 66 insertions(+), 11 deletions(-)

diff --git a/nfs4.1/dataserver.py b/nfs4.1/dataserver.py
index c400d22..dd81b20 100644
--- a/nfs4.1/dataserver.py
+++ b/nfs4.1/dataserver.py
@@ -13,8 +13,8 @@ import socket
 
 log = logging.getLogger("Dataserver Manager")
 
-class DataServer(object):
-    def __init__(self, server, port, path, flavor=rpc.AUTH_SYS, active=True, mdsds=True, multipath_servers=None):
+class DataServer41(object):
+    def __init__(self, server, port, path, flavor=rpc.AUTH_SYS, active=True, mdsds=True, multipath_servers=None, summary=None):
         self.mdsds = mdsds
         self.server = server
         self.port = int(port)
@@ -32,6 +32,8 @@ class DataServer(object):
         else:
             self.multipath_servers = []
 
+        self.summary = summary
+
         if active:
             self.up()
 
@@ -47,7 +49,8 @@ class DataServer(object):
         # only support root with AUTH_SYS for now
         s1 = rpc.security.instance(rpc.AUTH_SYS)
         self.cred1 = s1.init_cred(uid=0, gid=0)
-        self.c1 = nfs4client.NFS4Client(self.server, self.port)
+        self.c1 = nfs4client.NFS4Client(self.server, self.port,
+                                        summary=self.summary)
         self.c1.set_cred(self.cred1)
         self.c1.null()
         c = self.c1.new_client("DS.init_%s" % self.server)
@@ -173,7 +176,7 @@ class DSDevice(object):
         self.address_body = None # set by load()
         self.mdsds = mdsds # if you are both the DS and the MDS we are the only server
 
-    def load(self, filename):
+    def load(self, filename, server_obj):
         """ Read dataservers from configuration file:
         where each line has format e.g. server[:[port][/path]]
         """
@@ -195,8 +198,9 @@ class DSDevice(object):
                 try:
                     log.info("Adding dataserver ip:%s port:%s path:%s" %
                              (server, port, '/'.join(path)))
-                    ds = DataServer(server, port, path, mdsds=self.mdsds,
-                                    multipath_servers=server_list)
+                    ds = DataServer41(server, port, path, mdsds=self.mdsds,
+                                    multipath_servers=server_list,
+                                    summary=server_obj.summary)
                     self.list.append(ds)
                 except socket.error:
                     log.critical("cannot access %s:%i/%s" %
diff --git a/nfs4.1/nfs4client.py b/nfs4.1/nfs4client.py
index 0ba84bd..4ae884a 100644
--- a/nfs4.1/nfs4client.py
+++ b/nfs4.1/nfs4client.py
@@ -21,7 +21,7 @@ logging.basicConfig(level=logging.INFO,
 log_cb = logging.getLogger("nfs.client.cb")
 
 class NFS4Client(rpc.Client, rpc.Server):
-    def __init__(self, host='localhost', port=2049, minorversion=1, ctrl_proc=16):
+    def __init__(self, host='localhost', port=2049, minorversion=1, ctrl_proc=16, summary=None):
         rpc.Client.__init__(self, 100003, 4)
         self.prog = 0x40000000
         self.versions = [1] # List of supported versions of prog
@@ -36,6 +36,7 @@ class NFS4Client(rpc.Client, rpc.Server):
         self.c1 = self.connect(self.server_address)
         self.sessions = {} # XXX Really, this should be per server
         self.ctrl_proc = ctrl_proc
+        self.summary = summary
 
     def set_cred(self, credinfo):
         self.default_cred = credinfo
@@ -83,6 +84,10 @@ class NFS4Client(rpc.Client, rpc.Server):
         pipe = kwargs.get("pipe", None)
         res = self.listen(xid, pipe=pipe)
         log_cb.info("compound result = %r" % (res,))
+        if self.summary:
+            self.summary.show_op('call v4.1 %s:%s' % self.server_address,
+                [ nfs_opnum4[a.argop].lower()[3:] for a in args[0] ],
+                nfsstat4[res.status])
         return res
     
     def listen(self, xid, pipe=None, timeout=10.0):
diff --git a/nfs4.1/nfs4server.py b/nfs4.1/nfs4server.py
index a495d3c..3d2d4cf 100755
--- a/nfs4.1/nfs4server.py
+++ b/nfs4.1/nfs4server.py
@@ -502,6 +502,41 @@ class Slot(object):
 
     # STUB - for client, need to track slot usage
 
+class SummaryOutput:
+    def __init__(self, enabled=True):
+        self._enabled = enabled
+        self._last = None
+        self._last_role = None
+        self._repeat_count = 0
+
+    def show_op(self, role, opnames, status):
+        if not self._enabled:
+            return
+
+        summary_line = "  %s" % ', '.join(opnames)
+
+        if status != "NFS4_OK" and status != "NFS3_OK":
+            summary_line += " -> %s" % (status,)
+
+        print_summary_line = True
+        if summary_line != self._last or role != self._last_role:
+            if self._last and self._repeat_count:
+                print "  (repeated %u times)" % self._repeat_count
+            self._last = summary_line
+            self._repeat_count = 0
+        else:
+            print_summary_line = False
+            self._repeat_count += 1
+
+        if self._last_role != role:
+            print
+            print role
+            self._last_role = role
+
+        if print_summary_line:
+            print summary_line
+
+
 ##################################################
 # The primary class - it is excessively long     #
 ##################################################
@@ -527,6 +562,8 @@ class NFS4Server(rpc.Server):
             log_41.setLevel(9)
             log_cfg.setLevel(20)
 
+        self.summary = SummaryOutput(kwargs.pop('show_summary', False))
+
         rpc.Server.__init__(self, prog=NFS4_PROGRAM, versions=[4], port=port,
                             **kwargs)
         self.root = RootFS().root # Root of exported filesystem tree
@@ -776,6 +813,7 @@ class NFS4Server(rpc.Server):
             return env
         # Handle the individual operations
         status = NFS4_OK
+        opnames = []
         for arg in args.argarray:
             opname = nfs_opnum4.get(arg.argop, 'op_illegal')
             log_41.info("*** %s (%d) ***" % (opname, arg.argop))
@@ -805,10 +843,14 @@ class NFS4Server(rpc.Server):
                     result = encode_status_by_name(opname.lower()[3:],
                                                    NFS4ERR_SERVERFAULT)
             env.results.append(result)
+            opnames.append(opname.lower()[3:])
             status = result.status
             if status != NFS4_OK:
                 break
         log_41.info("Replying.  Status %s (%d)" % (nfsstat4[status], status))
+        client_addr = '%s:%s' % cred.connection._s.getpeername()[:2]
+        self.summary.show_op('handle v4.1 %s' % client_addr,
+                             opnames, nfsstat4[status])
         return env
 
     def delete_session(self, session, sessionid):
@@ -2059,6 +2101,8 @@ def scan_options():
                  help="Reset and clear any disk-based filesystems")
     p.add_option("-v", "--verbose", action="store_true", default=False,
                  help="Print debug info to screen and enter interpreter on ^C")
+    p.add_option("-s", "--show_summary", action="store_true", default=False,
+                 help="Print short summary of operations")
     p.add_option("--use_block", action="store_true", default=False,
                  help="Mount a block-pnfs fs")
     p.add_option("--use_files", action="store_true", default=False,
@@ -2092,7 +2136,8 @@ if __name__ == "__main__":
     S = NFS4Server(port=opts.port,
                    is_mds=opts.use_block or opts.use_files,
                    is_ds = opts.is_ds,
-                   verbose = opts.verbose)
+                   verbose = opts.verbose,
+                   show_summary = opts.show_summary)
     read_exports(S, opts)
     if True:
         S.start()
diff --git a/nfs4.1/server_exports.py b/nfs4.1/server_exports.py
index d96b27b..ef857ee 100644
--- a/nfs4.1/server_exports.py
+++ b/nfs4.1/server_exports.py
@@ -15,7 +15,7 @@ def mount_stuff(server, opts):
         E = BlockLayoutFS(5, backing_device=dev)
         server.mount(E, path="/block")
     if opts.use_files:
-        dservers = _load_dataservers(opts.dataservers, server.is_ds and server.is_mds)
+        dservers = _load_dataservers(opts.dataservers, server)
         if dservers is None:
             return
         F = FileLayoutFS(6, dservers)
@@ -33,7 +33,8 @@ def _create_simple_block_dev():
     c1 = Concat([s3, s1])
     return BlockVolume(c1)
 
-def _load_dataservers(file, connect_to_ds=False):
+def _load_dataservers(filename, server):
+    connect_to_ds = server.is_ds and server.is_mds
     dss = DSDevice(connect_to_ds)
-    dss.load(file)
+    dss.load(filename, server)
     return dss;
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 08/16] dataserver: make generic interface to ops
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (6 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 07/16] 4.1 server: add -s option to print summary of ops Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 09/16] dataserver: don't import * from nfs4 specific mods Weston Andros Adamson
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

Hide the execute method to make DataServer objects more generic.

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/dataserver.py | 41 ++++++++++++++++++++++++++++++++++-------
 nfs4.1/fs.py         | 24 ++++--------------------
 2 files changed, 38 insertions(+), 27 deletions(-)

diff --git a/nfs4.1/dataserver.py b/nfs4.1/dataserver.py
index dd81b20..16be4c4 100644
--- a/nfs4.1/dataserver.py
+++ b/nfs4.1/dataserver.py
@@ -64,7 +64,7 @@ class DataServer41(object):
     def disconnect(self):
         pass
 
-    def execute(self, ops, exceptions=[], delay=5, maxretries=3):
+    def _execute(self, ops, exceptions=[], delay=5, maxretries=3):
         """ execute the NFS call
         If an error code is specified in the exceptions it means that the
         caller wants to handle the error himself
@@ -118,16 +118,16 @@ class DataServer41(object):
         kind = createtype4(NF4DIR)
         for comp in self.path:
             existing_path.append(comp)
-            res = self.execute(nfs4lib.use_obj(existing_path),
+            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._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)])
+        res = self._execute(nfs4lib.use_obj(self.path_fh) + [op.access(need)])
         if res.resarray[-1].access != need:
             raise RuntimeError
         # XXX clean DS directory
@@ -147,7 +147,7 @@ class DataServer41(object):
             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])
+            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)
@@ -163,10 +163,37 @@ class DataServer41(object):
         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)
+        res = self._execute(ops)
         # ignoring return
         del self.filehandles[mds_fh]
 
+    def read(self, fh, pos, count):
+        ops = [op.putfh(fh),
+               op.read(nfs4lib.state00, pos, count)]
+        # There are all sorts of error handling issues here
+        res = self._execute(ops)
+        data = res.resarray[-1].data
+        return data
+
+    def write(self, fh, pos, data):
+        ops = [op.putfh(fh),
+               op.write(nfs4lib.state00, pos, FILE_SYNC4, data)]
+        # There are all sorts of error handling issues here
+        res = self._execute(ops)
+
+    def truncate(self, fh, size):
+        ops = [op.putfh(fh),
+               op.setattr(nfs4lib.state00, {FATTR4_SIZE: size})]
+        res = self._execute(ops)
+
+    def get_size(self, fh):
+        ops = [op.putfh(fh),
+               op.getattr(1L << FATTR4_SIZE)]
+        res = self._execute(ops)
+        attrdict = res.resarray[-1].obj_attributes
+        return attrdict.get(FATTR4_SIZE, 0)
+
+
 class DSDevice(object):
     def __init__(self, mdsds):
         self.list = [] # list of DataServer instances
diff --git a/nfs4.1/fs.py b/nfs4.1/fs.py
index 6ef283b..8fc49ef 100644
--- a/nfs4.1/fs.py
+++ b/nfs4.1/fs.py
@@ -1567,12 +1567,7 @@ class FilelayoutVolWrapper(object):
         self._pos = 0
 
     def read(self, count):
-        # STUB stateid0 is illegal to a ds
-        ops = [op.putfh(self._fh),
-               op.read(nfs4lib.state00, self._pos, count)]
-        # There are all sorts of error handling issues here
-        res = self._ds.execute(ops)
-        data = res.resarray[-1].data
+        data = self._ds.read(self._fh, self._pos, count)
         self._pos += len(data)
         return data
 
@@ -1580,25 +1575,14 @@ class FilelayoutVolWrapper(object):
         self._pos = offset
 
     def write(self, data):
-        ops = [op.putfh(self._fh),
-               op.write(nfs4lib.state00, self._pos, FILE_SYNC4, data)]
-        # There are all sorts of error handling issues here
-        res = self._ds.execute(ops)
+        self._ds.write(self._fh, self._pos, data)
         self._pos += len(data)
-        return
 
     def truncate(self, size):
-        ops = [op.putfh(self._fh),
-               op.setattr(nfs4lib.state00, {FATTR4_SIZE: size})]
-        res = self._ds.execute(ops)
-        return
+        self._ds.truncate(self._fh, size)
 
     def get_size(self):
-        ops = [op.putfh(self._fh),
-               op.getattr(1L << FATTR4_SIZE)]
-        res = self._ds.execute(ops)
-        attrdict = res.resarray[-1].obj_attributes
-        return attrdict.get(FATTR4_SIZE, 0)
+        return self._ds.get_size(self._fh)
 
 ################################################
 
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 09/16] dataserver: don't import * from nfs4 specific mods
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (7 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 08/16] dataserver: make generic interface to ops Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 10/16] 4.1 server: move nfs4_ops.py to nfs_ops.py Weston Andros Adamson
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

don't pollute the global namespace with constants and types from nfs4_*

this is in preparation for NFSv3 DSes.

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/dataserver.py | 60 ++++++++++++++++++++++++++--------------------------
 1 file changed, 30 insertions(+), 30 deletions(-)

diff --git a/nfs4.1/dataserver.py b/nfs4.1/dataserver.py
index 16be4c4..f9e9740 100644
--- a/nfs4.1/dataserver.py
+++ b/nfs4.1/dataserver.py
@@ -1,8 +1,8 @@
 import rpc
 import nfs4lib
-from xdrdef.nfs4_type import *
+import xdrdef.nfs4_type as type4
 from xdrdef.nfs4_pack import NFS4Packer
-from xdrdef.nfs4_const import *
+import xdrdef.nfs4_const as const4
 import time
 import logging
 import nfs4client
@@ -56,7 +56,7 @@ class DataServer41(object):
         c = self.c1.new_client("DS.init_%s" % self.server)
         # This is a hack to ensure MDS/DS communication path is at least
         # as wide as the client/MDS channel (at least for linux client)
-        fore_attrs = channel_attrs4(0, 16384, 16384, 2868, 8, 8, [])
+        fore_attrs = type4.channel_attrs4(0, 16384, 16384, 2868, 8, 8, [])
         self.sess = c.create_session(fore_attrs=fore_attrs)
         sess.compound([op.reclaim_complete(FALSE)])
         self.make_root()
@@ -69,12 +69,12 @@ class DataServer41(object):
         If an error code is specified in the exceptions it means that the
         caller wants to handle the error himself
         """
-        retry_errors = [NFS4ERR_DELAY, NFS4ERR_GRACE]
-        state_errors = [NFS4ERR_STALE_CLIENTID, NFS4ERR_BADSESSION,
-                        NFS4ERR_BADSLOT, NFS4ERR_DEADSESSION]
+        retry_errors = [const4.NFS4ERR_DELAY, const4.NFS4ERR_GRACE]
+        state_errors = [const4.NFS4ERR_STALE_CLIENTID, const4.NFS4ERR_BADSESSION,
+                        const4.NFS4ERR_BADSLOT, const4.NFS4ERR_DEADSESSION]
         while True:
             res = self.sess.compound(ops)
-            if res.status == NFS4_OK or res.status in exceptions:
+            if res.status == const4.NFS4_OK or res.status in exceptions:
                 return res
             elif res.status in retry_errors:
                 if maxretries > 0:
@@ -96,7 +96,7 @@ class DataServer41(object):
         uaddr = '.'.join([self.server,
                           str(self.port >> 8),
                           str(self.port & 0xff)])
-        return netaddr4(self.proto, uaddr)
+        return type4.netaddr4(self.proto, uaddr)
 
     def get_multipath_netaddr4s(self):
         netaddr4s = []
@@ -109,24 +109,24 @@ class DataServer41(object):
             if server.find(':') >= 0:
                 proto = "tcp6"
 
-            netaddr4s.append(netaddr4(proto, uaddr))
+            netaddr4s.append(type4.netaddr4(proto, uaddr))
         return netaddr4s
 
 
-    def make_root(self, attrs={FATTR4_MODE:0777}):
+    def make_root(self, attrs={const4.FATTR4_MODE:0777}):
         existing_path = []
-        kind = createtype4(NF4DIR)
+        kind = type4.createtype4(const4.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:
+                               exceptions=[const4.NFS4ERR_NOENT])
+            if res.status == const4.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
+        need = const4.ACCESS4_READ | const4.ACCESS4_LOOKUP | const4.ACCESS4_MODIFY | const4.ACCESS4_EXTEND
         res = self._execute(nfs4lib.use_obj(self.path_fh) + [op.access(need)])
         if res.resarray[-1].access != need:
             raise RuntimeError
@@ -136,25 +136,25 @@ class DataServer41(object):
         return hashlib.sha1("%r" % mds_fh).hexdigest()
 
     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):
+                  access=const4.OPEN4_SHARE_ACCESS_BOTH, deny=const4.OPEN4_SHARE_DENY_NONE,
+                  attrs={const4.FATTR4_MODE: 0777}, owner = "mds", mode=const4.GUARDED4):
         verifier = self.sess.c.verifier
-        openflag = openflag4(OPEN4_CREATE, createhow4(mode, attrs, verifier))
+        openflag = type4.openflag4(const4.OPEN4_CREATE, type4.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:
+                              type4.open_owner4(self.sess.client.clientid, owner),
+                              openflag, type4.open_claim4(const4.CLAIM_NULL, name))
+            res = self._execute(nfs4lib.use_obj(self.path_fh) + [open_op, op.getfh()], exceptions=[const4.NFS4ERR_EXIST])
+            if res.status == const4.NFS4_OK:
                  ds_fh = res.resarray[-1].opgetfh.resok4.object
-                 ds_openstateid = stateid4(0, res.resarray[-2].stateid.other)
+                 ds_openstateid = type4.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)
+            elif res.status == const4.NFS4ERR_EXIST:
+                 openflag = type4.openflag4(const4.OPEN4_NOCREATE)
             else:
                 raise RuntimeError
 
@@ -177,26 +177,26 @@ class DataServer41(object):
 
     def write(self, fh, pos, data):
         ops = [op.putfh(fh),
-               op.write(nfs4lib.state00, pos, FILE_SYNC4, data)]
+               op.write(nfs4lib.state00, pos, const4.FILE_SYNC4, data)]
         # There are all sorts of error handling issues here
         res = self._execute(ops)
 
     def truncate(self, fh, size):
         ops = [op.putfh(fh),
-               op.setattr(nfs4lib.state00, {FATTR4_SIZE: size})]
+               op.setattr(nfs4lib.state00, {const4.FATTR4_SIZE: size})]
         res = self._execute(ops)
 
     def get_size(self, fh):
         ops = [op.putfh(fh),
-               op.getattr(1L << FATTR4_SIZE)]
+               op.getattr(1L << const4.FATTR4_SIZE)]
         res = self._execute(ops)
         attrdict = res.resarray[-1].obj_attributes
-        return attrdict.get(FATTR4_SIZE, 0)
+        return attrdict.get(const4.FATTR4_SIZE, 0)
 
 
 class DSDevice(object):
     def __init__(self, mdsds):
-        self.list = [] # list of DataServer instances
+        self.list = [] # list of DataServer41 instances
         # STUB only one data group supported for now
         self.devid = 0
         self.active = 0
@@ -248,7 +248,7 @@ class DSDevice(object):
                 netaddrs.append(multipath)
                 stripe_indices.append(index)
                 index = index + 1
-        addr = nfsv4_1_file_layout_ds_addr4(stripe_indices, netaddrs)
+        addr = type4.nfsv4_1_file_layout_ds_addr4(stripe_indices, netaddrs)
         p = NFS4Packer()
         p.pack_nfsv4_1_file_layout_ds_addr4(addr)
         return p.get_buffer()
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 10/16] 4.1 server: move nfs4_ops.py to nfs_ops.py
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (8 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 09/16] dataserver: don't import * from nfs4 specific mods Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 11/16] add mntv3, portmapv2 and nfsv3 .x files Weston Andros Adamson
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

Also replace ugly exec & inspect code to just define a class with
a __getattr__ switch.

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/dataserver.py | 32 ++++++++++---------
 nfs4.1/fs.py         |  2 --
 nfs4.1/nfs4_ops.py   | 61 -----------------------------------
 nfs4.1/nfs4client.py | 14 +++++----
 nfs4.1/nfs4lib.py    |  8 +++--
 nfs4.1/nfs4state.py  |  8 +++--
 nfs4.1/nfs_ops.py    | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 124 insertions(+), 90 deletions(-)
 delete mode 100644 nfs4.1/nfs4_ops.py
 create mode 100644 nfs4.1/nfs_ops.py

diff --git a/nfs4.1/dataserver.py b/nfs4.1/dataserver.py
index f9e9740..d092cf7 100644
--- a/nfs4.1/dataserver.py
+++ b/nfs4.1/dataserver.py
@@ -8,11 +8,13 @@ import logging
 import nfs4client
 import hashlib
 import sys
-import nfs4_ops as op
+import nfs_ops
 import socket
 
 log = logging.getLogger("Dataserver Manager")
 
+op4 = nfs_ops.NFS4ops()
+
 class DataServer41(object):
     def __init__(self, server, port, path, flavor=rpc.AUTH_SYS, active=True, mdsds=True, multipath_servers=None, summary=None):
         self.mdsds = mdsds
@@ -122,12 +124,12 @@ class DataServer41(object):
                                exceptions=[const4.NFS4ERR_NOENT])
             if res.status == const4.NFS4ERR_NOENT:
                 cr_ops = nfs4lib.use_obj(existing_path[:-1]) + \
-                    [op.create(kind, comp, attrs)]
+                    [op4.create(kind, comp, attrs)]
                 self._execute(cr_ops)
-        res = self._execute(nfs4lib.use_obj(self.path) + [op.getfh()])
+        res = self._execute(nfs4lib.use_obj(self.path) + [op4.getfh()])
         self.path_fh = res.resarray[-1].object
         need = const4.ACCESS4_READ | const4.ACCESS4_LOOKUP | const4.ACCESS4_MODIFY | const4.ACCESS4_EXTEND
-        res = self._execute(nfs4lib.use_obj(self.path_fh) + [op.access(need)])
+        res = self._execute(nfs4lib.use_obj(self.path_fh) + [op4.access(need)])
         if res.resarray[-1].access != need:
             raise RuntimeError
         # XXX clean DS directory
@@ -144,10 +146,10 @@ class DataServer41(object):
         while True:
             if mds_fh in self.filehandles:
                 return
-            open_op = op.open(seqid, access, deny,
+            open_op = op4.open(seqid, access, deny,
                               type4.open_owner4(self.sess.client.clientid, owner),
                               openflag, type4.open_claim4(const4.CLAIM_NULL, name))
-            res = self._execute(nfs4lib.use_obj(self.path_fh) + [open_op, op.getfh()], exceptions=[const4.NFS4ERR_EXIST])
+            res = self._execute(nfs4lib.use_obj(self.path_fh) + [open_op, op4.getfh()], exceptions=[const4.NFS4ERR_EXIST])
             if res.status == const4.NFS4_OK:
                  ds_fh = res.resarray[-1].opgetfh.resok4.object
                  ds_openstateid = type4.stateid4(0, res.resarray[-2].stateid.other)
@@ -162,33 +164,33 @@ class DataServer41(object):
         """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)]
+        ops = [op4.putfh(fh)] + [op4.close(seqid, stateid)]
         res = self._execute(ops)
         # ignoring return
         del self.filehandles[mds_fh]
 
     def read(self, fh, pos, count):
-        ops = [op.putfh(fh),
-               op.read(nfs4lib.state00, pos, count)]
+        ops = [op4.putfh(fh),
+               op4.read(nfs4lib.state00, pos, count)]
         # There are all sorts of error handling issues here
         res = self._execute(ops)
         data = res.resarray[-1].data
         return data
 
     def write(self, fh, pos, data):
-        ops = [op.putfh(fh),
-               op.write(nfs4lib.state00, pos, const4.FILE_SYNC4, data)]
+        ops = [op4.putfh(fh),
+               op4.write(nfs4lib.state00, pos, const4.FILE_SYNC4, data)]
         # There are all sorts of error handling issues here
         res = self._execute(ops)
 
     def truncate(self, fh, size):
-        ops = [op.putfh(fh),
-               op.setattr(nfs4lib.state00, {const4.FATTR4_SIZE: size})]
+        ops = [op4.putfh(fh),
+               op4.setattr(nfs4lib.state00, {const4.FATTR4_SIZE: size})]
         res = self._execute(ops)
 
     def get_size(self, fh):
-        ops = [op.putfh(fh),
-               op.getattr(1L << const4.FATTR4_SIZE)]
+        ops = [op4.putfh(fh),
+               op4.getattr(1L << const4.FATTR4_SIZE)]
         res = self._execute(ops)
         attrdict = res.resarray[-1].obj_attributes
         return attrdict.get(const4.FATTR4_SIZE, 0)
diff --git a/nfs4.1/fs.py b/nfs4.1/fs.py
index 8fc49ef..8947014 100644
--- a/nfs4.1/fs.py
+++ b/nfs4.1/fs.py
@@ -1557,8 +1557,6 @@ class FileLayoutFile(object): # XXX This should inherit from fs_base.py
         vol = FilelayoutVolWrapper(self._obj, device.list[index])
         return vol, v_pos, remaining
 
-import nfs4_ops as op
-
 class FilelayoutVolWrapper(object):
     def __init__(self, obj, dataserver):
         self._obj = obj
diff --git a/nfs4.1/nfs4_ops.py b/nfs4.1/nfs4_ops.py
deleted file mode 100644
index 35a10ca..0000000
--- a/nfs4.1/nfs4_ops.py
+++ /dev/null
@@ -1,61 +0,0 @@
-"""For each OP_<NAME> in nfs_argop4 and nfs_cb_argop4, create a function
-<name>() that returns the appropriate *_argop4 structure, hiding
-this routine packing from the user.
-"""
-import xdrdef.nfs4_type as _type
-import xdrdef.nfs4_const as _const
-
-# This string is our general function template
-code = """\
-def %(funct_name)s(%(funct_args)s):
-    %(create_args)s
-    return _type.%(argop)s(_const.OP_%(enum_name)s, %(set_args)s)
-"""
-
-def _mappings():
-    return _pull_argops(_const.nfs_opnum4) + _pull_argops(_const.nfs_cb_opnum4)
-
-def _pull_argops(op_dict):
-    """ For each entry in op_dict, create an appropriate dictionary that can
-        be used to fill the 'code' template.
-    """
-    import inspect
-    out = []
-    keys = op_dict.keys()
-    keys.sort() # Not necessary, but makes scanning the printout easier
-    for k in keys:
-        # Create a dictionary that will be used to fill the 'code' template
-        d = {}
-        d["enum_name"] = enum_name = op_dict[k][3:] # <NAME>
-        d["funct_name"] = "%s" % enum_name.lower() # <name>
-        class_name = "%s4args" % enum_name
-        klass = getattr(_type, class_name, None)
-        if klass is None:
-            # This operation takes no arguments
-            d["funct_args"] = d["create_args"] = d["set_args"] = ""
-        else:
-            if type(klass) is dict:
-                arg_list = "enum_value"
-                d["create_args"] = "args = enum_value"
-            else:
-                arg_list = ", ".join(inspect.getargspec(klass.__init__)[0][1:])
-                d["create_args"] = "args = _type.%s(%s)" % (class_name, arg_list)
-            d["funct_args"] = arg_list
-            if enum_name.startswith("CB_"):
-                d["set_args"] = "opcb%s=args" % enum_name.lower()[3:]
-            else:
-                d["set_args"] = "op%s=args" % enum_name.lower()
-        if enum_name.startswith("CB_"):
-            d["argop"] = "nfs_cb_argop4"
-        else:
-            d["argop"] = "nfs_argop4"
-        out.append(d)
-    return out
-
-if __name__ == "__main__":
-    for _d in _mappings():
-        print code % _d
-else:
-    for _d in _mappings():
-        exec code % _d
-    
diff --git a/nfs4.1/nfs4client.py b/nfs4.1/nfs4client.py
index 4ae884a..6912565 100644
--- a/nfs4.1/nfs4client.py
+++ b/nfs4.1/nfs4client.py
@@ -5,7 +5,7 @@ from nfs4lib import NFS4Error, NFS4Replay, inc_u32
 from xdrdef.nfs4_type import *
 from xdrdef.nfs4_const import *
 from xdrdef.sctrl_pack import SCTRLPacker, SCTRLUnpacker
-import nfs4_ops as op
+import nfs_ops
 import time, struct
 import threading
 import hmac
@@ -20,6 +20,8 @@ logging.basicConfig(level=logging.INFO,
                     format="%(levelname)-7s:%(name)s:%(message)s")
 log_cb = logging.getLogger("nfs.client.cb")
 
+op4 = nfs_ops.NFS4ops()
+
 class NFS4Client(rpc.Client, rpc.Server):
     def __init__(self, host='localhost', port=2049, minorversion=1, ctrl_proc=16, summary=None):
         rpc.Client.__init__(self, 100003, 4)
@@ -275,7 +277,7 @@ class NFS4Client(rpc.Client, rpc.Server):
         owner = client_owner4(verf, name)
         if protect is None:
             protect = state_protect4_a(SP4_NONE)
-        res = self.compound([op.exchange_id(owner, flags, protect,
+        res = self.compound([op4.exchange_id(owner, flags, protect,
                                             [self.impl_id])],
                             cred)
         nfs4lib.check(res, expect)
@@ -287,7 +289,7 @@ class NFS4Client(rpc.Client, rpc.Server):
     def new_client_session(self, name, flags=0, sec=None):
         c = self.new_client(name, flags=flags)
         s = c.create_session(sec=sec)
-        s.compound([op.reclaim_complete(FALSE)])
+        s.compound([op4.reclaim_complete(FALSE)])
         return s
 
 class ClientStateProtection(object):
@@ -339,7 +341,7 @@ class ClientRecord(object):
         if prog is None:
             prog = self.c.prog
         for item in xrange(max_retries):
-            res = self.c.compound([op.create_session(self.clientid, self.seqid,
+            res = self.c.compound([op4.create_session(self.clientid, self.seqid,
                                                  flags,
                                                  fore_attrs, back_attrs,
                                                  prog, sec)],
@@ -429,7 +431,7 @@ class SessionRecord(object):
             raise RuntimeError
             slot = self.fore_channel.slots[slot]
         # STUB, need to properly set highest
-        return op.sequence(self.sessionid, slot.get_seqid(seq_delta),
+        return op4.sequence(self.sessionid, slot.get_seqid(seq_delta),
                            slot.id, slot.id, cache_this)
 
     def set_ssv(self, ssv=None, *args, **kwargs):
@@ -442,7 +444,7 @@ class SessionRecord(object):
         p = nfs4lib.FancyNFS4Packer()
         p.pack_SEQUENCE4args(seq_op.opsequence)
         digest =  protect.context.hmac(p.get_buffer(), SSV4_SUBKEY_MIC_I2T)
-        ssv_op = op.set_ssv(ssv, digest)
+        ssv_op = op4.set_ssv(ssv, digest)
         res = self.c.compound([seq_op, ssv_op], *args, **kwargs)
         # STUB - do some checking
         protect.context.set_ssv(ssv)
diff --git a/nfs4.1/nfs4lib.py b/nfs4.1/nfs4lib.py
index 116324a..02352e1 100644
--- a/nfs4.1/nfs4lib.py
+++ b/nfs4.1/nfs4lib.py
@@ -3,7 +3,7 @@ import rpc
 import xdrdef.nfs4_const
 from xdrdef.nfs4_pack import NFS4Packer, NFS4Unpacker
 import xdrdef.nfs4_type
-import nfs4_ops as op
+import nfs_ops
 import time
 import collections
 import hmac
@@ -30,6 +30,8 @@ state01 = xdrdef.nfs4_type.stateid4(1, "\0" * 12)
 
 import hashlib # Note this requires 2.5 or higher
 
+op4 = nfs_ops.NFS4ops()
+
 # Note that all the oid strings have tag and length bytes prepended, as
 # per description of sec_oid4 in draft26 sect 3.2
 
@@ -626,9 +628,9 @@ def use_obj(file):
     if file is None or file == [None]:
         return []
     elif type(file) is str:
-        return [op.putfh(file)]
+        return [op4.putfh(file)]
     else:
-        return [op.putrootfh()] + [op.lookup(comp) for comp in file]
+        return [op4.putrootfh()] + [op4.lookup(comp) for comp in file]
 
 ###############################################
 # Attribute information
diff --git a/nfs4.1/nfs4state.py b/nfs4.1/nfs4state.py
index 2f3cd59..2214c0d 100644
--- a/nfs4.1/nfs4state.py
+++ b/nfs4.1/nfs4state.py
@@ -8,12 +8,14 @@ from nfs4lib import NFS4Error
 #from xdrdef.nfs4_type import stateid4
 from xdrdef.nfs4_type import *
 from xdrdef.nfs4_const import *
-import nfs4_ops as op
+import nfs_ops
 import rpc
 import logging
 
 log = logging.getLogger("nfs.server.state")
 
+op4 = nfs_ops.NFS4ops()
+
 POSIXLOCK = False
 
 SHARE, BYTE, DELEG, LAYOUT, ANON = range(5) # State types
@@ -748,9 +750,9 @@ class DelegEntry(StateTableEntry):
         # ANSWER - we care about self.status, which can be set to 
         # INVALID anytime by deleg_return
         slot = session.channel_back.choose_slot()
-        seq_op = op.cb_sequence(session.sessionid, slot.get_seqid(),
+        seq_op = op4.cb_sequence(session.sessionid, slot.get_seqid(),
                                 slot.id, slot.id, True, []) # STUB
-        recall_op = op.cb_recall(self.get_id(cb=True), False, self.file.fh)
+        recall_op = op4.cb_recall(self.get_id(cb=True), False, self.file.fh)
         if self.invalid:
             # Race here doesn't matter, but would like to avoid the
             # RPC if possible.
diff --git a/nfs4.1/nfs_ops.py b/nfs4.1/nfs_ops.py
new file mode 100644
index 0000000..0753716
--- /dev/null
+++ b/nfs4.1/nfs_ops.py
@@ -0,0 +1,89 @@
+"""For each OP_<NAME> in nfs_argop4 and nfs_cb_argop4, create a function
+<name>() that returns the appropriate *_argop4 structure, hiding
+this routine packing from the user.
+"""
+
+from xdrdef import nfs4_type
+from xdrdef import nfs4_const
+
+from xdrdef import nfs3_type
+from xdrdef import nfs3_const
+
+def nfs4_op_names():
+    skip = len('OP_')
+    ops = [ x.lower()[skip:] for x in nfs4_const.nfs_opnum4.values() ]
+    ops.extend([ x.lower()[skip:] for x in nfs4_const.nfs_cb_opnum4.values()])
+    return ops
+
+def nfs3_proc_names():
+    pre = 'NFSPROC3_'
+    skip = len(pre)
+    procs = [ x.lower()[skip:] for x in dir(nfs3_const) if x.startswith(pre) ]
+    return procs
+
+class NFSops:
+    def __init__(self, is_v4):
+        self._is_v4 = is_v4
+        if is_v4:
+            self._op_names = nfs4_op_names()
+            self._type = nfs4_type
+            self._const = nfs4_const
+            self._args_suffix = '4args'
+            self._op_prefix = 'OP_'
+        else:
+            self._op_names = nfs3_proc_names()
+            self._type = nfs3_type
+            self._const = nfs3_const
+            self._args_suffix = '3args'
+            self._op_prefix = 'NFSPROC3_'
+
+    def __getattr__(self, attrname):
+        if attrname in self._op_names:
+            return lambda *args: self._handle_op(attrname, args)
+
+    def _handle_op(self, opname, args):
+        enum_name = opname.upper()
+
+        # RPC "args" class to create
+        class_name = "%s%s" % (enum_name, self._args_suffix)
+        klass = getattr(self._type, class_name, None)
+
+        if self._is_v4:
+            # stuff class into argop
+
+            # args to pass to argop __init__
+            opnum = getattr(self._const, self._op_prefix + enum_name)
+            kwargs = {}
+
+            if klass:
+                # otherwise it takes no arguments
+                if type(klass) is dict:
+                    assert len(args) == 1
+                    arg = args[0]
+                else:
+                    arg = klass(*args)
+
+                if enum_name.startswith("CB_"):
+                    kwargs['opcb%s' % enum_name.lower()] = arg
+                else:
+                    kwargs['op%s' % enum_name.lower()] = arg
+
+            if enum_name.startswith("CB_"):
+                argop = self._type.nfs_cb_argop4
+            else:
+                argop = self._type.nfs_argop4
+
+            return argop(opnum, **kwargs)
+
+        else:
+            # for v3 just return an instance
+            return klass(*args)
+
+class NFS3ops(NFSops):
+    def __init__(self):
+        NFSops.__init__(self, False)
+
+class NFS4ops(NFSops):
+    def __init__(self):
+        NFSops.__init__(self, True)
+
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 11/16] add mntv3, portmapv2 and nfsv3 .x files
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (9 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 10/16] 4.1 server: move nfs4_ops.py to nfs_ops.py Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 12/16] dataserver: separate generic and 4.1 code Weston Andros Adamson
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

mntv3 and nfsv3 .x files made from IETF specs by Tom Haynes
<thomas.haynes@primarydata.com>.

portmap2 .x files made from IETF specs by Weston Andros Adamson
<dros@primarydata.com>.

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/xdrdef/mnt3.x    |  68 ++++
 nfs4.1/xdrdef/nfs3.x    | 818 ++++++++++++++++++++++++++++++++++++++++++++++++
 nfs4.1/xdrdef/portmap.x |  51 +++
 3 files changed, 937 insertions(+)
 create mode 100644 nfs4.1/xdrdef/mnt3.x
 create mode 100644 nfs4.1/xdrdef/nfs3.x
 create mode 100644 nfs4.1/xdrdef/portmap.x

diff --git a/nfs4.1/xdrdef/mnt3.x b/nfs4.1/xdrdef/mnt3.x
new file mode 100644
index 0000000..b632322
--- /dev/null
+++ b/nfs4.1/xdrdef/mnt3.x
@@ -0,0 +1,68 @@
+const MNTPATHLEN = 1024;   /* Maximum bytes in a path name */
+const MNTNAMLEN = 255;     /* Maximum bytes in a name */
+const FHSIZE3 = 64;        /* Maximum bytes in a V3 file handle */
+
+typedef opaque  fhandle3 <FHSIZE3>;
+typedef string  dirpath <MNTPATHLEN>;
+typedef string  name <MNTNAMLEN>;
+
+struct mountres3_ok {
+        fhandle3        fhandle;
+        int             auth_flavors <>;
+};
+
+union mountres3 switch (mountstat3 fhs_status) {
+case MNT3_OK:
+        mountres3_ok mountinfo;
+default:
+        void;
+};
+
+struct mountbody {
+        name            ml_hostname;
+        dirpath         ml_directory;
+        mountlist       ml_next;
+};
+
+typedef mountbody *mountlist;
+
+
+struct groupnode {
+        name            gr_name;
+        groups          gr_next;
+};
+
+typedef groupnode *groups;
+
+
+struct exportnode {
+        dirpath         ex_dir;
+        groups          ex_groups;
+        exports         ex_next;
+};
+
+typedef exportnode *exports;
+
+enum mountstat3 {
+        MNT3_OK = 0,                     /* no error */
+        MNT3ERR_PERM = 1,                /* Not owner */
+        MNT3ERR_NOENT = 2,               /* No such file or directory */
+        MNT3ERR_IO = 5,                  /* I/O error */
+        MNT3ERR_ACCES = 13,              /* Permission denied */
+        MNT3ERR_NOTDIR = 20,             /* Not a directory */
+        MNT3ERR_INVAL = 22,              /* Invalid argument */
+        MNT3ERR_NAMETOOLONG = 63,        /* Filename too long */
+        MNT3ERR_NOTSUPP = 10004,         /* Operation not supported */
+        MNT3ERR_SERVERFAULT = 10006      /* A failure on the server */
+};
+
+program MOUNT_PROGRAM {
+        version MOUNT_V3 {
+                void            MOUNTPROC3_NULL(void) = 0;
+                mountres3       MOUNTPROC3_MNT(dirpath) = 1;
+                mountlist       MOUNTPROC3_DUMP(void) = 2;
+                void            MOUNTPROC3_UMNT(dirpath) = 3;
+                void            MOUNTPROC3_UMNTALL(void) = 4;
+                exports         MOUNTPROC3_EXPORT(void) = 5;
+        } = 3;
+} = 100005;
diff --git a/nfs4.1/xdrdef/nfs3.x b/nfs4.1/xdrdef/nfs3.x
new file mode 100644
index 0000000..ddd1395
--- /dev/null
+++ b/nfs4.1/xdrdef/nfs3.x
@@ -0,0 +1,818 @@
+const NFS3_FHSIZE = 64;        /* Maximum bytes in a V3 file handle */
+
+const FALSE = 0;
+const TRUE = 1;
+
+const NFS3_COOKIEVERFSIZE = 8;
+const NFS3_CREATEVERFSIZE = 8;
+const NFS3_WRITEVERFSIZE = 8;
+
+typedef unsigned hyper uint64;
+typedef hyper   int64;
+typedef unsigned int uint32;
+typedef int    int32;
+typedef string  filename3 <>;
+typedef string  nfspath3 <>;
+typedef uint64  fileid3;
+typedef uint64  cookie3;
+typedef opaque  cookieverf3[NFS3_COOKIEVERFSIZE];
+typedef opaque  createverf3[NFS3_CREATEVERFSIZE];
+typedef opaque  writeverf3[NFS3_WRITEVERFSIZE];
+typedef uint32  uid3;
+typedef uint32  gid3;
+typedef uint64  size3;
+typedef uint64  offset3;
+typedef uint32  mode3;
+typedef uint32  count3;
+
+enum nfsstat3 {
+        NFS3_OK = 0,
+        NFS3ERR_PERM = 1,
+        NFS3ERR_NOENT = 2,
+        NFS3ERR_IO = 5,
+        NFS3ERR_NXIO = 6,
+        NFS3ERR_ACCES = 13,
+        NFS3ERR_EXIST = 17,
+        NFS3ERR_XDEV = 18,
+        NFS3ERR_NODEV = 19,
+        NFS3ERR_NOTDIR = 20,
+        NFS3ERR_ISDIR = 21,
+        NFS3ERR_INVAL = 22,
+        NFS3ERR_FBIG = 27,
+        NFS3ERR_NOSPC = 28,
+        NFS3ERR_ROFS = 30,
+        NFS3ERR_MLINK = 31,
+        NFS3ERR_NAMETOOLONG = 63,
+        NFS3ERR_NOTEMPTY = 66,
+        NFS3ERR_DQUOT = 69,
+        NFS3ERR_STALE = 70,
+        NFS3ERR_REMOTE = 71,
+        NFS3ERR_BADHANDLE = 10001,
+        NFS3ERR_NOT_SYNC = 10002,
+        NFS3ERR_BAD_COOKIE = 10003,
+        NFS3ERR_NOTSUPP = 10004,
+        NFS3ERR_TOOSMALL = 10005,
+        NFS3ERR_SERVERFAULT = 10006,
+        NFS3ERR_BADTYPE = 10007,
+        NFS3ERR_JUKEBOX = 10008
+};
+
+enum ftype3 {
+        NF3REG = 1,
+        NF3DIR = 2,
+        NF3BLK = 3,
+        NF3CHR = 4,
+        NF3LNK = 5,
+        NF3SOCK = 6,
+        NF3FIFO = 7
+};
+
+struct specdata3 {
+        uint32          specdata1;
+        uint32          specdata2;
+};
+
+struct nfs_fh3 {
+        opaque          data <NFS3_FHSIZE>;
+};
+
+struct nfstime3 {
+        uint32          seconds;
+        uint32          nseconds;
+};
+
+struct fattr3 {
+        ftype3          type;
+        mode3           mode;
+        uint32          nlink;
+        uid3            uid;
+        gid3            gid;
+        size3           size;
+        size3           used;
+        specdata3       rdev;
+        uint64          fsid;
+        fileid3         fileid;
+        nfstime3        atime;
+        nfstime3        mtime;
+        nfstime3        ctime;
+};
+
+union post_op_attr switch (bool attributes_follow) {
+case TRUE:
+        fattr3 attributes;
+case FALSE:
+        void;
+};
+
+struct wcc_attr {
+        size3           size;
+        nfstime3        mtime;
+        nfstime3        ctime;
+};
+
+union pre_op_attr switch (bool attributes_follow) {
+case TRUE:
+        wcc_attr attributes;
+case FALSE:
+        void;
+};
+
+struct wcc_data {
+        pre_op_attr     before;
+        post_op_attr    after;
+};
+
+union post_op_fh3 switch (bool handle_follows) {
+case TRUE:
+        nfs_fh3 handle;
+case FALSE:
+        void;
+};
+
+enum time_how {
+        DONT_CHANGE = 0,
+        SET_TO_SERVER_TIME = 1,
+        SET_TO_CLIENT_TIME = 2
+};
+
+union set_mode3 switch (bool set_it) {
+case TRUE:
+        mode3 mode;
+default:
+        void;
+};
+
+union set_uid3 switch (bool set_it) {
+case TRUE:
+        uid3 uid;
+default:
+        void;
+};
+
+union set_gid3 switch (bool set_it) {
+case TRUE:
+        gid3 gid;
+default:
+        void;
+};
+
+union set_size3 switch (bool set_it) {
+case TRUE:
+        size3 size;
+default:
+        void;
+};
+
+union set_atime switch (time_how set_it) {
+case SET_TO_CLIENT_TIME:
+        nfstime3 atime;
+default:
+        void;
+};
+
+union set_mtime switch (time_how set_it) {
+case SET_TO_CLIENT_TIME:
+        nfstime3 mtime;
+default:
+        void;
+};
+
+struct sattr3 {
+        set_mode3       mode;
+        set_uid3        uid;
+        set_gid3        gid;
+        set_size3       size;
+        set_atime       atime;
+        set_mtime       mtime;
+};
+
+struct diropargs3 {
+        nfs_fh3         dir;
+        filename3       name;
+};
+
+struct GETATTR3args {
+        nfs_fh3         object;
+};
+
+struct GETATTR3resok {
+        fattr3          obj_attributes;
+};
+
+union GETATTR3res switch (nfsstat3 status) {
+case NFS3_OK:
+        GETATTR3resok resok;
+default:
+        void;
+};
+
+union sattrguard3 switch (bool check) {
+case TRUE:
+        nfstime3 obj_ctime;
+case FALSE:
+        void;
+};
+
+struct SETATTR3args {
+        nfs_fh3         object;
+        sattr3          new_attributes;
+        sattrguard3     guard;
+};
+
+struct SETATTR3resok {
+        wcc_data        obj_wcc;
+};
+
+struct SETATTR3resfail {
+        wcc_data        obj_wcc;
+};
+
+union SETATTR3res switch (nfsstat3 status) {
+case NFS3_OK:
+        SETATTR3resok resok;
+default:
+        SETATTR3resfail resfail;
+};
+
+struct LOOKUP3args {
+        diropargs3      what;
+};
+
+struct LOOKUP3resok {
+        nfs_fh3         object;
+        post_op_attr    obj_attributes;
+        post_op_attr    dir_attributes;
+};
+
+struct LOOKUP3resfail {
+        post_op_attr    dir_attributes;
+};
+
+union LOOKUP3res switch (nfsstat3 status) {
+case NFS3_OK:
+        LOOKUP3resok resok;
+default:
+        LOOKUP3resfail resfail;
+};
+
+const           ACCESS3_READ = 0x0001;
+const           ACCESS3_LOOKUP = 0x0002;
+const           ACCESS3_MODIFY = 0x0004;
+const           ACCESS3_EXTEND = 0x0008;
+const           ACCESS3_DELETE = 0x0010;
+const           ACCESS3_EXECUTE = 0x0020;
+
+struct ACCESS3args {
+        nfs_fh3         object;
+        uint32          access;
+};
+
+struct ACCESS3resok {
+        post_op_attr    obj_attributes;
+        uint32          access;
+};
+
+struct ACCESS3resfail {
+        post_op_attr    obj_attributes;
+};
+
+union ACCESS3res switch (nfsstat3 status) {
+case NFS3_OK:
+        ACCESS3resok resok;
+default:
+        ACCESS3resfail resfail;
+};
+
+struct READLINK3args {
+        nfs_fh3         symlink;
+};
+
+struct READLINK3resok {
+        post_op_attr    symlink_attributes;
+        nfspath3        data;
+};
+
+struct READLINK3resfail {
+        post_op_attr    symlink_attributes;
+};
+
+union READLINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+        READLINK3resok resok;
+default:
+        READLINK3resfail resfail;
+};
+
+struct READ3args {
+        nfs_fh3         file;
+        offset3         offset;
+        count3          count;
+};
+
+struct READ3resok {
+        post_op_attr    file_attributes;
+        count3          count;
+        bool            eof;
+        opaque          data <>;
+};
+
+struct READ3resfail {
+        post_op_attr    file_attributes;
+};
+
+union READ3res switch (nfsstat3 status) {
+case NFS3_OK:
+        READ3resok resok;
+default:
+        READ3resfail resfail;
+};
+
+enum stable_how {
+        UNSTABLE = 0,
+        DATA_SYNC = 1,
+        FILE_SYNC = 2
+};
+
+struct WRITE3args {
+        nfs_fh3         file;
+        offset3         offset;
+        count3          count;
+        stable_how      stable;
+        opaque          data <>;
+};
+
+struct WRITE3resok {
+        wcc_data        file_wcc;
+        count3          count;
+        stable_how      committed;
+        writeverf3      verf;
+};
+
+struct WRITE3resfail {
+        wcc_data        file_wcc;
+};
+
+union WRITE3res switch (nfsstat3 status) {
+case NFS3_OK:
+        WRITE3resok resok;
+default:
+        WRITE3resfail resfail;
+};
+
+enum createmode3 {
+        UNCHECKED = 0,
+        GUARDED = 1,
+        EXCLUSIVE = 2
+};
+
+union createhow3 switch (createmode3 mode) {
+case UNCHECKED:
+case GUARDED:
+        sattr3 obj_attributes;
+case EXCLUSIVE:
+        createverf3 verf;
+};
+
+struct CREATE3args {
+        diropargs3      where;
+        createhow3      how;
+};
+
+struct CREATE3resok {
+        post_op_fh3     obj;
+        post_op_attr    obj_attributes;
+        wcc_data        dir_wcc;
+};
+
+struct CREATE3resfail {
+        wcc_data        dir_wcc;
+};
+
+union CREATE3res switch (nfsstat3 status) {
+case NFS3_OK:
+        CREATE3resok resok;
+default:
+        CREATE3resfail resfail;
+};
+
+struct MKDIR3args {
+        diropargs3      where;
+        sattr3          attributes;
+};
+
+struct MKDIR3resok {
+        post_op_fh3     obj;
+        post_op_attr    obj_attributes;
+        wcc_data        dir_wcc;
+};
+
+struct MKDIR3resfail {
+        wcc_data        dir_wcc;
+};
+
+union MKDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+        MKDIR3resok resok;
+default:
+        MKDIR3resfail resfail;
+};
+
+struct symlinkdata3 {
+        sattr3          symlink_attributes;
+        nfspath3        symlink_data;
+};
+
+struct SYMLINK3args {
+        diropargs3      where;
+        symlinkdata3    symlink;
+};
+
+struct SYMLINK3resok {
+        post_op_fh3     obj;
+        post_op_attr    obj_attributes;
+        wcc_data        dir_wcc;
+};
+
+struct SYMLINK3resfail {
+        wcc_data        dir_wcc;
+};
+
+union SYMLINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+        SYMLINK3resok resok;
+default:
+        SYMLINK3resfail resfail;
+};
+
+struct devicedata3 {
+        sattr3          dev_attributes;
+        specdata3       spec;
+};
+
+union mknoddata3 switch (ftype3 type) {
+case NF3CHR:
+case NF3BLK:
+        devicedata3 device;
+case NF3SOCK:
+case NF3FIFO:
+        sattr3 pipe_attributes;
+default:
+        void;
+};
+
+struct MKNOD3args {
+        diropargs3      where;
+        mknoddata3      what;
+};
+
+struct MKNOD3resok {
+        post_op_fh3     obj;
+        post_op_attr    obj_attributes;
+        wcc_data        dir_wcc;
+};
+
+struct MKNOD3resfail {
+        wcc_data        dir_wcc;
+};
+
+union MKNOD3res switch (nfsstat3 status) {
+case NFS3_OK:
+        MKNOD3resok resok;
+default:
+        MKNOD3resfail resfail;
+};
+
+struct REMOVE3args {
+        diropargs3      object;
+};
+
+struct REMOVE3resok {
+        wcc_data        dir_wcc;
+};
+
+struct REMOVE3resfail {
+        wcc_data        dir_wcc;
+};
+
+union REMOVE3res switch (nfsstat3 status) {
+case NFS3_OK:
+        REMOVE3resok resok;
+default:
+        REMOVE3resfail resfail;
+};
+
+struct RMDIR3args {
+        diropargs3      object;
+};
+
+struct RMDIR3resok {
+        wcc_data        dir_wcc;
+};
+
+struct RMDIR3resfail {
+        wcc_data        dir_wcc;
+};
+
+union RMDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+        RMDIR3resok resok;
+default:
+        RMDIR3resfail resfail;
+};
+
+struct RENAME3args {
+        diropargs3      fromfile;
+        diropargs3      tofile;
+};
+
+struct RENAME3resok {
+        wcc_data        fromdir_wcc;
+        wcc_data        todir_wcc;
+};
+
+struct RENAME3resfail {
+        wcc_data        fromdir_wcc;
+        wcc_data        todir_wcc;
+};
+
+union RENAME3res switch (nfsstat3 status) {
+case NFS3_OK:
+        RENAME3resok resok;
+default:
+        RENAME3resfail resfail;
+};
+
+struct LINK3args {
+        nfs_fh3         file;
+        diropargs3      link;
+};
+
+struct LINK3resok {
+        post_op_attr    file_attributes;
+        wcc_data        linkdir_wcc;
+};
+
+struct LINK3resfail {
+        post_op_attr    file_attributes;
+        wcc_data        linkdir_wcc;
+};
+
+union LINK3res switch (nfsstat3 status) {
+case NFS3_OK:
+        LINK3resok resok;
+default:
+        LINK3resfail resfail;
+};
+
+struct READDIR3args {
+        nfs_fh3         dir;
+        cookie3         cookie;
+        cookieverf3     cookieverf;
+        count3          count;
+};
+
+struct entry3 {
+        fileid3         fileid;
+        filename3       name;
+        cookie3         cookie;
+        entry3         *nextentry;
+};
+
+struct dirlist3 {
+        entry3         *entries;
+        bool            eof;
+};
+
+struct READDIR3resok {
+        post_op_attr    dir_attributes;
+        cookieverf3     cookieverf;
+        dirlist3        reply;
+};
+
+struct READDIR3resfail {
+        post_op_attr    dir_attributes;
+};
+
+union READDIR3res switch (nfsstat3 status) {
+case NFS3_OK:
+        READDIR3resok resok;
+default:
+        READDIR3resfail resfail;
+};
+
+struct READDIRPLUS3args {
+        nfs_fh3         dir;
+        cookie3         cookie;
+        cookieverf3     cookieverf;
+        count3          dircount;
+        count3          maxcount;
+};
+
+struct entryplus3 {
+        fileid3         fileid;
+        filename3       name;
+        cookie3         cookie;
+        post_op_attr    name_attributes;
+        post_op_fh3     name_handle;
+        entryplus3     *nextentry;
+};
+
+struct dirlistplus3 {
+        entryplus3     *entries;
+        bool            eof;
+};
+
+struct READDIRPLUS3resok {
+        post_op_attr    dir_attributes;
+        cookieverf3     cookieverf;
+        dirlistplus3    reply;
+};
+
+struct READDIRPLUS3resfail {
+        post_op_attr    dir_attributes;
+};
+
+union READDIRPLUS3res switch (nfsstat3 status) {
+case NFS3_OK:
+        READDIRPLUS3resok resok;
+default:
+        READDIRPLUS3resfail resfail;
+};
+
+struct FSSTAT3args {
+        nfs_fh3         fsroot;
+};
+
+struct FSSTAT3resok {
+        post_op_attr    obj_attributes;
+        size3           tbytes;
+        size3           fbytes;
+        size3           abytes;
+        size3           tfiles;
+        size3           ffiles;
+        size3           afiles;
+        uint32          invarsec;
+};
+
+struct FSSTAT3resfail {
+        post_op_attr    obj_attributes;
+};
+
+union FSSTAT3res switch (nfsstat3 status) {
+case NFS3_OK:
+        FSSTAT3resok resok;
+default:
+        FSSTAT3resfail resfail;
+};
+
+const           FSF3_LINK = 0x0001;
+const           FSF3_SYMLINK = 0x0002;
+const           FSF3_HOMOGENEOUS = 0x0008;
+const           FSF3_CANSETTIME = 0x0010;
+
+struct FSINFOargs {
+        nfs_fh3         fsroot;
+};
+
+struct FSINFO3resok {
+        post_op_attr    obj_attributes;
+        uint32          rtmax;
+        uint32          rtpref;
+        uint32          rtmult;
+        uint32          wtmax;
+        uint32          wtpref;
+        uint32          wtmult;
+        uint32          dtpref;
+        size3           maxfilesize;
+        nfstime3        time_delta;
+        uint32          properties;
+};
+
+struct FSINFO3resfail {
+        post_op_attr    obj_attributes;
+};
+
+union FSINFO3res switch (nfsstat3 status) {
+case NFS3_OK:
+        FSINFO3resok resok;
+default:
+        FSINFO3resfail resfail;
+};
+
+struct PATHCONF3args {
+        nfs_fh3         object;
+};
+
+struct PATHCONF3resok {
+        post_op_attr    obj_attributes;
+        uint32          linkmax;
+        uint32          name_max;
+        bool            no_trunc;
+        bool            chown_restricted;
+        bool            case_insensitive;
+        bool            case_preserving;
+};
+
+struct PATHCONF3resfail {
+        post_op_attr    obj_attributes;
+};
+
+union PATHCONF3res switch (nfsstat3 status) {
+case NFS3_OK:
+        PATHCONF3resok resok;
+default:
+        PATHCONF3resfail resfail;
+};
+
+struct COMMIT3args {
+        nfs_fh3         file;
+        offset3         offset;
+        count3          count;
+};
+
+struct COMMIT3resok {
+        wcc_data        file_wcc;
+        writeverf3      verf;
+};
+
+struct COMMIT3resfail {
+        wcc_data        file_wcc;
+};
+
+union COMMIT3res switch (nfsstat3 status) {
+case NFS3_OK:
+        COMMIT3resok resok;
+default:
+        COMMIT3resfail resfail;
+};
+
+program         NFS_PROGRAM {
+        version         NFS_V3 {
+
+                void
+                NFSPROC3_NULL(void) = 0;
+
+                GETATTR3res
+                NFSPROC3_GETATTR(GETATTR3args) = 1;
+
+                SETATTR3res
+                NFSPROC3_SETATTR(SETATTR3args) = 2;
+
+                LOOKUP3res
+                NFSPROC3_LOOKUP(LOOKUP3args) = 3;
+
+                ACCESS3res
+                NFSPROC3_ACCESS(ACCESS3args) = 4;
+
+                READLINK3res
+                NFSPROC3_READLINK(READLINK3args) = 5;
+
+                READ3res
+                NFSPROC3_READ(READ3args) = 6;
+
+                WRITE3res
+                NFSPROC3_WRITE(WRITE3args) = 7;
+
+                CREATE3res
+                NFSPROC3_CREATE(CREATE3args) = 8;
+
+                MKDIR3res
+                NFSPROC3_MKDIR(MKDIR3args) = 9;
+
+                SYMLINK3res
+                NFSPROC3_SYMLINK(SYMLINK3args) = 10;
+
+                MKNOD3res
+                NFSPROC3_MKNOD(MKNOD3args) = 11;
+
+                REMOVE3res
+                NFSPROC3_REMOVE(REMOVE3args) = 12;
+
+                RMDIR3res
+                NFSPROC3_RMDIR(RMDIR3args) = 13;
+
+                RENAME3res
+                NFSPROC3_RENAME(RENAME3args) = 14;
+
+                LINK3res
+                NFSPROC3_LINK(LINK3args) = 15;
+
+                READDIR3res
+                NFSPROC3_READDIR(READDIR3args) = 16;
+
+                READDIRPLUS3res
+                NFSPROC3_READDIRPLUS(READDIRPLUS3args) = 17;
+
+                FSSTAT3res
+                NFSPROC3_FSSTAT(FSSTAT3args) = 18;
+
+                FSINFO3res
+                NFSPROC3_FSINFO(FSINFO3args) = 19;
+
+                PATHCONF3res
+                NFSPROC3_PATHCONF(PATHCONF3args) = 20;
+
+                COMMIT3res
+                NFSPROC3_COMMIT(COMMIT3args) = 21;
+        } = 3;
+} = 100003;
diff --git a/nfs4.1/xdrdef/portmap.x b/nfs4.1/xdrdef/portmap.x
new file mode 100644
index 0000000..1158d4e
--- /dev/null
+++ b/nfs4.1/xdrdef/portmap.x
@@ -0,0 +1,51 @@
+const PMAP_PORT = 111;      /* portmapper port number */
+
+struct mapping {
+	unsigned int prog;
+	unsigned int vers;
+	unsigned int prot;
+	unsigned int port;
+};
+
+const IPPROTO_TCP = 6;      /* protocol number for TCP/IP */
+const IPPROTO_UDP = 17;     /* protocol number for UDP/IP */
+
+struct pmaplist {
+	mapping map;
+	pmaplist next;
+};
+
+struct call_args {
+	unsigned int prog;
+	unsigned int vers;
+	unsigned int proc;
+	opaque args<>;
+};
+
+struct call_result {
+	unsigned int port;
+	opaque res<>;
+};
+
+program PMAP_PROG {
+	version PMAP_VERS {
+		void
+		PMAPPROC_NULL(void)         = 0;
+
+		bool
+		PMAPPROC_SET(mapping)       = 1;
+
+		bool
+		PMAPPROC_UNSET(mapping)     = 2;
+
+		unsigned int
+		PMAPPROC_GETPORT(mapping)   = 3;
+
+		pmaplist
+		PMAPPROC_DUMP(void)         = 4;
+
+		call_result
+		PMAPPROC_CALLIT(call_args)  = 5;
+	} = 2;
+} = 100000;
+
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 12/16] dataserver: separate generic and 4.1 code
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (10 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 11/16] add mntv3, portmapv2 and nfsv3 .x files Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 13/16] 4.1 server: add support for NFSv3 data servers Weston Andros Adamson
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/dataserver.py | 102 ++++++++++++++++++++++++++++-----------------------
 1 file changed, 57 insertions(+), 45 deletions(-)

diff --git a/nfs4.1/dataserver.py b/nfs4.1/dataserver.py
index d092cf7..5c604dc 100644
--- a/nfs4.1/dataserver.py
+++ b/nfs4.1/dataserver.py
@@ -15,7 +15,7 @@ log = logging.getLogger("Dataserver Manager")
 
 op4 = nfs_ops.NFS4ops()
 
-class DataServer41(object):
+class DataServer(object):
     def __init__(self, server, port, path, flavor=rpc.AUTH_SYS, active=True, mdsds=True, multipath_servers=None, summary=None):
         self.mdsds = mdsds
         self.server = server
@@ -43,29 +43,47 @@ class DataServer41(object):
         self.active = True
         if not self.mdsds:
             self.connect()
+            self.make_root()
 
     def down(self):
+        self.disconnect()
         self.active = False
 
+    def reset(self):
+        self.down()
+        self.up()
+
+    def get_netaddr4(self):
+        # STUB server multipathing not supported yet
+        uaddr = '.'.join([self.server,
+                          str(self.port >> 8),
+                          str(self.port & 0xff)])
+        return type4.netaddr4(self.proto, uaddr)
+
+    def get_multipath_netaddr4s(self):
+        netaddr4s = []
+        for addr in self.multipath_servers:
+            server, port = addr
+            uaddr = '.'.join([server,
+                            str(port >> 8),
+                            str(port & 0xff)])
+            proto = "tcp"
+            if server.find(':') >= 0:
+                proto = "tcp6"
+
+            netaddr4s.append(type4.netaddr4(proto, uaddr))
+        return netaddr4s
+
+    def fh_to_name(self, mds_fh):
+        return hashlib.sha1("%r" % mds_fh).hexdigest()
+
     def connect(self):
-        # only support root with AUTH_SYS for now
-        s1 = rpc.security.instance(rpc.AUTH_SYS)
-        self.cred1 = s1.init_cred(uid=0, gid=0)
-        self.c1 = nfs4client.NFS4Client(self.server, self.port,
-                                        summary=self.summary)
-        self.c1.set_cred(self.cred1)
-        self.c1.null()
-        c = self.c1.new_client("DS.init_%s" % self.server)
-        # This is a hack to ensure MDS/DS communication path is at least
-        # as wide as the client/MDS channel (at least for linux client)
-        fore_attrs = type4.channel_attrs4(0, 16384, 16384, 2868, 8, 8, [])
-        self.sess = c.create_session(fore_attrs=fore_attrs)
-        sess.compound([op.reclaim_complete(FALSE)])
-        self.make_root()
+        raise NotImplemented
 
     def disconnect(self):
         pass
 
+class DataServer41(DataServer):
     def _execute(self, ops, exceptions=[], delay=5, maxretries=3):
         """ execute the NFS call
         If an error code is specified in the exceptions it means that the
@@ -86,36 +104,29 @@ class DataServer41(object):
                     log.error("Too many retries with DS %s" % self.server)
                     raise Exception("Dataserver communication retry error")
             elif res.status in state_errors:
-                self.disconnect()
-                self.connect()
+                self.reset()
             else:
                 log.error("Unhandled status %s from DS %s" %
                           (nfsstat4[res.status], self.server))
                 raise Exception("Dataserver communication error")
 
-    def get_netaddr4(self):
-        # STUB server multipathing not supported yet
-        uaddr = '.'.join([self.server,
-                          str(self.port >> 8),
-                          str(self.port & 0xff)])
-        return type4.netaddr4(self.proto, uaddr)
-
-    def get_multipath_netaddr4s(self):
-        netaddr4s = []
-        for addr in self.multipath_servers:
-            server, port = addr
-            uaddr = '.'.join([server,
-                            str(port >> 8),
-                            str(port & 0xff)])
-            proto = "tcp"
-            if server.find(':') >= 0:
-                proto = "tcp6"
-
-            netaddr4s.append(type4.netaddr4(proto, uaddr))
-        return netaddr4s
-
+    def connect(self):
+        # only support root with AUTH_SYS for now
+        s1 = rpc.security.instance(rpc.AUTH_SYS)
+        self.cred1 = s1.init_cred(uid=0, gid=0)
+        self.c1 = nfs4client.NFS4Client(self.server, self.port,
+                                        summary=self.summary)
+        self.c1.set_cred(self.cred1)
+        self.c1.null()
+        c = self.c1.new_client("DS.init_%s" % self.server)
+        # This is a hack to ensure MDS/DS communication path is at least
+        # as wide as the client/MDS channel (at least for linux client)
+        fore_attrs = type4.channel_attrs4(0, 16384, 16384, 2868, 8, 8, [])
+        self.sess = c.create_session(fore_attrs=fore_attrs)
+        self.sess.compound([op4.reclaim_complete(const4.FALSE)])
 
-    def make_root(self, attrs={const4.FATTR4_MODE:0777}):
+    def make_root(self):
+        attrs = {const4.FATTR4_MODE:0777}
         existing_path = []
         kind = type4.createtype4(const4.NF4DIR)
         for comp in self.path:
@@ -134,12 +145,13 @@ class DataServer41(object):
             raise RuntimeError
         # XXX clean DS directory
 
-    def fh_to_name(self, mds_fh):
-        return hashlib.sha1("%r" % mds_fh).hexdigest()
-
-    def open_file(self, mds_fh, seqid=0,
-                  access=const4.OPEN4_SHARE_ACCESS_BOTH, deny=const4.OPEN4_SHARE_DENY_NONE,
-                  attrs={const4.FATTR4_MODE: 0777}, owner = "mds", mode=const4.GUARDED4):
+    def open_file(self, mds_fh):
+        seqid=0
+        access = const4.OPEN4_SHARE_ACCESS_BOTH
+        deny = const4.OPEN4_SHARE_DENY_NONE
+        attrs = {const4.FATTR4_MODE: 0777}
+        owner = "mds"
+        mode = const4.GUARDED4
         verifier = self.sess.c.verifier
         openflag = type4.openflag4(const4.OPEN4_CREATE, type4.createhow4(mode, attrs, verifier))
         name = self.fh_to_name(mds_fh)
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 13/16] 4.1 server: add support for NFSv3 data servers
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (11 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 12/16] dataserver: separate generic and 4.1 code Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 14/16] 4.1 server: get rid of old op_getdeviceinfo Weston Andros Adamson
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

Add the NFSv3 client and a new DataServer class that handles DS ops
using the v3 client.

DataServer3 is not used yet, as it requires flexfile layouts in order
to pass a v3 DS to clients.

Tested with linux client mounting pnfs MDS via v4.1 (disabling pnfs)
and a linux server acting as the v3 DS.

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/dataserver.py | 100 ++++++++++++++++++++++++++++
 nfs4.1/nfs3client.py | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 280 insertions(+)
 create mode 100644 nfs4.1/nfs3client.py

diff --git a/nfs4.1/dataserver.py b/nfs4.1/dataserver.py
index 5c604dc..f32f3d7 100644
--- a/nfs4.1/dataserver.py
+++ b/nfs4.1/dataserver.py
@@ -3,9 +3,12 @@ import nfs4lib
 import xdrdef.nfs4_type as type4
 from xdrdef.nfs4_pack import NFS4Packer
 import xdrdef.nfs4_const as const4
+import xdrdef.nfs3_type as type3
+import xdrdef.nfs3_const as const3
 import time
 import logging
 import nfs4client
+import nfs3client
 import hashlib
 import sys
 import nfs_ops
@@ -14,6 +17,7 @@ import socket
 log = logging.getLogger("Dataserver Manager")
 
 op4 = nfs_ops.NFS4ops()
+op3 = nfs_ops.NFS3ops()
 
 class DataServer(object):
     def __init__(self, server, port, path, flavor=rpc.AUTH_SYS, active=True, mdsds=True, multipath_servers=None, summary=None):
@@ -207,6 +211,102 @@ class DataServer41(DataServer):
         attrdict = res.resarray[-1].obj_attributes
         return attrdict.get(const4.FATTR4_SIZE, 0)
 
+class DataServer3(DataServer):
+    def _execute(self, procnum, procarg, exceptions=(), delay=5, maxretries=3):
+        """ execute the NFS call
+        If an error code is specified in the exceptions it means that the
+        caller wants to handle the error himself
+        """
+        retry_errors = []
+        while True:
+            res = self.c1.proc(procnum, procarg)
+            if res.status == const3.NFS3_OK or res.status in exceptions:
+                return res
+            elif res.status in retry_errors:
+                if maxretries > 0:
+                    maxretries -= 1
+                    time.sleep(delay)
+                else:
+                    log.error("Too many retries with DS %s" % self.server)
+                    raise Exception("Dataserver communication retry error")
+            else:
+                log.error("Unhandled status %s from DS %s" %
+                          (const3.nfsstat3[res.status], self.server))
+                raise Exception("Dataserver communication error")
+
+    def connect(self):
+        # only support root with AUTH_SYS for now
+        s1 = rpc.security.instance(rpc.AUTH_SYS)
+        self.cred1 = s1.init_cred(uid=0, gid=0)
+        self.c1 = nfs3client.NFS3Client(self.server, self.port,
+                                        summary=self.summary)
+        self.c1.set_cred(self.cred1)
+        self.rootfh = type3.nfs_fh3(self.c1.mntclnt.get_rootfh(self.path))
+        self.c1.null()
+
+    def make_root(self):
+        """ don't actually make a root path - we must use it as the export """
+        need = const3.ACCESS3_READ | const3.ACCESS3_LOOKUP | \
+               const3.ACCESS3_MODIFY | const3.ACCESS3_EXTEND
+        arg = op3.access(self.rootfh, need)
+        res = self._execute(const3.NFSPROC3_ACCESS, arg)
+        if res.resok.access != need:
+            raise RuntimeError
+        # XXX clean DS directory
+
+    def open_file(self, mds_fh):
+        name = self.fh_to_name(mds_fh)
+        where = type3.diropargs3(self.rootfh, name)
+        attr = type3.sattr3(mode=type3.set_mode3(True, 0777),
+                            uid=type3.set_uid3(True, 0),
+                            gid=type3.set_gid3(True, 0),
+                            size=type3.set_size3(False),
+                            atime=type3.set_atime(False),
+                            mtime=type3.set_mtime(False))
+        how = type3.createhow3(const3.GUARDED, attr)
+        arg = op3.create(where, how)
+        res = self._execute(const3.NFSPROC3_CREATE, arg,
+                            exceptions=(const3.NFS3ERR_EXIST,))
+
+        if res.status == const3.NFS3_OK:
+            self.filehandles[mds_fh] = (res.resok.obj.handle, None)
+
+        else:
+            arg = op3.lookup(type3.diropargs3(self.rootfh, name))
+            res = self._execute(const3.NFSPROC3_LOOKUP, arg)
+
+            self.filehandles[mds_fh] = (res.resok.object, None)
+
+    def close_file(self, mds_fh):
+        del self.filehandles[mds_fh]
+
+    def read(self, fh, pos, count):
+        arg = op3.read(fh, pos, count)
+        res = self._execute(const3.NFSPROC3_READ, arg)
+        # XXX check res.status?
+        return res.resok.data
+
+    def write(self, fh, pos, data):
+        arg = op3.write(fh, pos, len(data), const3.FILE_SYNC, data)
+        # There are all sorts of error handling issues here
+        res = self._execute(const3.NFSPROC3_WRITE, arg)
+
+    def truncate(self, fh, size):
+        attr = type3.sattr3(mode=type3.set_mode3(False),
+                            uid=type3.set_uid3(False),
+                            gid=type3.set_gid3(False),
+                            size=type3.set_size3(True, size),
+                            atime=type3.set_atime(False),
+                            mtime=type3.set_mtime(False))
+        arg = op3.setattr(fh, attr, type3.sattrguard3(check=False))
+        res = self._execute(const3.NFSPROC3_SETATTR, arg)
+
+    def get_size(self, fh):
+        arg = op3.getattr(fh)
+        res = self._execute(const3.NFSPROC3_GETATTR, arg)
+        # XXX check res.status?
+        return res.resok.obj_attributes.size
+
 
 class DSDevice(object):
     def __init__(self, mdsds):
diff --git a/nfs4.1/nfs3client.py b/nfs4.1/nfs3client.py
new file mode 100644
index 0000000..79a6f0e
--- /dev/null
+++ b/nfs4.1/nfs3client.py
@@ -0,0 +1,180 @@
+import use_local # HACK so don't have to rebuild constantly
+import rpc
+import nfs4lib
+#from nfs4lib import NFS4Error, NFS4Replay, inc_u32
+from xdrdef.sctrl_pack import SCTRLPacker, SCTRLUnpacker
+from xdrdef.nfs3_type import *
+from xdrdef.nfs3_const import *
+from xdrdef.nfs3_pack import NFS3Packer, NFS3Unpacker
+from xdrdef.mnt3_type import *
+from xdrdef.mnt3_const import *
+from xdrdef.mnt3_pack import MNT3Packer, MNT3Unpacker
+from xdrdef.portmap_type import *
+from xdrdef.portmap_const import *
+from xdrdef.portmap_pack import PORTMAPPacker, PORTMAPUnpacker
+import nfs_ops
+import time, struct
+import threading
+import hmac
+import os.path
+
+import traceback
+import logging
+logging.basicConfig(level=logging.INFO,
+                    format="%(levelname)-7s:%(name)s:%(message)s")
+log_cb = logging.getLogger("nfs.client.cb")
+
+op3 = nfs_ops.NFS3ops()
+
+class PORTMAPClient(rpc.Client):
+    def __init__(self, host='localhost', port=PMAP_PORT):
+        rpc.Client.__init__(self, PMAP_PROG, PMAP_VERS)
+        self.server_address = (host, port)
+        self.c1 = self.connect(self.server_address)
+
+    def proc_async(self, procnum, procarg, credinfo=None, pipe=None,
+                   checks=True, packer=PORTMAPPacker):
+        if credinfo is None:
+            credinfo = self.default_cred
+        if pipe is None:
+            pipe = self.c1
+        p = packer(check_enum=checks, check_array=checks)
+        arg_packer = getattr(p, 'pack_%s' % procarg.__class__.__name__)
+        arg_packer(procarg)
+        return self.send_call(pipe, procnum, p.get_buffer(), credinfo)
+
+    def proc(self, procnum, procarg, restypename, **kwargs):
+        xid = self.proc_async(procnum, procarg, **kwargs)
+        pipe = kwargs.get("pipe", None)
+        res = self.listen(xid, restypename, pipe=pipe)
+        return res
+
+    def listen(self, xid, restypename, pipe=None, timeout=10.0):
+        if pipe is None:
+            pipe = self.c1
+        header, data = pipe.listen(xid, timeout)
+        if data:
+            p = PORTMAPUnpacker(data)
+            res_unpacker = getattr(p, 'unpack_%s' % restypename)
+            data = res_unpacker()
+        return data
+
+    def get_port(self, prog, vers):
+        arg = mapping(prog, vers, IPPROTO_TCP, 0)
+
+        res = self.proc(PMAPPROC_GETPORT, arg, 'uint')
+        return res
+
+class Mnt3Client(rpc.Client):
+    def __init__(self, host='localhost', port=None):
+        rpc.Client.__init__(self, MOUNT_PROGRAM, MOUNT_V3)
+        self.server_address = (host, port)
+        self.c1 = self.connect(self.server_address)
+
+    def proc_async(self, procnum, procarg, credinfo=None, pipe=None,
+                   checks=True, packer=MNT3Packer):
+        if credinfo is None:
+            credinfo = self.default_cred
+        if pipe is None:
+            pipe = self.c1
+        p = packer(check_enum=checks, check_array=checks)
+        arg_packer = getattr(p, 'pack_%s' % procarg.__class__.__name__)
+        arg_packer(procarg)
+        return self.send_call(pipe, procnum, p.get_buffer(), credinfo)
+
+    def proc(self, procnum, procarg, restypename, **kwargs):
+        xid = self.proc_async(procnum, procarg, **kwargs)
+        pipe = kwargs.get("pipe", None)
+        res = self.listen(xid, restypename, pipe=pipe)
+        return res
+
+    def listen(self, xid, restypename, pipe=None, timeout=10.0):
+        if pipe is None:
+            pipe = self.c1
+        header, data = pipe.listen(xid, timeout)
+        if data:
+            p = MNT3Unpacker(data)
+            res_unpacker = getattr(p, 'unpack_%s' % restypename)
+            data = res_unpacker()
+        return data
+
+    def get_rootfh(self, export):
+
+        class dirpath(str):
+            pass
+
+        arg = dirpath('/' + os.path.join(*export))
+        res = self.proc(MOUNTPROC3_MNT, arg, 'mountres3')
+        return res.mountinfo.fhandle
+
+class NFS3Client(rpc.Client):
+    def __init__(self, host='localhost', port=None, ctrl_proc=16, summary=None):
+        rpc.Client.__init__(self, 100003, 3)
+        #self.prog = 0x40000000
+        #self.versions = [1] # List of supported versions of prog
+
+        #self.minorversion = minorversion
+        #self.minor_versions = [minorversion]
+        #self.tag = "default tag"
+        #self.impl_id = nfs_impl_id4("citi.umich.edu", "pynfs X.X",
+        #                            nfs4lib.get_nfstime())
+
+        self.portmap = PORTMAPClient(host=host)
+        self.mntport = self.portmap.get_port(MOUNT_PROGRAM, MOUNT_V3)
+        if not port:
+            self.port = self.portmap.get_port(100003, 3)
+        else:
+            self.port = port
+
+        self.verifier = struct.pack('>d', time.time())
+        self.server_address = (host, self.port)
+        self.c1 = self.connect(self.server_address)
+        #self.sessions = {} # XXX Really, this should be per server
+        self.ctrl_proc = ctrl_proc
+        self.summary = summary
+        self.mntclnt = Mnt3Client(host=host, port=self.mntport)
+
+    def set_cred(self, credinfo):
+        self.default_cred = credinfo
+
+    def null_async(self, data=""):
+        return self.send_call(self.c1, 0, data)
+
+    def null(self, *args, **kwargs):
+        xid = self.null_async(*args, **kwargs)
+        return self.listen(xid)
+
+    def proc_async(self, procnum, procarg, credinfo=None, pipe=None,
+                   checks=True, packer=NFS3Packer):
+        if credinfo is None:
+            credinfo = self.default_cred
+        if pipe is None:
+            pipe = self.c1
+        p = packer(check_enum=checks, check_array=checks)
+        arg_packer = getattr(p, 'pack_%s' % procarg.__class__.__name__)
+        arg_packer(procarg)
+        return self.send_call(pipe, procnum, p.get_buffer(), credinfo)
+
+    def proc(self, procnum, procarg, **kwargs):
+        xid = self.proc_async(procnum, procarg, **kwargs)
+        pipe = kwargs.get("pipe", None)
+        res = self.listen(xid, procarg=procarg, pipe=pipe)
+        if self.summary:
+            self.summary.show_op('call v3 %s:%s' % self.server_address,
+                [ procarg.__class__.__name__.lower()[:-1 * len('3args')] ],
+                nfsstat3[res.status])
+        return res
+
+    def listen(self, xid, procarg=None, pipe=None, timeout=10.0):
+        if pipe is None:
+            pipe = self.c1
+        header, data = pipe.listen(xid, timeout)
+        if data:
+            p = NFS3Unpacker(data)
+            argname = procarg.__class__.__name__
+            # FOO3args -> FOO3res
+            resname = argname[:-4] + 'res'
+            res_unpacker = getattr(p, 'unpack_%s' % resname)
+            data = res_unpacker()
+        return data
+
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 14/16] 4.1 server: get rid of old op_getdeviceinfo
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (12 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 13/16] 4.1 server: add support for NFSv3 data servers Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 15/16] rpc: on socket error, close and mark pipe inactive Weston Andros Adamson
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

This has been commented out for a while.

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/nfs4server.py | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/nfs4.1/nfs4server.py b/nfs4.1/nfs4server.py
index 3d2d4cf..7ca4d92 100755
--- a/nfs4.1/nfs4server.py
+++ b/nfs4.1/nfs4server.py
@@ -1867,27 +1867,6 @@ class NFS4Server(rpc.Server):
                                   new_cookie >= len(list))
         return encode_status(NFS4_OK, res)
 
-#     def op_getdeviceinfo(self, arg, env): # STUB
-#         check_session(env)
-#         # check_cfh(env)
-#         # fs = env.cfh.fs
-#         # STUB - only deals with block volumes
-#         kind = arg.gdia_layout_type
-#         if kind != LAYOUT4_BLOCK_VOLUME:
-#             return encode_status(NFS4ERR_INVAL)
-#         # STUB - want to pull this from fs, not block module
-#         d = block.devices.get(arg.gdia_device_id, None)
-#         if d is None:
-#             return encode_status(NFS4ERR_INVAL)
-#         address = device_addr4(LAYOUT4_BLOCK_VOLUME, d.get_addr())
-#         # Check that we don't exceed count
-#         p = nfs4lib.FancyNFS4Packer()
-#         p.pack_device_addr4(address)
-#         if len(p.get_buffer()) > arg.gdia_maxcount:
-#             return encode_status(NFS4ERR_TOOSMALL, gdir_mincount = len(p.get_buffer()))
-#         res = GETDEVICEINFO4resok(address, 0)
-#         return encode_status(NFS4_OK, res)
-
     def op_getdeviceinfo(self, arg, env): # STUB
         # STUB - ignoring notifications
         check_session(env)
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 15/16] rpc: on socket error, close and mark pipe inactive
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (13 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 14/16] 4.1 server: get rid of old op_getdeviceinfo Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 13:55 ` [PATCH pynfs v2 16/16] nfs3clnt: reconnect when sending on inactive pipe Weston Andros Adamson
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

call _event_close() on socket errors instead of tracing back and mark the
pipe as inactive so callers can reconnect as needed.

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 rpc/rpc.py | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/rpc/rpc.py b/rpc/rpc.py
index 250e945..4801883 100644
--- a/rpc/rpc.py
+++ b/rpc/rpc.py
@@ -351,6 +351,7 @@ class RpcPipe(Pipe):
         self._pending = {} # {xid:defer}
         self._lock = threading.Lock() # Protects fields below
         self._xid = 0
+        self.set_active()
 
     def _get_xid(self):
         with self._lock:
@@ -358,6 +359,15 @@ class RpcPipe(Pipe):
             self._xid = inc_u32(out)
         return out
 
+    def set_active(self):
+        self._active = True
+
+    def clear_active(self):
+        self._active = False
+
+    def is_active(self):
+        return self._active
+
     def listen(self, xid, timeout=None):
         """Wait for a reply to a CALL."""
         self._pending[xid].wait(timeout)
@@ -500,15 +510,24 @@ class ConnectionHandler(object):
                 log_p.warn(1, "polling error from %i" % fd)
                 # STUB - now what?
             for fd in w:
-                self._event_write(fd)
+                try:
+                    self._event_write(fd)
+                except socket.error, e:
+                    self._event_close(fd)
             for fd in r:
                 if fd in self.listeners:
-                    self._event_connect_incoming(fd)
+                    try:
+                        self._event_connect_incoming(fd)
+                    except socket.error, e:
+                        self._event_close(fd)
                 elif fd == self._alarm_poll.fileno():
                     commands = self._alarm_poll.recv(self.rsize)
                     for c in commands:
                         data = self._alarm.pop()
-                        switch[c](data)
+                        try:
+                            switch[c](data)
+                        except socket.error, e:
+                            self._event_close(fd)
                 else:
                     try:
                         data = self.sockets[fd].recv_records(self.rsize)
@@ -557,6 +576,7 @@ class ConnectionHandler(object):
         self.writelist -= temp
         self.readlist -= temp
         self.errlist -= temp
+        self.sockets[fd].clear_active()
         self.sockets[fd].close()
         del self.sockets[fd]
 
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH pynfs v2 16/16] nfs3clnt: reconnect when sending on inactive pipe
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (14 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 15/16] rpc: on socket error, close and mark pipe inactive Weston Andros Adamson
@ 2014-06-05 13:55 ` Weston Andros Adamson
  2014-06-05 14:19 ` [PATCH pynfs v2 00/16] prep for flex file layout server J. Bruce Fields
  2014-06-09 21:25 ` J. Bruce Fields
  17 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 13:55 UTC (permalink / raw)
  To: bfields; +Cc: linux-nfs, Weston Andros Adamson

Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
---
 nfs4.1/nfs3client.py | 45 +++++++++++++++++++++++++--------------------
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/nfs4.1/nfs3client.py b/nfs4.1/nfs3client.py
index 79a6f0e..176765c 100644
--- a/nfs4.1/nfs3client.py
+++ b/nfs4.1/nfs3client.py
@@ -30,14 +30,19 @@ class PORTMAPClient(rpc.Client):
     def __init__(self, host='localhost', port=PMAP_PORT):
         rpc.Client.__init__(self, PMAP_PROG, PMAP_VERS)
         self.server_address = (host, port)
-        self.c1 = self.connect(self.server_address)
+        self._pipe = None
+
+    def get_pipe(self):
+        if not self._pipe or not self._pipe.is_active():
+           self._pipe = self.connect(self.server_address)
+        return self._pipe
 
     def proc_async(self, procnum, procarg, credinfo=None, pipe=None,
                    checks=True, packer=PORTMAPPacker):
         if credinfo is None:
             credinfo = self.default_cred
         if pipe is None:
-            pipe = self.c1
+            pipe = self.get_pipe()
         p = packer(check_enum=checks, check_array=checks)
         arg_packer = getattr(p, 'pack_%s' % procarg.__class__.__name__)
         arg_packer(procarg)
@@ -51,7 +56,7 @@ class PORTMAPClient(rpc.Client):
 
     def listen(self, xid, restypename, pipe=None, timeout=10.0):
         if pipe is None:
-            pipe = self.c1
+            pipe = self.get_pipe()
         header, data = pipe.listen(xid, timeout)
         if data:
             p = PORTMAPUnpacker(data)
@@ -69,14 +74,19 @@ class Mnt3Client(rpc.Client):
     def __init__(self, host='localhost', port=None):
         rpc.Client.__init__(self, MOUNT_PROGRAM, MOUNT_V3)
         self.server_address = (host, port)
-        self.c1 = self.connect(self.server_address)
+        self._pipe = None
+
+    def get_pipe(self):
+        if not self._pipe or not self._pipe.is_active():
+            self._pipe = self.connect(self.server_address)
+        return self._pipe
 
     def proc_async(self, procnum, procarg, credinfo=None, pipe=None,
                    checks=True, packer=MNT3Packer):
         if credinfo is None:
             credinfo = self.default_cred
         if pipe is None:
-            pipe = self.c1
+            pipe = self.get_pipe()
         p = packer(check_enum=checks, check_array=checks)
         arg_packer = getattr(p, 'pack_%s' % procarg.__class__.__name__)
         arg_packer(procarg)
@@ -90,7 +100,7 @@ class Mnt3Client(rpc.Client):
 
     def listen(self, xid, restypename, pipe=None, timeout=10.0):
         if pipe is None:
-            pipe = self.c1
+            pipe = self.get_pipe()
         header, data = pipe.listen(xid, timeout)
         if data:
             p = MNT3Unpacker(data)
@@ -110,15 +120,6 @@ class Mnt3Client(rpc.Client):
 class NFS3Client(rpc.Client):
     def __init__(self, host='localhost', port=None, ctrl_proc=16, summary=None):
         rpc.Client.__init__(self, 100003, 3)
-        #self.prog = 0x40000000
-        #self.versions = [1] # List of supported versions of prog
-
-        #self.minorversion = minorversion
-        #self.minor_versions = [minorversion]
-        #self.tag = "default tag"
-        #self.impl_id = nfs_impl_id4("citi.umich.edu", "pynfs X.X",
-        #                            nfs4lib.get_nfstime())
-
         self.portmap = PORTMAPClient(host=host)
         self.mntport = self.portmap.get_port(MOUNT_PROGRAM, MOUNT_V3)
         if not port:
@@ -128,17 +129,21 @@ class NFS3Client(rpc.Client):
 
         self.verifier = struct.pack('>d', time.time())
         self.server_address = (host, self.port)
-        self.c1 = self.connect(self.server_address)
-        #self.sessions = {} # XXX Really, this should be per server
         self.ctrl_proc = ctrl_proc
         self.summary = summary
+        self._pipe = None
         self.mntclnt = Mnt3Client(host=host, port=self.mntport)
 
+    def get_pipe(self):
+        if not self._pipe or not self._pipe.is_active():
+            self._pipe = self.connect(self.server_address)
+        return self._pipe
+
     def set_cred(self, credinfo):
         self.default_cred = credinfo
 
     def null_async(self, data=""):
-        return self.send_call(self.c1, 0, data)
+        return self.send_call(self.get_pipe(), 0, data)
 
     def null(self, *args, **kwargs):
         xid = self.null_async(*args, **kwargs)
@@ -149,7 +154,7 @@ class NFS3Client(rpc.Client):
         if credinfo is None:
             credinfo = self.default_cred
         if pipe is None:
-            pipe = self.c1
+            pipe = self.get_pipe()
         p = packer(check_enum=checks, check_array=checks)
         arg_packer = getattr(p, 'pack_%s' % procarg.__class__.__name__)
         arg_packer(procarg)
@@ -167,7 +172,7 @@ class NFS3Client(rpc.Client):
 
     def listen(self, xid, procarg=None, pipe=None, timeout=10.0):
         if pipe is None:
-            pipe = self.c1
+            pipe = self.get_pipe()
         header, data = pipe.listen(xid, timeout)
         if data:
             p = NFS3Unpacker(data)
-- 
1.8.5.2 (Apple Git-48)


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH pynfs v2 00/16] prep for flex file layout server
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (15 preceding siblings ...)
  2014-06-05 13:55 ` [PATCH pynfs v2 16/16] nfs3clnt: reconnect when sending on inactive pipe Weston Andros Adamson
@ 2014-06-05 14:19 ` J. Bruce Fields
  2014-06-05 14:22   ` Weston Andros Adamson
  2014-06-09 21:25 ` J. Bruce Fields
  17 siblings, 1 reply; 22+ messages in thread
From: J. Bruce Fields @ 2014-06-05 14:19 UTC (permalink / raw)
  To: Weston Andros Adamson; +Cc: linux-nfs

On Thu, Jun 05, 2014 at 09:55:28AM -0400, Weston Andros Adamson wrote:
> Changes in v2:
> 
>  - moved "4.1 client: reclaim_complete after create_session" to
>    "dataserver: reclaim_complete after create_session" as the implicit
>    reclaim complete is needed in DS path, but not in all server tests.
> 
>  - dropped "4.1 server: service RECLAIM_COMPLETE operations" as it's
>    unneeded.
> 
>  - formatted these patches with -M flag so we can see moved files
> 
> .. and I pushed the changes to my ff_prep branch.
> 
> Thanks!
>  -dros
> 
> 
> These patches are in preparation for the pynfs implementation of a flex
> file layout server.
> 
> I already have patches for a working flex file server, but I figure those
> should wait until the spec is complete ;)
> 
> I pushed these patches to my linux-nfs.org tree on branch 'ff_prep':
> 
>  git://git.linux-nfs.org/projects/dros/pynfs.git

  $ git pull git://git.linux-nfs.org/projects/dros/pynfs.git ff_prep

  fatal: remote error: access denied or repository not exported:
  /projects/dros/pynfs.git

No big deal, just using git-am instead.....

--b.

> 
> The prep includes:
> 
>  - patches that enable pynfs mds using real v4.1 DSes (on the backend,
>    not usable from clients as there is no stateid sharing between mds and ds)
> 
>  - fix several bugs in pnfs path
> 
>  - move .x files to subdir 'xdrdef' - the nfs4.1 directory was getting crowded
>    and we're going to add several more .x files along with all of the
>    autogenerated files.  Note this change touches server tests too.
> 
>  - clean up the nfs4server's output - no longer print out EVERY part of EVERY
>    operation which was very efficient at hiding tracebacks and made pynfs
>    even slower. Old functionality is now switched on with -v flag. Also
>    added an in-between mode "-s" that prints a summary of whats going on.
> 
>  - support for NFSv3 backend communication - this is not actually used yet,
>    but can be tested with file layout by always returning
>    NFS4ERR_LAYOUTUNAVAILABLE in layoutget and using DataServer3 class instead
>    of DataServer41
> 
> 
> Weston Andros Adamson (16):
>   dataserver: reclaim_complete after create_session
>   dataserver: only catch connection error
>   4.1 server: avoid traceback in DS disconnect()
>   move .x files to subdir 'xdrdef'
>   4.1 client: remove unused imports
>   4.1 server: add -v flag & silence random output
>   4.1 server: add -s option to print summary of ops
>   dataserver: make generic interface to ops
>   dataserver: don't import * from nfs4 specific mods
>   4.1 server: move nfs4_ops.py to nfs_ops.py
>   add mntv3, portmapv2 and nfsv3 .x files
>   dataserver: separate generic and 4.1 code
>   4.1 server: add support for NFSv3 data servers
>   4.1 server: get rid of old op_getdeviceinfo
>   rpc: on socket error, close and mark pipe inactive
>   nfs3clnt: reconnect when sending on inactive pipe
> 
>  nfs4.1/block.py                             |   8 +-
>  nfs4.1/client41tests/environment.py         |   4 +-
>  nfs4.1/config.py                            |   8 +-
>  nfs4.1/dataserver.py                        | 308 ++++++++---
>  nfs4.1/fs.py                                |  38 +-
>  nfs4.1/nfs3client.py                        | 185 +++++++
>  nfs4.1/nfs4_ops.py                          |  61 ---
>  nfs4.1/nfs4client.py                        |  47 +-
>  nfs4.1/nfs4commoncode.py                    |  10 +-
>  nfs4.1/nfs4lib.py                           |  62 ++-
>  nfs4.1/nfs4server.py                        | 163 +++---
>  nfs4.1/nfs4state.py                         |  15 +-
>  nfs4.1/nfs_ops.py                           |  89 +++
>  nfs4.1/server41tests/environment.py         |   4 +-
>  nfs4.1/server41tests/st_block.py            |   4 +-
>  nfs4.1/server41tests/st_compound.py         |   4 +-
>  nfs4.1/server41tests/st_create_session.py   |   4 +-
>  nfs4.1/server41tests/st_current_stateid.py  |   8 +-
>  nfs4.1/server41tests/st_debug.py            |   4 +-
>  nfs4.1/server41tests/st_delegation.py       |   4 +-
>  nfs4.1/server41tests/st_destroy_clientid.py |   2 +-
>  nfs4.1/server41tests/st_destroy_session.py  |   4 +-
>  nfs4.1/server41tests/st_exchange_id.py      |   4 +-
>  nfs4.1/server41tests/st_getdevicelist.py    |   4 +-
>  nfs4.1/server41tests/st_lookup.py           |   2 +-
>  nfs4.1/server41tests/st_lookupp.py          |   2 +-
>  nfs4.1/server41tests/st_open.py             |   8 +-
>  nfs4.1/server41tests/st_putfh.py            |   2 +-
>  nfs4.1/server41tests/st_reboot.py           |   4 +-
>  nfs4.1/server41tests/st_reclaim_complete.py |   2 +-
>  nfs4.1/server41tests/st_rename.py           |   4 +-
>  nfs4.1/server41tests/st_secinfo.py          |   4 +-
>  nfs4.1/server41tests/st_secinfo_no_name.py  |   4 +-
>  nfs4.1/server41tests/st_sequence.py         |   4 +-
>  nfs4.1/server41tests/st_trunking.py         |   4 +-
>  nfs4.1/server41tests/st_verify.py           |   2 +-
>  nfs4.1/server_exports.py                    |   7 +-
>  nfs4.1/setup.py                             |  33 +-
>  nfs4.1/testclient.py                        |   2 +-
>  nfs4.1/testserver.py                        |   2 +-
>  nfs4.1/xdrdef/__init__.py                   |   0
>  nfs4.1/xdrdef/mnt3.x                        |  68 +++
>  nfs4.1/xdrdef/nfs3.x                        | 818 ++++++++++++++++++++++++++++
>  nfs4.1/{ => xdrdef}/nfs4.x                  |   0
>  nfs4.1/{ => xdrdef}/nfs4.x.diff             |   0
>  nfs4.1/{ => xdrdef}/pnfs_block.x            |   0
>  nfs4.1/xdrdef/portmap.x                     |  51 ++
>  nfs4.1/{ => xdrdef}/sctrl.x                 |   0
>  rpc/rpc.py                                  |  26 +-
>  49 files changed, 1704 insertions(+), 389 deletions(-)
>  create mode 100644 nfs4.1/nfs3client.py
>  delete mode 100644 nfs4.1/nfs4_ops.py
>  create mode 100644 nfs4.1/nfs_ops.py
>  create mode 100644 nfs4.1/xdrdef/__init__.py
>  create mode 100644 nfs4.1/xdrdef/mnt3.x
>  create mode 100644 nfs4.1/xdrdef/nfs3.x
>  rename nfs4.1/{ => xdrdef}/nfs4.x (100%)
>  rename nfs4.1/{ => xdrdef}/nfs4.x.diff (100%)
>  rename nfs4.1/{ => xdrdef}/pnfs_block.x (100%)
>  create mode 100644 nfs4.1/xdrdef/portmap.x
>  rename nfs4.1/{ => xdrdef}/sctrl.x (100%)
> 
> -- 
> 1.8.5.2 (Apple Git-48)
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH pynfs v2 00/16] prep for flex file layout server
  2014-06-05 14:19 ` [PATCH pynfs v2 00/16] prep for flex file layout server J. Bruce Fields
@ 2014-06-05 14:22   ` Weston Andros Adamson
  2014-06-05 14:24     ` J. Bruce Fields
  0 siblings, 1 reply; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-05 14:22 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: linux-nfs list

Oh! Sorry I still needed to make it public.

Try now

-dros



On Jun 5, 2014, at 10:19 AM, J. Bruce Fields <bfields@fieldses.org> wrote:

> On Thu, Jun 05, 2014 at 09:55:28AM -0400, Weston Andros Adamson wrote:
>> Changes in v2:
>> 
>> - moved "4.1 client: reclaim_complete after create_session" to
>>   "dataserver: reclaim_complete after create_session" as the implicit
>>   reclaim complete is needed in DS path, but not in all server tests.
>> 
>> - dropped "4.1 server: service RECLAIM_COMPLETE operations" as it's
>>   unneeded.
>> 
>> - formatted these patches with -M flag so we can see moved files
>> 
>> .. and I pushed the changes to my ff_prep branch.
>> 
>> Thanks!
>> -dros
>> 
>> 
>> These patches are in preparation for the pynfs implementation of a flex
>> file layout server.
>> 
>> I already have patches for a working flex file server, but I figure those
>> should wait until the spec is complete ;)
>> 
>> I pushed these patches to my linux-nfs.org tree on branch 'ff_prep':
>> 
>> git://git.linux-nfs.org/projects/dros/pynfs.git
> 
>  $ git pull git://git.linux-nfs.org/projects/dros/pynfs.git ff_prep
> 
>  fatal: remote error: access denied or repository not exported:
>  /projects/dros/pynfs.git
> 
> No big deal, just using git-am instead.....
> 
> --b.
> 
>> 
>> The prep includes:
>> 
>> - patches that enable pynfs mds using real v4.1 DSes (on the backend,
>>   not usable from clients as there is no stateid sharing between mds and ds)
>> 
>> - fix several bugs in pnfs path
>> 
>> - move .x files to subdir 'xdrdef' - the nfs4.1 directory was getting crowded
>>   and we're going to add several more .x files along with all of the
>>   autogenerated files.  Note this change touches server tests too.
>> 
>> - clean up the nfs4server's output - no longer print out EVERY part of EVERY
>>   operation which was very efficient at hiding tracebacks and made pynfs
>>   even slower. Old functionality is now switched on with -v flag. Also
>>   added an in-between mode "-s" that prints a summary of whats going on.
>> 
>> - support for NFSv3 backend communication - this is not actually used yet,
>>   but can be tested with file layout by always returning
>>   NFS4ERR_LAYOUTUNAVAILABLE in layoutget and using DataServer3 class instead
>>   of DataServer41
>> 
>> 
>> Weston Andros Adamson (16):
>>  dataserver: reclaim_complete after create_session
>>  dataserver: only catch connection error
>>  4.1 server: avoid traceback in DS disconnect()
>>  move .x files to subdir 'xdrdef'
>>  4.1 client: remove unused imports
>>  4.1 server: add -v flag & silence random output
>>  4.1 server: add -s option to print summary of ops
>>  dataserver: make generic interface to ops
>>  dataserver: don't import * from nfs4 specific mods
>>  4.1 server: move nfs4_ops.py to nfs_ops.py
>>  add mntv3, portmapv2 and nfsv3 .x files
>>  dataserver: separate generic and 4.1 code
>>  4.1 server: add support for NFSv3 data servers
>>  4.1 server: get rid of old op_getdeviceinfo
>>  rpc: on socket error, close and mark pipe inactive
>>  nfs3clnt: reconnect when sending on inactive pipe
>> 
>> nfs4.1/block.py                             |   8 +-
>> nfs4.1/client41tests/environment.py         |   4 +-
>> nfs4.1/config.py                            |   8 +-
>> nfs4.1/dataserver.py                        | 308 ++++++++---
>> nfs4.1/fs.py                                |  38 +-
>> nfs4.1/nfs3client.py                        | 185 +++++++
>> nfs4.1/nfs4_ops.py                          |  61 ---
>> nfs4.1/nfs4client.py                        |  47 +-
>> nfs4.1/nfs4commoncode.py                    |  10 +-
>> nfs4.1/nfs4lib.py                           |  62 ++-
>> nfs4.1/nfs4server.py                        | 163 +++---
>> nfs4.1/nfs4state.py                         |  15 +-
>> nfs4.1/nfs_ops.py                           |  89 +++
>> nfs4.1/server41tests/environment.py         |   4 +-
>> nfs4.1/server41tests/st_block.py            |   4 +-
>> nfs4.1/server41tests/st_compound.py         |   4 +-
>> nfs4.1/server41tests/st_create_session.py   |   4 +-
>> nfs4.1/server41tests/st_current_stateid.py  |   8 +-
>> nfs4.1/server41tests/st_debug.py            |   4 +-
>> nfs4.1/server41tests/st_delegation.py       |   4 +-
>> nfs4.1/server41tests/st_destroy_clientid.py |   2 +-
>> nfs4.1/server41tests/st_destroy_session.py  |   4 +-
>> nfs4.1/server41tests/st_exchange_id.py      |   4 +-
>> nfs4.1/server41tests/st_getdevicelist.py    |   4 +-
>> nfs4.1/server41tests/st_lookup.py           |   2 +-
>> nfs4.1/server41tests/st_lookupp.py          |   2 +-
>> nfs4.1/server41tests/st_open.py             |   8 +-
>> nfs4.1/server41tests/st_putfh.py            |   2 +-
>> nfs4.1/server41tests/st_reboot.py           |   4 +-
>> nfs4.1/server41tests/st_reclaim_complete.py |   2 +-
>> nfs4.1/server41tests/st_rename.py           |   4 +-
>> nfs4.1/server41tests/st_secinfo.py          |   4 +-
>> nfs4.1/server41tests/st_secinfo_no_name.py  |   4 +-
>> nfs4.1/server41tests/st_sequence.py         |   4 +-
>> nfs4.1/server41tests/st_trunking.py         |   4 +-
>> nfs4.1/server41tests/st_verify.py           |   2 +-
>> nfs4.1/server_exports.py                    |   7 +-
>> nfs4.1/setup.py                             |  33 +-
>> nfs4.1/testclient.py                        |   2 +-
>> nfs4.1/testserver.py                        |   2 +-
>> nfs4.1/xdrdef/__init__.py                   |   0
>> nfs4.1/xdrdef/mnt3.x                        |  68 +++
>> nfs4.1/xdrdef/nfs3.x                        | 818 ++++++++++++++++++++++++++++
>> nfs4.1/{ => xdrdef}/nfs4.x                  |   0
>> nfs4.1/{ => xdrdef}/nfs4.x.diff             |   0
>> nfs4.1/{ => xdrdef}/pnfs_block.x            |   0
>> nfs4.1/xdrdef/portmap.x                     |  51 ++
>> nfs4.1/{ => xdrdef}/sctrl.x                 |   0
>> rpc/rpc.py                                  |  26 +-
>> 49 files changed, 1704 insertions(+), 389 deletions(-)
>> create mode 100644 nfs4.1/nfs3client.py
>> delete mode 100644 nfs4.1/nfs4_ops.py
>> create mode 100644 nfs4.1/nfs_ops.py
>> create mode 100644 nfs4.1/xdrdef/__init__.py
>> create mode 100644 nfs4.1/xdrdef/mnt3.x
>> create mode 100644 nfs4.1/xdrdef/nfs3.x
>> rename nfs4.1/{ => xdrdef}/nfs4.x (100%)
>> rename nfs4.1/{ => xdrdef}/nfs4.x.diff (100%)
>> rename nfs4.1/{ => xdrdef}/pnfs_block.x (100%)
>> create mode 100644 nfs4.1/xdrdef/portmap.x
>> rename nfs4.1/{ => xdrdef}/sctrl.x (100%)
>> 
>> -- 
>> 1.8.5.2 (Apple Git-48)
>> 


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH pynfs v2 00/16] prep for flex file layout server
  2014-06-05 14:22   ` Weston Andros Adamson
@ 2014-06-05 14:24     ` J. Bruce Fields
  0 siblings, 0 replies; 22+ messages in thread
From: J. Bruce Fields @ 2014-06-05 14:24 UTC (permalink / raw)
  To: Weston Andros Adamson; +Cc: linux-nfs list

On Thu, Jun 05, 2014 at 10:22:33AM -0400, Weston Andros Adamson wrote:
> Oh! Sorry I still needed to make it public.
> 
> Try now

Works for me now, thanks!--b.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH pynfs v2 00/16] prep for flex file layout server
  2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
                   ` (16 preceding siblings ...)
  2014-06-05 14:19 ` [PATCH pynfs v2 00/16] prep for flex file layout server J. Bruce Fields
@ 2014-06-09 21:25 ` J. Bruce Fields
  2014-06-10  1:41   ` Weston Andros Adamson
  17 siblings, 1 reply; 22+ messages in thread
From: J. Bruce Fields @ 2014-06-09 21:25 UTC (permalink / raw)
  To: Weston Andros Adamson; +Cc: linux-nfs

On Thu, Jun 05, 2014 at 09:55:28AM -0400, Weston Andros Adamson wrote:
> Changes in v2:
> 
>  - moved "4.1 client: reclaim_complete after create_session" to
>    "dataserver: reclaim_complete after create_session" as the implicit
>    reclaim complete is needed in DS path, but not in all server tests.
> 
>  - dropped "4.1 server: service RECLAIM_COMPLETE operations" as it's
>    unneeded.
> 
>  - formatted these patches with -M flag so we can see moved files
> 
> .. and I pushed the changes to my ff_prep branch.

Thanks for the patches!  Applied, checked that they didn't break
anything for me, and pushed out.

(The only thing I noticed was that I had to rebuild things, to account
for the renamed files.)

--b.

> 
> Thanks!
>  -dros
> 
> 
> These patches are in preparation for the pynfs implementation of a flex
> file layout server.
> 
> I already have patches for a working flex file server, but I figure those
> should wait until the spec is complete ;)
> 
> I pushed these patches to my linux-nfs.org tree on branch 'ff_prep':
> 
>  git://git.linux-nfs.org/projects/dros/pynfs.git
> 
> The prep includes:
> 
>  - patches that enable pynfs mds using real v4.1 DSes (on the backend,
>    not usable from clients as there is no stateid sharing between mds and ds)
> 
>  - fix several bugs in pnfs path
> 
>  - move .x files to subdir 'xdrdef' - the nfs4.1 directory was getting crowded
>    and we're going to add several more .x files along with all of the
>    autogenerated files.  Note this change touches server tests too.
> 
>  - clean up the nfs4server's output - no longer print out EVERY part of EVERY
>    operation which was very efficient at hiding tracebacks and made pynfs
>    even slower. Old functionality is now switched on with -v flag. Also
>    added an in-between mode "-s" that prints a summary of whats going on.
> 
>  - support for NFSv3 backend communication - this is not actually used yet,
>    but can be tested with file layout by always returning
>    NFS4ERR_LAYOUTUNAVAILABLE in layoutget and using DataServer3 class instead
>    of DataServer41
> 
> 
> Weston Andros Adamson (16):
>   dataserver: reclaim_complete after create_session
>   dataserver: only catch connection error
>   4.1 server: avoid traceback in DS disconnect()
>   move .x files to subdir 'xdrdef'
>   4.1 client: remove unused imports
>   4.1 server: add -v flag & silence random output
>   4.1 server: add -s option to print summary of ops
>   dataserver: make generic interface to ops
>   dataserver: don't import * from nfs4 specific mods
>   4.1 server: move nfs4_ops.py to nfs_ops.py
>   add mntv3, portmapv2 and nfsv3 .x files
>   dataserver: separate generic and 4.1 code
>   4.1 server: add support for NFSv3 data servers
>   4.1 server: get rid of old op_getdeviceinfo
>   rpc: on socket error, close and mark pipe inactive
>   nfs3clnt: reconnect when sending on inactive pipe
> 
>  nfs4.1/block.py                             |   8 +-
>  nfs4.1/client41tests/environment.py         |   4 +-
>  nfs4.1/config.py                            |   8 +-
>  nfs4.1/dataserver.py                        | 308 ++++++++---
>  nfs4.1/fs.py                                |  38 +-
>  nfs4.1/nfs3client.py                        | 185 +++++++
>  nfs4.1/nfs4_ops.py                          |  61 ---
>  nfs4.1/nfs4client.py                        |  47 +-
>  nfs4.1/nfs4commoncode.py                    |  10 +-
>  nfs4.1/nfs4lib.py                           |  62 ++-
>  nfs4.1/nfs4server.py                        | 163 +++---
>  nfs4.1/nfs4state.py                         |  15 +-
>  nfs4.1/nfs_ops.py                           |  89 +++
>  nfs4.1/server41tests/environment.py         |   4 +-
>  nfs4.1/server41tests/st_block.py            |   4 +-
>  nfs4.1/server41tests/st_compound.py         |   4 +-
>  nfs4.1/server41tests/st_create_session.py   |   4 +-
>  nfs4.1/server41tests/st_current_stateid.py  |   8 +-
>  nfs4.1/server41tests/st_debug.py            |   4 +-
>  nfs4.1/server41tests/st_delegation.py       |   4 +-
>  nfs4.1/server41tests/st_destroy_clientid.py |   2 +-
>  nfs4.1/server41tests/st_destroy_session.py  |   4 +-
>  nfs4.1/server41tests/st_exchange_id.py      |   4 +-
>  nfs4.1/server41tests/st_getdevicelist.py    |   4 +-
>  nfs4.1/server41tests/st_lookup.py           |   2 +-
>  nfs4.1/server41tests/st_lookupp.py          |   2 +-
>  nfs4.1/server41tests/st_open.py             |   8 +-
>  nfs4.1/server41tests/st_putfh.py            |   2 +-
>  nfs4.1/server41tests/st_reboot.py           |   4 +-
>  nfs4.1/server41tests/st_reclaim_complete.py |   2 +-
>  nfs4.1/server41tests/st_rename.py           |   4 +-
>  nfs4.1/server41tests/st_secinfo.py          |   4 +-
>  nfs4.1/server41tests/st_secinfo_no_name.py  |   4 +-
>  nfs4.1/server41tests/st_sequence.py         |   4 +-
>  nfs4.1/server41tests/st_trunking.py         |   4 +-
>  nfs4.1/server41tests/st_verify.py           |   2 +-
>  nfs4.1/server_exports.py                    |   7 +-
>  nfs4.1/setup.py                             |  33 +-
>  nfs4.1/testclient.py                        |   2 +-
>  nfs4.1/testserver.py                        |   2 +-
>  nfs4.1/xdrdef/__init__.py                   |   0
>  nfs4.1/xdrdef/mnt3.x                        |  68 +++
>  nfs4.1/xdrdef/nfs3.x                        | 818 ++++++++++++++++++++++++++++
>  nfs4.1/{ => xdrdef}/nfs4.x                  |   0
>  nfs4.1/{ => xdrdef}/nfs4.x.diff             |   0
>  nfs4.1/{ => xdrdef}/pnfs_block.x            |   0
>  nfs4.1/xdrdef/portmap.x                     |  51 ++
>  nfs4.1/{ => xdrdef}/sctrl.x                 |   0
>  rpc/rpc.py                                  |  26 +-
>  49 files changed, 1704 insertions(+), 389 deletions(-)
>  create mode 100644 nfs4.1/nfs3client.py
>  delete mode 100644 nfs4.1/nfs4_ops.py
>  create mode 100644 nfs4.1/nfs_ops.py
>  create mode 100644 nfs4.1/xdrdef/__init__.py
>  create mode 100644 nfs4.1/xdrdef/mnt3.x
>  create mode 100644 nfs4.1/xdrdef/nfs3.x
>  rename nfs4.1/{ => xdrdef}/nfs4.x (100%)
>  rename nfs4.1/{ => xdrdef}/nfs4.x.diff (100%)
>  rename nfs4.1/{ => xdrdef}/pnfs_block.x (100%)
>  create mode 100644 nfs4.1/xdrdef/portmap.x
>  rename nfs4.1/{ => xdrdef}/sctrl.x (100%)
> 
> -- 
> 1.8.5.2 (Apple Git-48)
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH pynfs v2 00/16] prep for flex file layout server
  2014-06-09 21:25 ` J. Bruce Fields
@ 2014-06-10  1:41   ` Weston Andros Adamson
  0 siblings, 0 replies; 22+ messages in thread
From: Weston Andros Adamson @ 2014-06-10  1:41 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: linux-nfs list

On Jun 9, 2014, at 5:25 PM, J. Bruce Fields <bfields@fieldses.org> wrote:

> On Thu, Jun 05, 2014 at 09:55:28AM -0400, Weston Andros Adamson wrote:
>> Changes in v2:
>> 
>> - moved "4.1 client: reclaim_complete after create_session" to
>>   "dataserver: reclaim_complete after create_session" as the implicit
>>   reclaim complete is needed in DS path, but not in all server tests.
>> 
>> - dropped "4.1 server: service RECLAIM_COMPLETE operations" as it's
>>   unneeded.
>> 
>> - formatted these patches with -M flag so we can see moved files
>> 
>> .. and I pushed the changes to my ff_prep branch.
> 
> Thanks for the patches!  Applied, checked that they didn't break
> anything for me, and pushed out.
> 
> (The only thing I noticed was that I had to rebuild things, to account
> for the renamed files.)
> 

Great, thanks!

-dros


> --b.
> 
>> 
>> Thanks!
>> -dros
>> 
>> 
>> These patches are in preparation for the pynfs implementation of a flex
>> file layout server.
>> 
>> I already have patches for a working flex file server, but I figure those
>> should wait until the spec is complete ;)
>> 
>> I pushed these patches to my linux-nfs.org tree on branch 'ff_prep':
>> 
>> git://git.linux-nfs.org/projects/dros/pynfs.git
>> 
>> The prep includes:
>> 
>> - patches that enable pynfs mds using real v4.1 DSes (on the backend,
>>   not usable from clients as there is no stateid sharing between mds and ds)
>> 
>> - fix several bugs in pnfs path
>> 
>> - move .x files to subdir 'xdrdef' - the nfs4.1 directory was getting crowded
>>   and we're going to add several more .x files along with all of the
>>   autogenerated files.  Note this change touches server tests too.
>> 
>> - clean up the nfs4server's output - no longer print out EVERY part of EVERY
>>   operation which was very efficient at hiding tracebacks and made pynfs
>>   even slower. Old functionality is now switched on with -v flag. Also
>>   added an in-between mode "-s" that prints a summary of whats going on.
>> 
>> - support for NFSv3 backend communication - this is not actually used yet,
>>   but can be tested with file layout by always returning
>>   NFS4ERR_LAYOUTUNAVAILABLE in layoutget and using DataServer3 class instead
>>   of DataServer41
>> 
>> 
>> Weston Andros Adamson (16):
>>  dataserver: reclaim_complete after create_session
>>  dataserver: only catch connection error
>>  4.1 server: avoid traceback in DS disconnect()
>>  move .x files to subdir 'xdrdef'
>>  4.1 client: remove unused imports
>>  4.1 server: add -v flag & silence random output
>>  4.1 server: add -s option to print summary of ops
>>  dataserver: make generic interface to ops
>>  dataserver: don't import * from nfs4 specific mods
>>  4.1 server: move nfs4_ops.py to nfs_ops.py
>>  add mntv3, portmapv2 and nfsv3 .x files
>>  dataserver: separate generic and 4.1 code
>>  4.1 server: add support for NFSv3 data servers
>>  4.1 server: get rid of old op_getdeviceinfo
>>  rpc: on socket error, close and mark pipe inactive
>>  nfs3clnt: reconnect when sending on inactive pipe
>> 
>> nfs4.1/block.py                             |   8 +-
>> nfs4.1/client41tests/environment.py         |   4 +-
>> nfs4.1/config.py                            |   8 +-
>> nfs4.1/dataserver.py                        | 308 ++++++++---
>> nfs4.1/fs.py                                |  38 +-
>> nfs4.1/nfs3client.py                        | 185 +++++++
>> nfs4.1/nfs4_ops.py                          |  61 ---
>> nfs4.1/nfs4client.py                        |  47 +-
>> nfs4.1/nfs4commoncode.py                    |  10 +-
>> nfs4.1/nfs4lib.py                           |  62 ++-
>> nfs4.1/nfs4server.py                        | 163 +++---
>> nfs4.1/nfs4state.py                         |  15 +-
>> nfs4.1/nfs_ops.py                           |  89 +++
>> nfs4.1/server41tests/environment.py         |   4 +-
>> nfs4.1/server41tests/st_block.py            |   4 +-
>> nfs4.1/server41tests/st_compound.py         |   4 +-
>> nfs4.1/server41tests/st_create_session.py   |   4 +-
>> nfs4.1/server41tests/st_current_stateid.py  |   8 +-
>> nfs4.1/server41tests/st_debug.py            |   4 +-
>> nfs4.1/server41tests/st_delegation.py       |   4 +-
>> nfs4.1/server41tests/st_destroy_clientid.py |   2 +-
>> nfs4.1/server41tests/st_destroy_session.py  |   4 +-
>> nfs4.1/server41tests/st_exchange_id.py      |   4 +-
>> nfs4.1/server41tests/st_getdevicelist.py    |   4 +-
>> nfs4.1/server41tests/st_lookup.py           |   2 +-
>> nfs4.1/server41tests/st_lookupp.py          |   2 +-
>> nfs4.1/server41tests/st_open.py             |   8 +-
>> nfs4.1/server41tests/st_putfh.py            |   2 +-
>> nfs4.1/server41tests/st_reboot.py           |   4 +-
>> nfs4.1/server41tests/st_reclaim_complete.py |   2 +-
>> nfs4.1/server41tests/st_rename.py           |   4 +-
>> nfs4.1/server41tests/st_secinfo.py          |   4 +-
>> nfs4.1/server41tests/st_secinfo_no_name.py  |   4 +-
>> nfs4.1/server41tests/st_sequence.py         |   4 +-
>> nfs4.1/server41tests/st_trunking.py         |   4 +-
>> nfs4.1/server41tests/st_verify.py           |   2 +-
>> nfs4.1/server_exports.py                    |   7 +-
>> nfs4.1/setup.py                             |  33 +-
>> nfs4.1/testclient.py                        |   2 +-
>> nfs4.1/testserver.py                        |   2 +-
>> nfs4.1/xdrdef/__init__.py                   |   0
>> nfs4.1/xdrdef/mnt3.x                        |  68 +++
>> nfs4.1/xdrdef/nfs3.x                        | 818 ++++++++++++++++++++++++++++
>> nfs4.1/{ => xdrdef}/nfs4.x                  |   0
>> nfs4.1/{ => xdrdef}/nfs4.x.diff             |   0
>> nfs4.1/{ => xdrdef}/pnfs_block.x            |   0
>> nfs4.1/xdrdef/portmap.x                     |  51 ++
>> nfs4.1/{ => xdrdef}/sctrl.x                 |   0
>> rpc/rpc.py                                  |  26 +-
>> 49 files changed, 1704 insertions(+), 389 deletions(-)
>> create mode 100644 nfs4.1/nfs3client.py
>> delete mode 100644 nfs4.1/nfs4_ops.py
>> create mode 100644 nfs4.1/nfs_ops.py
>> create mode 100644 nfs4.1/xdrdef/__init__.py
>> create mode 100644 nfs4.1/xdrdef/mnt3.x
>> create mode 100644 nfs4.1/xdrdef/nfs3.x
>> rename nfs4.1/{ => xdrdef}/nfs4.x (100%)
>> rename nfs4.1/{ => xdrdef}/nfs4.x.diff (100%)
>> rename nfs4.1/{ => xdrdef}/pnfs_block.x (100%)
>> create mode 100644 nfs4.1/xdrdef/portmap.x
>> rename nfs4.1/{ => xdrdef}/sctrl.x (100%)
>> 
>> -- 
>> 1.8.5.2 (Apple Git-48)
>> 


^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2014-06-10  1:41 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-05 13:55 [PATCH pynfs v2 00/16] prep for flex file layout server Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 01/16] dataserver: reclaim_complete after create_session Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 02/16] dataserver: only catch connection error Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 03/16] 4.1 server: avoid traceback in DS disconnect() Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 04/16] move .x files to subdir 'xdrdef' Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 05/16] 4.1 client: remove unused imports Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 06/16] 4.1 server: add -v flag & silence random output Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 07/16] 4.1 server: add -s option to print summary of ops Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 08/16] dataserver: make generic interface to ops Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 09/16] dataserver: don't import * from nfs4 specific mods Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 10/16] 4.1 server: move nfs4_ops.py to nfs_ops.py Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 11/16] add mntv3, portmapv2 and nfsv3 .x files Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 12/16] dataserver: separate generic and 4.1 code Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 13/16] 4.1 server: add support for NFSv3 data servers Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 14/16] 4.1 server: get rid of old op_getdeviceinfo Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 15/16] rpc: on socket error, close and mark pipe inactive Weston Andros Adamson
2014-06-05 13:55 ` [PATCH pynfs v2 16/16] nfs3clnt: reconnect when sending on inactive pipe Weston Andros Adamson
2014-06-05 14:19 ` [PATCH pynfs v2 00/16] prep for flex file layout server J. Bruce Fields
2014-06-05 14:22   ` Weston Andros Adamson
2014-06-05 14:24     ` J. Bruce Fields
2014-06-09 21:25 ` J. Bruce Fields
2014-06-10  1:41   ` Weston Andros Adamson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).