Skip to content

Tags: oferchen/rsync

Tags

v0.6.3

Toggle v0.6.3's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
docs: update CHANGELOG and README for v0.6.3 release (#5505)

Add 45 new entries covering daemon features (pre/post-xfer exec,
--password-command, rsyncd.conf parsing), transfer options (--stop-at
forwarding, --remote-option, --compress-threads), 21 performance
optimizations (no-change scan, FileEntry compaction, flush discipline,
SSH path optimizations, INC_RECURSE RSS reclamation), 4 bug fixes,
3 test entries, and 8 benchmark scaffolds.

Update README "What's New (v0.6.3)" section with highlights.

v0.6.2

Toggle v0.6.2's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
fix(ssh): resolve goodbye-phase deadlock + load ~/.ssh/config in russ…

…h path (#4154)

* fix(ssh): resolve goodbye-phase deadlock + load ~/.ssh/config in russh path

Two SSH transport fixes:

1. Subprocess path deadlock (primary). After the SSH child exits, the
   parent's stderr drain thread could remain parked in `read(2)` on the
   socketpair/pipe endpoint because the kernel had not yet propagated
   EOF -- a re-execed ssh helper occasionally inherits the write end and
   keeps it open for a brief window after the main `ssh` process is
   reaped. `wait_with_stderr()` then blocked forever in
   `JoinHandle::join`, which prevented the rsync process from returning
   to the user even though every protocol byte had already been written
   and the SSH child had exited cleanly.

   Confirmed via gdb on an aarch64 Debian 13 / kernel 6.18 reproducer:
   both threads parked in `futex_do_wait`, drain thread named
   `ssh-stderr-drai` blocked in `syscall()` on the parent end of the
   socketpair while the main thread waited in `pthread_join`. On CI
   (x86_64 Ubuntu 24.04) the same race resolved soon enough that the
   benchmark merely recorded the no-change push at 1.5x upstream rather
   than hanging outright.

   Fix: extend `StderrAuxChannel` with a `shutdown_read()` hook, and
   call it from both `SshConnection::wait*` and
   `SshChildHandle::wait*` once the child has been reaped.
   `SocketpairStderrChannel` holds a `try_clone()` of the parent
   endpoint and shuts it down via `UnixStream::shutdown(Both)`, which
   forces the pending `read(2)` to return zero immediately.
   `PipeStderrChannel` has no safe out-of-band wake-up, so `join()` is
   bounded by `DRAIN_JOIN_TIMEOUT` (50 ms) and the drain thread is
   abandoned if it does not exit in time; it terminates naturally on
   process teardown. All changes stay within the `#![deny(unsafe_code)]`
   policy for `rsync_io`.

   Before (aarch64 reproducer): 10.0 s wall, exit 124 (timeout-killed).
   After: 0.214 s, exit 0 (matches upstream `rsync 3.4.1` at 0.21 s).
   10K-file dataset (177 MB, push to localhost) drops from infinite
   hang to 1.12 s initial / 0.36 s no-change vs upstream 1.02 / 0.19 s.

2. russh path missing `~/.ssh/config`. The embedded transport never
   consulted the user's SSH config, so `Host` aliases, `Hostname`
   rewrites, `User`, `Port`, `IdentityFile`, `IdentitiesOnly`, and
   `IdentityAgent` directives were silently ignored. This is why the
   3-way SSH benchmark's russh runs returned exit 5 on the
   GitHub-hosted runner: russh attempted to connect to `localhost` with
   no matching identity even though the runner had keys configured for
   the alias the test typed.

   Adds `SshConfig::apply_ssh_config(host_alias)` (and a
   `apply_ssh_config_from(path, alias)` variant for tests) plus a
   minimal `~/.ssh/config` parser that handles `Host` patterns with
   `*`/`?`/`!` wildcards and applies the directives above. URL-supplied
   fields win over file directives, with the exception of `Hostname`
   which always overrides the URL alias to match OpenSSH semantics.
   `from_url()` now calls `apply_ssh_config(raw_host)` so the russh
   transport picks up the config automatically.

   Missing, unreadable, or malformed config files are treated as empty
   so a broken config never blocks a transfer.

* style: remove duplicate blank line after default_ssh_config_path

v0.6.1

Toggle v0.6.1's commit message
fix(fast_io): skip criterion io_uring bench on RLIMIT_MEMLOCK failure (

…#3572)

The kernel-level `is_io_uring_available()` probe does not catch ring
allocation failures from RLIMIT_MEMLOCK, which GitHub Actions runners
impose. When the limit is too low, `IoUringReader::open` /
`IoUringWriter::create` fail mid-iteration with ENOMEM and the entire
benchmark process panics, taking down the rest of the suite.

Sentinel-allocate one ring up front (outside `b.iter`). If allocation
succeeds, run the io_uring sub-benchmark; if it fails, log a clear
skip message and continue. The standard_io baseline still runs, and
the rest of the criterion suite remains usable.

Surfaced by Criterion Benchmarks workflow on tag v0.6.1:
> io_uring init failed: Cannot allocate memory (os error 12)

v0.6.0

Toggle v0.6.0's commit message
chore: update Homebrew formulas for v0.6.0 (#3119)

Co-authored-by: oc-rsync-bot <actions@github.com>

v0.5.9

Toggle v0.5.9's commit message
perf: parallelize basis file signature computation in pipeline fill (#…

…2735)

Restructure the pipeline fill loop to compute basis file signatures in
parallel using rayon when the batch size exceeds PARALLEL_STAT_THRESHOLD
(64 files). Signature computation involves opening basis files and
computing rolling + strong checksums - CPU-intensive for large files
with MD4/MD5.

The three-phase approach:
1. Collect files up to available pipeline slots (batch)
2. Compute signatures in parallel via rayon par_iter
3. Send requests sequentially to preserve wire order

Wire protocol is unchanged - only the scheduling of CPU-intensive
signature computation is parallelized. The sender sees identical
NDX + iflags + sum_head + signature blocks in the same order.

v0.5.8

Toggle v0.5.8's commit message
feat: produce distinct Linux artifacts with and without OpenSSL

- musl static builds now produce both pure-Rust and OpenSSL-vendored tarballs
- Pure Rust: *-musl.tar.gz (zero dependencies)
- OpenSSL: *-musl-openssl.tar.gz (vendored, statically linked)
- GNU .deb/.rpm packages include OpenSSL (dynamically linked)
- Fix README: replace inaccurate "single-process" claim with correct
  description of threaded architecture
- Update release template and README to document OpenSSL variants

v0.5.7

Toggle v0.5.7's commit message
Merge pull request #2333 from oferchen/chore/bump-v0.5.7

chore: bump version to v0.5.7

v0.5.5

Toggle v0.5.5's commit message
docs: add release variant table; fix Windows test compilation

Add stable/beta/nightly variant descriptions to README so users know
what to download. Gate child_exit_status_tests module with #[cfg(unix)]
since all tests are Unix-only and imports are unused on Windows.

v0.5.4

Toggle v0.5.4's commit message
fix: remove artifacts, test data, and stale files from repository

Remove 1485 files that should not be tracked:
- test-dest/: 1463 Linux kernel source files (test data artifact)
- Root-level .md files: AI-generated session docs (13 files)
- Build artifacts: .rlib compiled libraries (3 files)
- Benchmark results: benchmark-results.txt, benchmark_results.csv
- Stale files: fix_tests.sh, package-lock.json, googlee6ace3121e2ad895.html
- Binary capture: tools/ci/run_interop.pcap (2.8MB)

Update .gitignore to prevent re-addition of test-dest/, *.rlib,
*.pcap, benchmark results, and package-lock.json.

v0.5.3

Toggle v0.5.3's commit message
fix: correct YAML syntax in brew-formula PR body