snapper
Für die Verwaltung von Snapshots hat SUSE das Tool snapper entwickelt. Dieses eignet sich meiner Meinung nach auch prima für Raspberry Pi OS.
Alternative 1: Snapper aus dem Repository von Raspberry Pi OS installieren
Inzwischen müssen die Binärdateien nicht mehr selbst erzeugt werden. Sie finden sich in den offiziellen Quellen von Debian und auch Raspberry Pi OS wieder.
$ sudo apt-get install snapper
Alternative 2: Snapper aus den Sourcen selber bauen
Voraussetzungen
$ sudo apt-get install libdbus-1-dev libacl1-dev libboost-all-dev libxml2-dev libmount-dev xsltproc docbook-utils xmlto ldp-docbook-xsl libpam-dev gettext e2fslibs-dev libjson-c-dev libbtrfs-dev $ sudo apt-get remove xpdf $ sudo apt-get autoremove
Snapper Sourcen herunterladen und entpacken
$ wget https://github.com/openSUSE/snapper/archive/v0.8.7.zip $ unzip v0.8.7.zip $ cd snapper-0.8.7
Übersetzung vorbereiten
$ make -f Makefile.repo
Der nächste Schritt ist nur in früheren Versionen nötig; in der aktuellen Version ist er nicht mehr erforderlich.
$ ./configure LIBS="-lboost_system -lboost_thread"
Übersetzen
$ make
Das temporäre Filesystem des Compilers
Kommt es bei der Übersetzung zu der Fehlermeldung "No space left on device", obwohl im Filesystem mit den Quelldateien genügend Platz vorhanden ist, muss evt. das temporäre Filesystem des gcc angepasst werden:
$ export TMPDIR=/run/shm
Beim nächsten Übersetzungsversuch sollte die Fehlermeldung nicht mehr erscheinen.
Korrektur von Version 3.3 bis 4.1
Die Datei snapper/BtrfsUtils.cc habe ich in den Sourcen im oberen Teil um eine Zeile ergänzen müssen:
#define BTRFS_QGROUP_LEVEL_SHIFT 48
Erst danach klappte die Übersetzung. Bitte darauf achten, dass die Zeile nicht von einem "#ifndef ... #endif" oder ähnlichem umschlossen wird.
Installieren
$ sudo make install
Korrekturen der snapper-files für cron:
Man beachte, dass der Cron von Raspberry Pi OS keine Punkte im Dateinamen der cron-files mag.
# mv /etc/cron.hourly/suse.de-snapper /etc/cron.hourly/snapper # mv /etc/cron.daily/suse.de-snapper /etc/cron.daily/snapper
Es geht los
Mit cron sollen regelmäßige Snapshots des btrfs-root-Filesystems erzeugt werden. Die dazu notwendigen Dateien haben Sie ja bereits installiert bzw. kompiliert. Was noch fehlt, ist die Konfiguration und ein Subvolume, in welchem der snapper die read-only snapshots sammelt.
# btrfs subvolume create /.snapshots # mkdir /etc/sysconfig # echo 'SNAPPER_CONFIGS="root"' > /etc/sysconfig/snapper # cp /etc/snapper/config-templates/default /etc/snapper/configs/root
Die Konfigurationsdatei beinhaltet Regeln, denen folgend snapper die snapshots verwaltet.
# subvolume to snapshot
SUBVOLUME="/"
# filesystem type
FSTYPE="btrfs"
# users and groups allowed to work with config
ALLOW_USERS=""
ALLOW_GROUPS=""
# sync users and groups from ALLOW_USERS and ALLOW_GROUPS to .snapshots
# directory
SYNC_ACL="no"
# start comparing pre- and post-snapshot in background after creating
# post-snapshot
BACKGROUND_COMPARISON="yes"
# run daily number cleanup
NUMBER_CLEANUP="yes"
# limit for number cleanup
NUMBER_MIN_AGE="1800"
NUMBER_LIMIT="50"
NUMBER_LIMIT_IMPORTANT="10"
# create hourly snapshots
TIMELINE_CREATE="yes"
# cleanup hourly snapshots after some time
TIMELINE_CLEANUP="yes"
# limits for timeline cleanup
TIMELINE_MIN_AGE="1800"
TIMELINE_LIMIT_HOURLY="10"
TIMELINE_LIMIT_DAILY="10"
TIMELINE_LIMIT_WEEKLY="0"
TIMELINE_LIMIT_MONTHLY="10"
TIMELINE_LIMIT_YEARLY="10"
# cleanup empty pre-post-pairs
EMPTY_PRE_POST_CLEANUP="yes"
# limits for empty pre-post-pair cleanup
EMPTY_PRE_POST_MIN_AGE="1800"
Ein wenig mit Snapper spielen
pi@fhem ~ $ echo "alt" > datei pi@fhem ~ $ sudo snapper list Type | # | Pre # | Date | User | Cleanup | Description | Userdata -------+---+-------+------+------+---------+-------------+--------- single | 0 | | | root | | current | pi@fhem ~ $ sudo snapper create -d "sicherung" pi@fhem ~ $ sudo snapper list Type | # | Pre # | Date | User | Cleanup | Description | Userdata -------+---+-------+--------------------------+------+-----------+-------------+--------- single | 0 | | | root | | current | single | 1 | | Sat Mar 7 00:55:27 2015 | root | | sicherung | pi@fhem ~ $ echo "neu" > datei pi@fhem ~ $ sudo snapper create -d "jetzt" pi@fhem ~ $ sudo snapper list Type | # | Pre # | Date | User | Cleanup | Description | Userdata -------+---+-------+--------------------------+------+-----------+-------------+--------- single | 0 | | | root | | current | single | 1 | | Sat Mar 7 00:55:27 2015 | root | | sicherung | single | 2 | | Sat Mar 7 00:56:54 2015 | root | | jetzt | pi@fhem ~ $ sudo snapper -v undochange 1..2 create:0 modify:6 delete:0 modifying /home/pi/datei modifying /opt/fhem/log/FBDECT_garage-2015.log modifying /var/log/auth.log modifying /var/log/daemon.log modifying /var/log/snapper.log modifying /var/log/syslog pi@fhem ~ $ cat datei alt pi@fhem ~ $
Um nur den Inhalt einer bestimmten Datei zurückzusetzen, können Sie diese als Option mitgeben:
pi@rpi ~ $ sudo snapper -v undochange 1..2 "/home/pi/datei"
Mit der Zeit wächst die Liste der Snapshots natürlich
pi@rpi ~ $ sudo snapper list Typ | # | Vorher # | Datum | Benutzer | Bereinigen | Beschreibung | Benutzerdaten -------+------+----------+------------------------------+----------+------------+--------------+-------------- single | 0 | | | root | | current | single | 1 | | Mo 12 Mär 2018 21:17:02 CET | root | timeline | timeline | single | 2642 | | So 01 Jul 2018 00:17:01 CEST | root | timeline | timeline | single | 3386 | | Mi 01 Aug 2018 00:17:02 CEST | root | timeline | timeline | single | 4130 | | Sa 01 Sep 2018 00:17:02 CEST | root | timeline | timeline | single | 4850 | | Mo 01 Okt 2018 00:17:01 CEST | root | timeline | timeline | single | 5563 | | Do 01 Nov 2018 00:17:02 CET | root | timeline | timeline | single | 6282 | | Sa 01 Dez 2018 00:17:01 CET | root | timeline | timeline | single | 7026 | | Di 01 Jan 2019 00:17:01 CET | root | timeline | timeline | single | 7770 | | Fr 01 Feb 2019 00:17:01 CET | root | timeline | timeline | single | 8442 | | Fr 01 Mär 2019 00:17:01 CET | root | timeline | timeline | single | 9185 | | Mo 01 Apr 2019 00:17:01 CEST | root | timeline | timeline | single | 9233 | | Mi 03 Apr 2019 00:17:01 CEST | root | timeline | timeline | single | 9257 | | Do 04 Apr 2019 00:17:01 CEST | root | timeline | timeline | single | 9281 | | Fr 05 Apr 2019 00:17:01 CEST | root | timeline | timeline | single | 9305 | | Sa 06 Apr 2019 00:17:01 CEST | root | timeline | timeline | single | 9329 | | So 07 Apr 2019 00:17:01 CEST | root | timeline | timeline | single | 9353 | | Mo 08 Apr 2019 00:17:01 CEST | root | timeline | timeline | single | 9377 | | Di 09 Apr 2019 00:17:01 CEST | root | timeline | timeline | single | 9401 | | Mi 10 Apr 2019 00:17:01 CEST | root | timeline | timeline | single | 9425 | | Do 11 Apr 2019 00:17:01 CEST | root | timeline | timeline | single | 9446 | | Do 11 Apr 2019 21:17:01 CEST | root | timeline | timeline | single | 9447 | | Do 11 Apr 2019 22:17:01 CEST | root | timeline | timeline | single | 9448 | | Do 11 Apr 2019 23:17:01 CEST | root | timeline | timeline | single | 9449 | | Fr 12 Apr 2019 00:17:01 CEST | root | timeline | timeline | single | 9450 | | Fr 12 Apr 2019 01:17:01 CEST | root | timeline | timeline | single | 9451 | | Fr 12 Apr 2019 02:17:01 CEST | root | timeline | timeline | single | 9452 | | Fr 12 Apr 2019 03:17:01 CEST | root | timeline | timeline | single | 9453 | | Fr 12 Apr 2019 04:17:01 CEST | root | timeline | timeline | single | 9454 | | Fr 12 Apr 2019 05:17:01 CEST | root | timeline | timeline | single | 9455 | | Fr 12 Apr 2019 06:17:01 CEST | root | timeline | timeline | single | 9456 | | Fr 12 Apr 2019 07:17:02 CEST | root | timeline | timeline | single | 9457 | | Fr 12 Apr 2019 08:17:01 CEST | root | timeline | timeline | single | 9458 | | Fr 12 Apr 2019 09:17:01 CEST | root | timeline | timeline | single | 9459 | | Fr 12 Apr 2019 10:17:02 CEST | root | timeline | timeline | single | 9460 | | Fr 12 Apr 2019 11:17:01 CEST | root | timeline | timeline | single | 9461 | | Fr 12 Apr 2019 12:17:01 CEST | root | timeline | timeline | single | 9462 | | Fr 12 Apr 2019 13:17:01 CEST | root | timeline | timeline | single | 9463 | | Fr 12 Apr 2019 14:17:02 CEST | root | timeline | timeline | single | 9464 | | Fr 12 Apr 2019 15:17:01 CEST | root | timeline | timeline | single | 9465 | | Fr 12 Apr 2019 16:17:01 CEST | root | timeline | timeline | single | 9466 | | Fr 12 Apr 2019 17:17:01 CEST | root | timeline | timeline | single | 9467 | | Fr 12 Apr 2019 18:17:01 CEST | root | timeline | timeline | single | 9468 | | Fr 12 Apr 2019 19:17:01 CEST | root | timeline | timeline | single | 9469 | | Fr 12 Apr 2019 20:17:02 CEST | root | timeline | timeline | single | 9470 | | Fr 12 Apr 2019 21:17:02 CEST | root | timeline | timeline |
Bekannte Fehler
Auf einem System kam es beim Aufruf von Snapper zu folgender Fehlermeldung:
pi@rpi ~ $ sudo snapper list Fehler (org.freedesktop.DBus.Error.Spawn.ExecFailed).
Dieses Kommando schaffte Abhilfe:
pi@rpi ~ $ sudo chmod o+x /usr/lib/dbus-1.0/dbus-daemon-launch-helper