BeSo-Homepage
Wie man korrupte tar-Archive repariert...
Udo Rader
2003-08-11 2005-10-17

Der Alptraum jedes Systemadministrators: Man hat ein Backup von wichtigen Dateien erstellt, will diese später wieder entpacken - aber das tar-Archiv ist aus unerfindlichen Gründen defekt ...

Genau das ist mir einmal (und hoffentlich nie wieder) passiert und ich habe seeeeehr viel Zeit dafür gebraucht, diese Dateien (oder zumindest einen brauchbaren Teil davon) aus dem Archiv herauszubekommen.

Bevor wir loslegen, hier noch ein paar notwendige Annahmen, um die Sache klarer zu gestalten:

  • tar bedeutet GNU-tar
  • das Archiv wurde auch bzip2 komprimiert
    (wenn auch der Kompressionstyp im Endeffekt nebensächlich ist)
  • das tar-Archiv ist an einem zugänglichen Platz verfügbar

(GNU-)tar hat ja selbst einige Optionen, welche von sich behaupten, bei der Wiederherstellung von defekten Daten behilflich zu sein (Sie werden meinen Sarkasmus verstehen, wenn Sie weiterlesen ...) Aber, überprüfen wir zuerst, was das genaue Problem ist:

% tar xjf the_bad_bad_backup.tar.bz2
bzip2: Data integrity error when decompressing.
Input file = (stdin), output file = (stdout)

It is possible that the compressed file(s) have become corrupted.
You can use the -tvv option to test integrity of such files.

You can use the `bzip2recover' program to *attempt* to recover
data from undamaged sections of corrupted files.

tar: 56 garbage bytes ignored at end of archive
tar: Unexpected EOF in archive
tar: Unexpected EOF in archive
tar: Error is not recoverable: exiting now

Das zeigt uns also, daß ich bzip2recover "to *attempt* to recover data from undamaged sections verwenden soll. Klingt also nicht zu schlecht, oder?

Also verwenden wir bzip2recover:

% bzip2recover the_bad_bad_backup.tar.bz2

So passiert zumindest irgendetwas. Abhängig von der Größe des Archives, erstellt bzip2recover eine nette Anzahl von kleinen 'rec*' Dateien (typischerweise 900K groß), welche die normale Blocksatzgröße darstellt, die bzip2 als Standard für Kompression verwendet. "Die nette Anzahl von kleinen Dateien" kann jedoch leicht die Anwandlung haben, eine "RIESIGE Anzahl von kleinen Dateien" zu werden, wenn das Archiv groß war - und meines war groß!

Das von mir verwendete Archiv war über 200MB groß, was mehrere hundert(!) dieser "kleinen Dateien" zur Folge hatte. Naja, so schnell habe ich nicht aufgegeben und trotzdem daran geglaubt, daß ich die Daten aus den kleinen Dateien herausbekommen könnte, wenn ich die defekte "kleine Datei" irgendwie herausfinden könnte. So war also mein nächster Schritt, herauszufinden, welche der kleinen Dateien kaputt waren und welche nicht:

% bunzip2 rec*bz2

bunzip2 stoppt, wenn die erste (und damit hoffentlich auch die letzte) korrupte Datei gefunden wird - eigentlich genau das was wir hier brauchen. Da es keine Verwendung für die schlechten Dateien mehr gibt, habe ich die einfach gelöscht und erneut den obigen Befehl verwendet, inklusive Löschung aller weiteren korrupten Dateien. Das wirklich wichtige bei der Aktion ist, sich die Zahl der gelöschten Dateien zu merken (z.b. 00199, wenn die gelöschte Datei rec00199.bz2 geheißen hat).

Jetzt habe ich mir gedacht, daß es ab da einfach wäre: "Einfach tar auf die dekomprimierten Dateien anwenden ...", aber ich wurde eines besseren belehrt. Wenn rec00199 die erste (und letzte) korrupte Datei war, so beginnen wir mit rec00200:

% tar xf rec00200
tar: this doesn't look like a »tar«-archive
tar: jumping to the next header
tar: error upon exit caused by previous errors

"Shit." ... Und bei jeder weiteren der >200 verbleibenden Dateien immer dieselbe Fehlermeldung erhalten. Suchen über google und diverse Postings in verschiedenen Mailinglists haben mir keine verwertbaren Ergebnisse gebracht.

Tar behaupt von sich, auch korrupte Dateien nach tar-Headern zu scannen, aber dieses sogenannte Feature hat einen entscheidenden Nachteil: Es funktioniert nur, wenn keines der Bytes in der Datei verloren und/oder verschoben ist, weil tar beim Scannen nach Fileheadern die jeweiligen Fileheader exakt 512 Bytes groß erwartet. Wenn auch nur ein einziges Byte in einem Header (oder einem folgenden Datenblock) verloren ist, ist dieses "Wiederherstellungs-Feature" eine reine Zeitverschwendung.

Aber das Glück ist einige Wochen später zurückgekehrt: Ich erhielt eine Email von einem netten Typen, der ein kleines perl-script geschrieben hatte, das eine Datei nach einem tar-Header Byte für Byte untersucht und sich nicht an die "512 Bytes" Art von tar hält. Sie können dieses hier downloaden.

Um die Dinge zum Laufen zu bringen, habe ich den zweiten Teil der bunzip'ten Dateien zu einer einzigen großen Datei kombiniert (die Dateien nach der schlechten rec00199 Datei):

% cat rec00[2-4][0-9][0-9] > good_tail.tar

Der obige Befehl kombiniert alle Dateien von rec00200 bis rec00499 in einem großen good_tail.jar Archiv.

Jetzt mußte ich nur noch das Script starten, um die Position des ersten guten tar-Headers im good_tail.tar Archiv zu finden:

% perl find_tar_headers.pl good_tail.tar
good_tail.tar:17185:top/secret/warp_reactor.so:157106
good_tail.tar:75041:top/secret/kernel_injectors.so:153125
good_tail.tar:130849:top/secret/dampening_fields.so:145746
good_tail.tar:183585:top/secret/plasma_controls.so:157035
[...]

Das einzige was zählt, ist die erste Zeile des Outputs. Es zeigt, dass der erste gute tar-Header im good_tail.tar Archiv auf der Position 17185 liegt. Was blieb, war das Entpacken beginnend ab der gefundenen Position:

% tail -c +17185 good_tail.tar > extracted_tail.tar
% tar xf extracted_tail.tar

Happy End der Geschichte!

multifile
string replacement
tar repair tool
exclude files
find_tar_headers.pl.bz2




© 2006 BestSolution.@t GmbH
consulting IT tirol innsbruck österreich tyrol austria europa europeSoftware, Development, Softwareentwicklung, programming, Programmierung, SE, SD, Tirol, Tyrol, Innsbruck, Austria, Österreich, Europa, EuropeSystemadministration, Linux, Tirol, Sysadmin, Netzwerke, network, Linux, Windows, migration, tirol, tyrol, innsbruck, Österreich austria Europa, EuropeIT-Sicherheit, IT-Security, security network, EDV-Sicherheit, Netzwerksicherheit, tirol, tyrol innsbruck, Österreich Austria Europa, EuropeHosting, combeso, typo3, xims, Linux, server, tirol, tyrol innsbruck, Österreich, Austria Europa, EuropeLinux, Open Source, OSS, UNIX, Windows, tirol, tyrol innsbruck, Österreich, Austria, Europa, EuropeBISCAT, BiSCAT, Personenverwaltung, client administration tool, Mitarbeiterverwaltung, staff, Österreich, Austria, tirol innsbruck Europa, EuropedrawSWF, flash, grafiken, graphics, erstellung, development, tirol tyrol, innsbruck, Österreich, Austria, Europa, Europehomepage, webshop, günstig, easy cheap, umfangreich, comprehensive, tirol tyrol, innsbruck, Österreich, Austria, Europa, Europe