Tachchen,
nachdem mein Plünich-Pseudo-RAID Controller (Promise) letzte Woche mal wieder den
Dienst versagte, sah ich mich gezwungen mal in ein USB HDD Gehäuse zu investieren.
Was mir dann eigentlich nur fehlte war ein Backup-Skript.
Folgende Überlegungen:
* inkrementelles dump der Systempartitionen (ähnlich wie im Wiki, nur ohne cron, da
mein Rechenknecht nicht jede Nacht durchrennt)
* Synchronisation von /home und /share
Rausgekommen ist dann das angefügte awk Skript und die entsprechende
Konfigurationsdatei. Möglich sind die Angaben dump, nodump und sync.
Die dumps werden in der in level festgelegten Reihenfolge angelegt, dabei
wird der angegebene Dateiname um das aktuelle Datum, eine Kennung für das
dump Level und die Nummer der Reihenfolge ergänzt.
Bisher habe ich leider noch keine Idee, wie ich das Skript beim
Herunterfahren anwerfen kann (stfw - ich weis...).
Vieleicht kann es ja noch jemand gebrauchen.
Weiterhin würde ich mich über Verbesserungsvorschläge und Anregungen freuen.
Aufruf:
cat backup.conf:
cat backup.awk
nachdem mein Plünich-Pseudo-RAID Controller (Promise) letzte Woche mal wieder den
Dienst versagte, sah ich mich gezwungen mal in ein USB HDD Gehäuse zu investieren.
Was mir dann eigentlich nur fehlte war ein Backup-Skript.
Folgende Überlegungen:
* inkrementelles dump der Systempartitionen (ähnlich wie im Wiki, nur ohne cron, da
mein Rechenknecht nicht jede Nacht durchrennt)
* Synchronisation von /home und /share
Rausgekommen ist dann das angefügte awk Skript und die entsprechende
Konfigurationsdatei. Möglich sind die Angaben dump, nodump und sync.
Die dumps werden in der in level festgelegten Reihenfolge angelegt, dabei
wird der angegebene Dateiname um das aktuelle Datum, eine Kennung für das
dump Level und die Nummer der Reihenfolge ergänzt.
Bisher habe ich leider noch keine Idee, wie ich das Skript beim
Herunterfahren anwerfen kann (stfw - ich weis...).
Vieleicht kann es ja noch jemand gebrauchen.
Weiterhin würde ich mich über Verbesserungsvorschläge und Anregungen freuen.
Aufruf:
Code:
backup.awk < backup.conf
cat backup.conf:
Code:
# Konfiguration für Backup Skript
# Wohin soll gesichert werden?
# dst /absoluter/Pfad
dst /mnt/usb
# In welchen Level Reihenfolgen soll gesichert werden?
level 0 2 2 2 2 2 2 1 2 2 2 2 2 2 1 2 2 2 2 2 2 1 2 2 2 2 2 2
# Welche Verzeichnisse sollen nicht gesichert werden?
# nodump /absoluter/Pfad
nodump /usr/local/portsnap
nodump /usr/ports
nodump /usr/src
nodump /usr/obj
# Welche Partitionen sollen gesichert werden?
# dump /absoluter/Pfad NameDerSicherungsdatei
dump / root
dump /opt opt
dump /usr usr
dump /var var
# Welche Verzeichnisse sollen synchronisiert werden?
# Erfordert rsync (/usr/ports/net/rsync)!
# sync /absoluter/Pfad
sync /mnt/ar0usr/home
sync /share
cat backup.awk
Code:
#!/usr/bin/awk -f
/^dst/ { dst=$2 }
/^level/ { for(i = 2; i <= NF; i++) { levels[i - 1] = $i } }
/^nodump/ { nodumps[$2]++ }
/^dump/ { dumps[$2] = $3 }
/^sync/ { syncs[$2]++ }
END {
# nodumps
print "Setze nodump flag:"
for(path in nodumps) {
print path
if(system("chflags -R nodump " path))
errors[++error] = "nodump " path " > Setzen des nodump flags nicht möglich."
else
results[++result] = "nodump " path
}
# dumps
print "Sichere Partitionen:"
for(path in dumps) {
print path
r = dump(path, dst "/" dumps[path], levels)
if(r)
errors[++error] = "dump " path " " dumps[path] " > " r
else
results[++result] = "dump " path " " dumps[path]
}
# syncs
print "Synchronisiere Verzeichnisse:"
for(path in syncs) {
print path
if(system("rsync -av " path " " dst))
errors[++error] = "sync " path " > Synchronisation abgebrochen."
else
results[++result] = "sync " path
}
# Statusbericht ausgeben
print "\n\n>> Backup " getDate("%Y-%m-%d %H:%M:%S") " <<"
print "Zielverzeichnis: " dst
if(result > 0) {
print "\nFolgende Aktionen wurden erfolgreich ausgeführt:"
for(i = 1; i <= length(results); i++) print " " results[i]
} else {
print "\nEs wurden keine Aktionen erfolgreich ausgeführt."
}
if(error > 0) {
print "\nFolgende Aktionen sind fehlgeschlagen:"
for(i = 1; i <= length(errors); i++) print " " errors[i]
}
}
# Sichert eine Partition, abhängig von den übergebenen Leveln.
function dump(path, dst, levels) {
# Name der letzten dump Datei holen
lscmd = "ls -r " dst "*"
lscmd | getline ls
close lscmd
# Levelnummer der letzten Datei holen und neue Nummer setzen
l = split(ls, a, "_");
n = a[l] + 1
if(n > length(levels)) n = 1
# dump ausführen
if(system("dump -" levels[n] " -Lauf " dst "_" getDate("%Y%m%d%H%M%S") "_" levels[n] "_" n " " path))
return "Sicherung fehlgeschlagen!"
# wenn erstes Dump, dann alle anderen löschen
if(n == 1)
for(i = 2; i <= length(levels); i++)
if(system("rm -f " dst "*_" levels[i] "_" i))
r = r "Sicherung \"" ls "\" konnte nicht gelöscht werden.\n"
return r
}
# Gibt die akteulle Zeit im gewünschten Format zurück.
function getDate(format) {
datecmd = "date +'" format "'"
datecmd | getline date
close datecmd
return date
}