OmniCube Reference Manualdefault.conf(5)

default.conf(5)

File Formats · OmniCube · August 10, 2026

NAME

default.conf, policies - OmniCube snapshot retention policy file

SYNOPSIS

/opt/omnicube/backup/policies/default.conf

/opt/omnicube/backup/policies/policy.conf

/var/opt/omnicube/backup/policies/policy.conf

DESCRIPTION

A snapshot policy file tells autosnap(8) how many ZFS snapshots of each cadence to create, autocleansnap(8) how many to keep, and autosync(8) where to replicate them. Each policy is a plain bash(1) fragment that the three jobs source into their own shell, so the file is a set of shell assignments and not a key/value format parsed by OmniCube itself.

default.conf is the policy shipped with the package and the one used by every dataset that does not name another. Additional policies are ordinary files in the same directory named policy.conf and are selected per dataset (see Policy resolution below).

The jobs never read a policy for its own sake: they first enumerate the datasets they are responsible for, using the site-prefixed ZFS user properties described in omnicube(7), and then resolve one policy per dataset:

autosnap(8)

processes every dataset with site:snapshotting=yes and uses RETENTION[type] to decide which snapshots to create.

autocleansnap(8)

processes the same site:snapshotting=yes datasets across every configured svc:/omnicube/sysadm instance and uses RETENTION[type] to decide how many to keep, plus the BKP* keys to clean the remote counterparts.

autosync(8)

processes every dataset with site:remotebackup=yes and uses the BKP* keys, IS_SYNC and IS_ENCRYPT to replicate snapshots to the backup host.

File syntax

*

The file is sourced by bash(1). One assignment per line, no white space around =, shell quoting rules apply.

*

A line whose first non-blank character is # is a comment. Blank lines are ignored.

*

RETENTION is a bash associative array and must be declared before use, with declare -A RETENTION as the first statement of the file. Without the declaration the RETENTION[type]=N assignments silently become assignments to element 0 of an indexed array and the policy has no effect.

*

Anything else valid in a shell script is accepted, because the file is executed. Do not rely on this: the consumers only read the variables listed in KEYS below, and any command in the file runs with the privileges of the job.

Policy resolution

The policy of a dataset is the value of its site:snappolicy ZFS user property, where site is the value of config/site on the SMF instance the job runs against (svc:/omnicube/sysadm:default unless overridden; see ENVIRONMENT). The property value is a bare policy name without the .conf suffix. It is resolved by get_snap_policy_path in omnicube_utils(3) (see also oc_policy(3)) in this order:

1.

An unset property, an empty value, or the ZFS "no value" placeholder - is normalised to the name default.

2.

/var/opt/omnicube/backup/policies/policy.conf is used if it exists. This is the site-local directory: a file placed here shadows the packaged policy of the same name and survives a package upgrade.

3.

Otherwise /opt/omnicube/backup/policies/policy.conf is used. This is the packaged directory, and the only file the package ships into it is default.conf.

4.

If neither path exists the job logs Backup policy policy does not exist through error() (syslog plus a throttled oc-alert mail) and skips the dataset. No snapshot is created, kept or sent for it.

Overriding is therefore per file and per dataset, never per key: a policy file is used whole or not at all. There is no inheritance from default.conf into another policy and no merging of individual keys. Each consumer clears the policy variables with unset before sourcing, so a key a policy does not set is unset for that dataset rather than left over from default.conf or from the dataset processed just before it. Every policy file must consequently be self-contained: copy default.conf and edit it rather than writing a file that sets only the keys that differ.

autocleansnap(8) is the one exception, and it merges across instances rather than across files. It enumerates every svc:/omnicube/sysadm instance, collects the distinct policies that the instances' own site:snappolicy properties select for one dataset, and keeps, for each snapshot type, the highest RETENTION[type] any of those policies defines — the most conservative value wins, so no instance's policy can cause another instance's snapshots to be destroyed early. The BKP* keys are not merged: remote cleanup is performed once per policy, each with its own destination.

KEYS

Each key is introduced by its units and its default, in parentheses. The default given is the value assigned in the shipped default.conf; "unset" means the key is absent from default.conf and the consumers' fallback applies.

Retention

RETENTION[type]

(number of snapshots; see below.) How many snapshots of cadence type to create and to keep. type is one of frequent, hourly, daily, weekly or yearly. The shipped default.conf sets RETENTION[yearly]=0, RETENTION[weekly]=1, RETENTION[daily]=4, RETENTION[hourly]=6 and RETENTION[frequent]=0.

The value is interpreted differently by the two jobs, and the difference matters:

autosnap(8)

0 or unset means do not create snapshots of this type; a value greater than 0 means create one on every tick of that cadence (subject to the -time and -day gates below). The numeric value itself is not a limit here.

autocleansnap(8)

unset means leave existing snapshots of this type alone — they may be managed by something outside these policies. A value of 0 is an explicit "keep none" and destroys every snapshot of that type. A value N greater than 0 keeps the N newest and destroys the rest, oldest first.

A value that is not a string of digits is a configuration error. Both jobs log a warning naming the policy and the type and then skip that type (autosnap skips creation, and autocleansnap skips cleanup) rather than treating the value as 0, which shell arithmetic would otherwise do.

Deletion is additionally gated by the per-snapshot safety properties site:bckcandel, site:insync and site:remotebackup; a snapshot that a remote-backed instance has not yet confirmed as sent is kept regardless of the retention count. See autocleansnap(8).

RETENTION[type-time]

(hour of the day, 0-23; unset.) Read by autosnap(8) only. When set, a snapshot of that type is created only on the run whose date +%H equals this value; on every other run the type is skipped. Unset means create on every run of the job, i.e. at whatever cadence cron(8) invokes it. Leading zeros are accepted (the value is normalised with printf's %d conversion), so 03 and 3 are the same hour.

RETENTION[type-day]

(day of the week, 1-7, Monday to Sunday; unset.) Read by autosnap(8) only. When set, a snapshot of that type is created only on the run whose date +%u equals this value. Unset means every day. Combines with RETENTION[type-time] — both gates must match on the same run.

Replication

BKPUSER

(user name; JDOE.) Login on the backup host used for ssh, zfs recv and remote zfs destroy. Validated with validate_name before it reaches a command line, so it must begin with an alphanumeric character followed by alphanumerics, dot, underscore or hyphen. The shipped value is a placeholder and must be changed. autosync(8) skips a dataset whose policy fails this check; autocleansnap(8) warns and disables remote cleanup for that policy but still cleans locally.

BKPHOST

(host name; EXAMPLE.COM.) Backup host. Same validation and the same failure behaviour as BKPUSER, and likewise a placeholder in the shipped file. Both jobs pre-flight the host with a non-interactive ssh probe (ssh_reachable in oc_ssh(3)) before locking anything, and skip the dataset when it fails; the host key must already be in known_hosts because StrictHostKeyChecking=yes is enforced.

BKPDS

(ZFS dataset; omnicube/backup.) Destination dataset on the backup host. Its meaning depends on IS_SYNC:

IS_SYNC=1

root-pool replacement. The local dataset's top-level pool name is replaced by BKPDS, the rest of the path being preserved, so rpool/zones/VM/root becomes BKPDS/zones/VM/root. BKPDS must therefore be a pool or a single dataset with no path components of its own.

IS_SYNC=0

legacy container mode. On a first sync the whole local path is nested under BKPDS, so rpool/zones/VM becomes BKPDS/rpool/zones/VM. If the backup host already holds a dataset whose leaf name matches the zone, autosync(8) sends under that dataset's parent instead, so an existing replication chain is continued rather than duplicated. Because the destination depends on remote state, autocleansnap(8) does not clean remote snapshots in this mode; they are left to their own cycle.

In both modes the value is validated with validate_dataset (alphanumerics, dot, underscore, hyphen and /). It is required unless BKPZP is set.

BKPZP

(ZFS dataset; unset.) Zones-path mirror. When set it takes precedence over BKPDS and over IS_SYNC: the destination is BKPZP followed by whatever follows the first /zones/ segment of the local dataset name, so with BKPZP=dpool/zones both rpool/zones/VM and tank/zones/VM map to dpool/zones/VM. A dataset with no /zones/ segment cannot be mapped: the dataset is skipped with a warning. autosync(8) also warns when BKPZP and BKPDS are both set, and asks for BKPDS to be removed from the policy.

IS_SYNC

(0 or 1; 0.) Selects the BKPDS mode described above. Any other value is a configuration error: autocleansnap(8) warns and treats it as 0, which disables remote cleanup for that policy. Note that this key has nothing to do with SYNC and ASYNC zones — it names the replication layout only.

IS_ENCRYPT

(0 or 1; 0.) Read by autosync(8) only. When 1, the receive side runs zfs recv -x encryption so the sent encryption property is discarded and the received dataset takes the encryption of its parent on the backup host. Use it when the source is unencrypted and the destination pool encrypts, or the reverse. Any value other than 1 means no option is passed.

BKPPRIV

(bare command name; empty.) Privilege prefix for the zfs(8) commands (create, recv, destroy) that autosync(8) and autocleansnap(8) run on the backup host. Leave it empty when the backup host is Linux (where pfexec does not exist), when BKPUSER is root, or when the destination datasets are delegated with zfs allow. Set it to pfexec when the backup host is an illumos system and BKPUSER is a non-root account holding an RBAC profile. Only a bare command name is accepted — no arguments, no second command; a value containing anything else is ignored with a diagnostic on stderr and in syslog (_bkp_priv in omnicube_utils(3)). The unprivileged probes are deliberately left unprefixed, so a missing privilege grant surfaces as a failed destroy rather than as a missing snapshot.

EXAMPLES

Example 1: the shipped default.conf

Keep six hourly, four daily and one weekly snapshot, create no frequent and no yearly snapshots, and configure no usable replication destination (the BKP* values are placeholders):

declare -A RETENTION
RETENTION[yearly]=0
RETENTION[weekly]=1
RETENTION[daily]=4
RETENTION[hourly]=6
RETENTION[frequent]=0
amp;
IS_ENCRYPT=0
BKPUSER=JDOE
BKPHOST=EXAMPLE.COM
BKPDS=omnicube/backup
IS_SYNC=0
BKPPRIV=

Example 2: a site policy with timed dailies and a real destination

/var/opt/omnicube/backup/policies/prod.conf, keeping 14 dailies taken at 03:00 and 8 weeklies taken on Sunday, replicating to an illumos backup host with a non-root account:

declare -A RETENTION
RETENTION[hourly]=24
RETENTION[daily]=14
RETENTION[daily-time]=3
RETENTION[weekly]=8
RETENTION[weekly-day]=7
RETENTION[frequent]=0
RETENTION[yearly]=0
amp;
IS_ENCRYPT=0
IS_SYNC=1
BKPUSER=ocbackup
BKPHOST=bkp01.example.com
BKPDS=dpool
BKPPRIV=pfexec

Attach it to a dataset and let the jobs pick it up (the efit prefix below is this site's config/site value):

pfexec zfs set efit:snapshotting=yes   rpool/zones/zvm01
pfexec zfs set efit:remotebackup=yes   rpool/zones/zvm01
pfexec zfs set efit:snappolicy=prod    rpool/zones/zvm01

Example 3: local-only high-cadence snapshots

A policy for a dataset that needs minute-granularity local recovery but no off-node copy. Note that @frequent- snapshots are excluded from replication by autosync(8) in any case:

declare -A RETENTION
RETENTION[frequent]=60
RETENTION[hourly]=24
RETENTION[daily]=7

weekly and yearly are left unset, so autocleansnap(8) does not touch snapshots of those types even if some exist, and BKPUSER and BKPHOST are absent, which is harmless as long as the dataset is not marked site:remotebackup=yes.

Example 4: checking which policy a dataset resolves to

zfs get -H -o value efit:snappolicy rpool/zones/zvm01
ls -l /var/opt/omnicube/backup/policies/prod.conf \\
      /opt/omnicube/backup/policies/prod.conf

The first of those two paths that exists is the file in force.

FILES

/opt/omnicube/backup/policies/default.conf

The packaged default policy. Overwritten by package upgrades; do not edit it in place.

/opt/omnicube/backup/policies/policy.conf

Packaged policies. Searched second.

/var/opt/omnicube/backup/policies/policy.conf

Site-local policies. Searched first, and the correct place for local modifications, including a local default.conf.

/opt/omnicube/lib/common/utils.sh

Defines get_snap_policy_path and _bkp_priv, which implement the resolution and validation described here.

ENVIRONMENT

OC_SMF_INSTANCE

Selects the svc:/omnicube/sysadm instance whose config/site property supplies the ZFS property prefix, and therefore which site:snappolicy property is consulted. Unset means the default instance. autosync(8) also accepts -i NAME, which overrides the variable. autocleansnap(8) ignores it and iterates over every instance.

SECURITY

A policy file is executed by bash(1) inside jobs that go on to run pfexec zfs locally and privileged commands over ssh remotely. Anything in the file runs with those jobs' privileges, so write access to a policy file is equivalent to root on the node. Both policy directories and every .conf in them must be owned by root and must not be group or world writable. The validate_name and validate_dataset checks on BKPUSER, BKPHOST, BKPDS and BKPZP, and the bare-command-name check on BKPPRIV, exist to stop a typo or a copy-and-paste error from injecting a second command into a remote command line; they are not a containment boundary around an untrusted policy file.

SEE ALSO

oc_policy(3), oc_ssh(3), oc_validate(3), omnicube_utils(3), omnicube(7), autocleansnap(8), autosnap(8), autosync(8).

NOTES

autosnap(8) creates only frequent, hourly, daily and weekly snapshots. RETENTION[yearly] is honoured by autocleansnap(8), so it governs the retention of yearly snapshots created by some other means, but setting it does not cause any to be created.

Snapshot names encode the cadence and the time, from date at creation: frequent-YY-WW-DD-HH-MM, hourly-YY-WW-DD-HH, daily-YY-WW-DD, weekly-YY-WW and yearly-YY. Retention is applied per type by matching the type prefix, so renaming a snapshot takes it out of the policy's control.

Changing a retention count takes effect on the next run of the jobs; lowering one deletes the excess snapshots at that point, subject to the safety properties. Changing BKPDS, BKPZP or IS_SYNC on a policy that is already replicating changes the destination path and starts a new full send, because no snapshot at the new destination is marked site:insync=yes.

A dataset whose site:snappolicy names a file that does not exist is skipped entirely and generates an alert mail on every run of every job. Create the policy or clear the property.

man5/default.conf.5generated 2026-09-02 05:17 CEST