test: add more cases for vfsFifoTest
This commit is contained in:
1 parent
3b72ea3aee
commit
6005863c35
1 file changed
+84
@@ -319,3 +319,87 @@ KTEST(sfsBackedFifoReopenAfterCompletedRoundTripGetsFreshWorkingSession)
|
||||
int rfd2 = vfsOpen("/mnt/fifoRoundTrip", oReadOnly);
|
||||
KT_GE(t, rfd2, 0);
|
||||
|
||||
/* A genuinely fresh pipe reports "try again" here, exactly like a
|
||||
first-ever open -- a stale, no-longer-attached handle would instead
|
||||
report -1 forever for an entirely different reason (pipeAt finding
|
||||
nothing "used" at that slot), which the write assertion below is
|
||||
what actually tells apart from this one. */
|
||||
char probe[4];
|
||||
KT_EQ(t, vfsRead(rfd2, probe, sizeof(probe)), -1);
|
||||
|
||||
int wfd2 = vfsOpen("/mnt/fifoRoundTrip", oWriteOnly);
|
||||
KT_GE(t, wfd2, 0);
|
||||
KT_EQ(t, vfsWrite(wfd2, "two", 3), 3);
|
||||
char second[4];
|
||||
memset(second, 0, sizeof(second));
|
||||
KT_EQ(t, vfsRead(rfd2, second, sizeof(second)), 3);
|
||||
KT_TRUE(t, memcmp(second, "two", 3) == 0);
|
||||
|
||||
vfsClose(rfd2);
|
||||
vfsClose(wfd2);
|
||||
KT_EQ(t, vfsUnlink("/mnt/fifoRoundTrip"), 0);
|
||||
}
|
||||
|
||||
KTEST(sfsBackedFifoBindingSurvivesReformatOfAnUnrelatedInode)
|
||||
{
|
||||
/* sfsTest.c's tests each start with their own sfsFormat(), reusing
|
||||
inode numbers dozens of times a boot. A fifo binding left open
|
||||
ACROSS such a reformat (contrived here, but exactly the shape
|
||||
reclaimOpenFds/sched.c would leave behind for a thread that died
|
||||
without closing its fd -- see sched.c) must never let the fresh
|
||||
filesystem's completely unrelated reuse of the same inode number
|
||||
inherit the old, orphaned session. */
|
||||
KT_TRUE(t, sfsFormat());
|
||||
KT_EQ(t, vfsMkfifo("/mnt/fifoGenA"), 0);
|
||||
int32 firstInode = sfsLookup("/fifoGenA");
|
||||
KT_GE(t, firstInode, 0);
|
||||
|
||||
/* Left deliberately open across the reformat below -- an orphaned
|
||||
session, on purpose, is exactly what must NOT leak into the new one. */
|
||||
int staleRfd = vfsOpen("/mnt/fifoGenA", oReadOnly);
|
||||
KT_GE(t, staleRfd, 0);
|
||||
|
||||
/* A full reformat: every old inode number, including firstInode, now
|
||||
means whatever the fresh, empty filesystem below reassigns it to. */
|
||||
KT_TRUE(t, sfsFormat());
|
||||
KT_EQ(t, vfsMkfifo("/mnt/fifoGenA"), 0);
|
||||
int32 secondInode = sfsLookup("/fifoGenA");
|
||||
KT_GE(t, secondInode, 0);
|
||||
/* Deterministic on a freshly formatted, otherwise-empty filesystem:
|
||||
both are the very first entry created after root, so the numbers
|
||||
collide -- exactly the scenario that makes the generation check
|
||||
necessary rather than merely defensive. */
|
||||
KT_EQ(t, secondInode, firstInode);
|
||||
|
||||
int rfd = vfsOpen("/mnt/fifoGenA", oReadOnly);
|
||||
int wfd = vfsOpen("/mnt/fifoGenA", oWriteOnly);
|
||||
KT_GE(t, rfd, 0);
|
||||
KT_GE(t, wfd, 0);
|
||||
KT_EQ(t, vfsWrite(wfd, "new", 3), 3);
|
||||
|
||||
/* The discriminating check: if the binding table wrongly inherited the
|
||||
pre-reformat session (generation check not actually doing its job),
|
||||
staleRfd would be a SECOND reader attached to the very same
|
||||
underlying pipe wfd just wrote into, and -- read before rfd below --
|
||||
would steal the payload meant for the new session's own reader.
|
||||
Correct isolation means staleRfd's pipe never had any writer at all
|
||||
(it only ever attached as a reader), so it must still report "try
|
||||
again", never the new session's bytes. */
|
||||
char stalePeek[4];
|
||||
KT_EQ(t, vfsRead(staleRfd, stalePeek, sizeof(stalePeek)), -1);
|
||||
|
||||
char buffer[4];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
KT_EQ(t, vfsRead(rfd, buffer, sizeof(buffer)), 3);
|
||||
KT_TRUE(t, memcmp(buffer, "new", 3) == 0);
|
||||
|
||||
vfsClose(rfd);
|
||||
vfsClose(wfd);
|
||||
/* The orphaned pre-reformat fd is cleaned up here rather than left to
|
||||
leak a pipe.c slot for the rest of the boot -- vfsClose only ever
|
||||
touches pipe.c state (pipeCloseRead), never re-derefs the long-gone
|
||||
inode, so this is safe regardless of what the fresh filesystem did
|
||||
with the number. */
|
||||
vfsClose(staleRfd);
|
||||
vfsUnlink("/mnt/fifoGenA");
|
||||
}
|
||||
Reference in new issue
Block a user