diff options
Diffstat (limited to '9ns/test/mntgen.sh')
| -rwxr-xr-x | 9ns/test/mntgen.sh | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/9ns/test/mntgen.sh b/9ns/test/mntgen.sh index aade76c..7dada53 100755 --- a/9ns/test/mntgen.sh +++ b/9ns/test/mntgen.sh @@ -254,14 +254,18 @@ echo "# --debug and --no-direct-io reach the mntgen dispatcher" DEBUG_ERR=$(timeout 60 "$NS" --mntgen --debug -- sh -c "ls $M/alpha >/dev/null" 2>&1 >/dev/null) expect_contains "--debug traces the dispatcher" "lookup 'alpha'" "$DEBUG_ERR" -echo "# a dial parked on a mute server unwedges when the program exits" -# A server that accepts the connection but never answers Tversion parks the -# dispatcher in the dial (pinned: no dial timeout, no concurrent dial). The -# dial must watch stop_fd through the whole handshake: when the program's -# main flow exits while a background walk is parked there, 9ns must follow it -# out instead of wedging forever (pre-fix it survived SIGTERM). +echo "# a mute server costs only the walks into its own name" +# A server that accepts the connection but never answers Tversion. The dial +# runs on that name's worker, inside the walk that asked, so: every other +# name (and the root) keeps answering; a signal releases the parked walker +# at once (the dial is abandoned, EINTR); a fresh walk parks again and is +# just as interruptible; and when the program exits with a walk still +# parked, 9ns follows it out. Background jobs of a non-interactive sh ignore +# SIGINT, so the parked walker is sent SIGTERM; the foreground `timeout -s +# INT` case covers Ctrl-C. Pre-fix the dial ran on the dispatcher thread and +# parked the whole mount, unkillably, until the program exited. if command -v python3 > /dev/null; then - python3 - "$REG/mute" <<'PYEOF' & + python3 - "$REG/mute" <<'MUTEEOF' & import socket, sys, os path = sys.argv[1] try: @@ -273,22 +277,45 @@ s.bind(path) s.listen(8) while True: conn, _ = s.accept() # accept, then never say a word -PYEOF +MUTEEOF MUTEPID=$! PIDS+=($MUTEPID) sleep 0.3 + MUTE_OUT=$(timeout 60 "$NS" --mntgen -- sh -c ' + stat '"$M"'/mute >/dev/null 2>&1 & W=$! + sleep 0.3 + echo "alpha=$(timeout 5 cat '"$M"'/alpha/build/zig_version)" + echo "root=$(timeout 5 ls '"$M"' | grep -c .)" + echo "readdir_alpha=$(timeout 5 ls '"$M"'/alpha | grep -c .)" + s=$(date +%s%N); kill -TERM $W; wait $W; echo "term_rc=$? term_ms=$(( ($(date +%s%N) - s) / 1000000 ))" + s=$(date +%s%N); timeout -s INT 2 stat '"$M"'/mute >/dev/null 2>&1; echo "int_rc=$? int_ms=$(( ($(date +%s%N) - s) / 1000000 ))" + echo "alpha_again=$(timeout 5 cat '"$M"'/alpha/build/zig_version)" + ' 2>"$TMP/mute.err") + expect_eq "another name is served while a walk into mute is parked" "alpha=$(zig version)" "$(printf '%s\n' "$MUTE_OUT" | grep '^alpha=')" + ROOT_N=$(printf '%s\n' "$MUTE_OUT" | sed -n 's/^root=//p') + [ -n "$ROOT_N" ] && [ "$ROOT_N" -ge 2 ] && pass "the root lists while a walk into mute is parked ($ROOT_N entries)" || fail "the root listing did not answer" "$MUTE_OUT" + READDIR_N=$(printf '%s\n' "$MUTE_OUT" | sed -n 's/^readdir_alpha=//p') + [ -n "$READDIR_N" ] && [ "$READDIR_N" -ge 1 ] && pass "a readdir on another name is served meanwhile" || fail "readdir on alpha did not answer" "$MUTE_OUT" + expect_eq "SIGTERM releases the parked walker (died of the signal)" "term_rc=143" "$(printf '%s\n' "$MUTE_OUT" | sed -n 's/^\(term_rc=[0-9]*\) .*/\1/p')" + TERM_MS=$(printf '%s\n' "$MUTE_OUT" | sed -n 's/.*term_ms=//p') + [ -n "$TERM_MS" ] && [ "$TERM_MS" -lt 1500 ] && pass "released promptly (${TERM_MS}ms)" || fail "release of the parked walker was slow or missing" "term_ms=$TERM_MS" + expect_eq "a fresh walk into mute is interruptible (Ctrl-C after 2s)" "int_rc=124" "$(printf '%s\n' "$MUTE_OUT" | sed -n 's/^\(int_rc=[0-9]*\) .*/\1/p')" + INT_MS=$(printf '%s\n' "$MUTE_OUT" | sed -n 's/.*int_ms=//p') + [ -n "$INT_MS" ] && [ "$INT_MS" -ge 1900 ] && [ "$INT_MS" -lt 4000 ] && pass "the interrupted walk came back on the signal (${INT_MS}ms)" || fail "interrupted walk timing off" "int_ms=$INT_MS" + expect_eq "alpha still served after all that" "alpha_again=$(zig version)" "$(printf '%s\n' "$MUTE_OUT" | grep '^alpha_again=')" + HANG_START=$(date +%s) timeout 20 "$NS" --mntgen -- bash -c "(stat $M/mute >/dev/null 2>&1) & sleep 1" >/dev/null 2>&1 HANG_RC=$? HANG_SECONDS=$(( $(date +%s) - HANG_START )) if [ "$HANG_RC" -eq 124 ] || [ "$HANG_SECONDS" -ge 15 ]; then - fail "9ns unwedges after the program exits a parked dial" "rc=$HANG_RC after ${HANG_SECONDS}s (wedged)" + fail "9ns exits with a walk still parked in a dial" "rc=$HANG_RC after ${HANG_SECONDS}s (wedged)" else - pass "9ns unwedges after the program exits a parked dial (rc=$HANG_RC after ${HANG_SECONDS}s)" + pass "9ns exits with a walk still parked in a dial (rc=$HANG_RC after ${HANG_SECONDS}s)" fi rm -f "$REG/mute" else - echo "SKIP: mute-server dial-hang check needs python3" + echo "SKIP: mute-server checks need python3" fi echo |
