Tags: oferchen/rsync
Tags
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.
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
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)
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.
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
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.
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.
PreviousNext