debugfs практическое руководство

При восстановлении системы после сбоев жесткого диска (например, при восстановлении программного RAID1 массива в случае выхода из строя двух жестких дисков) крайней полезной бывает информация об использовании файловой системой дефективного сектора.

Существует ряд незаменимых руководств:

Большинство указанных руководств предлагают использовать команду fdisk -lu для получения информации о таблице разделов. Указанная команда работает исключительно, если у Вас устаревшая MSDOS таблица. В случае использования GPT Вы получите сообщение:

# fdisk -lu /dev/sda

WARNING: GPT (GUID Partition Table) detected on '/dev/sda'! The util fdisk doesn't support GPT. Use GNU Parted.


Disk /dev/sda: 3000.6 GB, 3000592982016 bytes
256 heads, 63 sectors/track, 363376 cylinders, total 5860533168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disk identifier: 0x00000000

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1               1  4294967295  2147483647+  ee  GPT
Partition 1 does not start on physical sector boundary.

Для отображения информации на дисках с GPT таблицей необходимо использовать команду

parted -s -- /dev/sda u s print

Ключ -s указывает, что необходимо запустить программу и не взаимодействовать с пользователем. «/dev/sda u s print» указывает, что необходимо отобразить на консоль информацию о таблице для диска /dev/sda в секторах. Например,

# parted -s -- /dev/sda u s print
Model: ATA ST33000651AS (scsi)
Disk /dev/sda: 5860533168s
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start      End          Size         File system  Name  Flags
 4      2048s      4095s        2048s                           bios_grub
 1      4096s      4198399s     4194304s                        raid
 2      4198400s   37752831s    33554432s                       raid
 3      37752832s  5860533134s  5822780303s                     raid

#

В качестве примера, рассмотрим ситуацию, когда сбой произошел в секторе 34066232. В этом случае команды smartctl -l selftest /dev/sda (предварительно необходимо, чтобы проверка smartctl -t long /dev/sda завершилась) и badblocks -v -b 512 /dev/sda вернут номер требуемого дефективного сектора

# smartctl -l selftest /dev/sda
smartctl 5.41 2011-06-09 r3365 [x86_64-linux-3.10.25] (local build)
Copyright (C) 2002-11 by Bruce Allen, http://smartmontools.sourceforge.net

=== START OF READ SMART DATA SECTION ===
SMART Self-test log structure revision number 1
Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Extended offline    Completed: read failure       20%     13620         34066232

# badblocks -v -b 512 /dev/sda
...
Checking for bad blocks (read-only test): 34066232

Для наглядности таблица разделов (вынесены значения исключительно начала разделов и конца диска) и расположение дефективного сектора представлена на изображении. Расположение дефективного сектора обозначено красной стрелкой.
Расположение дефективного сектора

Таким образом видно, что сектор располагается на третьем разделе в диапазоне секторов 4198400 — 37752831. Важно понимать, что значение сектора 34066232 исчисляется от начала жесткого диска. Все программы, которые работают со структурой файловой системы, требуют смещения от начала раздела. Для вычисления этого смещения необходимо воспользоваться формулой:

${Рассматриваемый сектор} — ${Начало раздела, которому рассматриваемый сектор принадлежит}

В нашем случае началом раздела является сектор 4198400. 34066232 — 4198400 = 29867832.

На основании файла /etc/fstab выясняем, что третий раздел является корневым и использует файловую систему EXT4.

Важно! debugfs оперируют блоками различного размера. Таким образом нам необходимо выяснить текущий размер блока, который используется на найденном разделе.

tune2fs -l /dev/md1 | grep 'Block size'
Block size:               4096

Таким образом нам предстоит еще одно вычисление. Объединяем все в одну формулу и получаем

( ${Рассматриваемый сектор} — ${Начало раздела, которому рассматриваемый сектор принадлежит} ) / (Размер блока файловой системы / 512)

Таким образом для нашего случая необходимый блок файловой системы, который содержит сектор 34066232 будет равен 3733479

( 34066232 - 4198400 ) / (4096 / 512) = 3733479

Теперь подключаемся к файловой системе для выяснения обстоятельств использования блока 3733479. По умолчанию debugfs подключает в режиме read only таким образом команда безопасна даже на примонтированной файловой системе

debugfs /dev/md1 
debugfs 1.42 (29-Nov-2011)
debugfs:  testb 3733479
Block 3733479 not in use
debugfs:  

В этом случае блок 3733479 размером 4096 байт не используется и следовательно исходный дефективный сектор 34066232 может быть безболезненно перезаписан. Важно! Команде dd или hdparm --write-sector ... --yes-i-know-what-i-am-doing необходимо указывать именно сектор 34066232! Как корректно перезаписать сектор подробно рассмотрено в руководстве.

Для случая, если избушка развернулась к Вам задом, и блок 3733479 используется файловой системой, командой icheck и ncheck можно выяснить какому файлу он принадлежит

debugfs /dev/md1 
debugfs 1.42 (29-Nov-2011)
debugfs:  testb 3733479
Block 3733479 marked in use
debugfs:  icheck 3733479
Block	Inode number
3733479	536979
debugfs:  ncheck 536979
Inode	Pathname
536979	/etc/issue
debugfs:  

В этом примере файл не является ценными и исходный дефективный сектор 34066232 может быть перезаписан командой dd

dd if=/dev/zero of=/dev/sda seek=34066232 oflag=direct count=1

Добавить комментарий

Ваш e-mail не будет опубликован.