• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Shell skript für Backup

Nostrike

Newbie
Hallo cracks,
bin noch immer an meinem Problem.
Nachdem ich mein Tape nicht benennen kann möchte ich nun wenigstens eine Aufforderung des richtigen Bandes für den richtigen Tag.
Ich mache 5x pro Woche also montag,dienstag,mittwoch,donnerstag,freitag ein backup.

Folgendes habe ich schon geschreiben und das funzt auch schon ein bißchen, Ich werde gebeten ein Band einzulegen und danach looped die Abfrage bis ein Band eingelegt wird, wenn keines drin ist. Aber ich bekomme kein Anzeige " Band wird ausgeworfen" wenn eines drin war und am Schluß kommt wieder die Anzeige Band einlegen.
Was stimmt denn hier nicht?

Zusätzlich möchte ich noch mit dem date +%A den Tag abfragen und diesen Tag dann an die Eingabe weitergeben. So etwa date +%A zeigt Friday -- dann Ausgabe bitte Band Freitag einlegen. und loopen bis das Band eingelegt ist. Danach vorerst mal das Band wieder auswerfen und Aktion Ende anzeigen.

Mein bisheriges Skript sieht folgendermaßen aus:
#! /bin/bash
# Tape zurückspielen auf Anfang
egal=True
while [ egal ]; do
echo Bitte Band einlegen
read egal
if mt -f/dev/nst0 status | grep -q "No medium found" ; then echo Band wird ausgeworfen

egal=False
else
egal=True

fi

mt -f/dev/nst0 rewoffl
done


Danke für Eure Ünterstützung eines Newbie

Peter
 
A

Anonymous

Gast
Dein Problem mit dem Bandnamen kannst du folgend lösen.
Die erste Datei auf jedem Band enthält klar definierte Zeilen oder Felder wie zB. Bandname, Achive, Sicherungsdatum, Rechnername, Blocksize verwendetes Sicherungsprogramm usw. alles was du für wichtig empfindest. Diese Datei schreibst du als selbständiges Archiv mit cpio, dd oder tar auf jedes Band. Wird ein Band eingelegt und erkannt,
dann liest das Script diese Datei und vergleicht ob es auch das richtige Band ist. Du musst nur sicherstellen, dass nach einem rewind während der Sicherung immer ein fsf1 folgen muss damit das Label nicht überschrieben und damit zerstört wird, selbiges gilt dann auch für ein evtl. recover.
Profisicherungsprogramme machen das nicht anders.

Warum dein Script nicht funktioniert kann ich im Moment nicht richtig nachstellen, da bei mir der mt status nicht richtig funktioniert wenn kein Band eingelegt ist, Aber sehr vorsichtig mit dem Ausgaben von mt status. Das wirklich entscheidende ist wahrscheinlich ONLINE. Alle anderen Angaben wie zB. kein Band oder Filenummer oder BOT können unter Umständen falsch sein wenn es zB. zu irgend einem Fehlerzustand gekommen ist. Wenn du wie oben beschrieben mit einem Label arbeitest und das script gezielt das Label ließt und auswertet, dann kannst du diese Probleme größtenteils umgehen, hast allerdings ein vielfaches an Programmieraufwand.

Wenn du also das von vorne herein so gut wie möglich machen willst, dann hole etwas weiter aus bei der Programmierung.

robi
 
A

Anonymous

Gast
Habe mein Problem erkannt, ziemlich langer Timeout wenn kein Band geladen, und dann Fehlermeldung I/O-Error, ist aber normal bei SCSI-Tape mit dem st-Treiber. Habe dein Script mal so umgeschrieben wie es mir besser gefällt und wie es bei mir auch funktioniert, versuche mal darauf aufzubauen.

robi

Code:
#! /bin/bash
egal=True
DATE=`date +%A`

#wenn schon geladen dann entladen
if mt -f/dev/nst0 status  2>/dev/null | grep -q  "ONLINE" ; then
   echo "altes Band erkannt, wird entladen"
   mt -f /dev/nst0 offline
fi

#Band anfordern
while [ $egal = True ]; do
    echo "Bitte Band vom $DATE einlegen und mit ENTER bestaetigen"
    read egal
    if mt -f/dev/nst0 status 2>/dev/null | grep -q  "ONLINE" ; then
        egal=False
        echo "Band erkannt "
        mt -f/dev/nst0 rewind     
     else
       egal=True
     fi
done 

echo "Programmende Band wird entladen"
mt -f /dev/nst0 offline
 
A

Anonymous

Gast
Hab mal ein Demo geschrieben, wie man mit Labeln umgehen kann. Benötigt Paket mt_st ( ist meiner Meinung nach viel besser als mt) Durch die Interaktive Führung ist es jedoch nicht für Cronjobs geeignet, also selbst Kopf anstrengen. Admin soll verzeihen wenn der Code etwas länger ist, aber Funktionalität braucht etwas Platz und beim Buckup kommt es nicht darauf an, am Freitag die Sicherung auf Band zu bekommen, sondern sie Monatag noch zu finden und auch lesen zu können.

robi
Code:
#! /bin/bash 
# Demoscript zum Umgang mit Label auf Magnetbaendern
# interaktiv Labeln, Sichern, Einlesen und Scannen von einem oder
# mehreren Verzeichnissbaeumen
# ! Bitte erst grundlich mit eurer HW testen bevor ihr euch darauf verlasst !
# ! keine Garantie auf Fehlerfreiheit !

BLKSIZE=65536
PROGRAM=CPIO
BANDNAME=`date +%A`
ARCHIV=Test
DATUM=`date +%D`
RECHNER=`uname -n`
SAVEDIR="<Band ist leer>"

LABEL=/tmp/.label_script1.dat
LABELNEU=/tmp/.label_script2.dat
LOADSLEEP=15

LOAD=False
DATE=`date +%A`  
STATUS=0
ANTWORT=Q

#Label als Datei anlegen
echo -e "DATUM $DATUM\nPROGRAM $PROGRAM\nBLKSIZE $BLKSIZE\nBANDNAME $BANDNAME\nARCHIV $ARCHIV\nRECHNER $RECHNER\nSAVEDIR $SAVEDIR" > $LABELNEU

#wenn schon geladen dann entladen
STATUS=`mtst -f /dev/nst0 status  | grep ONLINE | wc -l`
if [ "$STATUS" = 1 ] ; then 
   echo "altes Band erkannt, wird entladen"
   mtst -f /dev/nst0 offline
fi

#Band anfordern
while [ $LOAD = False ]; do 
    echo -e "\aBitte Band fuer $DATE einlegen und mit ENTER bestaetigen;  ^C fuer Abbruch" 
    read LOAD 
    sleep $LOADSLEEP
    STATUS=`mtst -f /dev/nst0 status | grep ONLINE | wc -l`
    if [ "$STATUS" = 1 ] ; then 
       LOAD=True 
        echo "Band erkannt "
        mtst -f /dev/nst0 rewind 
        mtst -f /dev/nst0 setblk 0
#Label überpruefen
        dd if=/dev/nst0 of=$LABEL count=1 2>/dev/null
          PROGRAM=`grep PROGRAM $LABEL 2>/dev/null | cut -f2 -d" "`
        if [  -e "$LABEL"  -a  "$PROGRAM" = "CPIO" ] ; then
            echo "Label erkannt"
            BANDNAME_O=`grep BANDNAME $LABEL | cut -f2 -d" " `
            DATUM_O=`grep DATUM $LABEL | cut -f2 -d" "`
            RECHNER_O=`grep RECHNER $LABEL | cut -f2 -d" "`
            SAVEDIR_O=`grep SAVEDIR $LABEL | cut -f2- -d" "`
            echo "Sicherung vom $BANDNAME_O vom Rechner $RECHNER_O am $DATUM_O Directory $SAVEDIR_O"
            echo  "moechten sie das Band ueberschreiben ? <Z>urueckspielen ? oder <S>canen ?"
            echo -e "\a <J/N/Z/S> bitte auswaehlen  :  \c"
            ANTWORT=
            while [ -z "$ANTWORT" ]; do read ANTWORT; done
            case "$ANTWORT" in
              N)       mtst -f /dev/nst0 offline
                       LOAD=False
                       rm $LABEL 
                       ;;
              J)       break ;;
              S)       BLKSIZE=`grep BLKSIZE $LABEL | cut -f2 -d" " `
                        SAVEDIR=`grep SAVEDIR $LABEL | cut -f2- -d" "`
                       mtst -f /dev/nst0 asf 2
                       echo "$SAVEDIR" | tr " " "\n" | while read i
                       do
                          cpio -ivctC$BLKSIZE < /dev/nst0
                       done
                       mtst -f /dev/nst0 offline 
                       LOAD=False 
                       rm $LABEL 
                       ;;
              Z)       BLKSIZE=`grep BLKSIZE $LABEL | cut -f2 -d" " `
                       SAVEDIR=`grep SAVEDIR $LABEL | cut -f2- -d" "`                       
                       mtst -f /dev/nst0 asf 2
                       echo -e "moechten sie wirklich die Sicherung zurueckspielen <J/N> : \c"
                       ANTWORT=
                       while [ -z "$ANTWORT" ]; do read ANTWORT; done
                       if [ "$ANTWORT" = J ]; then
                          echo "$SAVEDIR" | tr " " "\n" | while  read i
                           do
                            cpio -icvduC$BLKSIZE < /dev/nst0
                           done                        
                       fi
                       mtst -f /dev/nst0 offline 
                       LOAD=False 
                       rm $LABEL 
                       ;;
             *)        mtst -f /dev/nst0 offline
                       LOAD=False
                       rm $LABEL 
             esac     
       else 
          echo "kein gueldiges Label erkannt"
          echo -e "\amoechten sie das Band mit einem Label versehen ?  <J/N> :  \c"
          ANTWORT=
          while [ -z "$ANTWORT" ]; do read ANTWORT; done
          if [ "$ANTWORT" != J ]; then
            mtst -f /dev/nst0 offline
            LOAD=False
          else
            mtst -f /dev/nst0 rewind 
            dd if=$LABELNEU of=/dev/nst0  2>/dev/null                 
            mtst -f /dev/nst0 weof
            mtst -f /dev/nst0 offline
            LOAD=False
          fi
       fi
     else 
       LOAD=False
       rm $LABEL 2>/dev/null 
    fi 
done 
if [ $? ] ; then
  #Datensicherung vorbereiten
  BLKSIZE=`grep BLKSIZE $LABEL | cut -f2 -d" " `
  echo "Welches Verzeichnis moechten sie sichern,"
  echo -e "\aden kompletten Path der/des Verzeichnis (zwischen mehreren Verzeichnissen jeweils 1 Leerzeichen) : \c"
  read SAVEPATH
  SAVEDIR="$SAVEPATH"
  echo -e "DATUM $DATUM\nPROGRAM $PROGRAM\nBLKSIZE $BLKSIZE\nBANDNAME $BANDNAME\nARCHIV $ARCHIV\nRECHNER $RECHNER\nSAVEDIR $SAVEDIR" > $LABEL
  mtst -f /dev/nst0 rewind 
  dd if=$LABEL of=/dev/nst0  2>/dev/null                
  mtst -f /dev/nst0 weof
  echo "$SAVEDIR" | tr " " "\n" | while read i
    do
      find $i -mount | cpio -oVcC$BLKSIZE  > /dev/nst0 
   done
fi
echo "Ende --- Band wird entladen"
mt -f /dev/nst0 status 2>&1 >/dev/null
mt -f /dev/nst0 offline
rm $LABELNEU $LABEL 2>/dev/null
 
OP
N

Nostrike

Newbie
Danke, Danke, danke

Robi!!!!!!

puh Dein Skrip ist ja irre, das ist erst mal zuviel für mich.
Zeigt das Du ein Profi bei Skripten bist.
Ich möchte das ganze gerne Schriftt für Schritt auflösen, damit ich das auch begreifen kann, denn in Deinem Skript kapier ich so gut wie noch gar nichts.
Wieso bist Du eigentlich Newbie und nicht Profi???

Hast Du etwas dagegen wenn ich Dich so pöh a pöh kontaktiere und mit meinen naiven Fragen belästige.

Deine erste Antwort:
Die erste Datei auf jedem Band enthält klar definierte Zeilen oder Felder wie zB. Bandname, Achive, Sicherungsdatum, Rechnername, Blocksize verwendetes Sicherungsprogramm usw. alles was du für wichtig empfindest. Diese Datei schreibst du als selbständiges Archiv mit cpio, dd oder tar auf jedes Band. Wird ein Band eingelegt und erkannt,
dann liest das Script diese Datei und vergleicht ob es auch das richtige Band ist.


Wie mache ich das mit tar und welchen Qualifiern?????
Wie lese ich das wieder aus?????
Möchte nur den Tag drauf haben.


Bitte erst mal diese Schritte.

Danke für Deine Ausführungen.

Gruß
peter
 
A

Anonymous

Gast
Na gut, Backup ist für viele doch eine Sache mit einigen Siegeln, also werde ich in einigen Schritten wesentliche Teile erklären, aber nicht auf alles eingehen, also immer noch mal die man Dateien zu den einzelnen Befehlen durchlesen. Auf die interaktive Ablaufsteuerung werde ich nicht eingehen, die ist zwar für das Demo notwendig aber das können andere viel besser schreiben. Übrigens komme ich ehr aus der C/C++ Welt und bin auch nicht 100% sattelfest in Scriptprogrammierung, also wenn jemand für ein Problem eine bessere Befehlsfolge hat, dann posten.

1. Vorbereitung:

Code:
 BLKSIZE=65536 
 PROGRAM=CPIO 
 BANDNAME=`date +%A` 
 ARCHIV=Test 
 DATUM=`date +%D` 
 RECHNER=`uname -n` 
 SAVEDIR="<Band ist leer>"
hier legen wir einige Variablen fest, die später unser Label enthalten soll und belegen diese mit Daten vor.
Code:
 LABEL=/tmp/.label_script1.dat 
 LABELNEU=/tmp/.label_script2.dat
hier legen wir 2 Dateinamen fest, in die wir unser Label zwischenspeichern wollen und weisen diese auch Variablen zu

Code:
echo -e "DATUM $DATUM\nPROGRAM $PROGRAM\nBLKSIZE $BLKSIZE\nBANDNAME $BANDNAME\nARCHIV $ARCHIV\nRECHNER $RECHNER\nSAVEDIR $SAVEDIR" > $LABELNEU
Damit schreiben wir den Inhalt unsere Variablen in eine Datei und erzeugen somit eine Labeldatei.

Unsere Datei sieht dann folgendermassen aus
DATUM 09/14/04
PROGRAM CPIO
BLKSIZE 65536
BANDNAME Dienstag
ARCHIV Test
RECHNER (Name unseres Rechners)
SAVEDIR <Band ist leer>
Die einzelnen Felder:pROGRAMM CPIO werden wir verwenden um unser Label zu identifizieren, BLKSIZE von 64KB damit werden wir die Blockgröße festlegen mit der wir auf dieses Band sichern, und hinter SAVEDIR werden wir die Verzeichnisse ablegen die auf unserem Band gespeichert sind. ARCHIV steht im Moment nur so als Platzhalter.

In unserem Label werden also ua. Bandname, Rechnername, Schreibdatum und auch die gesicherten Verzeichnisse stehen und wir brauchen nur das Label auszuwerten um zu wissen welches Band wir eingelegt haben. Das hilft uns gegebenenfalls spezielle Sicherungen schnell wieder zu finden.

robi
 
A

Anonymous

Gast
2. Band anfordern, Label lesen und Label auswerten

Zuerst testen wir mit mtst -f DEVICE status ob ein Band geladen ist, dazu suchen wir in der Ausgabe nach ONLINE. Wenn eins geladen, dann wird das Band erst einmal mit mtst ... offline entladen, nur so sicherheitshalber.

Code:
#Band anfordern 
 while [ $LOAD = False ]; do 
     echo -e "\aBitte Band fuer $DATE einlegen und mit ENTER bestaetigen;  ^C fuer Abbruch" 
     read LOAD 
     sleep $LOADSLEEP 
     STATUS=`mtst -f /dev/nst0 status | grep ONLINE | wc -l` 
     if [ "$STATUS" = 1 ] ; then 
        LOAD=True
Wir fordern ein Band an und nach einem sleep von einigen Sekunden testen wir wieder mit mtst ob ein Band erkannt wird, dazu verwenden wir wieder das ONLINE in der Ausgabe des status Befehles. Ob ein Band geladen ist speichern wir im Program zur Auswertung für die Ablaufsteuerung in der Variable LOAD. ( In professionellen Programmen müssten wir fast jeden Befehl auf das Bandlaufwerk gezielt nach Fehlern abfragen, um darauf gegebenenfalls zu reagieren, aber darauf verzichten wir hier großzügigerweise, das würde für ein Demo viel zu kompliziert und ist für die meisten kleineren Programme auch nicht zwingend notwendig.)


Code:
 echo "Band erkannt " 
         mtst -f /dev/nst0 rewind 
         mtst -f /dev/nst0 setblk 0
wurde ein Band gefunden dann spulen wir es erst noch mal zurück, ( ist zwar unnütz da das Band ja schon am Bandanfang steht und hat eigentlich nur die Aufgabe eventuelle Meldungen oder Fehler die das Laufwerk dem Rechner unbedingt melden möchte an den Treiber weiterzuleiten. Da der stTreiber scheinbar die Eigenschaft hat einige(zumindestens meine alle) Laufwerkstypen mit einer festen Blockgröße von 1024 Byte vorzukonfigurieren setzen wir im Laufwerk mit mtst ... setblk 0 eine variable Bockgröße, das heist, das Laufwerk schreibt immer die Blockgröße in der die Daten vom Programm übermittelt werden und das Programm stellt sicher das die Daten dann auch wieder mit der richtigen Blockgröße gelesen werde. Siehe auch http://www.linux-club.de/viewtopic.php?t=15435 da habe ich schon mal was dazu geschrieben.

Code:
 dd if=/dev/nst0 of=$LABEL count=1 2>/dev/null
wir versuchen mit dd physikalisch genau einen Block vom Band zu lesen und schreiben diesen in die andere Labeldatei. Eventuelle Fehlermeldungen gehen ungebremst in den Papierkorb. Genau an dieser Stelle würde sich unsere Labeldatei auf dem Band befinden. Ich habe mich für das Label für die Methode dd (dd = copy & convert siehe auch man dd ) entschieden, da wir damit wohl die wenigsten Probleme erwarten dürften wenn noch kein Label auf dem Band ist.


Code:
 PROGRAM=`grep PROGRAM $LABEL 2>/dev/null | cut -f2 -d" "`
          if [  -e "$LABEL"  -a  "$PROGRAM" = "CPIO" ] ; then 
             echo "Label erkannt" 
             BANDNAME_O=`grep BANDNAME $LABEL | cut -f2 -d" " ` 
             DATUM_O=`grep DATUM $LABEL | cut -f2 -d" "` 
             RECHNER_O=`grep RECHNER $LABEL | cut -f2 -d" "` 
             SAVEDIR_O=`grep SAVEDIR $LABEL | cut -f2- -d" "` 
             echo "Sicherung vom $BANDNAME_O vom Rechner $RECHNER_O am $DATUM_O Directory $SAVEDIR_O"

damit testen wir ob die Labeldatei jetzt existiert und ob darin die Wortgruppe "PROGRAM CPIO" vorkommt. Wenn ja dann sollte das uns genügen und wir gehen davon aus das wir ein gültiges Label gefunden haben.
Wir filtern dann noch aus dieser Labeldatei die Werte für BANDNAME, DATUM, RECHNER und SAVEDIR aus und bringen diese in einem Satz zum Ausdruck.

sollten wir keine gültigen Label gefunden haben, dann dürfen wir nicht vergessen die Labeldatei in die unser dd versucht hat zu schreiben zu löschen, sonst gibt es evtl. Unklarheiten beim nächsten Versuch einen Label zu erkennen, dieser Befehl ist innerhalb der while Schleife und den case Abschnitten mehrfach versteckt.

Und wie das Label nun auf das Band kommt erfahrt ihr morgen !

robi
 
OP
N

Nostrike

Newbie
Hallo robi,

nochmals danke fuer Deine Pionierarbeit.
Aber langsam klingelts auch bei mir.

Hab aber noch 1 Problem.

1.) Wenn ich das mtst Commando benutzen will bekomm ich folgende Fehlermeldung

linux:~ # mtst
usage: mt [-v] [--version] [-h] [ -f device ] command [ count ]
linux:~ #

dasselbe kommt auch, wenn ich das Kommando fuer Rewind eingebe.

Ich hab das Programm extra nachinstalliert -
was ist denn da los?

Gruss
Peter
 
A

Anonymous

Gast
schau mal ob du zwischen -f und dem DEVICE ein Leerzeichen hast oder nicht. mtst ist da ein bischen eigen und will unbedingt ein Leerzeichen dazwischen

robi
 
A

Anonymous

Gast
so nachdem jetzt das mit mtst -f LEERZEICHEN geklärt ist noch ein paar Worte zum Label, nicht dass es dann heißt ich hätte euch nur die Hälfte verraten und mal ein leichter und lehrreicher Abschnitt zwischen durch entspannt etwas.

Es gibt da doch wirklich einen Standart einen ISO VOLSER LABEL
ist genau 80Byte lang und müsste mit dd an den Anfang jeder Cartridge als selbständige Datei geschrieben werden, genau wie unser Label auch.
Byte 1-4 muss VOL1 sein
Byte 5-10 enthält den Volsername (nur große Buchstaben und Ziffern, Sonderzeichen wenn überhaupt nur ganz bestimmte) also zB: BAND05
Byte 11-80 wird im Moment von niemanden nicht verwendet und ist mit 0x00 zu füllen.

Das Problem mit diesem ISO Label ist, eigentlich sollte das Laufwerk den Label lesen und zB bei der laufwerksinternen Fehlerstatistik mit führen, aber es hällt sich kaum ein HW-Hersteller bei der Firmware Entwicklung daran und schon gar nicht bei der "billigen" Massenware, die Standarttreiber können überhaupt nichts damit anfangen, die Softwareentwickler machen was sie wollen zB einen eigenen Label mit 32KB Größe erfinden und einfach die ersten 80 Byte mit 0x00 füllen, usw und so fort. Es gibt also nur wenige Laufwerke die das überhaupt richtig unterstützen und noch weniger Anwendungen die sich daran halten. Ich kenne nur 2 Ausnahmen im Umfeld von IBM-Laufwerken bei denen das wirklich durchgängig vom Band über Laufwerk und Firmware bis hin zum Treiber und Backupsoftware einschließlich Fehlerloging benutzen wird. Da also jeder macht was er will, machen wir das hier im Demo auch und setzen Felder ein, die uns Informationen liefern können was auf dem Band drauf gesichert ist.

robi
 
A

Anonymous

Gast
Nach dem wir uns entschieden haben was wir mit dem Band anfangen wollen erfolgt eine Verzweigung
Code:
N)       mtst -f /dev/nst0 offline 
                        LOAD=False 
                        rm $LABEL 
                        ;;
und
Code:
 *)        mtst -f /dev/nst0 offline 
                        LOAD=False 
                        rm $LABEL
Also Antwort N und alles außer S J Z macht Band entladen und die Variablen wieder zurücksetzen, Labeldatei löschen, damit die Schleife mit neuer Bandanforderung wieder durchlaufen werden kann.

J macht an dieser Stelle gar nichts und dort geht der Progammablauf hinter der while Schleife weiter und dort gehen wir jetzt hin.

Code:
if [ $? ] ; then 
   #Datensicherung vorbereiten 
   BLKSIZE=`grep BLKSIZE $LABEL | cut -f2 -d" " ` 
   echo "Welches Verzeichnis moechten sie sichern," 
   echo -e "\aden kompletten Path der/des Verzeichnis (zwischen mehreren Verzeichnissen jeweils 1 Leerzeichen) : \c" 
   read SAVEPATH 
   SAVEDIR="$SAVEPATH" 
   echo -e "DATUM $DATUM\nPROGRAM $PROGRAM\nBLKSIZE $BLKSIZE\nBANDNAME $BANDNAME\nARCHIV $ARCHIV\nRECHNER $RECHNER\nSAVEDIR $SAVEDIR" > $LABEL

(na ja der if-Zweig ist hier unnötig geworden und stammt noch aus frühen Zeiten dieser Scriptentwicklung, typischer Fall von schlafendem Bug.)
Wir filtern noch einmal aus dem mit dd gelesenen Label die Bocksize aus und übergeben sie BLKSIZE. ( ist fast unnötig aber wegen dem möglichen mehrfachen Durchlaufen der while-Schleife könnte hier jedoch ein falscher Wert stehen, bezeichnen wirs mal als künstlerische Freiheit.)
Danach fordern wir zur Eingabe der Dateiverzeichnisse auf und erwarten zB: / /home/micha /opt/daten /usr/local/src
Also den absoluten Path zu den Verzeichnissen deren rekursiver Inhalt, soweit er sich im selben Filesystem befindet, gesichert werden soll und immer mit einem Leerzeichen dazwischen.
eigentlich sollten wir das hier alles kontrollieren, damit die Verzeichnisse auch existieren, (entfällt aus Platzgründen in der Demoversion) und übergeben das der Variable SAVEDIR ( in der hat bis jetzt noch <Band ist leer> gestanden.
mit dem echo Befehl legen wir dann ein neues Label an, das sich von dem Label das wir am Anfang erzeugt haben dadurch unterscheidet, das jetzt hinter SAVEDIR die zu sichernden Verzeichnisse stehen.



Code:
mtst -f /dev/nst0 rewind 
   dd if=$LABEL of=/dev/nst0  2>/dev/null                
   mtst -f /dev/nst0 weof
wir spulen das Band an den Anfang zurück und schreiben die soeben erzeugte Datei mit dem dd Kommando einfach auf das Band. Das dd wird nachdem es fertig ist automatisch ein EOF(End Of File) schreiben und damit das Archiv (oder File ) 0 abschließen. Zusätzlich erzeugen wir mit dem mtst ... weof noch ein weiteres EOF (leeres Archiv) und schließen damit auch das 1. File (Archiv) auf dem Band, warum? Eigentlich ist das nur eine zusätzliche Sicherung, und würde obendrein einen potentiellen Datenräuber der nicht mit diesem Tool arbeitet zusätzlich verwirren. File 0 und 1 abgeschlossen, das müssen wir uns merken, denn unsere Sicherungen gehen dann immer mit File 2 los und nicht am Bandanfang, denn da steht unser Label jetzt.

So jetzt könnten wir entlich sichern. ABER ABER ABER WIE

So und nun zur eigentlichen Sicherung. Zuerst bleibt die Frage mit welchem Programm soll ich nun sichern, tar, dump, cpio oder oder oder. Diese Frage läßt sich nicht so ganz schnell und schon gar nicht allgemeingültig beantworten.
Schauen wir uns mal ein paar Problemezonen an mit denen wir bei einem backup eventuell kämpfen müssen. Da gibt es normale Dateien, Verzeichnisse, 2 verschieden Linktypen, Gerätedateien, named Pipe, mountpoints, Zugriffsrechte, UserID und GruppenID und die jeweiligen Namen dazu, jede Datei führt mehrere Zeitstempel mit sich herum - und daraus ergeben sich evtl Gültigkeitsprobleme da wir mehrere Dateien gleichen Namens aber unterschiedlichen Datums haben, die größe der Inode der Dateien spielt in sehr großen Dateisystemen hin und wieder auch eine Rolle, da gibt es die verschiedensten Filesysteme und nicht immer alle mit den default Parametern angelegt, und jede Festplatte muß auch noch vor der Benutzung mit Partitionen versehen werden - wie war das denn auf der alten Festplatte ??, da muss das gespeicherte eventuell noch auf eine andere Plattform portiert werden, und ich will auch nach dem nächsten Update und eventuell in 10 Jahren die Sicherung auch noch einspielen können. Da ist das Filesystem größer als die Kapazität des Sicherungsmediums, da sind die Daten so geheim, dass man schon überlegt wie man sein Swapfilesystem auch noch verschlüsselt, nur das Backup auf Band kann jeder mit 2 einfachen Befehlen im Klartext lesen, da müssen Sicherungen übers Netz laufen, möglichst noch durch die Firewall, da gibt es Filesystemsicherungen, Datenbanksicherungen, ONline- und OFFlinesicherungen, welche Parameter braucht mein Laufwerk damit es möglichst optimal arbeiten kann, arbeite ich mit Harwarekompression oder doch lieber ohne, welche I/O Last erzeugt mein Backup und wie schnell geht das, und was passiert eigentlich bei einen Lesefehler - weitermachen? oder doch abbrechen? was bedeuten überhaupt die Fehlermeldungen vom st und kernel die ich jeden Tag zu Haufe in der /var/log/messages finde. usw usw usw. War euch doch alles gewusst und war bisher in eurem Backup auch alles beachtet - stimmts? oder müsst ihr jetzt schnell mal was ausprobieren? Hoffe ihr könnt jetzt noch ruig schlafen. Und die Meinung RAID 0 oder RAID 5 ersetzt mir ein aufwendiges Backup, träumt mal schön weiter, wie schnell man sich ein Filesystem löscht oder zerschießt werdet ihr schon irgendwann mal mitbekommen.
Daten weg, Platte tot - na Gott sei dank habe ich noch ne Sicherung - nur wo ??????? das ist zwar das häufigste aber nur eines von vielen Problemen beim Backup. Genau aus diesem Grunde gibt es die verschiedensten Programme und jedes mit einer riesen Liste vom Optionen. Man sollte sich also genauer überlegen was und warum man eigentlich sichert, denn es kommt schließlich darauf an, dass man nach dem Crash schnellstens den optimalsten Zustand wieder herstellen kann. Dazu sollte man wirklich jede Option die man setzt oder weglässt genau überlegt und auch getestet haben, und immer eine genaue Befehlsbeschreibung für den Notfall in der Schublade !!!!?
Doch ehe ich hier noch meine Doktorarbeit in Backup schreibe -- ich habe mich in diesem Demo für cpio entschieden - PASTA - fragt mich nicht warum ( siehe man cpio - kann ne ganze Menge ).

so und nun lasst mich mal nen Kaffee trinken, dann gehts richtig los.

robi
 
OP
N

Nostrike

Newbie
Hallo Robi,

guten morgen!!!
und nochmals Danke für Deine Spätschicht!!!

Bei Deiner Ausdauer und Deinem Wissen über Backup, würde ich sagen, solltest Du Dich mal an einer eigenen Sparte für Backup versuchen, die Du dann als Admin betreuen könntest.
Das würde Deinem Können gerecht werden und vielen vielen Tausend Linux Usern und Newbie das Leben erleichtern und wäre außerdem ein Super Nachschlagwerk.
Ich glaube, daß Backup ein sehr brennendes Thema bei allen Usern ist und die meisten gar nicht wissen wie man ein richtiges Backup anlegt oder den Restore macht. Geschweige denn ein Script dafür schreibt.
So ein Forum schritt für schritt wäre ein Suuuuper Ding. Angefangen bei den ganzen tar und mt Befehlen mit Beispielen, dann weiter zu Automatisierungsanleitungen und ausführlichen Ausführungen. Außerdem brauchst Du dann nicht jedesmal wieder von vorne für eine neue Anfrage zu beginnen und kannst einfach auf Dein Forum verweisen.
Außerdem gibt es solch ein Forum noch in keiner Linux-Hilfe-Seite, zumindest habe ich bis jetzt noch keines gefunden.
Wenn Du nichts dagegen hast würde ich das Moenk mal gerne vorschlagen.

Danke und schönen Tag
Gruß
Peter
 
A

Anonymous

Gast
an der Anzahl der Aufrufe dieses Themas merke ich schon das das scheinbar von Intresse ist, hätte ich das nur vorher gewusst- Aber ich habe nicht immer so viel Zeit und wenn Frau Kinder und Chef wieder anfangen zu nerven, dann wirds schnell eng. Auch habe ich schon ein Hobby-Projekt über 3 Server und mit derzeit ca. 80000 Zeilen eigener C-Code und ca. 2000 Zeilen Shell. Und ich mache etwas lieber richtig als halbherzig.

robi
 
A

Anonymous

Gast
!Achtung Achtung, wer das script schon einsetzt bitte noch mal hier abholen, habe 2 Zeilen dringend einfügen müssen, tut mir leid. musste aber sein.)

nun zur eigendlichen Sicherung.

Code:
   echo "$SAVEDIR" | tr " " "\n" | while read i 
     do 
       find $i -mount | cpio -oVcC$BLKSIZE  > /dev/nst0 
    done

echo $SAVEDIR ist die Ausgabe unserer Verzeichnisse die wir sichern wollen, ihr erinnert euch, es war aufgefordert dazwischen Leerzeichen.
durch die PIPE (|) geht die Standatausgabe von echo als Eingabe an tr das aus den Leerzeichen Zeilenvorschübe macht und dann über PIPE in die while-schleife, in der wir bei jedem Durchlauf der Variable i durch read einen Wert von der Standarteingabe zuweisen. Bei jedem Duchlauf der Schleife enthält also i genau eine Verzeichnissname aus SAVEDIR. Sind alle Werte durchgelaufen, endet die while-Schleife ( Netter Trick - benutze ich übigens oft)
In der Schleife sucht find dann rekursiv nach allen Dateien in diesem Verzeichniss, durch die Option -mount wird verhindert, dass find dabei das Filesystem verläßt und beim Rootfilesystem zB in /proc oder /windows/C runtersteigt, das sind ja eigene Mountpunkte mit eigenen Filesystemen. Durch die Pipe übergebe ich dann wieder die ganze Liste von Dateinamen die find erzeugt weiter an den Befehl cpio. Die Optionen -o ist create ist hier das wichtigste. -V gibt für jede verarbeitet Datei eine Punkt auf die Ausgabe, -c bezeichnet ein gut portierbares cpio-Format und mit -C$BLKSIZE übergebe ich die in der Variable gespeicherte Blocksize mit der cpio arbeiten soll. Diese Optionen sollten für die meisten einfachen Sicherungen das richtige sein. Manchmal muss man ein anderes Format wählen und - oder -usw. - man cpio wird man öfter mal brauchen, wichtig ist, dass wir uns die Optionen von der Sicherung merken, denn die brauchen wir wieder zum Auspacken. Das Archiv das cpio mit diesen Optionen auf den Standartausgang ausgibt lenken wir einfach auf unser Tape um. Ist cpio fertig schreibt es ein EOF und die Schleife mit dem nächsten Verzeichniss von vorne. So entstehen auf unserem Tape beginnend mit Archiv 2( wir erinnern uns warum) so viele neu Archive auf dem Tape, wie wir Verzeichnisse eingegeben habe.

Code:
echo "Ende --- Band wird entladen" 
 mt -f /dev/nst0 status 2>&1 >/dev/null 
 mt -f /dev/nst0 offline 
 rm $LABELNEU $LABEL 2>/dev/null
zum Schluss wird noch ein mt ( hier nicht ganz sauber programmiert man sollte entweder nur mt oder nur mtst verwenden) status abgegeben. Die Ausgabe und die Fehlerausgabe gehen in den Papierkorb. Damit will ich erreichen, dass der letzte schreibbefehl auch wirklich sauber abgeschlossen wird, kommt es beim Schreiben zu Problemen dann müsste ich die hier abfangen hier kann auch noch mal in der Ausgabe überprüfen werden ob auch wirklich File jetzt richtig gesetzt ist. (jedoch Fehler werden in dieser Demo-version jedoch weder erkannt noch ausgewertet.)
Nun noch entladen und die temporären Dateien wieder löschen und fertig ist unser Backup.

So jetzt haben wir aber einige Programmteile übersprungen.
Code:
echo "kein gueldiges Label erkannt" 
           echo -e "\amoechten sie das Band mit einem Label versehen ?  <J/N> :  \c" 
           ANTWORT= 
           while [ -z "$ANTWORT" ]; do read ANTWORT; done 
           if [ "$ANTWORT" != J ]; then 
             mtst -f /dev/nst0 offline 
             LOAD=False 
           else 
             mtst -f /dev/nst0 rewind 
             dd if=$LABELNEU of=/dev/nst0  2>/dev/null                  
             mtst -f /dev/nst0 weof 
             mtst -f /dev/nst0 offline 
             LOAD=False
hier her kommen wir wenn kein Label auf dem Band erkannt wird, wenn wir uns dafür entscheiden, dann wird in alt bekannter Manier aber jetzt die Labeldatei die wir ganz am Anfang vom Script erzeugt haben als Label auf das Band geschreiben. Wieder entladen und zurück in die Ladeschleife.

Code:
   S)       BLKSIZE=`grep BLKSIZE $LABEL | cut -f2 -d" " ` 
                        SAVEDIR=`grep SAVEDIR $LABEL | cut -f2- -d" "`
                        mtst -f /dev/nst0 asf 2 
                        echo "$SAVEDIR" | tr " " "\n" | while read i 
                        do 
                           cpio -ivctC$BLKSIZE < /dev/nst0 
                        done 
                        mtst -f /dev/nst0 offline 
                        LOAD=False 
                        rm $LABEL 
                        ;;
hierher kommen wir wenn wir Band scannen ausgewählt hätten. Zuerst lesen wir aus der Labeldatei die Blockgröße aus mit der dieses Band geschrieben wurde. und auch die Verzeichnisse die wir auf unser Band geschrieben haben lesen wir dort aus (das war eine der vergessenen Zeilen). Schau an, zu was so ein Label alles gut sein kann.
mit mtst ... asf 2 bewirken wir ein rewind mit anschließendem vorspulen auf den Anfang des 2 Archives, wir erinnern uns warum genau dort hin.( Sichwort Archiv 0 = LABEL - Achriv 1 = leer zur Verwirrung der bösen Datendiebe)
Dann kommt die berühmte while-Schleife ( die Variable i bräuchten wir hier nicht, aber sie dient zum Zählen der anzahl der Archive die cpio wieder auslesen soll) cpio hier mit der Option -i -t und den anderen Optionen die wir beim sichern genommen haben, wird hier mit den Daten auf dem Band gefüttert und ließt die Archive wirft sie aber weg und zeigt und nur die Dateienname an und zwar im Format das auch ls -l bringen würde. So können wir also schauen ob auch alles schön und richtig auf dem Band steht.
Danach wieder entladen und zurück zu Schleife.

Code:
  Z)       BLKSIZE=`grep BLKSIZE $LABEL | cut -f2 -d" " ` 
                        SAVEDIR=`grep SAVEDIR $LABEL | cut -f2- -d" "`                        
                        mtst -f /dev/nst0 asf 2 
                        echo -e "moechten sie wirklich die Sicherung zurueckspielen <J/N> : \c" 
                        ANTWORT= 
                        while [ -z "$ANTWORT" ]; do read ANTWORT; done 
                        if [ "$ANTWORT" = J ]; then 
                           echo "$SAVEDIR" | tr " " "\n" | while  read i 
                            do 
                             cpio -icvduC$BLKSIZE < /dev/nst0 
                            done                        
                        fi 
                        mtst -f /dev/nst0 offline 
                        LOAD=False 
                        rm $LABEL 
                        ;;
hierher kommen wir wenn wir die Sicherung wieder zurückspielen wollen.
Im Script gibt es eigentlich nichts neues ausser den Optionen von cpio
-i wir wollen das Archiv auspacken, -d legt Verzeichnisse an sollten sie zu dieser Zeit noch nicht existieren, und -u überschreibt auch Dateien gleichen Namens auch wenn sie neueren Datums sein sollten. -v gibt uns die Dateinamen aus die bearbeite wurden -c und -C stammen aus dem Sicherungsoptionen von cpio, die müssen hier wieder hin.

Was macht jetzt cpio. es holt alle Daten wieder vom Band und schreibt die Files wieder in das selbe Verzeichniss aus dem sie mal gesichert wurden. Wir hätten also wieder genau den Stand vor der Sicherung mit Ausname, sollten in der Zwischenzeit neue Dateien in die Verzeichnisse hinzugekommen sein, dann bleiben diese erhalten, sind allerdings Dateien in der Zwischenzeit geändert worden, dann ist diese Änderung wieder rückgängig gemacht worden. Diese Optionen eignen sich also für ein volles Backup.

Noch ein Wort, wir erinnern uns es wurde aufgefordert die absoluten Pathnamen für die Verzeichnisse anzugeben und das wurde auch nicht überprüft, sollten Verzeichnisse relativ angegeben worden sein zB ./otto/daten dann werden hier die Verzeichnisse auch wieder relativ zum Verzeichniss in dem wir uns befanden, als wir das script gestartet haben, wieder abgelegt. Kann gewollt sein, wenn wir zB Verzeichnisse verschieben wollen oder ungewollt, wenn wir nur dummerweise beim sichern und auspacken das script aus unterschiedlichen Verzeichnissen starten.

Und das war schon die ganze Kunst und morgen erkläre ich euch was ihr noch dazu programmieren müsst, damit ihr ein zwar einfaches aber durchaus gut brauchbares komplettes Sicherungskonzept erhaltet.

robi
 
A

Anonymous

Gast
So jetzt seit ihr schon so weit fit, dass ich euch nur noch Hinweise zu geben brauche, auf was es ankommt.

Was brauchen wir nun alles für ein komplettes Backupkonzept.
Als erstes würde ich sagen ein eigenes Verzeichniss, und wenn ich Admin währe, würde mir dort kein User reingucken geschweige denn da drinnen rumrühren, und wenn ein User mal ne Datei gelöscht hat die aber doch noch dringend braucht, dann ist ihm dass auch mindestens ein Kaffee wert, wenn ich ihm die Datei wieder zurückhole.

Zweitens wir brauchen ein Tool mit dem wir händisch Sichern, Recovern, Scannen, Labeln usw. können. Das haben wir ja schon zum Teil, es fehlen nur noch ein paar wichtige Funktionen, zB. müssen wir auch einzelne Vereichnisse und einzelen Dateien aus einer Sicherung wiederherstellen können und wir wollen nicht nur komplette Sicherungen machen sondern auch inkrementelle Sicherungen machen, und natürlich müssen wir das noch vom Handling und von der Ablaufsteuerung verbessern, darauf lasse ich jedoch nicht ein, da kann jeder selbst das Programmieren üben.

Drittens brauchen wir ein Reportsystem. Und zwar müssen wir jederzeit für jedes Band auf dem aktuelle Daten sind, auch das Log von der letzten Sicherung haben, damit wir jederzeit nachsehen können welche Datei wir wirklich gesichert haben und ob es zB bei der Sicherung schon Probleme gegeben hat. Damit können wir dann auch geziehlt suchen ob wir eine Datei in mehreren Sicherungen, haben um dann geziehlt einen bestimmten Filestand wiederherzustellen.
Wir brauchen darüber hinaus aber auch ein Log in dem steht wann wir welches Band bearbeitet haben und ob die Sicherung auch ok ist. Das hilft uns mit unseren Bändern und Sicherungen einen Überblick zu behalten.

Viertens wir brauchen ein Script, dass automatisch mit dem cron.daemon gestartet werden kann. Diese Script muss mit einer Konfigurationsdatei konfigurierbar sein und unser eben beschriebenes Reportsystem und natürlch unser manuales Backuptool voll unterstützen, sonst war die ganze Mühe umsonst.

Fünftens wir brauchen einen Sicherungsalgorythmus, in ihm müssen die über cron zu startenden Sicherungen einfach und
übersichtlich konfigurierbar sein, das ist dann auch gleich unsere Konfigurationsdatei.

Sechstens wir brauchen eine Idee wie wir zuverlässig die richtigen Cartridge vor der automatischen Sicherung die ja meist Nachts laufen wird, wenn wir nicht am Rechner sitzen, rechtzeitig in das Laufwerk bekommen.

Und siebendes wir brauchen Gewissheit dass das alles funktioniert. Und nicht zu vergessen, wir brauchen auch einiges an Dokumentation damit wir nach einem halben Jahr wenn wir uns gar nicht mehr an unser Backup erinnern, weil es doch so schön und automatisch funktioniert, auch schnell Hilfe für das Handling finden.

Das schafft ihr doch jetzt ganz ohne meine langweiligen Postings ??? oder soll ich hier noch weiter aus der Schule plaudern und das Wissen breittreten, mit dem andere sich dumm und dusselig verdienen ?


robi
 
robi schrieb:
Das schafft ihr doch jetzt ganz ohne meine langweiligen Postings ??? oder soll ich hier noch weiter aus der Schule plaudern und das Wissen breittreten, mit dem andere sich dumm und dusselig verdienen ?

Ich bitte darum!! Ich habe selten solch gute Erklärung zu einem Skript gelesen, incl. der Abläufe die zu beachten sind! Außerdem ist das Thema wirklich spannend.
 
A

Anonymous

Gast
Also machen wir auf Wunsch eines Einzelnen eben weiter, möge sich moenk rechtzeitig melden bevor ihm der Plattenplatz ausgeht. Nur werden wir etwas den Speed rausnehmen, es macht wenig Sinn hier Abschnitte zu überspringen also man sollte sich schon von oben nach unten durcharbeiten, und einige wollen sicher auch hin und wieder mal was selbst ausprobieren, ich muss das übrigens auch. Stellenweise komme ich nicht drum rum mal etwas tiefer ins UNIX abzutauchen um die Zusammenhänge richtig klarzustellen und dort ist für viele doch Grauzone und so ist es besser wenn man etwas mehr Zeit zum nachschlagen und ausprobieren hat. Frage mich ob es evtl. auch Sinn machen würde noch einen zweiten Task aufzumachen in dem ihr dann eure kleinen und größeren Probleme und Fragen los werdet und wo dann auch alle mit reden könnten, ohne dass wir das hier zu sehr zerstückeln, dann bleibt das hier ein Kochbuch und Nachschlagewerk auch für später. Habe so ein bissl das Gefühl ihr traut euch gar nicht richtig hier dazwischen zuplappern. Ist aber schwer einen Monolog zu führen, wenn man nicht genau weiss ob überhaupt jemand da ist der das auch hören will, könnte ich ja gleich ne Biographie schreiben. Der nächste der ne dumme Frage hat macht eben einen auf.

robi
 
A

Anonymous

Gast
Also zu Punkt 1 einem eigenem Verzeichniss, dazu gibt es nicht allzuviel zu sagen, /root/backup währe zB ein guter Platz. Jedenfalls sollte ich die Zugriffsrechte stark beschneiden, nur root hat dort was zu erledigen.
Was gehört nun da rein, selstverständlich unsere Scripte für das Backup, aber auch unsere Logdateien aus den Backups.
Auch sollte ich keinesfalls vergessen dort eine Kopie der /etc/fstab und eine Kopie der Konfiguration meines Bootloaders abzulegen, die Ausgaben von fdisk -l von all meinen Festplatten in einer Datei könnte mir auch mal weiterhelfen, und wenn ich spezielle Einstellungen bei der Erstellung meiner Filesysteme benutzt habe, dann gehört das auch hier hinterlegt, ( einige oft benutzte Filesysteme in der UNIXwelt haben dazu eine Option in mkfs die aus einem schon bestehenden Filesystem die genauen Optionen zu seiner Herstellung ausgibt, leider habe ich das bei den von LINUX bevorzugten leider noch nicht gefunden ), auch wenn ich sonstige spezielle Einstellungen oder Umstände habe, die ich zur Rekonstruktion meines LINUX wieder benötigen würde, dann sollte das hier hinterlegt sein.
Und wenn meine Rootplatte den Geist aufgibt ist alles weg, dann habe ich zwar die Sicherung der Rootplatte auf Band aber die Scripte und Konfigurationsdateien mit denen ich die Rootplatte wieder herstellen könnte kann ich nicht von Band starten. Desshalb muss ich dafür sorgen, dass ich auf meiner Sicherheits-CD auch alles für mein Backup mit drauf habe, also eine aktuelle Kopie der wichtigsten Dateien meines Backup und spezieller Pakete (mt_st ist da so was was man gerne vergisst) die ich zum wiederherstellen meines rootfilesystemes benötigen würde. Es kann keinesfals mal schaden, wenn ich die Sicherheits-CD mal ausprobiert habe und das Wiederherstellen der rootplatte vom Band mal getestet habe, bevor mir meine rootplatte abraucht.

Punt 2. Wichtige Funktionen die in unserem Demo bisher noch nicht drin sind. In den seltensten Fällen ist es notwendig ein komplette Sicherung zurückzuspielen, oft brauchen wir nur bestimmte Verzeichnisse oder einzelne Dateien oder nur ein bestimmtes Filesystem. Unser bisheriges Demo kann das noch nicht.
Die eigentliche Herausforderung besteht jetzt darin die interaktive Ablaufsteuerung des scriptes so zu ändern, dass solche Daten abgefragt werden, alle möglichen falschen Eingaben abzuweisen und die Ergebnisse in Variable abzulegen. darauf gehe ich nicht ein, ich zeige euch nur wie man mit diesen Daten dann weiterarbeitet.
Vereinbaren wir folgendes: Variable HALTDIR in ihr soll 0 stehen wenn wir alle Archive vom Band lesen sollen und 1 wenn wir nur ein einzelnes Archive vom Band lesen möchten, der Name dieses Archives steht dann in der Variable REVDIR. Zusätzlich führen wir noch eine Variable OPTION ein, mit ihr wollen wir die Funktionsweise des cpio Befehles steuern können.
Code:
      mtst -f /dev/nst0 asf 2
        echo -e "moechten sie wirklich die Sicherung zurueckspielen <J/N> : \c"
        ANTWORT=
        while [ -z "$ANTWORT" ]; do read ANTWORT; done
             if [ "$ANTWORT" = J -a "$HALTDIR" = 0 ]; then
                echo "$SAVEDIR_O" | tr " " "\n" | while  read i
                    do
                      cpio -i $OPTION -cvdumC$BLKSIZE_O < /dev/nst0
                    done                        
             else
                if [ "$HALTDIR" = 1 ] ; then
                echo "$SAVEDIR_O" | tr " " "\n" | while  read i
                   do
                      if [ "$REVDIR" = $i ] ; then
                        cpio -i $OPTION -cvdumC$BLKSIZE_O < /dev/nst0
                      else
                        mtst -f /dev/nst0 fsf 1
                      fi
                   done
                fi
             fi
        mtst -f /dev/nst0 offline

Wir haben hier erst mal eine Verzweigung eingefügt, je nach dem ob HALTDIR 0 oder 1 ist. Neu ist die Verzeigung mit HALTDIR=1 Dort fragen wir in der while-Schleife ab, ob der Verzeichnissname den unser Archive auf dem Band trägt gleich dem Verzeichnissnamen in der Variable REVDIR ist. Nur in diesem Fall wird dieses Archiv nach cpio geschickt in jedem andem Fall führen wir mtst ... fsf 1 aus, und das weißt unser Laufwerk an, ein Archiv nach vorne zu spulen.
Wenn wir uns die cpio Befehle anschauen, dann haben wir eine weiter Option -m hinzugefügt, sie bewirkt, dass die Dateien die wir zurückspielen wieder den selben Änderungszeitstempel tägt, wie die orginale Datei die wir mal gesichert haben. Zu Zeitsempeln gibts gleich bald noch mehr zu sagen. Desweitern haben wir die Variable OPTION in den cpio-Befehl mit eingefügt. Ist OPTION= dann bewirkt sie nichts, ist aber in OPTION="option" dann wird diese option dann genau so in unseren cpio-Befehl eingefügt. Wir können also durch setzen der Variable OPTION unser cpio steuern.

Und genau das nutzen wir, wenn wir nur einzelne Dateien zurückholen wollen. man cpio zeigt uns die option "--pattern-file=file" Das bedeutet wenn wir in eine Datei zB /root/backup/recover alle Dateien eintragen, die wir zurückholen möchten ( jede Zeile ein Eintrag, dabei dürfen auch Pattern verwendet werden zB * ? ) und in unserem Script OPTION folgendermassen belegen : OPTION="--pattern-file=/root/backup/recover" dann werden nur die Dateien von cpio verarbeitet die zu unserer Patterndatei passen. Somit können wir jetzt gezielt genau die Dateien wieder herstellen, die wir wollen und können auch gezielt ganze Archive überspringen, das spart uns viel Zeit.

Bis jetzt können wir mit unserem Script allerdings nur komplette Sicherungen machen. Dabei sichern wir jedes mal alles wieder und immer wieder komplett, auch wenn sich an unseren Dateien und Verzeichnissen gar nichts geändert hat, das ist sehr zeitaufwendig und auch nicht immer unbedingt notwendig. Manchmal reicht es ja durchaus, wenn wir gezielt nur die Dateien sichern die sich wirklich seit der letzten Sicherung geändert haben, das würde uns eine ganze Menge Zeit und Bandmaterial sparen. Doch dabei ist einiges zu beachten und dazu müssen wir etwas tiefer ins UNIX abtauchen, Als Backupneuling kann man dort ne ganze Menge falsch oder nicht ganz richtig machen weil man sich nicht aller Zusammenhänge bewusst ist, und genau desshalb verschieben wir das auf den nächsten Beitrag.

robi
 
A

Anonymous

Gast
Inkrementelle Sicherung, was ist das eigentlich, und was muss man beachten und wo liegen Gefahren?

Bis jetzt konnten wir mit unserem Demo nur komplette Sicherungen machen. Das reicht sicherlich aus wenn wir unsere Bilder, Videos, Audiodateien und andere Dokumente auf unserem Homerechner sichern. An solchen Dateien wird sich meist nichts oder nur wenig änderen, es kommen nur noch hin und wieder welche dazu, und nach einer gewissen Zeit müssen wir dann eben wieder eine komplette Sicherung machen. Sollten wir aber nun ein Filesystem auf unserem Rechner haben in dem sich mehrere Webdesigner monatelang Tag für Tag bemühen ein neues Webprojekt aus dem Boden zu stampfen, müssten wir jede Nacht eine Sicherung laufen lassen, damit bei einem Crash maximal die Arbeit eines einzigen Tages verloren währe. Ist auch kein Problem, aber wer schon mal versucht hat 2 160GB Platten voll mit Daten täglich zu sichern, merkt sicherlich schnell, das es doch schnell zum Problem werden kann. Also warum soll ich tag-täglich Unmengen von Daten sichern, wenn sich nicht einmal 1% davon gändert haben, würde doch reichen wenn ich nur die Verzeichnisse sichere in denen wirklich gearbeitet wurde oder geziehlt diese 1% die sich geändert haben, morgen sichere ich dann wieder was sich geändert hat usw. Sollte es jetzt zu einem Crash kommen, nehme ich die letzte komplette Sicherung und danach eine nach der anderen kleinen Änderungssicherung und spiele sie wieder ein. Wenn ich es mit der Anzahl an Änderungssicherungen nicht übertrieben habe, bevor ich wieder eine komplette Sicherung mache, ist das ja auch kein Problem, vorausgesetzt ich bin mir bewusst was ich so alles falsch laufen kann.

Zuerst einmal gezielt nur einzelne Verzeichnisse innerhalb eines Dateisystemens zu sichern, ist gefährlich sobald sich Hardlinks in dem Dateisystem befinden. (Ausnahme die Verzeichnissnamen selbst). Beim Zurückspielen solcher Archive werden aus zwei per Hardlink verbundener Dateinamen dann 2 eigenständige Dateien. ??? kann jeder ausprobieren und etwas später im Text werden wir solche Phänomäne noch mehrere sehen.

Also gehen wir über den mountpoint und suchen die Dateien nach der Zeit aus, mit ls -l kann man ja die letzte Änderungzeit einer Datei sehen. Wirklich ?? Ändert doch mal die Zugriffrechte den User und die Gruppe einer Datei und dann auch noch mit mv den Dateinamen und das Verzeichniss der Datei - und ist die Zeit mit ls -l jetzt richtig gesetzt oder waren unsere Änderungen jetzt so banal, dass wir diese Datei jetzt mit neuem Namen in einem anderm Verzeichniss und mit vollkommen anderen Zugriffsrechten nicht in eine Anderungssicherung aufzunehmen bräuchten?

Die Erklärung und das Zauberwort heist Inode. Die meisten kennen Inode nur als unnütze Zahl am Anfang jeder Zeile bei der Ausgabe von ls -il . Für jede physikalische existierende Datei gibt es genau eine Inode die jeweils pro Dateisystem als Liste organisiert sind, daher die Nummer. Die Inode sind der Dreh und Angelpunkt sämtlicher Dateizugriffe. In den Feldern jeder Inode stehen zB. Dateitype, UserID, GruppenID, Größe, Anzahl der Links auf Datei, die Datenblockaddressen und 4 Zeitstempel. Von diesen Zeitstempeln sind für uns aber nur 3 von Interesse, die Zugriffszeit, die Modifikationszeit und der Zeitpunkt der letzten Statusänderung. Eigentlich steht dort alles, ausser dem Dateinamen und dem Dateiinhalt selbst. Der Dateinamen bildet mit der dazugehörigen Inode den Dateiinhalt der Verzeichnisdatei. Für die Datensicherung relevant ist die "c-Zeit" die Stausänderung oder Create-Time der Inode.
(Siehe man find und man touch) Mit find und den Optionen -ctime -cmin -cnewer können wir geziehlt die Dateien auswählen die wir für unser Differenzsicherung auswählen müssen. Am besten zeige ich das mal für jeden auf seinem LINUX auch ohne TapeLaufwerk nachvollziehbar an einem kleinem Beispiel.

  • --------Dateien Anlegen und Vollsicherung ---------------------
    # mkdir test test/A test/B test/C
    # touch test/A/post
    # ln test/A/post test/B/post
    # ln -s ../A/post test/C/post
    # ls -il test/*/*
    176300 -rw-r--r-- 2 root root 0 2004-09-20 17:32 test/A/post
    176300 -rw-r--r-- 2 root root 0 2004-09-20 17:32 test/B/post
    176301 lrwxrwxrwx 1 root root 9 2004-09-20 17:32 test/C/post -> ../A/post
    # find test | cpio -oc > test0.cpio

    ---------------Eingabepause von mindestens 5 Minuten ----------
    ----------------Änderungen und danache Differenzsicherung -----
    # mv test/B/post test/B/ost
    # mv test/C/post test/C/ost
    # ls -il test/*/*
    176300 -rw-r--r-- 2 root root 0 2004-09-20 17:32 test/A/post
    176300 -rw-r--r-- 2 root root 0 2004-09-20 17:32 test/B/ost
    176301 lrwxrwxrwx 1 root root 9 2004-09-20 17:32 test/C/ost -> ../A/post
    # find test -cmin -5 | cpio -oc > test1.cpio

    ------------ Auspacken der Vollsicherung ----------------------
    # rm -rf test
    # cpio -iumd < test0.cpio
    # ls -il test/*/*
    176301 -rw-r--r-- 2 root root 0 2004-09-20 17:32 test/A/post
    176301 -rw-r--r-- 2 root root 0 2004-09-20 17:32 test/B/post
    176300 lrwxrwxrwx 1 root root 9 2004-09-20 17:51 test/C/post -> ../A/post

    ----Auspacken Diffsicherung Variante 1 und seine Folgen ------
    # cpio -iumd < test1.cpio
    # ls -il test/*/*
    176308 -rw-r--r-- 2 root root 0 2004-09-20 17:32 test/A/post
    176308 -rw-r--r-- 2 root root 0 2004-09-20 17:32 test/B/ost
    176301 -rw-r--r-- 1 root root 0 2004-09-20 17:32 test/B/post
    176303 lrwxrwxrwx 1 root root 9 2004-09-20 17:55 test/C/ost -> ../A/post
    176300 lrwxrwxrwx 1 root root 9 2004-09-20 17:51 test/C/post -> ../A/post

    ----Auspacken Diffsicherung Variante 2 und seine Folgen -------
    # cpio -imd < test1.cpio
    # ls -il test/*/*
    176301 -rw-r--r-- 2 root root 0 2004-09-20 17:32 test/A/post
    176308 -rw-r--r-- 1 root root 0 2004-09-20 17:32 test/B/ost
    176301 -rw-r--r-- 2 root root 0 2004-09-20 17:32 test/B/post
    176303 lrwxrwxrwx 1 root root 9 2004-09-20 17:57 test/C/ost -> ../A/post
    176300 lrwxrwxrwx 1 root root 9 2004-09-20 17:56 test/C/post -> ../A/post

An den Ergebnissen erkennen wir auch gleich einige Nachteile einer Differenzsicherung. Auf diese Weise kann jeder selbst experimentieren, es gibt da einiges an möglichen Ungenauigkeiten, die entstehen könnten.
Solche Ungenauigkeiten können sich uU summieren und dazu führen dass nach unserem nächstem Update einiges nicht mehr sauber funktioniert, dann ist aber eben nicht SUSE schuld, sondern unser Backup.
Wichtig ist folgendes zu wissen wenn wir mit Inkrementellen Sicherungen arbeiten. Die Vollsicherungen wenn möglichst in ein leeres Filesystem einlesen, Gelöschte oder umbenannte Dateien können wieder auftauchen, die Modifikationstime von Verzeichnissen und Symbolischen Links werden beim Neu anlegen nicht übernommen, wenn wir mit falschen Optionen arbeiten könnten leicht falsche Dateivarianten und Kombinationen entstehen und Hardlinks aufgelöst werden, bei Ketten-Differenzsicherungen müssen wir unbedingt auf die strikte Reihenfolge achten, die Differrenzzeit müssen wir stets so wählen dass sie mindestend den Beginn der letzten Sicherung einschließt. Um wirklich über diesen Weg ein Filesystem mit Sicherheit wieder 100% genau so herzustellen wie es vorher war, würden wir einige Funktionen mehr benötigen als ein normales Backup in der Regel beinhaltet. (Solche Programme zielen dann in Richtung Versionsverwaltungssoftware.)



Code:
 echo "Moechten sie eine Vollsicherung oder eine Differenzsicherung ?"
 echo -e "\ageben sie 0 oder die Anzahl der Tage ein  : \c"
 typeset -i SAVETYP
 read SAVETYP
 SAVEFLAG=
 if [ $SAVETYP -ne 0 ]; then
    SAVEFLAG="-ctime -$SAVETYP"
 fi
 echo "Welches Verzeichnis moechten sie sichern,"
 echo -e "\aden kompletten Path der/des Verzeichnis - zwischen Verzeichnissen jeweils 1 Leerzeichen : \c"
 read SAVEPATH
 SAVEDIR="$SAVEPATH"
 echo -e "DATUM $DATUM\nPROGRAM $PROGRAM\nBLKSIZE $BLKSIZE\nBANDNAME $BANDNAME\
\nARCHIV $ARCHIV\nRECHNER $RECHNER\nSAVEDIR $SAVEDIR" > $LABEL
 mtst -f /dev/nst0 rewind
 dd if=$LABEL of=/dev/nst0  2>/dev/null
 mtst -f /dev/nst0 weof
 echo "$SAVEDIR" | tr " " "\n" | while read i
    do
      find $i $SAVEFLAG -mount | cpio -oVcC$BLKSIZE  > /dev/nst0
    done

echo "Ende --- Band wird entladen"

In unserem Demoscript verwenden wir eine recht einfache Art der Diffenzsicherung. wir fragen interaktiv ab, wieviel Tage unsere Differenzsicherung umfassen soll, oder geben mit 0 eine Vollsicherung an(Variable SAVETYP). Die zweite Änderung in unserem Script umfasst die find | cpio -Zeile, dort wird mit SAVEFLAG die Optionen für find festgelegt.
Wesentlich komfortabler können wir Diffenenzsicherungen im cronjob-script einsetzen wenn das logging und die Konfiguration funktioniert und wir darauf aufsetzen.

Da unsere Differenzsicherungen bedeutend weniger Platz als unsere Vollsicherungen einnehmen ist es auch möglich ( nicht in unserem Demo ) mehrere Sicherungen auf einem Band abzulegen. Eine für manche interessante Möglichkeit ist dabei die Möglichkeit verschiedener Laufwerke mit partitionierten Bändern umzugehen. mtst kann mit 3 Partitionen arbeiten, wer mehr wissen möchte der kann mit man mtst und in der Dokumentation zu seinem Laufwerk mehr erfahren. Prizipiell kann man dann eine Partition beschreiben,die andern Partitionen bleiben unberührt. Im Nomalfall ist es ja so, dass wenn wir am Anfang eines Bandes etwas schreiben, dann ist der Rest auf dem Band nicht mehr aktuell und wir können ihn nicht mehr auslesen.

Ich hatte mal einen Test ( nicht LINUX) mit einem Band und 31 Partitionen, also für jeden Tag im Monat eine Partition auf einem Band. Hat zwar sauber funktioniert aber ich bin doch schnell wieder davon abgekommen, denn wenn das Bandmaterial einmal ausfällt, dann ist eben alles auf einmal weg.

robi
 
Oben