Skip to content

Commit f44f2b6

Browse files
authored
Merge pull request #2846 from bobleer/bob/fix-remote-sftp-handle-lifecycle
fix(remote-ssh): prevent SFTP handle exhaustion after repeated file operations
2 parents 71266d0 + 175d8c2 commit f44f2b6

8 files changed

Lines changed: 1064 additions & 119 deletions

File tree

‎docs/features/remote-workspaces.md‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,27 @@ The configured Docker CLI remains the security boundary. OpenBitFun does not exp
9999
the Docker daemon over the network or bypass the current user's Docker
100100
permissions.
101101

102+
### SFTP handle ownership
103+
104+
Whole-file SFTP transfers wait for CLOSE acknowledgement before reporting
105+
success, including reads. The file guard retains cleanup ownership after cancellation,
106+
I/O errors, or a dropped streaming reader; it also receives and closes late OPEN
107+
replies after the caller stops waiting. Writes are not replayed if their outcome
108+
is uncertain. A failed close or timed-out OPEN retires the affected SFTP subsystem
109+
so its unknown handles and client accounting cannot poison later operations.
110+
111+
Full and bounded directory enumeration use the same serialized raw SFTP path,
112+
which closes directory handles on errors as well as success. Cancellation retires
113+
that directory subsystem, and subsequent enumeration replaces it without
114+
invalidating the SSH transport or the separate file subsystem. No persisted
115+
profile, workspace, or wire shape changes are required.
116+
117+
The locked russh-sftp 2.3 dependency sends CLOSE on ordinary file drop without
118+
reducing its client-side handle count. Relying on that drop alone can therefore
119+
produce `Limit exceeded: handle limit reached` even after the server has closed
120+
every file. See [Desktop troubleshooting](../../src/apps/desktop/README.md#remote-ssh-file-handle-errors)
121+
for recovery guidance.
122+
102123
## Search on hosts without ripgrep
103124

104125
Agent Grep keeps one matching and result-processing implementation. For

‎src/apps/desktop/README.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,21 @@ controls can continue driving a host session, but do not expose WSL connection
4747
setup. Detached Dispatch does not provision WSL connections. SSH port forwarding
4848
is unavailable for native WSL targets; use Windows WSL networking to reach a
4949
Linux service.
50+
51+
## Remote SSH file handle errors
52+
53+
If writing files and browsing directories both start failing with
54+
`Limit exceeded: handle limit reached`, update OpenBitFun to a build containing
55+
the SFTP handle-lifecycle fix. Earlier builds can exhaust a client-side counter
56+
even when the server has already closed the files. Save ongoing work before
57+
manually disconnecting and reconnecting the remote workspace as a temporary
58+
recovery; reconnecting can interrupt its terminals and commands.
59+
60+
This message alone does not establish a server configuration problem. Raising
61+
server limits only delays a leaked-counter failure. Running `ulimit` in a new
62+
SSH shell does not change the limits of the already-running SFTP subsystem.
63+
OpenBitFun does not modify the remote user's shell startup files, SSH daemon
64+
configuration, or OS limits automatically. If the problem persists after the
65+
fix, capture the OpenBitFun version and logs plus the server's SFTP implementation
66+
and advertised limits so genuine concurrent-handle or server resource exhaustion
67+
can be distinguished from a client lifecycle problem.

‎src/crates/services/services-integrations/AGENTS.md‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,13 @@ On Windows with an initialized WSL distribution, set `OPENBITFUN_TEST_WSL_DISTRO
125125
and run `cargo test -p openbitfun-services-integrations --no-default-features
126126
--features remote-ssh-concrete --lib wsl_windows_workspace_transport -- --ignored`
127127
for binary filesystem/stdio, exit status, cancellation, and saved reconnect.
128+
129+
For SFTP handle ownership and cancellation regressions, run
130+
`cargo test --locked -p openbitfun-services-integrations --no-default-features
131+
--features remote-ssh-concrete --lib
132+
remote_ssh::manager::tests::workspace_sftp::`. These loopback SSH/SFTP tests
133+
advertise a small handle limit and are included in the existing CI
134+
`workspace_` filter. To exercise real OpenSSH file IO over loopback SSH, set
135+
`OPENBITFUN_TEST_SFTP_SERVER` to an installed `sftp-server` executable and run
136+
the same command with the filter ending in
137+
`workspace_sftp::openssh_real_files_over_loopback_ssh -- --ignored`.

0 commit comments

Comments
 (0)