Locks
restic is already using a lock to avoid running some operations at the same time.
Since resticprofile can run several commands in a profile, it could be better to run the whole batch in a lock so nobody can interfere in the meantime.
For this to happen you can specify a lock file in each profile:
version = "1"
[src]
lock = "/tmp/resticprofile-profile-src.lock"
[src.backup]
check-before = true
exclude = [ "/**/.git" ]
source = [ "~/go" ]
[src.retention]
after-backup = true
before-backup = false
compact = false
keep-within = "30d"
prune = true
version: "1"
src:
lock: "/tmp/resticprofile-profile-src.lock"
backup:
check-before: true
exclude:
- /**/.git
source:
- ~/go
retention:
after-backup: true
before-backup: false
compact: false
keep-within: 30d
prune: true
"src" = {
"lock" = "/tmp/resticprofile-profile-src.lock"
"backup" = {
"check-before" = true
"exclude" = ["/**/.git"]
"source" = ["~/go"]
}
"retention" = {
"after-backup" = true
"before-backup" = false
"compact" = false
"keep-within" = "30d"
"prune" = true
}
}
{
"version": "1",
"src": {
"lock": "/tmp/resticprofile-profile-src.lock",
"backup": {
"check-before": true,
"exclude": [
"/**/.git"
],
"source": [
"~/go"
]
},
"retention": {
"after-backup": true,
"before-backup": false,
"compact": false,
"keep-within": "30d",
"prune": true
}
}
}
For this profile, a lock will be set using the file /tmp/resticprofile-profile-src.lock
for the duration of the profile: check, backup and retention (via the forget command)
Please note restic locks and resticprofile locks are completely independent
Stale locks
In some cases, resticprofile as well as restic may leave a lock behind if the process died (or the machine rebooted).
For that matter, if you add the flag force-inactive-lock
to your profile, resticprofile will detect and remove stale locks:
- resticprofile locks: Check for the presence of a process with the PID indicated in the lockfile. If it can’t find any, it will try to delete the lock and continue the operation (locking again, running profile and so on…)
- restic locks: Evaluate if a restic command failed on acquiring a lock. If the lock is older than
restic-stale-lock-age
, invokerestic unlock
and retry the command that failed (can be disabled by settingrestic-stale-lock-age
to 0, default is 1h).
version = "1"
[global]
restic-stale-lock-age = "2h"
[src]
lock = "/tmp/resticprofile-profile-src.lock"
force-inactive-lock = true
version: "1"
global:
restic-stale-lock-age: 2h
src:
lock: "/tmp/resticprofile-profile-src.lock"
force-inactive-lock: true
"global" = {
"restic-stale-lock-age" = "2h"
}
"src" = {
"lock" = "/tmp/resticprofile-profile-src.lock"
"force-inactive-lock" = true
}
{
"version": "1",
"global": {
"restic-stale-lock-age": "2h"
},
"src": {
"lock": "/tmp/resticprofile-profile-src.lock",
"force-inactive-lock": true
}
}
Lock wait
By default, restic and resticprofile fail when a lock cannot be acquired as another process is currently holding it.
Depending on the use case (e.g. scheduled backups), it may be more appropriate to wait on another process to finish instead of failing immediately.
For that matter, if you add the commandline flag --lock-wait
or configure schedules with schedule-lock-wait
, resticprofile will wait on other backup processes:
- resticprofile locks: Retry acquiring the lockfile until it either succeeds (when the other resticprofile process released the lock) or fail as the lock-wait duration has passed without success.
- restic locks: Evaluate if a restic command failed on acquiring a lock. If the lock is not considered stale, retry the restic command every
restic-lock-retry-after
(default 1 minute) until it acquired the lock, or fail as the lock-wait duration has passed.
Note: The lock wait duration is cumulative. If various locks in one profile-run require lock wait, the total wait time may not exceed the duration that was specified.
restic lock management
resticprofile can retry restic commands that fail on acquiring a lock and can also ask restic to unlock stale locks. The behaviour is controlled by 2 settings inside the global
section:
version = "1"
[global]
# Retry a restic command that failed on acquiring a lock every minute
# (at least), for up to the time specified in "--lock-wait duration".
restic-lock-retry-after = "1m"
# Ask restic to unlock a stale lock when its age is more than 2 hours
# and the option "force-inactive-lock" is enabled in the profile.
restic-stale-lock-age = "2h"
version: "1"
global:
# Retry a restic command that failed on acquiring a lock every minute
# (at least), for up to the time specified in "--lock-wait duration".
restic-lock-retry-after: 1m
# Ask restic to unlock a stale lock when its age is more than 2 hours
# and the option "force-inactive-lock" is enabled in the profile.
restic-stale-lock-age: 2h
"global" = {
# Retry a restic command that failed on acquiring a lock every minute
# (at least), for up to the time specified in "--lock-wait duration".
"restic-lock-retry-after" = "1m"
# Ask restic to unlock a stale lock when its age is more than 2 hours
# and the option "force-inactive-lock" is enabled in the profile.
"restic-stale-lock-age" = "2h"
}
{
"version": "1",
"global": {
"restic-lock-retry-after": "1m",
"restic-stale-lock-age": "2h"
}
}
If restic lock management is not desired, it can be disabled by setting both values to 0.