Skip to content

Fix/max open files settings - #3145

Open
xirvik wants to merge 4 commits into
Novik:masterfrom
xirvik:fix/max-open-files-settings
Open

Fix/max open files settings#3145
xirvik wants to merge 4 commits into
Novik:masterfrom
xirvik:fix/max-open-files-settings

Conversation

@xirvik

@xirvik xirvik commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator

network.max_open_files.set has been an inert stub since 0.16.16 — it logs a
deprecation warning and discards the value. The file and HTTP socket limits belong
to libtorrent's socket manager instead, so the settings field silently does nothing.

Remapping the setter to system.sockets.<category>.max_alloc.set is not enough on
its own. max_alloc is a ceiling that can only lower the allocation, and nothing
takes effect until the socket manager recomputes. Measured against 0.16.19 with a
10240 file allocation: max_alloc.set(20000) leaves max_size at 10240 even after
a recompute, while min_alloc.set(20000) raises it. Raising the limit is the only
thing the setting is used for.

This sends min_alloc and max_alloc together so the allocation lands on exactly
the requested value in either direction, then emits system.sockets.adjust_alloc
once per settings batch, only when one of the two settings was present.

Restricted to 0.16.19 and later. Earlier versions abort on an over-budget
adjust_alloc, and the client cannot check the budget beforehand because its
reserve and min_generic terms are not exposed over RPC. 0.16.19 reports a
regular XMLRPC fault instead. Older versions keep their current behaviour.

Two related problems are fixed alongside it:

get_max_open_http read system.sockets.http.max_alloc, the ceiling rather than
the allocation in effect, so the dialog reported 1000000 against an effective 512.
It now reads system.sockets.http.max_size, matching how max_open_files reads
network.max_open_files. That command has existed since 0.16.15.

The socket manager stages min_alloc/max_alloc until adjust_alloc runs, and a
rejected recompute keeps the staged values — so one over-budget entry also broke
every later recompute, including saves of unrelated settings. The bounds in effect
are now read before being replaced and put back if the recompute is refused.
libtorrent has no revert call of its own, but the bounds are readable and restoring
a state valid moments earlier is accepted; a restore that is itself refused is
logged rather than passed over. This applies to the httprpc path; the client path
builds its batch up front and has no hook on the fault path, so it keeps the
simpler behaviour.

Verified end to end against 0.16.19: setting the field to 20000 raises
system.sockets.files.max_size and network.max_open_files from 10240 to 20000 and
the dialog reads back 20000; an over-budget value returns a clean fault with the
bounds restored, the process alive, and a subsequent valid save on another field
succeeding where it previously failed.

Adds tests/js/setsettings.spec.js covering command construction on both sides of
the version gate and the read-back mapping.

Fixes #3140

xirvik added 2 commits August 2, 2026 17:07
network.max_open_files.set has been an inert stub since 0.16.16: it logs a
deprecation warning and discards the value. The file and HTTP socket limits
belong to libtorrent's socket manager instead.

Remapping the setter to system.sockets.<category>.max_alloc.set is not enough
on its own. max_alloc is a ceiling that can only lower the allocation, and
nothing takes effect until the socket manager recomputes it. Measured against
0.16.19 with a 10240 file allocation, max_alloc.set(20000) leaves max_size at
10240 even after a recompute, while min_alloc.set(20000) raises it. Raising
the limit is the only thing the setting is used for.

Send min_alloc and max_alloc together so the allocation lands on exactly the
requested value in either direction, then emit system.sockets.adjust_alloc
once per settings batch, only when one of the two settings was present. The
commands share the request with the rest of the batch, so a rejected
allocation surfaces as a fault rather than the dialog reverting silently.

Restricted to 0.16.19 and later. Earlier versions abort on an over-budget
adjust_alloc, and the client cannot check the budget beforehand because its
reserve and min_generic terms are not exposed over RPC. 0.16.19 reports a
regular XMLRPC fault instead. Older versions keep their current behaviour.

Fixes Novik#3140
get_max_open_http read system.sockets.http.max_alloc, the ceiling rather than
the allocation in effect, so the settings dialog showed a number orders of
magnitude above the real limit: 1000000 against an effective 512. Read
system.sockets.http.max_size instead, which is what max_open_files already
does through network.max_open_files. That command has existed since 0.16.15,
so every version loading this alias file has it.

The socket manager stages min_alloc/max_alloc until adjust_alloc recomputes
the allocation, and a rejected recompute keeps the staged values. One
over-budget entry therefore also broke every later recompute, including saves
of unrelated settings that only touched the other category. Read the bounds in
effect before replacing them and put them back when the recompute is refused.
libtorrent exposes no revert of its own, but the staged bounds are readable,
and restoring a state that was valid moments earlier is accepted; a restore
that is somehow still refused is logged rather than passed over silently.

Applied to the httprpc path, where sequential control flow makes the
read/write/restore ordering natural. The client path builds its batch up front
and has no hook on the fault path, so it keeps the simpler behaviour.
xirvik added 2 commits August 2, 2026 20:48
A refused settings save told the user nothing. The response carried a fixed
"Warning: XMLRPC call is failed." while the reason -- which allocation would
not fit, and by how much -- reached only the server log. With a low open-file
limit the effect is that a raise is quietly clamped back to the old value and
the fix reads as not working, when rtorrent had in fact explained itself.

rXMLRPCRequest now keeps the faultString it already detects, and the failure
response sends it in place of the generic warning. That is the path the client
already reports through, so nothing in the request layer changes. A fault
nested in a system.multicall array is matched too, which is where a refused
allocation shows up.

Every settings write is also recorded, one line per setting, with the value in
effect before and after and whether it was taken:

  setsettings: max_open_files requested=70000 from=20000 to=20000 rejected
  setsettings: batch rejected (adjust_allocation: total + min_generic + 8
  reserve exceeds max_open : 71152 + 12288 + 8 > 76000)

The "to" side is read back rather than assumed, since a refused batch can
leave a value clamped or untouched, and that difference is the whole question
when a limit does not end up where it was asked to. Settings without a
symmetric getter -- the hash_* trio, which stopped being readable in 0.9.0,
and dht, reported through dht.statistics -- are logged as unavailable rather
than guessed at or dropped.
"XMLRPC call is failed" and "Maybe, rTorrent is down?" are not idiomatic English.
Reword both, keeping the distinction between no reply at all and a call that was
answered with a fault.
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.

The number of open files is displayed incorrectly

1 participant