UFS dump and restore on FreeBSD: Incrementals, Snapshots, and Recovery
Build and test FreeBSD UFS dump/restore workflows with live snapshots, incremental levels, catalog discipline, selective recovery, and safe filesystem restores.
FreeBSD’s dump(8) and restore(8) utilities provide a filesystem-oriented backup path for UFS. dump records files and filesystem metadata; restore can list, extract, or rebuild a filesystem from those archives. They are useful tools, but they are not a complete backup program by themselves. Operators still need to protect archive confidentiality and integrity, maintain the dump-level catalog, preserve off-host copies, and prove that restoration works on the hardware and FreeBSD release they intend to recover.
This workflow is specific to UFS. Do not apply it to ZFS datasets, whose native snapshots and send streams have different semantics, or assume a filesystem-level dump makes a database transactionally consistent. Applications with their own write-ahead logs or backup interfaces need an application-consistent procedure coordinated with filesystem capture.
Understand levels and the dump catalog
A level 0 dump is a full filesystem backup. A higher-numbered level is incremental: it includes files changed since the most recent dump at a lower-numbered level. That means a level 1 archive is not necessarily “changes since yesterday.” If the last lower-level dump was the weekly level 0, a daily level 1 includes all changes since that baseline. A restore plan must retain the complete chain required to reach the target point in time.
By default, dump consults /etc/dumpdates to determine the previous dump times and -u records a successful dump there. This small text file is operational state, not disposable clutter. If jobs run with different catalogs, hosts, or filesystem names, document each pairing and pass the same -D catalog to the corresponding backup job. A missing or replaced catalog can silently change which files an incremental archive contains. The dump -W and dump -w reports can help compare filesystem entries and dump dates, but the manual notes that unrecorded filesystems are not shown by those reports.
Keep every archive labeled with its filesystem, source host, level, completion time, and catalog lineage. Preserve the dumpdates catalog beside backup metadata, but do not let catalog state substitute for archive inventory. A practical retention plan has a known level-0 anchor, all incrementals needed after that anchor, and independent copies outside the source system’s failure domain.
Capture a mounted UFS filesystem consistently
For a mounted, writable filesystem, dump -L asks dump to create and use a UFS snapshot so the archive represents a stable point in time. The snapshot directory must already exist at the root of that filesystem. Check the mount type, capacity, destination, and snapshot path before scheduling the job:
mount -p
df -h /var /backup
test -d /var/.snap
The following example is a level-0 archive of /var; change the path and destination to match the host. /backup should be a separately managed filesystem or remote backup target, not a directory whose loss would accompany failure of /var.
archive="/backup/var-$(date +%Y%m%dT%H%M%S)-level0.dump"
dump -0u -L -f "$archive" /var
status=$?
printf 'dump exit status: %s\n' "$status"
test "$status" -eq 0
In an unattended script, make failure handling explicit: capture the command’s status, alert on nonzero exit, retain warnings, and do not mark the backup successful merely because a file exists. The -L snapshot consumes filesystem resources while it is active, and a full snapshot directory or insufficient space can prevent the intended operation. -L is ignored for an unmounted or read-only filesystem; the output should therefore be checked against the exact mounted source and the archive header. Do not dump an actively changing mounted UFS filesystem without the documented live-snapshot behavior and assume the result is point-in-time consistent.
Use dump -0u for a new baseline and a reviewed level schedule for later runs, for example a weekly level 0 followed by nightly level 1 dumps. That simple schedule re-captures the week’s changed files in each daily level 1 archive. More elaborate schedules can trade archive size for the number of incremental steps needed during recovery. Choose based on actual restore-time objectives, not only on how little data each nightly job writes.
Validate archives before relying on them
Read the archive’s header and list its contents without extracting anything:
restore -N -t -f /backup/var-20261003T020000-level0.dump
-t lists paths recorded in the archive; -N requests a no-write run. Compare the filesystem identity, dump date, level, and host against the job record and dumpdates catalog. A readable directory listing is a useful structural check, not proof that every data block is readable or that a restore will boot.
For a selective file test, use a new empty staging directory and inspect the destination before running extraction:
mkdir -p /var/tmp/restore-check
cd /var/tmp/restore-check
restore -x -f /backup/var-20261003T020000-level0.dump ./log
find ./log -maxdepth 2 -type f -print
The path argument is interpreted relative to the filesystem tree represented in the dump. Restoring into a staging directory limits accidental overwrite of live configuration. Compare representative ownership, modes, links, timestamps, extended attributes where relevant, and file contents with the intended recovery point. A file-level test cannot validate an incremental chain or prove that a full filesystem can be rebuilt.
Store a cryptographic checksum in a separate backup manifest after the dump has completed, and verify it after copying or retrieving the archive. Checksums detect transfer or storage corruption relative to the manifest; they do not establish that the original dump captured the correct filesystem or that all referenced incrementals are present. Retain logs, exit status, archive size, checksum, source mount, catalog revision, and off-host destination in the backup record.
Restore a complete filesystem into a prepared target
A full-filesystem restore is destructive if pointed at the wrong directory or device. First identify and prepare an isolated UFS target using a separately reviewed storage procedure. The target must be a pristine filesystem, mounted, and the working directory must be its root before using restore -r. The example below intentionally omits newfs(8) and device selection: those depend on the storage layout and can irreversibly erase data.
# Run only after an isolated, empty UFS target is prepared and mounted.
cd /mnt/ufs-restore
restore -r -f /backup/root-level0.dump
restore -r -f /backup/root-level1.dump
# Apply any later incrementals in chronological order.
Restore the baseline first, then each required incremental in the order produced by the backup plan. Do not mix chains from different filesystems, hosts, or dumpdates histories. restore -r maintains restoresymtable in the destination root to pass state between incremental restore passes. Remove that file after the final incremental has completed and the restored tree has been inspected. If a restore was interrupted, consult restore(8) and the archive’s volume layout before deciding whether -R is appropriate; it resumes a particular tape in a full restore and is not a generic “continue from any error” switch.
Run the appropriate filesystem check and inspect logs before mounting recovered data for production use. A filesystem restore can preserve file metadata without repairing application-level inconsistency, external configuration drift, missing secrets, or service dependencies. Rebuild the host’s boot and mount configuration under a controlled recovery plan, then validate services with their owners before changing traffic.
Operational controls that make recovery credible
The backup source and archive destination have different failure modes. Monitor UFS space, backup-target capacity, snapshot cleanup, duration, warning count, nonzero exits, and the age of the last verified level-0 backup. Alert when any expected incremental is absent, because a chain can look healthy at the latest timestamp while no longer being restorable from its anchor.
Test recovery to a disposable filesystem on a schedule. Verify at least one complete level-0-plus-incremental chain, a selected-file extraction, and the exact off-host copy used during a disaster. Measure how long the work takes, whether the required tools and media are available, and whether the restored application passes its own consistency checks. Keep the runbook and the credentials or access path needed to retrieve archives outside the production host.
dump and restore are dependable when treated as a stateful format and a tested recovery procedure. A successful process exit, a recent dump file, or a clean source filesystem is not a restore test. Recovery evidence comes from a verified archive chain, a prepared destination, and a rehearsed process that produces usable data.
Related:
- UFS Disk Quotas on FreeBSD: Enable, Enforce, Audit, and Recover
- UFS Soft Updates and Journaling on FreeBSD: What Each Mechanism Protects
Sources: