Skip to content

daemon: never run the detach handshake under the shells lock - #413

Merged
ethanpailes merged 1 commit into
shell-pool:masterfrom
dob323:fix/detach-shells-lock
Aug 26, 2026
Merged

daemon: never run the detach handshake under the shells lock#413
ethanpailes merged 1 commit into
shell-pool:masterfrom
dob323:fix/detach-shells-lock

Conversation

@dob323

@dob323 dob323 commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

The client_connection/client_connection_ack exchange is a rendezvous, so it only completes while the shell->client thread sits in its select loop. A client whose socket has stopped draining (a stalled ssh window, a suspended laptop) leaves that thread blocked in write(), and handle_detach ran the exchange while still holding the global shells lock — one unresponsive client wedged every list, attach, detach and kill in the daemon.

This resolves the requested names to Arcd ctl handles under the shells lock, drops it, then runs each handshake with the same bounded send/recv timeouts the session-message detach path already uses. A session that cannot complete the handshake in time is reported as not attached instead of being allowed to stall the daemon.

Regression test regression::detach_of_stalled_client_does_not_wedge_daemon: SIGSTOP the attach client, flood the socket buffers, detach. It times out on master and passes with the patch.

Found by stress-testing shpool 0.11.0 under a session manager that drives many concurrent sessions; we have been running this fix in production for a week. AI disclosure, as requested on #406: drafted with an AI assistant, reviewed and tested by a human before submission.

@ethanpailes ethanpailes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good, can you rebase against HEAD? My comments are mostly just nits.

Thanks for the fix!

Comment thread shpool/tests/regression.rs Outdated
Comment thread libshpool/src/daemon/server.rs Outdated
Comment thread libshpool/src/daemon/server.rs Outdated
@dob323
dob323 force-pushed the fix/detach-shells-lock branch from 60cc844 to 455150a Compare August 17, 2026 20:15
@ethanpailes
ethanpailes force-pushed the fix/detach-shells-lock branch 2 times, most recently from 5723448 to 924ede3 Compare August 26, 2026 20:13
client_connection/client_connection_ack are rendezvous channels, so the
exchange only completes while the shell->client thread sits in its select
loop. A client whose socket stopped draining (a stalled ssh window, a
suspended laptop) leaves that thread blocked in write(), and handle_detach
ran the exchange while still holding the global shells lock -- one
unresponsive client wedged every list, attach, detach and kill in the
daemon.

Resolve names to Arc'd ctl handles under the lock, drop it, then run each
handshake with the same bounded send/recv timeouts the session-message
detach path already uses. A session that cannot complete the handshake is
reported as not attached instead of being allowed to stall the daemon.

Regression test: stop the attach client with SIGSTOP, flood the socket
buffers, detach. On unpatched master the daemon wedges and the test times
out; patched, detach answers and a follow-up list completes.
@ethanpailes
ethanpailes force-pushed the fix/detach-shells-lock branch from 924ede3 to c025172 Compare August 26, 2026 20:20
@ethanpailes

Copy link
Copy Markdown
Contributor

I made some minor cleanups and rebased.

@ethanpailes
ethanpailes merged commit 140df46 into shell-pool:master Aug 26, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants