How to manage snapshots with Snapper on Linux

Snapper is a free and open source application we can use to manage snapshots on Linux. It was originally designed to work with BTRFS snapshots, but was extended to supports also LVM thin-provisioned logical volumes. In this tutorial, we learn how to install Snapper on the most used Linux distributions, and how to use it to manage snapshots on Linux.

In this tutorial you will learn:

  • How to install Snapper on the most used Linux distributions
  • How to generate Snapper configurations
  • How to create, modify and delete snapshots with Snapper
  • How to automatically create hourly snapshots
  • How to choose and apply a snapshot cleanup algorithm
How to manage snapshots on Linux with Snapper
How to manage snapshots on Linux with Snapper
Category Requirements, Conventions or Software Version Used
System Distribution agnostic
Software LVM thin provisioning setup or BTRFS
Other Root privileges
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

Installation

Originally created by the OpenSUSE developer Arvin Schnell, Snapper is now available in the official repositories of all the most used Linux distributions. To install the application on Fedora, we can use the dnf package manager:

$ sudo dnf install snapper

To install Snapper on Debian, and Debian-based distributions, instead, we use the following command:

$ sudo apt install snapper

Snapper is also available in the Archlinux “Extra” repository. We can install the application with pacman:

$ sudo pacman -S snapper

Finally, to install Snapper on OpenSUSE itself, we use the zypper package manager:

$ sudo zypper in snapper

Generating a Snapper configuration

Before we can use Snapper, we must generate a configuration for each filesystem we want to snapshot, using the create-config command. Suppose we have a BTRFS subvolume mounted at “/“. To generate a Snapper configuration for it, we would run:

$ sudo snapper -c myconfig create-config -f btrfs /



Let’s analyze the command above. We invoked snapper with the -c option: this is the short for --config: we use this option to specify a configuration name. In the example, we use “myconfig” as argument to the option, which is not mandatory: if we omit it, the default name is going to be used (“root”). We invoked the create-config command with the -f option (short for --fstype) to specify the snapshot backend. Since in this case we are working with a BTRFS filesystem, we passed “btrfs” as argument. If we were creating the configuration for a LVM thin-provisioned snapshot, we would have specified the filesystem on top of the logical volume, by running:

$ sudo snapper -c myconfig create-config -f "lvm(ext4)" /

Snapper configurations are saved under the /etc/snapper/configs directory.

Obtaining a list of created snapshots for a configuration

To get an overview of the snapshots created with Snapper we can use the ls command. Once again, if we don’t specify a configuration name with the -c option, the default one is assumed, so if we created a configuration with a custom name, we should explicitly point to it in all Snapper commands. In the previous example, we used “myconfig” as a configuration name; to obtain the list of snapshots associated to it, we would run:

$ sudo snapper -c myconfig ls

We didn’t create any snapshot yet, therefore the output of the command is the following:

 # | Type   | Pre # | Date | User | Cleanup | Description | Userdata
---+--------+-------+------+------+---------+-------------+---------
0  | single |       |      | root |         | current     |



The snapshot with ID 0 is not a “real” snapshot: it just points to the current state of the system. By default, the output of the command reports the following information:

  • The snapshot ID
  • The snapshot type (single, pre, or post – see below)
  • The ID of the related “pre” snapshot if the snapshot is of “post” type (again, see below)
  • The date in which the snapshot was created
  • The user who created the snapshot
  • The cleanup algorithm (number, timeline, or empty-pre-post)
  • The optional description provided for the snapshot
  • The list of key-value pairs provided for the snapshot

Creating snapshots with Snapper

Snapper organizes snapshots in three categories: “pre”, “post”, and “single” snapshots. There are no structural differences between these types of snapshots, only relational: “pre” and “post” snapshots are always related: each “post” snapshot has a corresponding “pre” snapshot associated to it. They are created to mark the filesystem state before and after an action or a command. “Single” snapshots, instead, as the name suggests, are “isolated”: they are not related to any other snapshot.



To create a snapshot with Snapper, we use the create command. When used with no other option, the command creates a “single” snapshot:

$ sudo snapper -c myconfig create

We can specify the type of snapshots we want to create by using the -t (--type) option. Just as an example, to create a “pre” snapshot, we would run:

$ sudo snapper -c myconfig create -t pre

When creating a “post” snapshot, we must specify the related “pre” snapshot ID; we can do it by passing it as argument to the --pre-number option, e.g:

$ sudo snapper -c myconfig create -t post --pre-number 1

To avoid manually creating related “pre” and “post” snapshots, we can use the --command option. This option takes a command as value: Snapper will automatically create a “pre” snapshot before executing the command, and a “post” snapshot after the command has been executed. Just as an example, to create a snapshot before updating the system, and one just after the system is updated, we would run:

$ sudo snapper -c myconfig create --command “dnf update”

Providing snapshots metadata

When creating a snapshot with Snapper, we can provide an optional description and a series of key-value pairs which can help us describe its role. To provide the snapshot description at creation time, we use the -d option (--description), and pass the description as argument. In the example below, we create a “single” snapshot with a dummy description (if the description includes spaces, it must be enclosed in single quotes):

$ sudo snapper -c myconfig create -d 'This is a dummy description'

We can also provide a list of comma separated key-value pairs via the -u (--userdata) option:

$ sudo snapper -c myconfig create -u important=yes

Specifying a cleanup algorithm for the snapshot

When creating a snapshot, we can associate it with one of the available cleanup algorithms. To specify a cleanup algorithm, we use the -c or --cleanup-algorithm option. In the example below, we create a snapshot and associated it with the “number” algorithm:

$ sudo snapper -c myconfig create -c number



Continue reading to know more about how the available cleanup algorithms work, and how to configure them. The cleanup algorithm associated with a snapshot, just as its metadata, can be modified once the snapshot has been created, using the modify command, using the corresponding options.

Automatically creating hourly snapshots

To automatically create hourly snapshot all we have to do is to set the TIMELINE_CREATE variable to “yes” in a Snapper configuration file, and then activate the systemd snapper-timeline.timer. Each systemd timer is associated with a systemd service which the same name. In this case, the timer will run the snapper-timeline.service once per hour. To activate the timer, we run:

$ sudo systemctl enable snapper-timeline.timer

Cleanup algorithms

Cleanup algorithms are used to “rotate” snapshots, and avoid accumulating them indefinitely. Currently available algorithm are: “number”, “timeline”, and “empty-pre-post”; let’s see how they work.

The “number” algorithm

The “number” algorithm is simply based on the maximum number of allowed snapshots. It can be configured via the following variables specified in a configuration file:

  • NUMBER_CLEANUP
  • NUMBER_MIN_AGE
  • NUMBER_LIMIT
  • NUMBER_LIMIT_IMPORTANT

The NUMBER_CLEANUP variable takes a boolean value and determines whether the “number” cleanup algorithm should run for the configuration. The NUMBER_MIN_AGE variable, instead, accepts the minimum age snapshots must have for the cleanup algorithm to be applied; the value is specified in seconds. With the NUMBER_LIMIT variable, we specify the maximum number of snapshots we want to keep at a time. Finally, the NUMBER_LIMIT_IMPORTANT variable is used to set the maximum number of important snapshots allowed. We can mark a snapshot as “important” by specifying the “important=yes” key-value pair as argument of the -u option when creating it, as we saw above.

The “timeline” algorithm

The “timeline” algorithm is based on the number of hourly, daily, weekly, monthly, and yearly snapshots which should be kept. Settings for the “timeline” algorithm are specified via the following variables:

  • TIMELINE_CLEANUP
  • TIMELINE_MIN_AGE
  • TIMELINE_HOURLY
  • TIMELINE_DAILY
  • TIMELINE_WEEKLY
  • TIMELINE_MONTHLY
  • TIMELINE_YEARLY

The TIMELINE_CLEANUP variable takes a boolean value: it is used to determine if the “timeline” algorithm should run for the specific configuration. The TIMELINE_MIN_AGE variable is used to determine the minimum age, in seconds, a snapshot should have, to be considered by the algorithm. Finally, the TIMELINE_HOURLY, TIMELINE_DAILY, TIMELINE_WEEKLY, TIMELINE_MONTHLY, and TIMELINE_YEARLY variable, are used to specify, how many hourly, daily, weekly, monthly, and yearly snapshot should be kept around.

The “empty-pre-post” algorithm

The “empty-pre-post” algorithm is used to delete pre/post-snapshots pairs with empty diffs (associated snapshots with no differences). We can tune the behavior of the algorithm, by using the following two variables:

  • EMPTY_PRE_POST_CLEANUP
  • EMPTY_PRE_POST_MIN_AGE

The EMPTY_PRE_POST variable takes a boolean value which basically switches on and off the cleanup algorithm for a configuration; the EMPTY_PRE_POST_MIN_AGE variable, instead, determines the minimum age, in seconds, a snapshot must have, to be considered by the algorithm.

Running a cleanup algorithm

Cleanup algorithms can be run manually via the Snapper cleanup command. When running the command, we specify the cleanup algorithm we want to run as first argument. To apply the “number” algorithm for the “myconfig” configuration, for example, we would run:

$ sudo snapper -c myconfig cleanup number



Snapper usually comes installed with a systemd cleanup timer and its related service. The timer is configured to run on 10 minutes after the systemd has booted up (OnBootSec=10m), and is disabled by default. To activate it, we run:

$ sudo systemctl enable snapper-cleanup.timer

The snapper-cleanup.service applies all activated cleanup algorithms in existing configuration files.

Deleting snapshots

To manually delete a snapshot, or a range of snapshots with Snapper, we can use the delete command. All we have to do is to pass the id(s) of the snapshots we want to delete. To remove the snapshot with ID 1, for example, we would run:

$ sudo snapper -c myconfig delete 1

To delete snapshots from 1 to 3, instead:

$ sudo snapper -c myconfig delete 1-3

Backend-specific commands

As we already said, Snapper supports both BTRFS and thin-provisioned lvm snapshots as a backend. Due to the very different nature of those types of snapshots, certain commands apply only when working with a specific backend.



The snapper mount command, for example, has sense only when working with LVM snapshots. What this command does is activating the specified thin snapshot (LVM thin snapshots are not activated by default) and mounting it in the appropriate directory. Other commands such as rollback work only if using BTRFS as a backend. To know more about these commands, please take a look at the Snapper manual.

Conclusions

In this tutorial, we saw how to install Snapper on the most used Linux distributions, and how to use it to manage snapshots. Snapper works as a frontend to both BTRFS and LVM thin-provisioned snapshots. We saw how to genereate a Snapper configuration for a filesystem, how to create, delete and modified snapshots, and how to apply available cleanup algorithms.



Comments and Discussions
Linux Forum