Skip to content

rsyncopts: accept and honor --whole-file/-W#59

Closed
tenox7 wants to merge 1 commit into
gokrazy:mainfrom
tenox7:whole-file-client-option
Closed

rsyncopts: accept and honor --whole-file/-W#59
tenox7 wants to merge 1 commit into
gokrazy:mainfrom
tenox7:whole-file-client-option

Conversation

@tenox7
Copy link
Copy Markdown

@tenox7 tenox7 commented May 6, 2026

Summary

The gokrazy fork parses but never acts on -W. This PR plumbs it end-to-end so callers (rsyncclient.New, rsynccmd.Command) can ask for whole-file mode and have it actually take effect on the wire and in the receiver.

Three coordinated changes:

  1. Parserinternal/rsyncopts/rsyncopts.go: uncomments the --whole-file/-W/--no-whole-file/--no-W entries in gokrazyTable() so the client side actually accepts these flags. Adds an Options.WholeFile() accessor.
  2. Wire (client → daemon)internal/rsyncopts/serveroptions.go: emits W in argstr when whole_file > 0, so the remote daemon learns the client is asking for whole-file mode.
  3. Receiverinternal/receiver/{generator,transfer}.go: plumbs WholeFile through TransferOpts and consults it in recvGenerator to short-circuit to requestFullFile() instead of generating rolling checksums against an existing local file. Wires the field at both internal/maincmd/clientmaincmd.go and rsyncd/rsyncd.go construction sites.

Why

Without this, even after enabling the parser, -W had no observable effect. A pull against an existing partial would still walk the slow delta-sync path because the receiver kept generating sums; pushes were also stuck on the slow path because the daemon never received -W and could not skip its own work.

Test plan

  • go build ./... clean
  • go test ./... pass (full suite, including internal/rsyncopts, rsyncclient, internal/maincmd, integration tests)
  • Repro: before this PR, rsynccmd.Command(\"rsync\", \"-W\", ...) failed with -W: unknown option; after, parses and propagates to wire.

Prior to this change, the gokrazy client option table had --whole-file,
-W, --no-whole-file, and --no-W commented out, so passing -W to
rsyncclient.New / rsynccmd.Command failed with "unknown option". Even when
the underlying field was set programmatically, two downstream sites still
ignored it:

  * ServerOptions did not append W to argstr, so the remote daemon never
    learned the client wanted whole-file mode.
  * The receiver generator unconditionally generated and sent rolling
    checksums against any existing local file, instead of short-circuiting
    to requestFullFile when -W is set.

This commit:

  * Uncomments the three client-side flag entries in gokrazyTable.
  * Adds an Options.WholeFile accessor.
  * Plumbs WholeFile through to receiver.TransferOpts and consults it in
    recvGenerator before opening the local file for sum generation.
  * Emits W in ServerOptions so the daemon sees the flag.

Without these, even after the parser change, a CLI invocation with
"rsync -W rsync://daemon/module/file /local/" against an existing partial
would still fall through the slow delta-sync path; pulls were also slow
because the daemon never received -W and could not skip its own work.
@tenox7 tenox7 force-pushed the whole-file-client-option branch from f58b3e1 to c4fbd58 Compare May 8, 2026 09:09
@tenox7 tenox7 changed the title rsyncopts: accept --whole-file/-W in client option table rsyncopts: accept and honor --whole-file/-W May 8, 2026
@tenox7 tenox7 closed this May 10, 2026
@tenox7 tenox7 deleted the whole-file-client-option branch May 10, 2026 07:40
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