Mit einer Rescue-CD und einem Perl-Skript lassen sich komplette Festplatten von Clients im lokalen Netz auf einem Backup-Server sichern.
Was tun, wenn die Festplatte ausfällt? Schnellstens eine neue kaufen und das letzte Backup einspielen, natürlich. Was aber, wenn mehrere Partitionen auf der Platte waren? Wieviel Platz war jeder zugeordnet? Welches Filesystem war dort installiert?
Am einfachsten ist es, rohe Partitionen zu sichern, die lassen sich nach einem Ausfall problemlos wieder restaurieren. Stellt die zu sichernde Partition jedoch das Root-Verzeichnis eines laufenden Linux-Systems oder läuft auf einem Laptop gar Windows, ist es nicht ohne weiteres möglich, während des Betriebes gefahrlos eine Kopie der rohen Platte zu sichern.
Auf sysresccd.org ([2]) gibt es allerdings eine Rescue-CD, die eine
beliebige x86-Machine in ein Minimal-Linux ohne X-Windows bootet,
das wichtige Tools wie partimage
, sfdisk
, fdisk
, perl
und
einen NFS-Client enthält. So kann man Kontakt mit einem NFS-basierten
Backup-Server (Installation siehe unten) aufnehmen und sowohl das
Partitionierungs-Layout als auch die Partitionen selbst sichern.
Aber natürlich möchte niemand umständliche Kommandos tippen, um ein Backup anzulegen. Nach dem Einlegen der CD in den zu sichernden Rechner sollte möglichst alles automatisch ablaufen. Deshalb stellen wir heute eine leicht angepasste Boot-CD her, die nur kurz fragt, um welchen Rechner es sich gerade handelt, und die dann selbständig Kontakt zum Backup- Server aufnimmt und alle Festplatten sichert.
(Bitte das Diagramm mit einem Grafikprogramm erstellen, danke!)
Abbildung 1: Rechner im lokalen Netz werden ueber die sysresccd auf einem NFS-Server gesichert. |
Wie das Diagramm in Abbildung 1 zeigt, nimmt ein mit der Backup-CD
gebooteter Rechner über das autorun
-Skript
sofort Kontakt mit dem unter der IP 192.168.0.40 angeschlossenen
Backup-Server auf. Ein zur sysrescCD hinzugefügtes autorun
-Skript
(Listing 1) initialisiert hierfür zunächst das Netzwerk und startet
anschließend NFS mit den zugehörigen Daemons lockd
und portmap
.
Dann mountet es das Verzeichnis /backup
des Backup-Servers unter
/mnt/backup
auf dem zu sichernden Rechner. Dort steht dann das zu einem
Binary kompilierte Perlskript bin/pbb.bin
(Partition-Based-Backup)
des Backup-Servers bereit. autorun
ruft es über NFS auf und lässt
es auf dem zu sichernden Rechner ablaufen.
Dieses fragt den User mit folgendem Menü nach dem Namen des zu sichernden Rechners:
[1] desktop1 [2] desktop2 [3] laptop1 Box [1]>
Tippt der User eine Menünummer und die Return-Taste, läuft das Backup unter dem ausgewählten Namen an. Steht hingegen eine Restaurierung an, bricht er einfach mit CTRL-C ab und operiert weiter in der dann aufkommenden Root-Shell.
01 IP=192.168.0.40 02 03 # Start network 04 /etc/init.d/net.eth0 start 05 /etc/init.d/nfs start 06 07 # Mount directory via NFS 08 mkdir /mnt/backup 09 mount $IP:/backup /mnt/backup || 10 (echo "Mount failed ($IP down?)"; 11 exit 1) 12 13 # Run backup script over NFS 14 /mnt/backup/bin/pbb.bin 15 16 # Close NFS 17 umount /mnt/backup
Listing pbb
zeigt die Source-Version des Backup-Skripts.
Die Funktion ask()
bietet voreingestellte Rechnernamen aus
einer Liste an und sfdisk
klappert danach alle sichtbaren IDE-Festplatten
auf dem gerade laufenden System ab.
Anschließend sichert es deren Partionierungstabellen und die Rohdaten
von Linux- oder Windows-Partitionen auf den Backup-Server.
Außerdem kopiert es den Master Boot Record der ersten Platte /dev/hda
dorthin. Die gesicherten Daten liegen dann
im Verzeichnis /backup/data/rechner
unter dem anfangs per Menü ausgewählten
Rechnernamen auf dem Backup-Server.
Abbildung 2: Das Tool partimage archiviert die Daten roher Festplattenpartitionen und restauriert sie wieder. |
Beim Sichern von Partitionen stellt sich das Problem, dass diese oft nicht vollständig gefüllt sind. Zieht man die Rohdaten nur mit
dd if=/dev/hda1 of=backup.img
ab, enthält das Backup-Image backup.img
mehr Daten als notwendig. Das Tool
partimage
hingegen kennt die Struktur bekannter Dateisysteme wie
ext2, ext3 oder des unter Windows gängigen NTFS.
Es bietet eine nützliche Fortschrittsanzeige,
speichert nur relevante Daten und komprimiert diese auch noch. So kann es
durchaus vorkommen, dass es aus einer spärlich gefüllten 30-Gig
großen Root-Partition eine Backup-Datei erzeugt, die nur einige
hundert MB groß ist.
Das Kommando
partimage -b -d -z1 -o save /dev/hda1 /backup_path/hda1.img.gz
ruft partimage
im Batch Mode (-b
) auf, damit es sich nach getaner
Arbeit automatisch beendet. Die Option -d
legt weiterhin fest, dass
dem Benutzer kein Kommentar für die Beschreibung der entstehenden
Image-Datei abgerungen wird. Mit -o
werden eventuell schon bestehende
Image-Dateien rücksichtslos überschrieben und -z1
bestimmt, dass
die Komprimierung mit gzip
durchgeführt wird. partimage
spaltet
die entstehende Backup-Datei zur leichteren Handhabung in 2 Gigabyte
große Teile, die es mit Endungen von ``.000'' an durchnumeriert.
Das als root
gestartete Shell-Kommando sfdisk -d /dev/hda
liest die Partitionierungstabelle der ersten IDE-Festplatte und
gibt sie so aus, dass ein
späterer Aufruf von sfdisk
sie anstandslos restaurieren kann
(Abbildung 3).
Um herauszufinden, welche Festplatten überhaupt auf dem zu sichernden
System installiert sind, hilft pbb
der Aufruf von sfdisk -l
, der
alle Partitionen aller gefundenen Platten auflistet. Das Backup-Skript
durchwandert diese und führt für alle im Array @ptypes
aufgeführten Partitionstypen einen Backup durch. Wie Abbildung 4
zeigt, sichert pbb
in der vorliegenden Fassung nur die Typen 7 (HPFS/NTFS) und 83 (Linux). So
fallen nicht sicherungswürdige Swap-Partitionen elegant unter den Tisch. Wer andere
Partitionstypen sichern möchte (W95 FAT32 hat zum Beispiel das Kürzel
``c''), braucht nur Zeile 12 im Listing
anzupassen. Zwar ist laut partimage
der Support fuer NTFS noch experimentell, durchgeführte
Tests funktionierten allerdings tadellos.
Abbildung 3: Das Kommando sfdisk gibt die Partitionierungsdaten einer Festplatte aus. |
Abbildung 4: Das Kommando 'l' im Programm fdisk gibt alle bekannten Partitionstypen aus. |
Bevor das Skript ein neues Backup anlegt, schiebt es zunächst das alte
Backup-Verzeichnis mit der Endung .old
zur Seite. Schließlich soll
der alte Backup bestehen bleiben, falls der neue schiefgeht oder die
Platte ausgerechnet
während des Backups den Geist aufgibt. Existiert allerdings schon
ein .old-Verzeichnis, liegt wohl etwas im Argen und der User muss von Hand
einschreiten, nachdem pbb
mit einem Fehler abgebrochen hat.
pbb
durchforstet die Ausgabe von sfdisk -l
nach dem Muster
``Id='', das den Typ jeder gefundenen Partition enthält
(z.B. ``83'' oder ``c''). Am Zeilenanfange steht dann der Device-Pfad
(z.B. /dev/hda1), und daraus leitet pbb
den Plattenpfad ab (/dev/hda). Für
SCSI-Disks funktioniert das freilich nicht, das Skript lässt sich
aber leicht erweitern.
Nach einem erfolgreichen Backup-Lauf entkoppelt sich das gesicherte
System in autorun
mit umount
wieder vom NFS-Server, um
sicherzustellen, dass die Backup-Daten vor dem Herunterfahren des
Rechners intakt auf der anderen Seite angekommen sind.
01 #!/usr/bin/perl -w 02 use strict; 03 use Pod::Usage; 04 use Sysadm::Install qw(:all); 05 use Log::Log4perl qw(:easy); 06 use Log::Log4perl::Appender::Screen; 07 08 Log::Log4perl->easy_init($DEBUG); 09 10 my $MDIR = "/mnt/backup/data"; 11 my %ptypes = map { $_ => 1 } 12 qw(83 7); 13 my @machnames = qw(desktop1 14 desktop2 laptop1); 15 my %machnames = map { $_ => 1 } @machnames; 16 17 my $mname = pick "Box", \@machnames, 1; 18 19 my %drive_done; 20 21 my $bdir = "$MDIR/$mname"; 22 my $oldbdir = "$MDIR/$mname.old"; 23 24 # Move old backup aside 25 if(-d $oldbdir) { 26 LOGDIE "$oldbdir already exists"; 27 } 28 mv $bdir, $oldbdir if -d $bdir; 29 mkd $bdir unless -d $bdir; 30 31 # Save the master boot record 32 # of the first IDE disk 33 tap qw(dd if=/dev/hda), 34 "of=$bdir/hda.mbr", 35 qw(count=1 bs=512); 36 37 my $sf = `sfdisk -d`; 38 39 while($sf =~ /^(.*Id=\s*(\w+).*)/mg) { 40 my($line, $id) = ($1, $2); 41 42 next unless exists $ptypes{$id}; 43 44 my($path) = split ' ', $line, 2; 45 (my $dev = $path) =~ s#.*/##; 46 (my $drive = $dev) =~ s/\d//g; 47 48 # Save partition drive's table 49 if(!$drive_done{$drive}++) { 50 sysrun "sfdisk -d /dev/$drive " . 51 ">$MDIR/$mname/$drive.pt"; 52 } 53 54 # Save partition 55 sysrun "partimage -b -d -z1 -o save" . 56 " /dev/$dev $bdir/$dev.img.gz"; 57 } 58 59 # Remove old backup 60 rmf $oldbdir if -d $oldbdir; 61 62 =head1 NAME 63 64 pbb - Partition Based Backup 65 66 =head1 SYNOPSIS 67 68 pbb 69 70 =head1 DESCRIPTION 71 72 Scans all IDE hard drives, and backs 73 them up by partiion.
Tritt der Ernstfall ein und eine neu gekaufte Platte muss mit dem letzten Backup initialisiert werden, wird das zu restaurierende System wiederum mit der Rescue-CD gebootet und anschließend die gesicherte Partitionierungstabelle auf der neuen Platte eingespielt:
# sfdisk </mnt/backup/data/laptop1/hda.pt
Handelt es sich, wie im Beispiel, um die Festplatte mit dem Master Boot Record, der in den ersten 512 Bytes gespeichert ist und für den Bootvorgang gebraucht wird, kommt dieser mit
dd if=/mnt/backup/data/laptop1/hda.mbr of=/dev/hda
wieder zurück auf die zu restaurierende erste IDE-Festplatte hda
.
Um die Daten auf einer Partition zu restaurieren, startet man
partimage
am besten von der Kommandozeile, wählt im
GUI Restore a partition from an image file aus und gibt
den Pfad zu dem gesicherten Image mit
/mnt/backup/data/laptop1/hda.img.gz.000
an. Die folgenden Teile
sucht partimage
sich anschließend im gleichen Verzeichnis selbst
zusammen.
Abbildung 5: Die gesicherten Daten eines Laptops mit einer Festplatte |
Auf der Rescue-CD ist zwar eine Perl-Installation enthalten, aber leider
fehlen CPAN-Module wie die im Skript pbb
verwendeten
Helfer
Sysadm::Install oder Log::Log4perl. Doch dank dem schon einmal
in [4] vorgestellten Perl Archive Toolkit PAR
wird aus dem Skript
auf einem vollständig mit allen notwendigen CPAN-Modulen
installierten und kompatiblen Linux-Rechner einfach ein Binärpaket
pbb.bin
geschnürt, das sowohl das Skript, als auch alle verwendeten
Module (und obendrein einen Perl-Interpreter) enthält.
Zu beachten ist allerdings, dass das System, auf der das Binärpaket geschnürt wird, mit einer Version der libc läuft, die kleiner oder gleich 2.3.2 ist. Das mit sysresccd gebootete System läuft nämlich damit, und falls das Perl-Bündel mit einer älteren Version erzeugt wurde, kann es Kompatibilitätsprobleme geben.
Der Aufruf des PAR-Compilers mit
pp -o ppb.bin ppb
macht aus dem Perl-Skript pbb
das Executable pbb.bin
, wenn auf dem ausführenden System das Paket
PAR vom CPAN installiert ist.
Log::Log4perl::Appender::Screen
zieht
pbb
übrigens extra herein, da pp
es sonst vergäße. Log4perl
zieht es zur Laufzeit heran, und pp
ermittelt die Abhängigkeiten
zur Compile-Zeit.
Als Backup-Server wurde ein alter PC mit einigen alten 120-Gigabyte-
Platten und einer neuen 400-GB-Platte zusammengeklopft. Als
Operationssystem kam Debians ``Sarge''-Release zum Einsatz -- keine
Gimmicks, nur ein leichtgewichtiges und stabiles System, das sich mit
apt-get leicht aktualisieren lässt.
Um einen großen zusammenhängenden Speicherbereich zu erhalten, wurden
die Einzelpartitionen der verschiedenen Festplatten mit dem Linux Volume Manager (LVM)
zusammengeschaltet. Um die Partition einer Festplatte (zum Beispiel
/dev/hdc1) für den Gebrauch mit dem LVM herzurichten, ist der
Aufruf pvcreate /dev/hdc1
erforderlich.
So erzeugte Physical Volumes fasst man anschließend zu einer Volume Group zusammen, die wiederum einem Logical Volume zugeordnet wird. Der Aufruf
vgcreate giantvg /dev/hdc1 ... lvcreate -L 600G -n giantlv giantvg
erzeugt ein 600 Gigabyte großes virtuelles virtuelles Device, das unter
/dev/giantvg/giantlv
verfügbar ist. Mit mkfs.ext3
lässt sich dort
ein ext3-Dateisystem installieren, das sich anschließend mit
mount /dev/giantlv/giantvg /backup
problemlos mounten lässt.
Die Root-Partition des Debian-Systems wurde mit 10 GB auf der ersten 120GB-Platte, angelegt, den verbleibenden Platz von 110 GB schlug eine LVM-Definition elegant dem großen Datenbereich für Backup-Zwecke zu. Der NFS-Server war nicht in der Grundinstallation dabei, er wurd einfach mit
apt-get install nfs-kernel-server nfs-common portmap
vom Netz gezogen und installiert. Damit die Rechner im lokalen Netz auf
das Verzeichnis /backup
lesend und schreibend zugreifen können,
ist der Eintrag
/backup 192.168.0.*(rw,sync)
erforderlich. Das Kommando exportfs -a
propagiert die Änderung.
Da die von sysresccd.org erhältliche Rescue-CD den Rechner bootet und die
nach dem Booten sichtbaren Programme in einer sogenannten cloop
einschließt, müssen beim Patchen einige vorgeschriebene
Schritte gemäß der PDF-Anleitung auf [2] eingehalten werden.
Das Shellskript in Listing mkcd
holt
die Datei autorun
aus dem bin
-Verzeichnis des gemounteten
Backup-Servers und kopiert sie ins Root-Verzeichnis der neuen CD.
mkcd
muss auf einem mit sysresccd
gebooteten System aufgerufen werden,
damit es die aktive Rescue-CD zunächst in ein temporäres Verzeichnis kopiert,
dann autorun
hinzufügt und anschließend mit einem ebenfalls von der CD
stammenden Skript eine modifizierte .iso-Datei erzeugt.
Diese legt es im Root-Verzeichnis des Backup-Servers
ab, und anschließend brennt man sie dort mit
cdrecord dev=/dev/cdrom speed=4 sysresccd-new.iso
auf eine neue CD. Wer zwei Laufwerke eingestöpselt hat, kann dies auch mit einem einzelnen Rechner bewerkstelligen.
01 02 CUST=/usr/sbin/sysresccd-custom 03 MNT=/mnt/backup 04 OUT=/mnt/custom 05 06 cd $MNT 07 08 dd if=/dev/zero of=fsimage bs=1M count=1000 09 mke2fs -F -q -N 50000 fsimage 10 mount -t ext2 -o loop fsimage $OUT 11 12 $CUST extract 13 $CUST cloop 300 20000 14 15 cp $MNT/bin/autorun $OUT/customcd/isoroot 16 17 $CUST setkmap speakup 18 $CUST isogen my_srcd 19 20 cp $OUT/customcd/isofile/sysresccd-new.iso /mnt/backup
http://www.partimage.org/forums/viewtopic.php?t=420
Vor dem Brennen der CD und dem
Einsatz des Skripts sind die IP-Adresse des Backup-Servers in autorun
,
sowie die Rechnernamen in pbb
anzupassen, und pbb
ist zu
kompilieren. Wer möchte, kann das Skript noch mit zusätzlichen
Funktionen zur Datenrestaurierung erweitern und dem nächsten
Festplattencrash gelassen entgegensehen.
Michael Schilliarbeitet als Software-Engineer bei Yahoo! in Sunnyvale, Kalifornien. Er hat "Goto Perl 5" (deutsch) und "Perl Power" (englisch) für Addison-Wesley geschrieben und ist unter mschilli@perlmeister.com zu erreichen. Seine Homepage: http://perlmeister.com. |