Backup unter Linux mit udev
Sinn und Zweck
Backup ist eine schwierige Sache und es gibt sicher viele Strategien.
Ich möchte im Folgenden meine bevorzugte Möglichkeit beschreiben:
- Externe HD (nicht im Gehäuse sondern so: SATA QuickPort USB3.0
- Daten wegen des einfacheren Zugriffs aufs Backup NICHT komprimieren sondern nur kopieren.
- Backup wird durch das Anschließen der HD automatisch gestartet.
Umsetzung
Udev bietet unter anderem, die Möglichkeit bash-scripte auszuführen, wenn Geräte angeschlossen werden. Dazu legt man unter /etc/udev/rules.d/ eine Datei an und schreibt seine Regeln rein. Zum Beispiel so:
/etc/udev/rules.d/10-local.rules:
SUBSYSTEM=="block", SUBSYSTEMS=="scsi", RUN+="/usr/script/backup/backup-hd-udev.sh"
Die udev-Attribute kann man sich auf einem halbwegs aktuellem System nicht mehr mittels udevinfo anzeigen lassen sonden eher so:
udevadm info --query=all --name=<DEVICENAME> --attribute-walk
Diese Regel ruft das Script „/usr/script/backup/backup-hd-udev.sh“ auf, wenn ein SCSI blockdevice angeschlossen wird. Das Script selber sieht so aus:
#!/bin/bash BACKUPROOT="<DESTINATION>" if [ $ACTION == "add" ] && [ $DEVTYPE == "partition" ]; then case $ID_SERIAL in "ST2000VX_002-12345_0000000000000002-0:0" ) mount $DEVNAME <DESTINATION> && rsync -avz <SOURCE> --exclude *<NOT_WANT>* $BACKUPROOT touch $BACKUPROOT/backup_vom_`date -I`.log umount $DEVNAME hdparm -S1 `echo $DEVNAME | rev | cut -b 2- | rev` ;; esac fi
wobei folgende Platzhalter noch zu ersetzen wären:
- <DESTINATION>: Ort an dem die Partition des Backup-HD eingehängt wird und an dem per rsync die Daten kopiert werden.
- <SOURCE>: Quellort der zu sichernden Daten.
- <NOT_WANT>: Auszuschließendes Verzeichnis im Quellort. Es können auch mehrere angegeben werden, dazu muss eben „–exclude…“ mehrmals wiederholt werden.
Funktionsweise des Scripts
Was macht das Script?
if [ $ACTION == "add" ] && [ $DEVTYPE == "partition" ]; then
Nur für den Fall weitermachen, dass ein Gerät des Typs „partition“ hinzugefügt wird.
case $ID_SERIAL in
Switch case über die Seriennummer, falls es mal mehr als eine Platte gibt, auf die wir sichern wollen.
"ST2000VX_002-12345_0000000000000002-0:0" )
Führe für genau diese Seriennummer aus.
mount $DEVNAME <DESTINATION> &&
Gerät einhängen UND nächste Zeile nur ausführen, wenn der Befehl erfolgreich war. Wir wollen nicht, dass irgendeine Partition vollgeschrieben wird, wenn das Einhängen fehlschlägt.
rsync -avz <SOURCE> --exclude *<NOT_WANT>* $BACKUPROOT
Kopiere die Daten mittels rsync.
touch $BACKUPROOT/backup_vom_`date -I`.log
Lege eine Datei an, die Auskunft über das Datum des Backups gibt.
umount $DEVNAME
Hänge das Gerät wieder aus.
hdparm -S1 `echo $DEVNAME | rev | cut -b 2- | rev`
Bringe die Backup-HD dazu in den standby-Modus zu gehen. Der Teil
echo $DEVNAME | rev | cut -b 2- | rev
macht hierbei aus „/dev/sdb1“ → „/dev/sdb“ indem der letzte Buchstabe abgeschnitten wird.
udev Umgebungsvariablen
Udev setzt Umgebungsvariablen, die vom aufgerufenen Script benutzt werden. Unter anderen sind das:
- ACTION: hat den Wert „add“, wenn das Gerät angeschlossen wird und „remove“, wenn das Gerät entfernt wird.
- DEVTYPE: hat den Wert „disk“, wenn das „disk“-Gerät von udev angelegt wird (z.b. /dev/sdb) oder „partition“, wenn von udev das Gerät für die Partition angelegt wird (z.b. /dev/sdb1)
- DEVNAME: der Name des eben angelegten Geräts: im Falle von DEVTYPE=„disk“ ist DEVNAME=/dev/sdb
Alle Umgebungsvariablen mit Wert in meinem Fall:
ID_USB_DRIVER=usb-storage ID_MODEL=002-12345 ID_MODEL_ENC=002-1AH166\x20\x20\x20\x20\x20\x20 ID_REVISION=CV01 DEVTYPE=partition ID_BUS=usb SUBSYSTEM=block ID_SERIAL=ST2000VX_002-12345_0000000000000002-0:0 ID_FS_UUID=eb354dc1-e6b1-48b1-8c69-c30671c58034 DEVPATH=/devices/pci0000:00/0000:00:1d.7/usb1/1-2/1-2:1.0/host18/target18:0:0/18:0:0:0/block/sde/sde1 ID_MODEL_ID=55aa ID_VENDOR_ENC=ST2000VX ID_FS_VERSION=1.0 MINOR=65 ACTION=add PWD=/ UDEV_LOG=3 ID_ FS_TYPE=ext3 MAJOR=8 DEVLINKS=/dev/block/8:65 /dev/disk/by-id/usb-ST2000VX_002-12345_0000000000000002-0:0-part1 /dev/disk/by-path/pci-0000:00:1d.7-usb-0:2:1.0-scsi-0:0:0:0-part1 /dev/disk/by-uuid/eb354dc1-e6b1-48b1-8c69-c30671c58034 ID_VENDOR_ID=174c DEVNAME=/dev/sde1 SHLVL=1 ID_FS_USAGE=filesystem ID_TYPE=disk ID_PART_TABLE_TYPE=dos ID_FS_SEC_TYPE=ext2 ID_FS_UUID_ENC=eb354dc1-e6b1-48b1-8c69-c30671c58034 ID_INSTANCE=0:0 ID_VENDOR=ST2000VX ID_USB_INTERFACE_NUM=00 ID_SERIAL_SHORT=0000000000000002 ID_PATH=pci-0000:00:1d.7-usb-0:2:1.0-scsi-0:0:0:0 ID_USB_INTERFACES=:080650: SEQNUM=1866
Links
Backup unter Linux mit shell
#!/bin/bash backupname=`hostname`_backup_`date -I`.tar.gz tar -C / -czpf - --exclude="./sys/*" --exclude="./proc/*" . | ssh berni@server "cat >/srv/data/muell/backup/${backupname}"