Automating File System Snapshots With the Snapper Utility

The Snapper utility can be used to automate the management of file system snapshots. The utility can make it easier to create and delete snapshots, while enabling users to compare the differences between snapshots and revert changes at the file level. For information about the Snapper utility, visit the upstream project page at http://snapper.io/.

Attention:

Snapshots record the state of the file system at a moment in time. As such, it's not possible to guarantee file system integrity for transactional processes that might have been in operation at the time when a snapshot was taken. While utilities such as the snapper command might help capture before and after snapshots for particular operations, such as when using the dnf command, these snapshots are still unaware of other processes that might be running on the system at the same time. If you have processes that might have intensive I/O or memory usage, such as database or middleware applications, stop these or ensure that all activity is complete before taking a snapshot to help reduce the likelihood of data integrity or file system corruption issues within the snapshot.

Installing Snapper

If not already installed, you can install the Snapper utility from the ol10_UEKR8 yum repository.

  1. Use the dnf command to install Snapper.
    sudo dnf install -y snapper

Creating a Snapper Configuration for a Subvolume

You can use the snapper command to create and manage snapshots of Btrfs subvolumes. You must create a configuration entry for each Btrfs subvolume that you want to use with Snapper. If a subvolume is mounted at a directory that's outside of the default SELinux policy configuration, you might need to update SELinux file contexts for that directory to use Snapper to create snapshots of that directory.

  1. Create a Snapper configuration for an existing mounted Btrfs subvolume.

    To set up the Snapper configuration for an existing mounted Btrfs subvolume:

    sudo snapper -c config_name create-config -f btrfs fs_name

    In the previous command, config_name is the name of the configuration and fs_name is the path of the mounted Btrfs subvolume. Running the command does the following:

    • Adds an entry for config_name to the /etc/sysconfig/snapper file.

    • Creates the configuration file /etc/snapper/configs/config_name .

    • Sets up a .snapshots subvolume for the snapshots.

    For example, the following command sets up the Snapper configuration for a Btrfs root file system:

    sudo snapper -c root_config create-config -f btrfs /
  2. Use the snapper list-configs command to list all the existing configurations:
    sudo snapper list-configs
    Config      | Subvolume
    ------------+----------
    home_config | /home    
    root_config | /        
  3. Update SELinux file contexts for any directories outside of the default policy.

    The default Snapper SELinux policy allows Snapper to manage snapshots in the /, /etc, /mnt, /usr, /var and HOME_ROOT (usually /home). If you create a directory, for example /data or /srv, you might need to set the SELinux file context for that directory so that Snapper can create and manage snapshots for that directory.

    For example to enable Snapper to manage snapshots on the /data directory, you can run:

    sudo semanage fcontext -a -t snapperd_data_t "/data/\.snapshots(/.*)?"
    sudo restorecon -R -v /data 

Understanding Different Types of Snapshots

You can create the following three types of snapshots by using the snapper command:

single

You use a single snapshot to record the state of a subvolume but it doesn't have any association with other snapshots of the subvolume.

pre

You use a pre snapshot to record the state of a subvolume before a modification. A pre snapshot is always paired with a post snapshot that you take immediately after you have completed the modification.

post

You use a post snapshot to record the state of a subvolume after a modification. A post snapshot is always paired with a pre snapshot that you take immediately before you make the modification.

To create a single snapshot of a subvolume, use the snapper create command, for example:

sudo snapper -c root_config create --description "Regular daily snapshot"

Single snapshots are useful for periodic backup purposes and can also be used to create a back-up timeline, as described in Configuring Automatic Snapper Snapshots.

For actions that are likely to result in specific file system modifications that you might need to roll back, you can use pre and post snapshots to capture snapshots of the file system before and after a transaction.

For example, the following commands create pre and post snapshots of a subvolume:

sudo snapper -c root_config create -t pre -p

After you have created the pre snapshot, perform some action that makes a change to the file system. Then run the following command to create a post snapshot.

sudo snapper -c root_config create -t post --pre-num N -p

Specifying the -p option with the snapper command displays the number of the snapshot so that you can reference it when creating the post snapshot or when comparing the contents of the pre and post snapshots.

The action of creating a pre and post snapshot can be condensed by using the --command option with the snapper create command to wrap a specified command line operation with pre and post snapshots. For example:

snapper -c root create --command "cd /tmp/build; make install" \
    --description "Installing a home built binary"

Pre and post snapshots are often used when performing system changes that might be too complex to revert manually, such as when installing or upgrading packages.

The DNF Snapper plugin that's described in Configuring Automatic Snapper Snapshots uses pre and post snapshots in exactly this way and uses the description field to store the DNF transaction that triggered the snapshot.

For example, in the following set of snapshots, you can identify periodic, single snapshots that are triggered as part of a timeline and then a pre and post snapshot that's triggered by the DNF Snapper plugin when the vim package is installed.

$ sudo snapper -c root list
 # | Type   | Pre # | Date                         | User | Cleanup  | Description              | Userdata
---+--------+-------+------------------------------+------+----------+--------------------------+---------
0  | single |       |                              | root |          | current                  |         
1  | single |       | Wed 25 Nov 2020 07:00:30 EST | root | timeline | timeline                 |         
2  | single |       | Wed 25 Nov 2020 08:00:01 EST | root | timeline | timeline                 |         
3  | single |       | Wed 25 Nov 2020 09:00:01 EST | root | timeline | timeline                 |         
4  | pre    |       | Wed 25 Nov 2020 09:07:21 EST | root | number   | /usr/bin/dnf install vim |         
5  | post   |     4 | Wed 25 Nov 2020 09:07:25 EST | root | number   | /usr/bin/dnf install vim |         
6  | single |       | Wed 25 Nov 2020 10:00:01 EST | root | timeline | timeline                 |         

Configuring Automatic Snapper Snapshots

Snapper can be configured to perform automatic periodic backups to create a system timeline that you can use to roll the system back to a moment in time. You can also use a DNF plugin with Snapper so that pre and post backups are created for every DNF transaction after the plugin has been installed.

Automated periodic backups are provided as a key feature included with Snapper. These backups take advantage of Snapper's single backup feature and use a systemd timer unit to automatically take backups on an hourly schedule. A second systemd timer unit is included to prune backups to reduce the number of snapshots stored on the system. The timeline options for each Snapper configuration can be customized for each subvolume.

See Automating Single Backups To Create a Snapper Timeline for more information about Snapper timeline configuration.

The DNF plugin for Snapper is a powerful tool that can be used to quickly roll a system back to the moment before you performed a software installation or upgrade. This tool is helpful if a software installation or upgrade is likely to perform significant changes to the file system or to current system configuration. See https://dnf-plugins-extras.readthedocs.io/en/latest/snapper.html for more information. SeeAutomating Pre And Post Backups For DNF Transactions to learn how to enable this feature on the system.

Automating Single Backups To Create a Snapper Timeline

Snapper can be configured to perform periodic single backups to create a Snapper timeline that you can roll back to for any of the subvolumes that you have configured on the system.

The following steps describe how to enable the systemd units that control Snapper timeline management, and how to configure the number of snapshots to store within the timeline. See the snapper(8) and snapper-configs(5) manual pages for more information.

  1. Enable the snapper-timeline systemd unit.

    Automatic snapshots are triggered by a systemd timer unit that you must enable to so that the timeline can be created:

    sudo systemctl enable --now snapper-timeline.timer
  2. Enable the snapper-cleanup systemd unit to automatically remove stale snapshots and keep snapshots manageable.
    sudo systemctl enable --now snapper-cleanup.timer
    By default, the Snapper timeline configuration keeps 10 hourly, 10 daily, 10 monthly, and 10 yearly snapshots. Snapshots are pruned by the cleanup timer.
  3. Review subvolume Snapper configurations to customize Snapper timeline configuration.

    Each Snapper configuration contains settings for a periodic backup, which is controlled by the TIMELINE_CREATE configuration variable in the /etc/snapper/configs/config_name file.

    When the systemd timer units are enabled, periodic snapshot events trigger automatically for every Snapper configuration that has the TIMELINE_CREATE variable enabled. To disable periodic snapshots for a particular subvolume configuration, change the variable value to no in the configuration file.

    You can also edit the configuration to control the number of timeline snapshots that are kept by the snapper-cleanup process. Set these values by changing the following configuration variables:

    TIMELINE_LIMIT_HOURLY="10"
    TIMELINE_LIMIT_DAILY="10"
    TIMELINE_LIMIT_WEEKLY="10"
    TIMELINE_LIMIT_MONTHLY="10"
    TIMELINE_LIMIT_YEARLY="10"

Automating Pre And Post Backups For DNF Transactions

You can install the DNF Snapper plugin on a system to automatically trigger pre and post snapshots for DNF transactions.

This feature can help you roll back changes in cases where system package upgrades cause a failure that you need to debug or to enable you to analyze which files were changed during an installation or upgrade. Note that this plugin requires no user configuration or interaction to work. Pre and post snapshots are created automatically for every DNF transaction after the plugin is installed on the system.

  1. Use the dnf command to install the plugin:
    sudo dnf install -y python3-dnf-plugin-snapper

Working With Btrfs Snapshots by Using Snapper

Use this tabulated summary of commonly performed actions as a reference when you're working with Snapper to manage Btrfs snapshots. For more information, see the snapper(8) manual page.

Table 4-1 Commonly Used Snapper Command Reference

Action Command and Description
Create a single snapshot.

To create a single snapshot of a subvolume, use the snapper create command, for example:

sudo snapper -c config_name create --description "description"
Create pre and post snapshots for a command.

Use the --command option with the snapper create command to wrap an operation with pre and post snapshots. For example:

snapper -c config_name create --command "command" \
    --description "description"

List snapshots for a configuration.

To list the snapshots that exist for a Snapper configuration or subvolume, run:

sudo snapper -c config_name list

View file and directory changes between snapshots.

To display the files and directories that have been added, removed, or changed between two snapshots, use the status subcommand and specify the numbers of the two snapshots that you want to compare:

sudo snapper -c config_name status N .. N'

Show the differences within files between snapshots.

To display the differences between the contents of all the files between two snapshots, use the diff subcommand:

sudo snapper -c config_name diff N .. N'

You can also display the difference in a single file over two snapshots by providing the full path to the file:

sudo snapper -c config_name diff N .. N' /path/to/file

Delete a snapshot.

To delete a snapshot, specify its number to the delete subcommand:

sudo snapper -c config_name delete N''

Undo the changes made to files between a pre and a post snapshot.

To undo the changes in the subvolume from post snapshot N' to pre snapshot N':

sudo snapper -c config_name undochange N .. N'

Note that undoing a change doesn't revert the file system to the previous snapshot but it reverts modifications made to existing files in the snapshot. This means that files created after the snapshot was taken continue to remain after an undochange operation. The undochange subcommand doesn't check data integrity for its changes. Be careful of using this command without clearly evaluating the implications of the changes that it's likely to make.

Mounting Snapper Snapshots

You can mount any snapshot generated by Snapper in the same way as any other Btrfs snapshot. You might need to correlate the snapshot volume id with the Snapper snapshot number to work out which snapshot to mount or restore.

  1. Run the snapper list command to identify the number of the snapshot to roll back to.

    For example, to see all pre and post snapshots, to roll back to a snapshot from before a DNF package update was run:

    sudo snapper -c root list -t pre-post

    Running the previous command might produce the following output:

    Pre # | Post # | Pre Date                     | Post Date                    | Description                     | Userdata
    ------+--------+------------------------------+------------------------------+---------------------------------+---------
       4  |     5  | Wed 25 Nov 2020 09:07:21 EST | Wed 25 Nov 2020 09:07:25 EST | /usr/bin/dnf install vim        |         
     127  |   128  | Mon 30 Nov 2020 08:25:42 EST | Mon 30 Nov 2020 08:30:57 EST | /usr/bin/dnf update             |         

    Note that the snapshot number of the pre snapshot that we intend to mount is 127 in this case.

  2. Use the btrfs subvolume list command to obtain the subvolume ID for the Snapper snapshot.

    For example, to get the subvolume ID of the snapshot with the Snapper snapshot number of 127.:

    sudo btrfs subvolume list /|grep .snapshots.*127  

    The output of the previous command is as follows:

    ID 521 gen 11533 top level 268 path .snapshots/127/snapshot

    Note that the subvolume ID is listed as 521 for this snapshot.

  3. Use the mount command with the subvolid option to specify the subvolume ID of the snapshot to mount:
    sudo mount -o subvolid=521 /dev/sda2 /mnt

    You can also use this information to boot into a snapshot of the root file system. See Mounting a Snapshot as the Root File System for more information.