Skip to content

Block sleep during backups - #2410

Open
rzeigler wants to merge 11 commits into
borgbase:masterfrom
rzeigler:block-sleep
Open

rzeigler wants to merge 11 commits into
borgbase:masterfrom
rzeigler:block-sleep

Conversation

@rzeigler

@rzeigler rzeigler commented Feb 17, 2026 •

Copy link
Copy Markdown
Contributor

Description

Use systemd on linux and iokit on mac to prevent sleep when borg create and borg init are running

Related Issue

Not an issue but seems like some people would want this.
#845

Motivation and Context

When borg goes to sleep things like network hiccups can occur, even if you are backing up to a local repo that happens to be on a network share. Nothing is ever going to be fully reliable but this should prevent the user from seeing low level borg errors because the system slept mid backup.

There is a tradeoff here in that it is possible for an initial backup to run for so long that it forces a system to do a low battery power off. It may make sense to extend this in the future with an option to skip backups when on battery power.

I've implemented this directly using dbus & objc rather than pulling in a library since its ultimately fairly small.

I am also not sure what set of operations should prevent sleep, init and create seemed like reasonable places to start but adding new job types should be easy.

How Has This Been Tested?

I performed a sequence of repo initialization and backup creation.
On linux I monitored the output via systemd-inhibit --list
On mac I monitored the output via pmset -g assertionslog

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • I have read the CONTRIBUTING guide.
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

I provide my contribution under the terms of the license of this repository and I affirm the Developer Certificate of Origin.

Currently this only works using systemd's login1 and returns a stub implementation otherwise.
Also switches the borg jobs to declare themselves as being inhibited.
@rzeigler
rzeigler force-pushed the block-sleep branch 2 times, most recently from 720686c to ec3cfff Compare September 30, 2026 19:43
@rzeigler

Copy link
Copy Markdown
Contributor Author

@m3nu Apologies for the ping. Is there a path to merging this? If not, I will stop maintaining it against merge conflicts.

@m3nu m3nu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this, the feature is wanted (#845). A few things before merging:

Blocking

  1. FdoInhibitor._fd is never initialized. If the logind call fails (Flatpak without login1 access, no elogind, polkit denial), uninhibit() raises AttributeError. Nothing catches it, so the SiteWorker thread dies with current_job still set and that repo can't run backups until Vorta restarts. Set _fd = None in __init__, and make sure __exit__ can't raise.
  2. os.close(self._fd.fileDescriptor()) closes an fd that QDBusUnixFileDescriptor owns, and Qt closes it again when the object is freed. With several threads, the second close can hit an fd that has been reused. Just drop the reference.
  3. On Linux, shutdown:sleep + block blocks suspend the user asked for and also shutdown/reboot, while on macOS PreventUserIdleSystemSleep only stops idle sleep. Please make the two match (e.g. idle:sleep, or sleep with delay), and don't block shutdown.

Also
4. Re-indenting all of run() is most of the diff and the reason for your merge conflicts. Keep the body unchanged as _run() and do with self.get_inhibitor(): self._run().
5. should_inhibit could be a class attribute on BorgCreateJob/BorgInitJob instead of overriding __init__.

should_inhibit is now a class attribute
make run delegate to a _ method to  minimize diff

stub the darwin import in test_darwin to allow test execution on linux
Initialize with None as _fd in case the inhibit call fails

set._fd = None instead of explicitly closing.
Relies on cpython ref-count for timely inhibitor release
Mac does not appear to expose an equivalent to shutdown:sleep so use idle
@rzeigler

Copy link
Copy Markdown
Contributor Author

I noticed that logind's idle is translated to 'prevent screen blank' by the DEs. This is the closest to the IOPM assertion but the desktops re-interpret it themselves. I am going to rework the linux implementation in another commit that uses the xdg inhibit portal instead of logind. This should make flatpak better supported anyway and exposes Suspend which should be the closest.

@rzeigler

Copy link
Copy Markdown
Contributor Author

@m3nu i think this covers the smaller changes as well as the difference between Mac and Linux behavior. It should also support being a flatpak now as well.

This branch has not been deployed

No deployments
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.

2 participants