Skip to content

A lightweight btrfs snapshot script as an alternative to timeshift or snapper

License

Notifications You must be signed in to change notification settings

phdenzel/btrsnap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

btrsnap

This is yet another btrfs snapshotting program. Ever since I’ve been using btrfs as the filesystem of my daily driver, I took advantage of the main feature of btrfs: (almost) instantaneous snapshots. I created them through timeshift, then I eventually switched to snapper, never realizing that btrfs-progs already ships with a pretty usable snapshotting utility itself. The advantage of btrfs-progs over timeshift or snapper, is that it leaves decisions to the user and doesn’t impose specific filesystem configurations or naming conventions. Over the time, I accumulated several bash scripts wrapping these utility functions, most of which I used to run as cron jobs.

This is a unified re-write of these separate functions into a proper framework unimaginatively called btrsnap. It imposes my configuration as defaults, but integrates environment variables and a configuration file, giving the user the option to fully customize to any setup. Moreover, it provides systemd service and timer templates which can be used to run timed and automated snapshots.

Install

Install btrsnap using

sudo make install

This will install the script to /usr/local/bin/ which should already be in your PATH.

Alternatively you can run

PREFIX=/path/of/your/choice make install

which might need sudo priviliges depending on your choice. Don’t forget to add the chosen prefix to your PATH.

In case you’re running on systemd (I have no opinions on the matter, and I’m not interested in discussions about it) and you want to automate btrsnap, use

sudo btrsnap gentemp / root --delay 0

or for snapshotting your home directories

sudo btrsnap gentemp /home home --delay 10

These commands create a directory services and [email protected] and [email protected] with corresponding btrsnap-*@.timer templates within.

They can be installed with

sudo make install-services

which copies the service files and their corresponding timers to /etc/systemd/system/.

Services can then be timed with e.g.

sudo systemctl enable --now [email protected]

which will run weekly snapshots of your root subvolume. You can also enable the following timers:

These service templates enable you to periodically snapshot your root subvolume mounted at / (or in case of [email protected] to snapshot /home). If you have a different setup simply add analogous files with your specifications using btrsnap-gentemp. Note that to avoid any issues with deadlocks due to simultaneously writing to the log files, it is advisable to choose different delays for different btrsnap tasks using the --delay flag.

To uninstall btrsnap (from any location) and installed btrsnap services and timers, simply run

sudo make uninstall

Usage

btrsnap has several subcommands which can be inspected using

sudo btrsnap help
Usage: sudo btrsnap <subcommand> [options]

Subcommands:
    e(nv)
        - Print all environment variables

    l(i)[s](t) [options] [source]
        - List all snapshots (and updates logs)

    i(nfo) [options] [snapshot]
        - Print info about a specific snapshot (wrapper for btrfs subvol show)

    c(reate) [options] [source] [target]
        - Create a snapshot in the target directory

    r(e)m(ove) [options] [snapshot]
        - Delete specific snapshots

    d(iff) [options] [snapshot-a] [snapshot-b]
        - Show diffs between two snapshots

    u(ndo) <file> [snapshot]
        - Undo changes to a specific file from a snapshot

    r(estore) [options] [snapshot] [subvolume]
        - Restore the filesystem to a former snapshot

    s(crub) [options] [source]
        - Scrub the oldest snapshots above the limits

    g(en)t(emp) [options] [source] [target]
        - Generate systemd service and timer templates

For help with each subcommand run:
    btrsnap <subcommand> -h|--help

The current basedir for btrsnap is BTRSNAP_BASEDIR=/snapshots
If arguments are given as relative paths, the BTRSNAP_BASEDIR variable
is used as base path, otherwise it is ignored.

btrsnap configuration and logs are in
    - .btrsnap/btrsnap.conf
    - .btrsnap/btrsnap.log

btrsnap-create

The most frequently used command would probably be

sudo btrsnap create / /snapshots/root

which saves a snapshot of the root subvolume mounted at / to /snapshots/root/%y%m%dT%H:%M:%S.%2N (this happens to be the default which is why sudo btrsnap c yields the same result).

You can also add a different name format and some description to the snapshot with

sudo btrsnap c -f special / /mydata/special_dir -m "A really special snapshot"

This saves the snapshot of / to /mydata/special_dir/special.

btrsnap-list

All snapshots, their most important attributes, and their description can be inspected using

sudo btrsnap ls
#  Snapshot                            Source  Time                        Flags  Mode    Description
1  /snapshots/root/220418T22:31:23.37  /       22-04-18 22:31:23.37 +0200  r      manual  
2  /mydata/special_dir/special         /       22-04-19 22:32:01.68 +0200  r      manual  A really special snapshot

btrsnap-remove

If at any point you decide to delete a snapshot, use

sudo btrsnap rm /mydata/special_dir/special

You can also select snapshots by index

sudo btrsnap rm 2

or since in this case it is the latest snapshot

sudo btrsnap rm -1

btrsnap-scrub

btrsnap works with modes and limit parameters (which of course can be reconfigured). Each mode has different limit defaults:

  • manual: 12
  • hourly: 4
  • daily: 3
  • weekly: 6
  • monthly: 4
  • yearly: 1

The scrub subcommand enforces these limits and deletes the oldest snapshots when the number of snapshots with that mode is exceeded.

For instance,

sudo btrsnap scrub /

clears all snapshots of root with all modes.

sudo btrsnap scrub --mode hourly

clears all snapshots taken in ‘hourly’ mode regardless of its source.

Configuration file

btrsnap integrates with environment variables and configuration files. In case you don’t want to change the program’s source code itself, add

export BTRSNAP_CONF=/snapshots/.btrsnap/btrsnap.conf~

to your .bashrc or .zshrc. In the configuration file you can define your own default values for

BTRSNAP_BASEDIR="/snapshots"
BTRSNAP_LOG=".$PROGNAME/$PROGNAME.log"
BTRSNAP_SRC='/'
BTRSNAP_TARGET="root"
BTRSNAP_MODE="manual"
BTRSNAP_WRITABLE=0
BTRSNAP_TIMEFORMAT="+%y%m%dT%H:%M:%S.%2N"
BTRSNAP_WARNINGS=1

BTRSNAP_MANUAL_LIMIT=12
BTRSNAP_MONTHLY_LIMIT=4
BTRSNAP_WEEKLY_LIMIT=3
BTRSNAP_DAILY_LIMIT=6
BTRSNAP_HOURLY_LIMIT=4
BTRSNAP_YEARLY_LIMIT=1

DRY_RUN=0
VERBOSE=0

Note, for now, snapshots have to reside on the same btrfs device.

  • [ ] btrsnap-remove: * w/ mode selection
  • [ ] compatibility with external devices/drives (for external devices you need to manually use btrfs send/receive and `btrfs property set` ro to false)
  • [ ] pacman hooks to automatically run btrsnap on installs or upgrades