Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I received messages in /var/log/kern.log that indicate drive failure. The messages occured while copying my $HOME between drives (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

The messages come in bulks, this is one of those bulks. sdb is the source drive.

How do I find out to which file/inode the sector belongs? I just want to know so I can recover the files in question from a backup. Anything faster than the following code plus a subsequent analysis of the output?

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

OS: Ubuntu Oneiric.

EDIT: The command above also outputs to stderr the files that could not be read.

share|improve this question

2 Answers 2

up vote 1 down vote accepted

The rough idea would be to

  1. do some calculations to find out the filesytem's block number based on the physical sector number
  2. use debugfs testb/ncheck/icheck commands to find out if the block is in use and the name of the file(s) that are using it

There is a bad block HOWTO over at the smartmontools project site describing the process in more detail.

share|improve this answer
    
Thanks for the pointer. Are you aware of a tool that automates this process? –  krlmlr Sep 26 '11 at 23:06
1  
No, but it should be rather easy to script something that fits the need. –  the-wabbit Sep 26 '11 at 23:10
  1. Find which partition the sector is in by running fdisk -lu /dev/sdb. Suppose it is "sdb2" which starts at sector 45612307.

  2. Subtract that from 95891008 to get 50278701.

  3. Next determine how many sectors per block: tune2fs -l /dev/sdb2 | grep Block. Suppose it is 4096.

  4. Calculate the block / sector ratio: 512 bytes/sector / 4096 bytes/block = 0.125 blocks/sector.

  5. Calculate the block from the sector: 50278701 * 0.125 = 6284837.625.

  6. Use debugfs to find out which is using the block. If icheck 6284837 returns inode 12345 then run ncheck 12345.

Caveats: You may need to turn off journaling. This may not work with ext4.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.