So bestimmen Sie, welche Datei / Inode einen bestimmten Sektor belegt

7

Ich habe Nachrichten erhalten /var/log/kern.log, die auf einen Laufwerksfehler hinweisen. Die Meldungen sind beim Kopieren $HOMEzwischen Laufwerken aufgetreten (ext4 -> ext3):

[ 5733.186033] sd 4:0:0:0: [sdb] Unhandled sense code
[ 5733.186038] sd 4:0:0:0: [sdb]  Result: hostbyte=invalid driverbyte=DRIVER_SENSE
[ 5733.186042] sd 4:0:0:0: [sdb]  Sense Key : Medium Error [current] 
[ 5733.186048] sd 4:0:0:0: [sdb]  Add. Sense: Unrecovered read error
[ 5733.186053] sd 4:0:0:0: [sdb] CDB: Read(10): 28 00 05 b7 2e 40 00 00 08 00
[ 5733.186064] end_request: critical target error, dev sdb, sector 95891008

Die Nachrichten kommen in großen Mengen, dies ist eine dieser Massen. sdbist das Quelllaufwerk.

Wie finde ich heraus, zu welcher Datei / Inode der Sektor gehört? Ich möchte nur wissen, damit ich die fraglichen Dateien aus einem Backup wiederherstellen kann. Etwas schneller als der folgende Code plus eine nachfolgende Analyse der Ausgabe?

find . -type f -print \
               -exec cp \{\} /dev/null \; \
               -exec tail -n 1 /var/log/kern.log \;

Betriebssystem: Ubuntu Oneiric.

BEARBEITEN: Der obige Befehl gibt auch stderrDateien aus, die nicht gelesen werden konnten.

krlmlr
quelle

Antworten:

3

Die grobe Idee wäre zu

  1. Führen Sie einige Berechnungen durch, um die Blocknummer des Dateisystems basierend auf der Nummer des physischen Sektors zu ermitteln
  2. Verwenden debugfsSie die Befehle testb / ncheck / icheck, um herauszufinden, ob der Block verwendet wird und wie die Datei (en) lauten, die ihn verwenden

Auf der Projektseite von smartmontools gibt es ein schlechtes Block-HOWTO , das den Prozess detaillierter beschreibt.

the-wabbit
quelle
Danke für den Zeiger. Kennen Sie ein Tool, das diesen Prozess automatisiert?
krlmlr
1
Nein, aber es sollte ziemlich einfach sein, etwas zu schreiben, das den Anforderungen entspricht.
The-Wabbit
5
  1. Finden Sie heraus, in welcher Partition sich der Sektor befindet, indem Sie ausführen fdisk -lu /dev/sdb. Angenommen, es ist "sdb2", das bei Sektor 45612307 beginnt.

  2. Subtrahieren Sie das von 95891008, um 50278701 zu erhalten.

  3. Bestimmen Sie als nächstes, wie viele Sektoren pro Block : tune2fs -l /dev/sdb2 | grep Block. Angenommen, es ist 4096.

  4. Berechnen Sie das Block / Sektor-Verhältnis: 512 Bytes / Sektor / 4096 Bytes / Block = 0,125 Blöcke / Sektor.

  5. Berechnen Sie den Block aus dem Sektor: 50278701 * 0,125 = 6284837,625.

  6. Verwenden Sie debugfs, um herauszufinden, welcher den Block verwendet. Wenn icheck 6284837inode 12345 zurückgegeben wird, führen Sie aus ncheck 12345.

Vorsichtsmaßnahmen: Möglicherweise müssen Sie das Journaling deaktivieren. Dies funktioniert möglicherweise nicht mit ext4.

Mark Wagner
quelle
Ich würde eine Möglichkeit hinzufügen, um zu überprüfen, ob Ihre Berechnungen korrekt sind, z. B. mithilfe von statoder FIBMAP / FIEMAP-iocalls.
Neutrinus
Auf meinem System icheckakzeptiert (C-Schnittstelle ABI / API-Prüfer) keine Sektornummer als Parameter?!
Hagen von Eitzen