При восстановлении системы после сбоев жесткого диска (например, при восстановлении программного 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