Sperre pro Config und atomare checkzfs-Ausgabe #17

Closed
thorsten.spille wants to merge 0 commits from thorsten.spille/fix-2-lock-per-config into main AGit

Behebt #2: überlappende Läufe derselben Config (Cron + Handstart) haben gleichzeitig Snapshots erzeugt und repliziert und sich die Spooldatei in /tmp geteilt (Failed to create snapshot, mv: cannot stat '/tmp/900_zsync_…').

Änderungen

  • Sperre pro Config: das Skript läuft unter flock -n -o erneut; ein zweiter Lauf mit derselben Config wird mit [ERROR] Another run … is still active (pid …) und Exit-Code 1 übersprungen, bevor er etwas tut. Andere Configs laufen weiter parallel. -o, weil der ssh-Master (ControlPersist) sonst die Sperre nach dem Lauf weiter hält (Gegenprobe gemacht). Ohne flock aus util-linux läuft alles wie bisher, mit [WARN].
  • Atomare checkzfs-Ausgabe: eigene Datei pro Lauf (mktemp), als Punktdatei neben den Spool kopiert und umbenannt – lokal und auf der Quelle. Kein Rest mehr in /tmp, Rechte 644 wie bisher.
  • Label nicht doppelt filtern, wenn es schon in snapshot_filter steht.
  • README: Cron-Beispiele (auch TrueNAS) hängen ans Log an (>>), sonst leert ein übersprungener Lauf das Log des aktiven Laufs.
  • Log-Rotation ohne logrotate: geht die Ausgabe in eine Datei, deren Verzeichnis keine logrotate-Config nennt (z. B. TrueNAS im Dataset), rotiert das Skript sie bei 10 MiB und behält 4 komprimierte alte Logs. Nur der Lauf mit der Sperre rotiert; Pipe, Journal und /var/log/bashclub-zsync (paketiertes logrotate) bleiben unverändert.

Replikations- und Löschalgorithmus unverändert.

Tests

  • Szenarien 1–8: verändernde Aufrufe identisch zu main, außer dem gewollten atomaren scp/mv in Szenario 3
  • neu 9-locked (Sperre gehalten → Lauf ohne einen einzigen zfs/ssh-Aufruf übersprungen) und 10-label-in-filter (jedes Intervall nur einmal geprüft; das eine destroy weniger im Vergleich kommt nur vom Stub, der nicht wirklich löscht)
  • echt parallel im Container: zweiter Lauf abgewiesen, erster läuft durch; Neustart trotz zurückgebliebener Hintergrundprozesse möglich; andere Config parallel ok; -h ohne Sperre; ohne flock nur Warnung
  • Log-Rotation im Container: 11 MiB in /mnt/… → rotiert, neues Log mit stdout+stderr; 5 Rotationen → höchstens .1–.4.gz; kleines Log, Verzeichnis in logrotate.d und Pipe → keine Rotation

Closes #2

🤖 Generated with Claude Code

Behebt #2: überlappende Läufe derselben Config (Cron + Handstart) haben gleichzeitig Snapshots erzeugt und repliziert und sich die Spooldatei in /tmp geteilt (`Failed to create snapshot`, `mv: cannot stat '/tmp/900_zsync_…'`). ## Änderungen - **Sperre pro Config:** das Skript läuft unter `flock -n -o` erneut; ein zweiter Lauf mit derselben Config wird mit `[ERROR] Another run … is still active (pid …)` und Exit-Code 1 übersprungen, bevor er etwas tut. Andere Configs laufen weiter parallel. `-o`, weil der ssh-Master (ControlPersist) sonst die Sperre nach dem Lauf weiter hält (Gegenprobe gemacht). Ohne `flock` aus util-linux läuft alles wie bisher, mit `[WARN]`. - **Atomare checkzfs-Ausgabe:** eigene Datei pro Lauf (`mktemp`), als Punktdatei neben den Spool kopiert und umbenannt – lokal und auf der Quelle. Kein Rest mehr in /tmp, Rechte 644 wie bisher. - **Label nicht doppelt filtern**, wenn es schon in `snapshot_filter` steht. - **README:** Cron-Beispiele (auch TrueNAS) hängen ans Log an (`>>`), sonst leert ein übersprungener Lauf das Log des aktiven Laufs. - **Log-Rotation ohne logrotate:** geht die Ausgabe in eine Datei, deren Verzeichnis keine logrotate-Config nennt (z. B. TrueNAS im Dataset), rotiert das Skript sie bei 10 MiB und behält 4 komprimierte alte Logs. Nur der Lauf mit der Sperre rotiert; Pipe, Journal und `/var/log/bashclub-zsync` (paketiertes logrotate) bleiben unverändert. Replikations- und Löschalgorithmus unverändert. ## Tests - Szenarien 1–8: verändernde Aufrufe identisch zu `main`, außer dem gewollten atomaren `scp`/`mv` in Szenario 3 - neu `9-locked` (Sperre gehalten → Lauf ohne einen einzigen zfs/ssh-Aufruf übersprungen) und `10-label-in-filter` (jedes Intervall nur einmal geprüft; das eine `destroy` weniger im Vergleich kommt nur vom Stub, der nicht wirklich löscht) - echt parallel im Container: zweiter Lauf abgewiesen, erster läuft durch; Neustart trotz zurückgebliebener Hintergrundprozesse möglich; andere Config parallel ok; `-h` ohne Sperre; ohne flock nur Warnung - Log-Rotation im Container: 11 MiB in /mnt/… → rotiert, neues Log mit stdout+stderr; 5 Rotationen → höchstens .1–.4.gz; kleines Log, Verzeichnis in logrotate.d und Pipe → keine Rotation Closes #2 🤖 Generated with [Claude Code](https://claude.com/claude-code)
A second run with the same configuration (e.g. cron and a manual start) created
snapshots and replicated at the same time as the active run, and both used the
same spool file in /tmp ("mv: cannot stat").

- the script runs again under flock (util-linux, -o so the background ssh master
  does not keep the lock); a second run is skipped with an error and exit code 1,
  without flock everything runs as before with a warning
- checkzfs writes to a temporary file of the run, which is copied next to the
  spool file as dot file and renamed, locally and on the source
- the snapshot label is not added to snapshot_filter a second time

Tests: scenarios for a held lock and for the label in the filter, hooks in run.sh,
scp stub copies, leftover files are listed.

Refs #2

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README: append to the log in the cron examples
All checks were successful
/ build (pull_request) Successful in 27s
/ test (ubuntu-24.04) (pull_request) Successful in 42s
/ test (debian-13) (pull_request) Successful in 43s
/ test (ubuntu-26.04) (pull_request) Successful in 49s
/ test (debian-12) (pull_request) Successful in 52s
/ publish (pull_request) Has been skipped
/ package (pull_request) Successful in 0s
f7b26fa2be
With ">" a skipped run would empty the log of the run that is still active.

Refs #2

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rotate a log file that is not covered by logrotate
All checks were successful
/ build (pull_request) Successful in 25s
/ test (debian-13) (pull_request) Successful in 43s
/ test (ubuntu-24.04) (pull_request) Successful in 43s
/ test (ubuntu-26.04) (pull_request) Successful in 47s
/ test (debian-12) (pull_request) Successful in 51s
/ publish (pull_request) Has been skipped
/ package (pull_request) Successful in 0s
ecdfc27052
With ">>" in the cron job the log on TrueNAS SCALE (in a dataset, no logrotate)
would grow without limit. If the output is appended to a file whose directory
no logrotate config mentions, the script rotates it at 10 MiB and keeps 4
compressed old logs. Only the run holding the lock rotates; output to a pipe,
the journal or /var/log/bashclub-zsync (packaged logrotate config) is unchanged.

Refs #2

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
Owner

Manuell nach main gemergt (522ae54), CI inkl. publish nach testing grün. Schließe den PR.

Manuell nach `main` gemergt (522ae54), CI inkl. publish nach testing grün. Schließe den PR.
thorsten.spille closed this pull request 2026-10-15 18:22:24 +02:00
All checks were successful
/ build (pull_request) Successful in 25s
/ test (debian-13) (pull_request) Successful in 43s
/ test (ubuntu-24.04) (pull_request) Successful in 43s
/ test (ubuntu-26.04) (pull_request) Successful in 47s
/ test (debian-12) (pull_request) Successful in 51s
/ publish (pull_request) Has been skipped
/ package (pull_request) Successful in 0s

Pull request closed

Sign in to join this conversation.
No reviewers
No labels
bug
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
bashclub/zsync!17
No description provided.