Skip to content

Fix SFTP prune deadlock when the connection pool has one client#375

Merged
folbricht merged 1 commit into
masterfrom
sftp-prune-deadlock
Jul 12, 2026
Merged

Fix SFTP prune deadlock when the connection pool has one client#375
folbricht merged 1 commit into
masterfrom
sftp-prune-deadlock

Conversation

@folbricht

Copy link
Copy Markdown
Owner

SFTPStore.Prune holds a client from the connection pool for the entire walk of the store, and removing an unreferenced chunk went through RemoveChunk, which waits for another client from the pool. With a single-connection store (-n 1), the first chunk to delete blocked forever waiting for a connection that could never be returned, hanging the prune command indefinitely.

The fix deletes chunks over the connection the prune already holds: the removal logic moves to a removeChunk method on the connection (SFTPStoreBase), RemoveChunk keeps its pool-acquire behavior and delegates, and Prune calls the method on its held client.

Since the repo had no SFTP test coverage (the store needs an SSH server), the new test doubles the test binary as the ssh command via CASYNC_SSH_PATH: when re-executed with a marker environment variable it serves the SFTP protocol on stdin/stdout using the server included in the existing github.com/pkg/sftp dependency. The regression test runs a prune against a single-connection store and fails on timeout if the removal deadlocks (verified against the unfixed code). Skipped on Windows, where the URL path can't address the local filesystem served by the test server.

SFTPStore.Prune holds a client from the connection pool for the whole
walk of the store. Removing an unreferenced chunk went through
RemoveChunk, which waits for another client from the pool, so a prune
over a store configured with a single connection (-n 1) blocked forever
as soon as it found a chunk to delete.

Delete chunks over the connection the prune already holds instead.

The test doubles the test binary as the ssh command, serving the SFTP
protocol on stdin/stdout, so it runs without an SSH server.
@folbricht
folbricht merged commit d4fa4e9 into master Jul 12, 2026
3 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.

1 participant