Mit folgendem Skript ist es möglich, einen kompletten Remoterechner als geziptes Image zu sichern. Ich benutze dies zur Sicherung meiner Raspberries. Im Prinzip geht das so, dass man vom eigenen PC aus auf dem RasPi ein Skript mittels ssh startet, das ein geziptes Image auf dem eigenen PC ablegt.
Da das Image im laufenden Betrieb des RasPi erstellt wird, ist dieses zwangsläufig nicht immer konsistent. Daher wird nach dem Erstellen des Images dieses überprüft und gfs repariert, und zwar mit ganz normalen Linux-Bordmitteln. Dazu wird das Image wieder ausgepackt und jede einzelne Partition darin mittels fschk überprüft. Zum Schluß wird das Image wieder gezipt. um Platz zu sparen.
Hier das Skript, das auf dem PC gestartet wird. Das auf dem Remotesystem gestartete Skript (mkimg2pc.sh) findet man weiter unten, auch jeweils zum Download.
#!/bin/bash #------------------------------------------------------------- # Skript zur Erstellung eines konsisten Image eines # entfernten Rechners, hier ein RasPi # ------------------------------------------------------------ # Kostanten, die jeweils zu besetzen sind remote=IP_des_remote_Rechner remote_pw=Passwort_fuer_root_auf_remote remote_ssh_port=ssh_port_auf_remote backup_dir=Verzeichnis_derSicherung # per plink (=ssh + Ausführung) auf den entfernten Rechner verbinden # und ein Skript zur Erstellung des gezipten Image aufrufen; # das gezipte Image liegt auf dem eigenen Rechner, nicht auf dem Remote, # dafür sorgt das Skript mkimg2pc.sh plink root@$remote -P $remote_ssh_port -pw $remote_pw "./mkimg2pc.sh" cd $backup_dir # die gesicherte Datei bestimmen, ist die neueste im Backupverzeichnis zipfile=`ls -tp *.gz | grep -v /$ | head -n 1` # file auspacken gunzip $zipfile # Name des Images bestimmen img=`ls -tp *.img | grep -v /$ | head -n 1` echo "Image file = $img" # Sektorgröße bestimmen sectorsize=`fdisk -l $img | grep "sector.*=" | cut -d' ' -f6` echo "sectorsize=$sectorsize" # alle Partitionen im Image überprüfen for i in {1..9} do # Startsektor bestimmen start=`fdisk -l $img | grep img$i | tr -s " " | cut -d' ' -f2` if [ "$start" != "" ] then echo "check $(fdisk -l $img | grep img$i | cut -d' ' -f1)" echo "start=$start" offset=$((start * sectorsize)) echo "offset=$offset" # partition als Loop-Device einhänge losetup --offset $offset /dev/loop2 $img # und auf Fehler prüfen und korrigieren fsck /dev/loop2 -f -p losetup -d /dev/loop2 echo "" fi done echo "neues zip anlegen: ${img}.gz" pv $img | gzip -c > "${img}.gz" if [ -e "${img}.gz" ]; then rm $img fi exit
Und hier das Skript, das auf dem remote System aufgerufen wird.
Die Konstanten am Anfang müssen noch jeweils angepasst werden. Im Prinzip wird dann mittels sshfs das Backupverzeichnis des aufrufenden PCs (=host) gemountet und dorthin das Image mittels dd erstellt und gezipt.
Dazu muß natürlich das Paket sshfs installiert sein.
Da man sich zum remote System per root verbindet, muß das Skript dort natürlich im Verzeichnis /root abgelegt werden.
host=`echo $SSH_CLIENT | cut -d' ' -f1` echo "host=$host" # Konstanten, die angepasst werden müssen pc_passwort=passwort_auf_dem_host_PC # zB pc_passwort=mein_passwort pc_user=user_name_auf_dem_host_PC # zB pc_user=ich pc_backup_dir=backup_verzeichnis_auf-host_PC # zB pc_backup_dir=/media/ich/data/backups/raspi mount_point=mount_point_hier_sowas_wie_media_host # zB mount_point=/media/host_pc pc_ssh_port=ssh_port_auf_host_pc # zB pc_ssh_port=22 # mittels sshfs ein entferntes verzeichnis auf dem Host=PC mounten echo $pc_passwort | sshfs $pc_user@$host:/$pc_backup_dir $mount_point -o password_stdin -o port=$pc_ssh_port cd $mount_point tag=`date +%Y%m%d` file=$tag".img.gz" echo "save to $file" start=$(date +%s) dd if=/dev/mmcblk0 bs=1M | gzip > $file # komplette SD-Karte cd ~ fusermount -u $mount_point end=$(date +%s) diff=$(( $end - $start )) echo "$tag : $diff secs" >> created_images.log
Download des Skriptes make_image_remote