Linux NFS development
 help / color / mirror / Atom feed
* [PATCH pynfs] RPLY14: reconnect before retransmitting the call
@ 2026-09-23 17:43 Jeff Layton
  2026-09-24 13:14 ` Chuck Lever
  2026-09-24 21:46 ` NeilBrown
  0 siblings, 2 replies; 4+ messages in thread
From: Jeff Layton @ 2026-09-23 17:43 UTC (permalink / raw)
  To: Calum Mackay
  Cc: Chuck Lever, NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey,
	linux-nfs, Jeff Layton

This test recently started failing with a change to the Linux kernel,
but we believe that the test is wrong. This test replays the same call
with the same XID over the same socket without reconnecting in between.

There is language in RFC1813 that implies that a reconnect is necessary
on a retransmit on a reliable transport like TCP. Change the test to
reconnect the socket before retransmitting.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 nfs4.0/lib/rpc/rpc.py           | 25 +++++++++++++++++++++++++
 nfs4.0/servertests/st_replay.py | 10 ++++++++--
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/nfs4.0/lib/rpc/rpc.py b/nfs4.0/lib/rpc/rpc.py
index 7a80241aa127..c530847a46d9 100644
--- a/nfs4.0/lib/rpc/rpc.py
+++ b/nfs4.0/lib/rpc/rpc.py
@@ -315,6 +315,31 @@ class RPCClient(object):
         out.settimeout(self.timeout)
         self.lock.release()
         return out
+
+    def reconnect_same_port(self):
+        """Drop the current connection and reconnect from the same local
+        port, so the server sees a new transport with an unchanged
+        (address, port) cache key. Used to test duplicate reply cache
+        behavior across connections.
+
+        The old socket is reset (RST) rather than closed gracefully: a
+        graceful close leaves the 4-tuple unusable until the server
+        also closes, while an RST frees the source port immediately.
+        """
+        t = threading.currentThread()
+        self.lock.acquire()
+        old = self._socket[t]
+        saddr = old.getsockname()
+        old.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
+                       struct.pack('ii', 1, 0))
+        old.close()
+        out = self._socket[t] = socket.socket(self.af, socket.SOCK_STREAM)
+        out.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        out.bind(saddr)
+        out.connect((self.remotehost, self.remoteport))
+        out.settimeout(self.timeout)
+        self.lock.release()
+        return out
         
     def send(self, procedure, data=b'', program=None, version=None):
         """Send an RPC call to the server
diff --git a/nfs4.0/servertests/st_replay.py b/nfs4.0/servertests/st_replay.py
index 48e5363432ec..fc8282151909 100644
--- a/nfs4.0/servertests/st_replay.py
+++ b/nfs4.0/servertests/st_replay.py
@@ -4,7 +4,7 @@ from xdrdef.nfs4_type import *
 import nfs_ops
 op = nfs_ops.NFS4ops()
 
-def _replay(env, c, ops, error=NFS4_OK):
+def _replay(env, c, ops, error=NFS4_OK, newconn=False):
     # Can send in an error list, but replays must return same error as orig
     if type(error) is list:
         check_funct = check
@@ -18,6 +18,12 @@ def _replay(env, c, ops, error=NFS4_OK):
     try:
         c.get_new_xid = lambda : xid
 
+        if newconn:
+            # Reconnect from the same source port before replaying:
+            # servers may drop a retransmit that arrives on the same
+            # connection as the original call.
+            c.reconnect_same_port()
+
         # note: this is really cheesy: we happen to know the current
         # Linux server implementation will drop a replay if it comes
         # "too quickly" (<.02 seconds).
@@ -260,4 +266,4 @@ def testMkdirReplay(t, env):
     c = env.c1
     c.init_connection()
     ops = c.go_home() + [op.create(createtype4(NF4DIR), t.word(), {})]
-    _replay(env, c, ops)
+    _replay(env, c, ops, newconn=True)

---
base-commit: cd4701827a8261fedbfb4c6e39029fb9671321a6
change-id: 20260923-rply14-d24b334cd6fa

Best regards,
-- 
Jeff Layton <jlayton@kernel.org>


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

end of thread, other threads:[~2026-09-25 14:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-23 17:43 [PATCH pynfs] RPLY14: reconnect before retransmitting the call Jeff Layton
2026-09-24 13:14 ` Chuck Lever
2026-09-24 21:46 ` NeilBrown
2026-09-25 14:04   ` Chuck Lever

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox