Freeze a Mounted Filesystem Safely with fsfreeze

fsfreeze pauses writes to a mounted filesystem for exactly as long as a hardware RAID snapshot needs to capture it. Get the freeze and unfreeze sequence right and the snapshot is consistent; get it wrong and every write behind it queues up until you let go. The examples use the fsfreeze binary from util-linux 2.41.3. The installed manpage identifies its source as util-linux 2.39.3, so the command-line contract below is limited to behaviour confirmed by both the local documentation and the installed binary.

Allow about ten minutes for a dry review, plus the time your snapshot system needs. You need a shell, a mounted filesystem that supports freezing, permission to run the command as root, and a snapshot operation you already understand. Freezing is service-disrupting: processes that write to the filesystem can block until you unfreeze it. Do not experiment first on a busy production mount.

1. Confirm the command and version

Check which executable will run and read its supported options. These are ordinary, read-only commands:

$ command -v fsfreeze
/home/linuxbrew/.linuxbrew/sbin/fsfreeze
$ fsfreeze --version
fsfreeze from util-linux 2.41.3
$ fsfreeze --help
Usage:
 fsfreeze [options] <mountpoint>

Checkpoint: Make sure the path shown by command -v is the binary you have reviewed. If a script or service uses another absolute path, inspect that copy too.

2. Verify the exact mountpoint

Choose the directory where the target filesystem is mounted. Replace /srv/data with your real path, then confirm it before changing anything:

$ TARGET_MOUNT=/srv/data
$ findmnt --target "$TARGET_MOUNT"
TARGET SOURCE     FSTYPE OPTIONS
/srv/data /dev/mapper/vg_data-lv_data ext4   rw,relatime

Your source, filesystem type and options will differ. The result you want is a row for the intended directory: a path that is merely an ordinary directory on another filesystem is an easy way to freeze the wrong thing, or get an error instead.

The filesystem must be mounted. The local manpage lists support including ext2, ext3, ext4, f2fs, JFS, nilfs2, ReiserFS and XFS, and says that list may be incomplete as support is added. If support is uncertain, test a small loopback mount in a maintenance environment first. Do not infer support from the filename or from the underlying block device.

Checkpoint: Save the output of findmnt --target "$TARGET_MOUNT" in the change record. It gives you a second check before the privileged operation.

3. Decide whether you need a manual freeze at all

Stop here if the snapshot is an LVM or other device-mapper snapshot. The manpage says device-mapper, including LVM, automatically freezes the filesystem when a snapshot is requested, so adding a separate manual freeze can make the outage longer and complicate recovery. Follow the snapshot tool's documented sequence instead.

For a hardware RAID snapshot that does not provide this coordination, continue only after confirming the target mount is the one the snapshot will capture. A freeze flushes dirty data, metadata and log information to disk once ongoing transactions complete; new writes and other filesystem modifications then wait.

4. Freeze the filesystem before the snapshot

This is the service-disrupting step, and it needs elevated privileges:

$ sudo fsfreeze --freeze "$TARGET_MOUNT"
$ printf 'freeze status: %s\n' "$?"
freeze status: 0

A successful command normally prints nothing and returns status 0. It waits for ongoing transactions to complete before the filesystem is frozen. A process attempting to write can remain blocked while the freeze is active, so start the snapshot promptly.

Warning: do not close the terminal, abandon the change record, or assume a failed snapshot automatically unfreezes the mount. If the snapshot command fails, go straight to the unfreeze step. The same applies if you lose confidence about whether the freeze completed.

5. Take the snapshot, then unfreeze immediately

Run the hardware RAID snapshot operation here, using its own documented command and verification. It is deliberately a placeholder, because its syntax and safety properties depend on the controller:

$ sudo /path/to/vendor-snapshot-command --source DEVICE --snapshot-id SNAPSHOT_ID
snapshot created: SNAPSHOT_ID

Replace every uppercase placeholder with a verified value; do not paste the example as written. As soon as the snapshot has either succeeded or failed, release the filesystem:

$ sudo fsfreeze --unfreeze "$TARGET_MOUNT"
$ printf 'unfreeze status: %s\n' "$?"
unfreeze status: 0

Unfreezing allows blocked modifications to continue. It does not undo the snapshot, roll back writes or delete any snapshot data: those actions belong to the storage system and need their own recovery plan.

Checkpoint: Treat status 0 from --unfreeze as the release confirmation. Then perform a harmless write test appropriate to the service, or check the service's health and logs. Do not use a write test that could create unwanted data on a production volume.

6. Wrap the sequence in a trap

If the snapshot is launched from a shell script, arrange for an error or interruption to attempt an unfreeze. This reduces the chance of leaving the mount blocked, but it cannot replace monitoring: a machine failure or a killed process can still need operator recovery.

#!/bin/sh
set -eu

TARGET_MOUNT=/srv/data
frozen=0

cleanup() {
    if [ "$frozen" -eq 1 ]; then
        fsfreeze --unfreeze "$TARGET_MOUNT" || {
            printf '%s\n' 'ERROR: filesystem may still be frozen' >&2
            exit 1
        }
    fi
}
trap cleanup EXIT HUP INT TERM

findmnt --target "$TARGET_MOUNT"
fsfreeze --freeze "$TARGET_MOUNT"
frozen=1
/path/to/vendor-snapshot-command --source DEVICE --snapshot-id SNAPSHOT_ID
fsfreeze --unfreeze "$TARGET_MOUNT"
frozen=0

Run this script as root, or invoke the individual commands through a carefully configured privilege mechanism. The placeholder snapshot command must not inherit untrusted arguments. Test the trap with a harmless test mount before using it around real data.

Common traps

Done means