From: Jianhong Yin <jiyin@redhat.com>
To: linux-nfs@vger.kernel.org
Cc: calum.mackay@oracle.com, jlayton@kernel.org, bcodding@redhat.com,
smayhew@redhat.com, jiyin@redhat.com,
Jianhong Yin <yin-jianhong@163.com>
Subject: [PATCH v2 1/4] pynfs: fix nfs4.1/nfs4server.py
Date: Fri, 27 Mar 2026 12:16:18 +0800 [thread overview]
Message-ID: <20260327041620.2115456-2-jiyin@redhat.com> (raw)
From: Scott Mayhew <smayhew@redhat.com>
Signed-off-by: Jianhong Yin <yin-jianhong@163.com>
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
---
nfs4.1/config.py | 20 ++++-----
nfs4.1/dataserver.py | 30 ++++++-------
nfs4.1/fs.py | 37 ++++++++--------
nfs4.1/nfs4client.py | 2 +-
nfs4.1/nfs4server.py | 73 ++++++++++++++++----------------
nfs4.1/nfs4state.py | 18 ++++----
nfs4.1/sample_code/ds_exports.py | 2 +-
nfs4.1/server_exports.py | 12 +++---
8 files changed, 93 insertions(+), 101 deletions(-)
diff --git a/nfs4.1/config.py b/nfs4.1/config.py
index 3777e31..8691e1c 100644
--- a/nfs4.1/config.py
+++ b/nfs4.1/config.py
@@ -117,8 +117,7 @@ class MetaConfig(type):
setattr(cls, attr.name, property(make_get(i), make_set(i),
None, attr.comment))
-class ServerConfig(object):
- __metaclass__ = MetaConfig
+class ServerConfig(metaclass=MetaConfig):
attrs = [ConfigLine("allow_null_data", False,
"Server allows NULL calls to contain data"),
ConfigLine("tag_info", True,
@@ -131,17 +130,16 @@ class ServerConfig(object):
def __init__(self):
self.minor_id = os.getpid()
- self.major_id = "PyNFSv4.1"
+ self.major_id = b"PyNFSv4.1"
self._owner = server_owner4(self.minor_id, self.major_id)
- self.scope = "Default_Scope"
- self.impl_domain = "citi.umich.edu"
- self.impl_name = "pynfs X.X"
+ self.scope = b"Default_Scope"
+ self.impl_domain = b"citi.umich.edu"
+ self.impl_name = b"pynfs X.X"
self.impl_date = 1172852767 # int(time.time())
self.impl_id = nfs_impl_id4(self.impl_domain, self.impl_name,
nfs4lib.get_nfstime(self.impl_date))
-class ServerPerClientConfig(object):
- __metaclass__ = MetaConfig
+class ServerPerClientConfig(metaclass=MetaConfig):
attrs = [ConfigLine("maxrequestsize", 16384,
"Maximum request size the server will accept"),
ConfigLine("maxresponsesize", 16384,
@@ -175,15 +173,13 @@ _invalid_ops = [
OP_RELEASE_LOCKOWNER, OP_ILLEGAL,
]
-class OpsConfigServer(object):
- __metaclass__ = MetaConfig
+class OpsConfigServer(metaclass=MetaConfig):
value = ['ERROR', 0, 0] # Note must have value == _opline(value)
attrs = (lambda value=value: [ConfigLine(name.lower()[3:], value, "Generic comment", _opline)
for name in nfs_opnum4.values()])()
-class Actions(object):
- __metaclass__ = MetaConfig
+class Actions(metaclass=MetaConfig):
attrs = [ConfigLine("reboot", 0,
"Any write here will simulate a server reboot",
_action),
diff --git a/nfs4.1/dataserver.py b/nfs4.1/dataserver.py
index f76ca5a..74ca864 100644
--- a/nfs4.1/dataserver.py
+++ b/nfs4.1/dataserver.py
@@ -59,27 +59,27 @@ class DataServer(object):
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)
+ uaddr = b'.'.join([self.server.encode("utf-8"),
+ str(self.port >> 8).encode("utf-8"),
+ str(self.port & 0xff).encode("utf-8")])
+ return type4.netaddr4(self.proto.encode("utf-8"), 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"
+ uaddr = b'.'.join([server.encode("utf-8"),
+ str(port >> 8).encode("utf-8"),
+ str(port & 0xff).encode("utf-8")])
+ proto = b"tcp"
if server.find(':') >= 0:
- proto = "tcp6"
+ proto = b"tcp6"
netaddr4s.append(type4.netaddr4(proto, uaddr))
return netaddr4s
def fh_to_name(self, mds_fh):
- return hashlib.sha1("%r" % mds_fh).hexdigest()
+ return hashlib.sha1(mds_fh).hexdigest()
def connect(self):
raise NotImplemented
@@ -122,7 +122,7 @@ class DataServer41(DataServer):
summary=self.summary)
self.c1.set_cred(self.cred1)
self.c1.null()
- c = self.c1.new_client("DS.init_%s" % self.server)
+ c = self.c1.new_client(b"DS.init_%s" % self.server.encode("utf-8"))
# 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, [])
@@ -154,11 +154,11 @@ class DataServer41(DataServer):
access = const4.OPEN4_SHARE_ACCESS_BOTH
deny = const4.OPEN4_SHARE_DENY_NONE
attrs = {const4.FATTR4_MODE: 0o777}
- owner = "mds"
+ owner = b"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)
+ name = self.fh_to_name(mds_fh).encode("utf-8")
while True:
if mds_fh in self.filehandles:
return
@@ -338,14 +338,14 @@ class DSDevice(object):
server_list = server_list[:-1]
try:
log.info("Adding dataserver ip:%s port:%s path:%s" %
- (server, port, '/'.join(path)))
+ (server, port, b'/'.join(path)))
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" %
- (server, port, '/'.join(path)))
+ (server, port, b'/'.join(path)))
sys.exit(1)
self.active = 1
self.address_body = self._get_address_body()
diff --git a/nfs4.1/fs.py b/nfs4.1/fs.py
index 7f690bb..41149f1 100644
--- a/nfs4.1/fs.py
+++ b/nfs4.1/fs.py
@@ -6,10 +6,7 @@ from nfs4lib import NFS4Error
import struct
import logging
from locking import Lock, RWLock
-try:
- import cStringIO.StringIO as StringIO
-except:
- from io import StringIO
+from io import BytesIO
import time
from xdrdef.nfs4_pack import NFS4Packer
@@ -182,7 +179,7 @@ class FSObject(object):
def init_file(self):
"""Hook for subclasses that want to use their own file class"""
- return StringIO()
+ return BytesIO()
def _init_hook(self):
pass
@@ -671,7 +668,7 @@ class RootFS(FileSystem):
self.fattr4_supported_attrs |= 1 << FATTR4_MAXWRITE
self.fattr4_supported_attrs |= 1 << FATTR4_MAXREAD
self.fsid = (0,0)
- self.read_only = True
+ self.read_only = False
def alloc_id(self):
self._nextid += 1
@@ -711,7 +708,7 @@ class ConfigObj(FSObject):
self._reset()
def _reset(self):
- self.file = StringIO()
+ self.file = BytesIO()
self.file.write("# %s\n" % self.configline.comment)
value = self.configline.value
if type(value) is list:
@@ -931,7 +928,7 @@ import shutil
import shelve
class StubFS_Disk(FileSystem):
- _fs_data_name = "fs_info" # DB name where we store persistent data
+ _fs_data_name = b"fs_info" # DB name where we store persistent data
def __init__(self, path, reset=False, fsid=None):
self._nextid = 0
self.path = path
@@ -991,17 +988,17 @@ class StubFS_Disk(FileSystem):
self.root = self.find(d["root"])
def find_on_disk(self, id):
- fd = open(os.path.join(self.path, "m_%i" % id), "r")
+ fd = open(os.path.join(self.path, b"m_%i" % id), "rb")
# BUG - need to trap for file not found error
meta = pickle.load(fd)
fd.close()
obj = self.objclass(self, id, meta)
if obj.type == NF4REG:
- fd = open(os.path.join(self.path, "d_%i" % id), "r")
- obj.file = StringIO(fd.read())
+ fd = open(os.path.join(self.path, b"d_%i" % id), "rb")
+ obj.file = BytesIO(fd.read())
fd.close()
elif obj.type == NF4DIR:
- fd = open(os.path.join(self.path, "d_%i" % id), "r")
+ fd = open(os.path.join(self.path, b"d_%i" % id), "rb")
obj.entries = pickle.load(fd)
fd.close()
return obj
@@ -1018,10 +1015,10 @@ class StubFS_Disk(FileSystem):
self._fs_data["_nextid"] = id
self._fs_data.sync()
# Create meta-data file
- fd = open(os.path.join(self.path, "m_%i" % id), "w")
+ fd = open(os.path.join(self.path, b"m_%i" % id), "wb")
fd.close()
# Create data file
- # fd = open(os.path.join(self.path, "d_%i" % id), "w")
+ # fd = open(os.path.join(self.path, b"d_%i" % id), "wb")
# fd.close()
finally:
self._disk_lock.release()
@@ -1032,11 +1029,11 @@ class StubFS_Disk(FileSystem):
self._disk_lock.acquire()
try:
# Remove meta-data file
- meta = os.path.join(self.path, "m_%i" % id)
+ meta = os.path.join(self.path, b"m_%i" % id)
if os.path.isfile(meta):
os.remove(meta)
# Remove data file
- data = os.path.join(self.path, "d_%i" % id)
+ data = os.path.join(self.path, b"d_%i" % id)
if os.path.isfile(data):
os.remove(data)
finally:
@@ -1049,20 +1046,20 @@ class StubFS_Disk(FileSystem):
try:
# Create meta-data file
log_fs.debug("writing metadata for id=%i" % id)
- fd = open(os.path.join(self.path, "m_%i" % id), "w")
+ fd = open(os.path.join(self.path, b"m_%i" % id), "wb")
log_fs.debug("%r" % obj.meta.__dict__)
pickle.dump(obj.meta, fd)
fd.close()
if obj.type == NF4REG:
# Create data file
- fd = open(os.path.join(self.path, "d_%i" % id), "w")
+ fd = open(os.path.join(self.path, b"d_%i" % id), "wb")
obj.file.seek(0)
fd.write(obj.file.read())
fd.close()
elif obj.type == NF4DIR:
# Create dir entries
log_fs.debug("writing dir %r" % obj.entries.keys())
- fd = open(os.path.join(self.path, "d_%i" % id), "w")
+ fd = open(os.path.join(self.path, b"d_%i" % id), "wb")
pickle.dump(obj.entries, fd)
fd.close()
finally:
@@ -1408,7 +1405,7 @@ class FSLayoutFSObj(FSObject):
def init_file(self):
self.stripe_size = NFL4_UFLG_STRIPE_UNIT_SIZE_MASK & 0x4000
if self.fs.dsdevice.mdsds:
- return StringIO()
+ return BytesIO()
else:
return FileLayoutFile(self)
diff --git a/nfs4.1/nfs4client.py b/nfs4.1/nfs4client.py
index f4fabcc..073ea8b 100644
--- a/nfs4.1/nfs4client.py
+++ b/nfs4.1/nfs4client.py
@@ -183,7 +183,7 @@ class NFS4Client(rpc.Client, rpc.Server):
return env
try:
self.check_utf8str_cs(args.tag)
- except NFS4Errror as e:
+ except NFS4Error as e:
env.results.set_empty_return(e.status, "Invalid utf8 tag")
return env
# Handle the individual operations
diff --git a/nfs4.1/nfs4server.py b/nfs4.1/nfs4server.py
index f56806e..47d6cba 100755
--- a/nfs4.1/nfs4server.py
+++ b/nfs4.1/nfs4server.py
@@ -21,7 +21,7 @@ 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.WARN,
+logging.basicConfig(level=logging.DEBUG,
format="%(levelname)-7s:%(name)s:%(message)s")
log_41 = logging.getLogger("nfs.server")
@@ -350,7 +350,7 @@ class ClientRecord(object):
state.delete()
# STUB - what about LAYOUT?
# STUB - config whether DELEG OK or not
- except StandardError as e:
+ except Exception as e:
log_41.exception("Ignoring problem during state removal")
self.state = {}
self.lastused = time.time()
@@ -365,7 +365,7 @@ class SessionRecord(object):
"""The server's representation of a session and its state"""
def __init__(self, client, csa):
self.client = client # reference back to client which created this session
- self.sessionid = "%08x%08x" % (client.clientid,
+ self.sessionid = b"%08x%08x" % (client.clientid,
client.session_replay.seqid) # XXX does this work?
self.channel_fore = Channel(csa.csa_fore_chan_attrs, client.config) # Normal communication
self.channel_back = Channel(csa.csa_back_chan_attrs, client.config) # Callback communication
@@ -570,18 +570,18 @@ class NFS4Server(rpc.Server):
self._fsids = {self.root.fs.fsid: self.root.fs} # {fsid: fs}
self.clients = ClientList() # List of attached clients
self.sessions = {} # List of attached sessions
- self.minor_versions = [1]
+ self.minor_versions = [1, 2]
self.config = ServerConfig()
self.opsconfig = OpsConfigServer()
self.actions = Actions()
- self.mount(ConfigFS(self), path="/config")
+ self.mount(ConfigFS(self), path=b"/config")
self.verifier = struct.pack('>d', time.time())
self.recording = Recording()
self.devid_counter = Counter(name="devid_counter")
self.devids = {} # {devid: device}
# default cred for the backchannel -- currently supports only AUTH_SYS
rpcsec = rpc.security.instance(rpc.AUTH_SYS)
- self.default_cred = rpcsec.init_cred(uid=4321,gid=42,name="mystery")
+ self.default_cred = rpcsec.init_cred(uid=4321,gid=42,name=b"mystery")
self.err_inc_dict = self.init_err_inc_dict()
def start(self):
@@ -796,7 +796,7 @@ class NFS4Server(rpc.Server):
self.check_utf8str_cs(str)
if not str:
raise NFS4Error(NFS4ERR_INVAL, tag="Empty component")
- if '/' in str:
+ if b'/' in str:
raise NFS4Error(NFS4ERR_BADCHAR)
def op_compound(self, args, cred):
@@ -808,7 +808,7 @@ class NFS4Server(rpc.Server):
return env
try:
self.check_utf8str_cs(args.tag)
- except NFS4Errror as e:
+ except NFS4Error as e:
env.results.set_empty_return(e.status, "Invalid utf8 tag")
return env
# Handle the individual operations
@@ -834,10 +834,10 @@ class NFS4Server(rpc.Server):
# catch error themselves to encode properly.
result = encode_status_by_name(opname.lower()[3:],
e.status, msg=e.tag)
- except NFS4Replay:
+ except NFS4Replay as e:
# Just pass this on up
raise
- except StandardError:
+ except Exception as e:
# Uh-oh. This is a server bug
traceback.print_exc()
result = encode_status_by_name(opname.lower()[3:],
@@ -919,7 +919,7 @@ class NFS4Server(rpc.Server):
check_session(env, unique=True)
if arg.csa_flags & ~nfs4lib.create_session_mask:
return encode_status(NFS4ERR_INVAL,
- msg="Unknown bits set in flag")
+ msg=b"Unknown bits set in flag")
# Step 1: Client record lookup
c = self.clients[arg.csa_clientid]
if c is None: # STUB - or if c.frozen ???
@@ -982,13 +982,13 @@ class NFS4Server(rpc.Server):
if protect.type != SP4_SSV:
# Per draft26 18.47.3
return encode_status(NFS4ERR_INVAL,
- msg="Did not request SP4_SSV protection")
+ msg=b"Did not request SP4_SSV protection")
# Do some argument checking
size = protect.context.ssv_len
if len(arg.ssa_ssv) != size:
- return encode_status(NFS4ERR_INVAL, msg="SSV size != %i" % size)
+ return encode_status(NFS4ERR_INVAL, msg=b"SSV size != %i" % size)
if arg.ssa_ssv == "\0" * size:
- return encode_status(NFS4ERR_INVAL, msg="SSV==0 not allowed")
+ return encode_status(NFS4ERR_INVAL, msg=b"SSV==0 not allowed")
# Now we need to compute and check digest, using SEQUENCE args
p = nfs4lib.FancyNFS4Packer()
p.pack_SEQUENCE4args(env.argarray[0].opsequence)
@@ -1009,10 +1009,10 @@ class NFS4Server(rpc.Server):
check_session(env, unique=True)
# Check arguments for blatent errors
if arg.eia_flags & ~nfs4lib.exchgid_mask:
- return encode_status(NFS4ERR_INVAL, msg="Unknown flag")
+ return encode_status(NFS4ERR_INVAL, msg=b"Unknown flag")
if arg.eia_flags & EXCHGID4_FLAG_CONFIRMED_R:
return encode_status(NFS4ERR_INVAL,
- msg="Client used server-only flag")
+ msg=b"Client used server-only flag")
if arg.eia_client_impl_id:
impl_id = arg.eia_client_impl_id[0]
self.check_utf8str_cis(impl_id.nii_domain)
@@ -1034,7 +1034,7 @@ class NFS4Server(rpc.Server):
if c is None:
if update:
# Case 7
- return encode_status(NFS4ERR_NOENT, msg="No such client")
+ return encode_status(NFS4ERR_NOENT, msg=b"No such client")
else:
# The simple, common case 1: a new client
c = self.clients.add(arg, env.principal, self.sec_flavors)
@@ -1042,7 +1042,7 @@ class NFS4Server(rpc.Server):
if update:
# Case 7
return encode_status(NFS4ERR_NOENT,
- msg="Client not confirmed")
+ msg=b"Client not confirmed")
else:
# Case 4
self.clients.remove(c.clientid)
@@ -1057,11 +1057,11 @@ class NFS4Server(rpc.Server):
if c.verifier != verf:
# Case 8
return encode_status(NFS4ERR_NOT_SAME,
- msg="Verifier mismatch")
+ msg=b"Verifier mismatch")
elif c.principal != env.principal:
# Case 9
return encode_status(NFS4ERR_PERM,
- msg="Principal mismatch")
+ msg=b"Principal mismatch")
else:
# Case 6 - update
c.update(arg, env.principal)
@@ -1069,7 +1069,7 @@ class NFS4Server(rpc.Server):
# Case 3
# STUB - need to check state
return encode_status(NFS4ERR_CLID_INUSE,
- msg="Principal mismatch")
+ msg=b"Principal mismatch")
elif c.verifier != verf:
# Case 5
# Confirmed client reboot: this is the hard case
@@ -1103,7 +1103,7 @@ class NFS4Server(rpc.Server):
c.protection.rv(arg.eia_state_protect),
self.config._owner, self.config.scope,
[self.config.impl_id])
- return encode_status(NFS4_OK, res, msg="draft21")
+ return encode_status(NFS4_OK, res, msg=b"draft21")
def client_reboot(self, c):
# STUB - locking?
@@ -1143,9 +1143,9 @@ class NFS4Server(rpc.Server):
if arg.bctsa_digest:
# QUESTION _INVAL or _BAD_SESSION_DIGEST also possible
return encode_status(NFS4ERR_CONN_BINDING_NOT_ENFORCED,
- msg="Expected zero length digest")
+ msg=b"Expected zero length digest")
if arg.bctsa_step1 is False:
- return encode_status(NFS4ERR_INVAL, msg="Expected step1==True")
+ return encode_status(NFS4ERR_INVAL, msg=b"Expected step1==True")
dir = bind_to_channels(arg.bctsa_dir)
nonce = session.get_nonce(connection, [arg.bctsa_nonce])
# STUB this should be a session method
@@ -1175,9 +1175,9 @@ class NFS4Server(rpc.Server):
old_s_nonce, old_c_nonce = session.nonce[connection]
except KeyError:
return encode_status(NFS4ERR_INVAL,
- msg="server has no record of step1")
+ msg=b"server has no record of step1")
if old_c_nonce == arg.bctsa_nonce:
- return encode_status(NFS4ERR_INVAL, msg="Client reused nonce")
+ return encode_status(NFS4ERR_INVAL, msg=b"Client reused nonce")
p = nfs4lib.FancyNFS4Packer()
p.pack_bctsr_digest_input4(bctsr_digest_input4(arg.bctsa_sessid,
arg.bctsa_nonce,
@@ -1208,8 +1208,7 @@ class NFS4Server(rpc.Server):
check_session(env)
# xxx add gss support
secinfo4_list = [ secinfo4(rpc.AUTH_SYS) ]
- res = SECINFO_NO_NAME4res(NFS4_OK, secinfo4_list)
- return encode_status(NFS4_OK, res)
+ return encode_status(NFS4_OK, secinfo4_list)
# op_putpubfh SHOULD be the same as op_putrootfh
# See draft23, section 18.20.3, line 25005
@@ -1356,14 +1355,14 @@ class NFS4Server(rpc.Server):
claim_type = arg.claim.claim
if claim_type != CLAIM_NULL and arg.openhow.opentype == OPEN4_CREATE:
return encode_status(NFS4ERR_INVAL,
- msg="OPEN4_CREATE not compatible with %s" %
+ msg=b"OPEN4_CREATE not compatible with %s" %
open_claim_type4[claim_type])
# emulate switch(claim_type)
try:
func = getattr(self,
"open_%s" % open_claim_type4[claim_type].lower())
except AttributeError:
- return encode_status(NFS4ERR_NOTSUPP, msg="Unsupported claim type")
+ return encode_status(NFS4ERR_NOTSUPP, msg=b"Unsupported claim type")
existing, cinfo, bitmask = func(arg, env)
# existing now points to file we want to open
if existing is None:
@@ -1462,7 +1461,7 @@ class NFS4Server(rpc.Server):
ace = nfsace4(ACE4_ACCESS_DENIED_ACE_TYPE, 0,
ACE4_GENERIC_EXECUTE |
ACE4_GENERIC_WRITE | ACE4_GENERIC_READ,
- "EVERYONE@")
+ b"EVERYONE@")
deleg = open_read_delegation4(entry.get_id(), False, ace)
return open_delegation4(entry.deleg_type, deleg)
@@ -1557,7 +1556,7 @@ class NFS4Server(rpc.Server):
check_cfh(env)
env.cfh.check_dir()
if arg.cookie in (1, 2) or \
- (arg.cookie==0 and arg.cookieverf != "\0" * 8):
+ (arg.cookie==0 and arg.cookieverf != b"\0" * 8):
return encode_status(NFS4ERR_BAD_COOKIE)
objlist, verifier = env.cfh.readdir(arg.cookieverf, env.session.client, env.principal) # (name, obj) pairs
# STUB - think through rdattr_error handling
@@ -1690,7 +1689,7 @@ class NFS4Server(rpc.Server):
check_session(env)
check_cfh(env)
if env.cfh.fattr4_type != NF4LNK:
- return encode_status(NFS4_INVAL, msg="cfh type was %i" % i)
+ return encode_status(NFS4_INVAL, msg=b"cfh type was %i" % i)
res = READLINK4resok(env.cfh.linkdata)
return encode_status(NFS4_OK, res)
@@ -1734,7 +1733,7 @@ class NFS4Server(rpc.Server):
self.check_component(arg.newname)
if not nfs4lib.test_equal(env.sfh.fattr4_fsid, env.cfh.fattr4_fsid,
kind="fsid4"):
- return encode_status(NFS4ERR_XDEV, msg="%r != %r" % (env.sfh.fattr4_fsid, env.cfh.fattr4_fsid))
+ return encode_status(NFS4ERR_XDEV, msg=b"%r != %r" % (env.sfh.fattr4_fsid, env.cfh.fattr4_fsid))
order = sorted(set([env.cfh, env.sfh])) # Used to prevent locking problems
# BUG fs locking
old_change_src = env.sfh.fattr4_change
@@ -1891,10 +1890,10 @@ class NFS4Server(rpc.Server):
check_session(env)
check_cfh(env)
if arg.loga_length == 0:
- return encode_status(NFS4_INVAL, msg="length == 0")
+ return encode_status(NFS4_INVAL, msg=b"length == 0")
if arg.loga_length != 0xffffffffffffffff:
if arg.loga_length + arg.loga_offset > 0xffffffffffffffff:
- return encode_status(NFS4_INVAL, msg="offset+length too big")
+ return encode_status(NFS4_INVAL, msg=b"offset+length too big")
if not env.session.has_backchannel:
raise NFS4Error(NFS4ERR_LAYOUTTRYLATER)
# STUB do state locking and check on iomode,offset,length triple
@@ -2047,7 +2046,7 @@ class NFS4Server(rpc.Server):
# "The server MUST specify...an ONC RPC version number equal to 4",
# Per the May 17, 2010 discussion on the ietf list, errataID 2291
# indicates it should in fact be 1
- return pipe.send_call(prog, 1, 0, "", credinfo)
+ return pipe.send_call(prog, 1, 0, b"", credinfo)
def cb_null(self, prog, pipe, credinfo=None):
""" Sends bc_null."""
diff --git a/nfs4.1/nfs4state.py b/nfs4.1/nfs4state.py
index e57b90a..d675a6b 100644
--- a/nfs4.1/nfs4state.py
+++ b/nfs4.1/nfs4state.py
@@ -215,10 +215,10 @@ class DictTree(object):
def itervalues(self):
def myiter(d, depth):
if depth == 1:
- for value in d.itervalues():
+ for value in d.values():
yield value
else:
- for sub_d in d.itervalues():
+ for sub_d in d.values():
for i in myiter(sub_d, depth - 1):
yield i
for i in myiter(self._data, self._depth):
@@ -250,7 +250,7 @@ class FileStateTyped(object):
# NOTE we are only using 9 bytes of 12
# NOTE this needs to be client-wide, since keys of client.state[]
# must be unique
- return "%s%s" % (struct.pack("!xxxB", self.type),
+ return b"%s%s" % (struct.pack("!xxxB", self.type),
client.get_new_other())
def grab_entry(self, key, klass):
@@ -290,13 +290,13 @@ class DelegState(FileStateTyped):
return True
# Find any delegation - use fact that all are of same type
for e in self._tree.itervalues():
+ # The only thing that doesn't conflict is access==READ with READ deleg
+ if e.deleg_type == OPEN_DELEGATE_READ and \
+ not (access & OPEN4_SHARE_ACCESS_WRITE):
+ return False
+ else:
+ return True
break
- # The only thing that doesn't conflict is access==READ with READ deleg
- if e.deleg_type == OPEN_DELEGATE_READ and \
- not (access & OPEN4_SHARE_ACCESS_WRITE):
- return False
- else:
- return True
def recall_conflicting_delegations(self, dispatcher, client, access, deny):
# NOTE OK to have extra access/deny flags
diff --git a/nfs4.1/sample_code/ds_exports.py b/nfs4.1/sample_code/ds_exports.py
index 5d31148..1975e16 100644
--- a/nfs4.1/sample_code/ds_exports.py
+++ b/nfs4.1/sample_code/ds_exports.py
@@ -6,4 +6,4 @@ from fs import StubFS_Mem
def mount_stuff(server, opts):
B = StubFS_Mem(2)
- server.mount(B, path="/pynfs_mds")
+ server.mount(B, path=b"/pynfs_mds")
diff --git a/nfs4.1/server_exports.py b/nfs4.1/server_exports.py
index ef857ee..1271c4a 100644
--- a/nfs4.1/server_exports.py
+++ b/nfs4.1/server_exports.py
@@ -4,22 +4,22 @@ from dataserver import DSDevice
def mount_stuff(server, opts):
"""Mount some filesystems to the server"""
# STUB - just testing stuff out
- A = StubFS_Disk("/tmp/py41/fs1", opts.reset, 1)
+ A = StubFS_Disk(b"/tmp/py41/fs1", opts.reset, 1)
B = StubFS_Mem(2)
C = StubFS_Mem(3)
- server.mount(A, path="/a")
- server.mount(B, path="/b")
- server.mount(C, path="/foo/bar/c")
+ server.mount(A, path=b"/a")
+ server.mount(B, path=b"/b")
+ server.mount(C, path=b"/foo/bar/c")
if opts.use_block:
dev = _create_simple_block_dev()
E = BlockLayoutFS(5, backing_device=dev)
- server.mount(E, path="/block")
+ server.mount(E, path=b"/block")
if opts.use_files:
dservers = _load_dataservers(opts.dataservers, server)
if dservers is None:
return
F = FileLayoutFS(6, dservers)
- server.mount(F, path="/files")
+ server.mount(F, path=b"/files")
def _create_simple_block_dev():
from block import Simple, Slice, Concat, Stripe, BlockVolume
--
2.53.0
next reply other threads:[~2026-03-27 4:18 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-27 4:16 Jianhong Yin [this message]
2026-03-27 4:16 ` [PATCH 2/4] pynfs: more nfs4.1/nfs4server.py fixes Jianhong Yin
2026-03-27 4:16 ` [PATCH 3/4] pynfs: fix nfs4.1/nfs4server.py error with python3.12+ Jianhong Yin
2026-03-27 4:16 ` [PATCH 4/4] pynfs: fix various types of errors in nfs4.1/nfs4proxy.py Jianhong Yin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260327041620.2115456-2-jiyin@redhat.com \
--to=jiyin@redhat.com \
--cc=bcodding@redhat.com \
--cc=calum.mackay@oracle.com \
--cc=jlayton@kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=smayhew@redhat.com \
--cc=yin-jianhong@163.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox