Backups can be a real lifesaver and the lack of them can make your life really miserable. I noticed this after my latest btrfs-disaster (yeah.. i switched back to ext4 for now). After this episode which involved some hackish btrfs restore usage I got really serious about backups.
I hear many people rant about systemd and while I can understand some concerns others might have with it I think it solves real problems and can do some pretty amazing stuff. This blog post should give you an overview of how to use some of these features to schedule automated hassle-free backups.
My goal was to be able to schedule backups to be run in specific intervals whenever the backup drive is connected to my notebook. Some more specific requirements were the following:
Ensure a backup is run as soon as possible if
- the system wasn’t running at the time the backup was scheduled
- the drive wasn’t connected at the time the backup was scheduled
Ensure backups are retried if they fail
fstab and Automount
First of all the backup drive needs to be recognized and automatically mounted
after it’s plugged in. I formatted the drive and gave it a label
can use this label to identify the drive and it should always be preferred over
device names such as
sdaX. Another option would be to use an UUID.
I added the following entry to
noauto-option here is important, otherwise the system won’t boot if
the device is not found.
For automatically mounting the partition with the label
backups systemd comes
Create a wants-directory in
media-backups.mount to that directory:
So what does this actually mean? All units in a wants-directory are started as
soon as the unit named in the directory is started successfully. This means that
as soon as the device
is run so that the device will be mounted at
Timers are another awesome feature of systemd and they can be used as a replacement for cron. Each timer unit needs a corresponding unit which will be triggered when the timer is due. Timers can also be written as template units like in my following example timer:
1 2 3 4 5 6 7 8 9 10
Persistent=true ensures that the timer is run as soon as possible
after being due if the system was shut down at that time.
Unit defines the
systemd unit that should be run when the timer is due.
%i is substituted with
whatever is used after the
@ in the unit name i.e.
email@example.com results in
%i having the value
I placed the timer into
$XDG_CONFIG_HOME/systemd/user/ and enabled and started
Scheduling the backup
Let’s take a look at
1 2 3 4 5 6 7
This too is placed into
This service not only enables the service which starts the backup but also tries
running it right away in
Wiring it all up
Finally let’s take a look at
1 2 3 4 5 6 7 8 9 10
This service is responsible for starting the actual backup script. In my case it receives the name of the backup as a parameter and runs it. There are two things to notice here:
WantedBy=media-backups.mount. Sound familiar? This is the Unit that is run when the device is plugged in. So when ever the device is plugged in it will be mounted at
/media/backupswhich in turn triggers all Units in
systemctl --user enableon this service and by doing so creates a symlink in this exact
ExecStartPostis set to disable the service when the command in
ExecStartis run successfully.
To start scheduling a daily backup for home all I need to do is:
systemctl --user start firstname.lastname@example.org (and enable it)
When the timer is due it runs
email@example.com which enables
firstname.lastname@example.org and tries to run it right away. If the drive wasn’t
plugged in at this time the backup will be run as soon as it’s attached again.