summaryrefslogtreecommitdiff
path: root/9ns/test/adv_bridge_hostile.py
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-09-19 23:55:47 -0300
committerGabriel Schneider <[email protected]>2026-09-19 23:55:47 -0300
commit3e9f8805f293f622bb885cf849b5ce47dc062ad1 (patch)
tree0f31107fd20e7a9aa065826c891d2d326efc2309 /9ns/test/adv_bridge_hostile.py
parentba996acfcad1698adbf4a1834fe50e73b1c6cab9 (diff)
downloadcloud9-3e9f8805f293f622bb885cf849b5ce47dc062ad1.tar.gz
cloud9-3e9f8805f293f622bb885cf849b5ce47dc062ad1.zip
9ns: --name and /mnt/9p/<name> mounts, qid.path as inode number, interrupts as Tflush
- --name NAME (default derived from the transport: socket basename, tcp-IP-PORT, spawned command, fdN) mounts at /mnt/9p/<name>; --mount still overrides. ensureMountpoint walks down and creates missing components, shadowing the deepest unwritable ancestor. NINE_MOUNT is the only exported variable. - The inode number reported to the kernel is the 9P qid.path for every node, root included; a server handing qid.path 1 to a file (Pardes /self) no longer collides with the root. - FUSE_INTERRUPT for the request in flight becomes Tflush; a blocked read returns EINTR when the server answers the flush, chunked transfers return short counts, other requests arriving meanwhile are stashed and served next. Servers ignoring Tflush still block until they answer. - 9ns-test now covers nine/bridge/fuse; new adv_bridge_interrupt suite (28); 9ns-itest grows to 88 checks. Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to '9ns/test/adv_bridge_hostile.py')
-rwxr-xr-x9ns/test/adv_bridge_hostile.py11
1 files changed, 10 insertions, 1 deletions
diff --git a/9ns/test/adv_bridge_hostile.py b/9ns/test/adv_bridge_hostile.py
index d353541..f676d2f 100755
--- a/9ns/test/adv_bridge_hostile.py
+++ b/9ns/test/adv_bridge_hostile.py
@@ -62,7 +62,8 @@ name_huge / has an entry with a 60000-byte name
name_dots / lists "." and ".." too
rerror_big Twalk to nope: Rerror with 65535 bytes of text
extra_reply Rread on /f: an unsolicited Rclunk (tag 9) precedes the real reply
-never Tread on /f: never reply (hang)
+never Tread on /f: never reply (hang); the server stops reading, so a Tflush is never seen
+never_flush Tread on /f: never reply, but keep serving: log every Tflush and answer Rflush
close_mid Tread on /f: close the socket without replying
renegotiate Tread on /f: an unsolicited Rversion precedes the real reply
length_max Tstat on /f: length = 2**64-1
@@ -142,6 +143,9 @@ class Server:
parent.children[name] = n
return n
+ def log(self, text):
+ print(text, flush=True)
+
# -- framing ---------------------------------------------------------
def frame(self, typ, tag, body):
return s32(7 + len(body)) + s8(typ) + s16(tag) + body
@@ -196,6 +200,8 @@ class Server:
self.fids[fid] = [self.root, False]
return self.frame(Rattach, tag, self.root.qid(self))
if typ == Tflush:
+ oldtag = r.u16()
+ self.log('Tflush tag=%d oldtag=%d' % (tag, oldtag))
return self.frame(Rflush, tag, b'')
if typ == Twalk:
fid, newfid, nw = r.u32(), r.u32(), r.u16()
@@ -292,6 +298,9 @@ class Server:
if m == 'never':
time.sleep(3600)
return None
+ if m == 'never_flush':
+ self.log('Tread tag=%d fid=%d hang' % (tag, fid))
+ return b''
if m == 'close_mid':
return None
if m == 'renegotiate':