Repository navigation
Conversation
1728663 to
937e646
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #12843 +/- ##
=========================================
Coverage 20.45% 20.45%
- Complexity 21417 21419 +2
=========================================
Files 6487 6487
Lines 589329 589329
Branches 72246 72246
=========================================
+ Hits 120554 120567 +13
+ Misses 455642 455630 -12
+ Partials 13133 13132 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@jmsperu can you please check on 4.21? |
Thanks for the heads up! I see 4.22 already has quiesce and improved error handling. I'll rebase onto 4.22 and update the PR to only include what's still missing: backup timeout, trap handler with VM resume, and free space check. The other PRs (compression, verification, bandwidth throttle, encryption, parallel execution) are still new features on top of 4.22. |
|
Belated reply @abh1sar — you were right, there's significant overlap with what's already landed on main. The quiesce support and EXIT_CLEANUP_FAILED handling from this PR have since been merged upstream (likely via the broader nasbackup.sh improvements in #12822 and others), so those bits are now redundant. What's still uniquely unaddressed by what landed:
I'll rebase against main to drop the overlapping changes and keep only those three, then push again. If you'd rather close this and open a fresh narrower PR with just those bits, also happy to do that — your call. |
937e646 to
0deb4c4
Compare
|
Rebased. Force-pushed 0deb4c4 and changed the base from What landed in main since this PR was opened (via other PRs):
So this PR is now reduced to just the three improvements those didn't cover:
Total: 71 +/3 - on one file. Ready for another look @abh1sar. |
|
Friendly nudge — the new push is sitting on GitHub Actions |
I’ve added you to the collaborators list @jmsperu . With great privileges comes great responsibility… ;) |
|
Friendly bump — this adds defensive hardening around nasbackup.sh:
Latest CI had a single shard failure in |
|
I’ll look at this and your other PRs tomorrow, bandwith permitting @jmsperu . |
There was a problem hiding this comment.
Pull request overview
This PR updates the KVM NAS backup helper script (nasbackup.sh) to improve reliability by adding a backup polling timeout, introducing an EXIT cleanup trap to avoid orphaned mounts/paused VMs, adding a pre-flight free-space check, and supporting optional guest filesystem quiescing via qemu-guest-agent.
Changes:
- Add
BACKUP_TIMEOUTand enforce it in thedomjobinfopolling loop (abort viadomjobaborton timeout). - Add
check_free_space()and call it before writing backup data. - Add an idempotent
cleanup()and installtrap cleanup EXITto ensure cleanup on all exit paths.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
DaanHoogland
left a comment
There was a problem hiding this comment.
co-pilot has some smarter comments than I ;)
|
Friendly nudge — all CI checks are green and the PR is Recap of what this adds to
Backwards-compatible: invoking the script without |
|
@abh1sar , can you have a look at this one, please? |
…ps (apache#12843) Address review feedback on apache#12843 (verified with a stubbed self-test): - domjobinfo 'Failed' branch: exit after cleanup instead of looping until BACKUP_TIMEOUT (the loop never broke on a failed virsh job). - backup_stopped_vm qemu-img convert failure: exit after cleanup so a partial backup is not treated as success; append to the agent log instead of truncating. - backup_stopped_vm success: unmount before returning, mirroring backup_running_vm/ delete_backup. Without this the 'trap cleanup EXIT' fired on success and ran 'rm -rf $dest', deleting the just-completed backup. - mount_operation: test mount's own exit in an if-condition so 'set -eo pipefail' no longer aborts before the check and a piped tee can't mask a mount failure. - cleanup: only umount when the path is actually a mount, so a non-mount umount error doesn't wrongly report EXIT_CLEANUP_FAILED via the EXIT trap.
|
Thanks @DaanHoogland / Copilot. Pushed
While testing this I also found that |
|
This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch. |
… and document the re-entrancy guard The flag is set on entry to cleanup(), not on completion: cleanup() can exit the script itself (EXIT_CLEANUP_FAILED) and that exit fires the EXIT trap, which would re-enter cleanup() while the first call is still running. The name now says so. Signed-off-by: James Peru <jmsperu@gmail.com>
|
@weizhouapache apologies for the slow reply here. The conflicts with #12822 were resolved on 28 Jul (merge of main into this branch) and the PR has been mergeable since. I've just pushed af4fbb8 for the remaining open comments:
Only Sonar coverage is red, and this PR is a shell script, so there is nothing for JaCoCo to measure. Could someone approve-and-run the workflows on the new SHA? |
|
@blueorangutan package |
|
@DaanHoogland a [SL] Jenkins job has been kicked to build packages. It will be bundled with no SystemVM templates. I'll keep you posted as I make progress. |
|
Packaging result [SF]: ✔️ el8 ✔️ el9 ✔️ el10 ✔️ debian ✔️ suse15. SL-JID 19378 |
|
@blueorangutan test |
|
@DaanHoogland a [SL] Trillian-Jenkins test job (ol8 mgmt + kvm-ol8) has been kicked to run smoke tests |
|
[SF] Trillian test result (tid-17067)
|
|
Thanks @DaanHoogland for running Trillian: tid-17067 on 3 Oct came back 156/156 OK, with no errors. The branch is mergeable with 4.22. If it looks good to you, could a committer review and merge it? |
we do ask for testing. @abh1sar can you? |
|
This pull request has merge conflicts. Dear author, please fix the conflicts and sync your branch with the base branch. |
Rebased on the latest main as one commit (the old branch had a merge from main that no longer replays cleanly). Same changes as before, combined with the quiesce and job-abort fixes from apache#14305: - BACKUP_TIMEOUT (default 6 h) bounds the domjobinfo wait loop; the deadline also covers the query retries from apache#14305, and on timeout cleanup() aborts the job through abort_backup_job() before removing the destination - MIN_FREE_SPACE (default 1 GiB) is checked right after mount, for running and stopped VMs - trap cleanup EXIT so every exit path resumes a paused VM, aborts an active backup job and unmounts; CLEANUP_STARTED guards re-entry, and cleanup only removes/unmounts what exists and is mounted - backup_stopped_vm unmounts on success so the trap does not remove a completed backup - mount_operation tests mount's own exit status instead of tee's Signed-off-by: James Peru <jmsperu@gmail.com>
af4fbb8 to
27c7dc6
Compare
|
Rebased on the latest main (27c7dc6), so the conflicts are gone. I folded the branch into one commit because its old merge from main no longer replayed cleanly. The conflict was with #14305 (quiesce fixes) in |
| # Trap ensures cleanup runs on any exit path, including SIGTERM/SIGINT and | ||
| # unexpected errors caught by set -e, not just the explicit failure branches. | ||
| # Prevents orphan NFS mounts from accumulating after non-graceful exits. | ||
| trap cleanup EXIT |
There was a problem hiding this comment.
@jmsperu if the last unmount of a running vm backup fails or times out, wont this trap delete the finished backup? the script carries on, so it can still report success
There was a problem hiding this comment.
Good catch, you are right, and it was worse than one path. Once the share was still mounted, the EXIT trap ran rm -rf on $dest, which at that point is the finished backup on the NAS. For a running VM, if the final umount timed out and the trap's own umount retry then succeeded, the script deleted the backup and still exited 0. A stopped VM backup lost its backup the same way, but at least reported a failure. In stats, $dest can be the root of the backup store, so a failed umount there could delete existing backups.
Fixed in 84c227c:
- A BACKUP_COMPLETE flag is set just before the final unmount. cleanup() removes $dest only for a backup that did not complete. For delete and stats the trap now only unmounts and removes the temporary mount directory.
- Both backup paths unmount through one helper. It tries umount with a time limit twice, then umount -l. If the share still lingers it logs a WARNING and keeps the success status, because the backup is intact.
- If timeout is not installed, plain umount is used.
- An interrupted backup is still aborted and removed as before.
I checked this with a stubbed harness (fake virsh, mount, umount, df, du and a fake NAS directory). Running VM backup with an umount that times out once: before, exit 0 with no files left on the NAS; after, exit 0 with all backup files present. With every umount failing, including the lazy one, the files are kept and the run succeeds with warnings. A failed backup job still exits 1 and its partial files are removed. Stats with a failing umount no longer deletes anything. Shellcheck reports nothing new.
…he cleanup trap Add a BACKUP_COMPLETE flag set just before the final unmount of a running or stopped VM backup. cleanup() now removes $dest only for an unfinished backup; delete and stats never remove anything from the trap. A completed backup is unmounted by one helper that retries a bounded umount, falls back to a lazy umount, and only logs a warning if the share lingers. Claude-Session: https://claude.ai/code/session_011DLKuGySDaq3JQs6SAw3TC
Summary
BACKUP_TIMEOUT(default 6 hours) to prevent indefinitely stuck backup jobs; aborts viadomjobabortwhen exceededEXITtrap withcleanup()that resumes paused VMs, removes temp dirs, and unmounts NFS on any exit (error, signal, or normal) — prevents orphan mounts from accumulatingcheck_free_space()pre-flight check (default 1 GB minimum) before writing backup data-q/--quiesceflag for optionalfsfreeze/thawvia qemu-guest-agent for application-consistent backupsset -eo pipefailfor stricter error handlingmount_operation(): properif mountinstead of broken$?check after pipeumount/rmdirfrom functions (now handled by trap)Motivation
The current
nasbackup.shhas several reliability issues observed in production:until domjobinfo --completed) runs forever if backup stalls, blocking the agent/tmp/csbackup.XXXXX) and paused VMs that never resume (related: KVM NAS backup: VM remains paused indefinitely when backup job fails #12821)$?after a pipe always returns the pipe's exit status, not the command'sTest plan
BACKUP_TIMEOUT=30— verify timeout anddomjobabort-qflag and qemu-guest-agent installed — verify fsfreeze/thaw in logs-qflag without qemu-guest-agent — verify graceful fallback