NAME
autosnap - create policy-driven ZFS snapshots of flagged datasets
SYNOPSIS
/opt/omnicube/backup/autosnap
DESCRIPTION
autosnap is the creation half of the OmniCube snapshot lifecycle. Driven from cron(8) once an hour, it walks every local ZFS filesystem and volume, keeps those whose user property ${PROPPREFIX}:snapshotting is exactly yes, and creates the periodic snapshots called for by each dataset's snapshot policy. Expiry is the job of autocleansnap(8), replication that of autosync(8).
${PROPPREFIX} is the site prefix read from the SMF property config/site of svc:/omnicube/sysadm:${OC_SMF_INSTANCE:-default} when /opt/omnicube/lib/common/utils.sh is sourced, so all properties below are per-instance and two instances can manage the same pool independently. Selection is
zfs list -H -r -t filesystem,volume -o name,${PROPPREFIX}:snapshotting
with an exact match on the second (tab separated) column, so a value that merely ends in yes selects nothing.
Per dataset, in order: the run-level guard is re-evaluated, so a shutdown starting mid-run stops the job before the next dataset; ${PROPPREFIX}:is_locked is read and the dataset skipped when it is true, meaning another OmniCube job (possibly of another instance) owns the pool; ${PROPPREFIX}:snappolicy is resolved to a file by get_snap_policy_path(), an unset value or - meaning the default policy and an unresolvable one skipping the dataset; the dataset's top-level zpool is marked ${PROPPREFIX}:is_locked=true so cleanup and replication back off; the policy file is sourced after RETENTION has been unset; the due snapshots are created; and the property is inherited away again.
Retention array and scheduling
The policy file is a bash fragment defining the associative array RETENTION; see default.conf(5). Types are considered in the order weekly, daily, hourly, frequent.
The shipped default.conf sets weekly=1, daily=4, hourly=6, frequent=0 and yearly=0, with no -time or -day key, so a dataset on the stock policy gets an hourly snapshot on every run plus a daily and a weekly one whenever that name does not exist yet. Names encode the type and the date:
frequent ${DS}@frequent-$(date +%y-%W-%d-%H-%M)
hourly ${DS}@hourly-$(date +%y-%W-%d-%H)
daily ${DS}@daily-$(date +%y-%W-%d)
weekly ${DS}@weekly-$(date +%y-%W)
yearly ${DS}@yearly-$(date +%y)
An existing name is never recreated (is_snapexists()), so running autosnap more often than the coarsest tick is harmless.
Locking and the is_locked trap
One instance runs at a time; the mutex is the directory ${LOCK_BASE}/${logtag}.sync_pool.lock created by acquire_lock_or_exit(). The sync_pool element of that name is historical: it does not interlock with sync_pool.sh(8), which has a lock of its own.
An EXIT HUP INT TERM trap removes the lock directory and inherits ${PROPPREFIX}:is_locked away on the pool being processed. Without it, a kill between the zfs set and the zfs inherit would leave the property stuck at true, which permanently wedges every later autosnap, autosync(8) and autocleansnap(8) run on that pool, since all three skip a locked dataset. The pool is recorded before the property is set, and zfs inherit on an unset property is harmless.
OPTIONS
This command takes no options and no operands; anything on the command line is ignored.
USAGE
The sample crontab in /opt/omnicube/share/README runs it hourly at six minutes past, thirty minutes ahead of autocleansnap(8):
6 * * * * /opt/omnicube/backup/autosnap >/dev/null
Flag a dataset for the stock policy (property prefix omnicube here) and run one pass by hand from single-user state:
pfexec zfs set omnicube:snapshotting=yes dpool/zones/zethosmariadb01 pfexec zfs set omnicube:snappolicy=default dpool/zones/zethosmariadb01 OC_IGNORE_RUNLEVEL=1 pfexec /opt/omnicube/backup/autosnap
Recover from a hard kill that left both halves of the lock behind:
pfexec zfs inherit omnicube:is_locked dpool pfexec rmdir /var/run/omnicube/omnicubeautosnap.sync_pool.lock
EXIT STATUS
FILES
ENVIRONMENT
SECURITY
Snapshot and property changes use pfexec, so the caller needs the OmniCube RBAC profile (/etc/security/prof_attr.d/omnicube, /etc/security/exec_attr.d/omnicube). Policy files are sourced as bash and run with the caller's privileges: they must be root-owned and not group or world writable.
SEE ALSO
autocleansnap(8), autosync(8), sync_pool.sh(8), default.conf(5), oc_lock(3), oc_policy(3), oc_runlevel(3), omnicube_utils(3), omnicube(7).
NOTES
The type loop covers weekly, daily, hourly and frequent only. The yearly naming rule exists in the code but is unreachable, so autosnap never creates yearly snapshots even with RETENTION[yearly] greater than zero, although autocleansnap(8) does handle the type.
is_locked is set on the top-level zpool, not on the dataset, so snapshotting one dataset briefly blocks OmniCube jobs on every dataset of that pool.