TL; DR сводка : преобразование номера сектора md в смещения (я) внутри /dev/mdX
устройства и как его исследовать xfs_db
. Номер сектора от sh->sector
в linux/drivers/md/raid5.c:handle_parity_checks5()
.
Я не знаю внутренностей MD, поэтому я не знаю точно, что делать с выводом из printk
журнала, который я добавил.
Смещения в компонентные устройства (для dd
или шестнадцатеричный редактор / просмотрщик) также были бы интересны.
Полагаю, мне следует спросить об этом в списке рассылки Linux-raid. Это только для подписчиков, или я могу публиковать без подписки?
У меня xfs прямо поверх MD RAID5 из 4 дисков на моем рабочем столе (без LVM). Недавняя очистка обнаружила ненулевое значение mismatch_cnt
(на самом деле 8, потому что md работает со страницами размером 4 Кбайт).
Это RAID5, а не RAID1 / RAID10, где mismatch_cnt
! = 0 может произойти во время нормальной работы . (Другие ссылки внизу этой вики-страницы могут быть полезны для некоторых людей.)
Я мог бы просто слепо repair
, но тогда я бы не знал, какой файл проверять на предмет возможного повреждения, кроме того, что я не мог выбрать, какой путь восстановить. Ответ Фростшуца на похожий вопрос - единственное предложение, которое я нашел для отслеживания различий в файловой системе. Это громоздко и медленно, и я бы предпочел использовать что-то лучше, чтобы сначала сузить его до нескольких файлов.
Ядро патч для добавления регистрации
Как ни странно, функция проверки md не сообщает, где была обнаружена ошибка . Я добавил printk
в мкр / raid5.c к необходимо войти sh->sector
в в if
отрасли , который увеличивается mddev->resync_mismatches
вhandle_parity_checks5()
(крохотном пятачке , опубликованную на GitHub , первоначально на основе 4,5-rc4 от kernel.org.) Для этого , чтобы быть хорошо для общего использования, было бы , вероятно , потребуется избегайте переполнения журналов при ремонте с большим количеством несоответствий (возможно, только журнал, если новое значение resync_mismatches
<1000?). Также возможно только войти для check
и нет repair
.
Я почти уверен, что записываю что-то полезное (хотя я и не знаю, что такое MD!), Потому что эта же функция печатает этот номер сектора в случае обработки ошибок вswitch
.
Я скомпилировал моё модифицированное ядро и загрузил его, затем снова запустил проверку:
[ 399.957203] md: data-check of RAID array md125
...
[ 399.957215] md: using 128k window, over a total of 2441757696k.
...
[21369.258985] md/raid:md125: check found mismatch at sector 4294708224 <-- custom log message
[25667.351869] md: md125: data-check done.
Теперь я не знаю точно, что делать с этим номером сектора. Является ли sh->sector * 512
линейный адрес внутри /dev/md/t-r5
(он же /dev/md125
)? Это номер сектора в каждом компонентном устройстве (поэтому он относится к трем данным и одному сектору четности)? Я предполагаю последнее, так как несоответствие четности в RAID5 означает, что N-1 секторы устройства md находятся в опасности, смещены относительно друг друга полосовым модулем. Является ли сектор 0 самым началом компонентного устройства, или это сектор после суперблока или что-то еще? Была ли там дополнительная информация, handle_parity_checks5()
которую я должен был рассчитать / зарегистрировать?
Если бы я хотел получить только несоответствующие блоки, это правильно?
dd if=/dev/sda6 of=mmblock.0 bs=512 count=8 skip=4294708224
dd if=/dev/sdb6 of=mmblock.1 bs=512 count=8 skip=4294708224
dd if=/dev/sda6 of=mmblock.2 bs=512 count=8 skip=4294708224
dd if=/dev/sdd of=mmblock.3 bs=512 count=8 skip=4294708224 ## not a typo: my 4th component is a smaller full-disk
# i.e.
sec_block() { for dev in {a,b,c}6 d; do dd if=/dev/sd"$dev" of="sec$1.$dev" skip="$1" bs=512 count=8;done; }; sec_block 123456
Я не думаю, потому что я получаю 4k нулей от всех четырех компонентов рейда, и 0^0 == 0
, так, должно быть правильное соотношение, верно?
Еще одно место, где я упоминал об использовании адресов секторов в md, - это for sync_min
и sync_max
(в sysfs). Нейл Браун в списке linux-raid , отвечая на вопрос о неисправном диске с номерами секторов hdrecover
, откуда Нил использовал номер сектора полного диска в качестве номера сектора MD. Это не правильно, не так ли? Разве номера секторов md не будут относиться к компонентным устройствам (в данном случае к разделам), а не к полному устройству, частью которого является раздел?
линейный сектор к имени файла XFS:
Прежде чем понять, что номер сектора md, вероятно, относится к компонентам, а не к устройству RAID, я попытался использовать его только для чтения xfs_db
:
Очень краткое предложение Дэйва Чиннера о том, как выяснить, как XFS использует данный блок, похоже, не сработало для меня. (Я бы ожидал какой-то результат для некоторого сектора, поскольку число не должно быть за пределами конца устройства, даже если это не несоответствующий сектор)
# xfs_db -r /dev/md/t-r5
xfs_db> convert daddr 4294708224 fsblock
0x29ad5e00 (699227648)
xfs_db> blockget -nv -b 699227648
xfs_db> blockuse -n # with or without -c 8
must run blockget first
да? Что я здесь не так делаю? Я думаю, это должен быть отдельный вопрос. Я заменю это ссылкой, если / когда я спрошу это или найду ответ на эту часть где-нибудь еще.
Мой RAID5 практически бездействует, без операций записи и минимального чтения (и noatime
, следовательно, чтение не производит записи).
Дополнительные сведения о моей настройке, ничего важного здесь
Многие из моих файлов представляют собой видео или другие сжатые данные, которые дают эффективный способ определить, правильны ли данные или нет (либо внутренние контрольные суммы в формате файла, либо просто ли они декодируются без ошибок). Это сделало бы этот петлевой метод только для чтения жизнеспособным, как только я узнаю, какой файл проверять Я не хотел запускать 4-стороннюю разность каждого файла в файловой системе, чтобы сначала найти несоответствие, когда ядро имеет необходимую информацию при проверке и может легко ее зарегистрировать.
мой /proc/mdstat
для моего массива данных массива:
md125 : active raid5 sdd[3] sda6[0] sdb6[1] sdc6[4]
7325273088 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/4] [UUUU]
bitmap: 0/19 pages [0KB], 65536KB chunk
Он находится на разделах на трех накопителях Toshiba 3 ТБ и однораздельном (медленном) жестком диске WD25EZRS, который я заменяю другим Toshiba. (Используется mdadm --replace
для того, чтобы сделать это в режиме онлайн без пробелов в избыточности. После одной копии я понял, что должен проверять работоспособность RAID до и после, чтобы обнаруживать проблемы. Именно тогда я обнаружил несоответствие. Возможно, это было в течение долгого времени , поскольку у меня были некоторые сбои почти год назад, но у меня нет старых журналов, и mdadm, похоже, не отправляет почту об этом по умолчанию (Ubuntu 15.10).
Мои другие файловые системы находятся на устройствах RAID10f2, созданных из более ранних разделов на трех больших жестких дисках (и RAID0 для / var / tmp). RAID5 только для массового хранения, а не /home
или /
.
С моими дисками все в порядке: количество ошибок SMART равно 0 для всех счетчиков сбойных блоков на всех дисках, а короткие и длинные SMART-тесты пройдены.
почти дубликаты этого вопроса, на которые нет ответов:
- Какие куски не совпадают в массиве Linux md?
- http://www.spinics.net/lists/raid/msg49459.html
- MDADM mismatch_cnt> 0. Любой способ определить, какие блоки не согласны?
- Другие вещи уже связаны внутри строки , но наиболее заметна идея петли только для чтения frostschutz .
- очистка на странице Arch wiki RAID
источник
mdadm -E /dev/xxx
..damaged
или что-то в этом роде, вместо того, чтобы просто знать, что где-то есть поврежденный файл.Ответы:
TL; DR sh-> сектор - число секторов в физических дисках после начала раздела данных
Настроить
Вот простая настройка теста для иллюстрации:
Теперь, чтобы начать, получить ненулевой блок и перезаписать его
Убедитесь, что кэш dm / md очищен путем остановки / повторной сборки массива, и проверьте:
Блок на дисках
Итак, сначала давайте проверим 16384 совпадения с тем, что мы написали. Мой рейд имеет 512K полосы , так что я уверен , что я написал что - то выровненное быть легко совпадет, мы писали в
1024*10240
то есть0xa00000
.Ваш патч дает информацию
16384
, о которой нужно знать, что данные не начинаются с 0:Так
printf "%x\n" $(((4096+16384)*512))
говорит, что это тоже0xa00000
хорошо. Хорошо.Блок в мд
Теперь узнать, где это находится на конце md, на самом деле проще: это просто позиция, указанная во времени секторов,
number_of_stripes
например, для меня у меня 4 диска (3 + 1) и 3 полосы.Здесь это означает,
16384*3*512
например0x1800000
. Я заполнил диск довольно хорошо, так что легко проверить, просто читая диск и ища 1k нулей:Блок в xfs
Круто. Давайте посмотрим, где это сейчас находится в xfs.
16384*3
is49152
(daddr принимает номер сектора):Конечно же, нули в этом файле:
Если мы перезаписываем этот файл, то нули исчезают в / dev / raidme / rd0 с правильным смещением (просто добавьте его в другой файл). Если вы снова напишите в / dev / raidme / rd0 (убедитесь, что вы снова остановили / запустили массив), то нули вернутся. Выглядит хорошо.
Однако есть еще одна проблема: если размер вашей полосы здесь такой же, как у меня (512 КБ), то у нас нет ни одного блока для обработки, но возможно повреждение 1,5 МБ данных ... Достаточно часто это может произойти один файл, но вы должны это проверить, вернувшись в xfs_db. Помните, инод раньше был 2052.
Размер блока здесь составляет 4096 байт (см.
xfs_info
), Поэтому наши 1,5 МБ составляют 384 блока. Наш поврежденный сегмент - это блок с 6144 по 6528 - в первом сегменте этого файла.Еще нужно взглянуть на то, как извлечь блоки вручную и проверить, где именно совпадают контрольные суммы, что, надо надеяться, даст вам 3 маленьких кусочка.
Наконец, о вашем патче я сам не md dev, но как бывший пользователь raid5 mdadm я был бы весьма заинтересован. Я бы сказал, что это определенно стоит того, чтобы немного его подтолкнуть. Упомянутая вами очистка может быть полезной, и я уверен, что разработчики получат некоторые комментарии после того, как вы отправите патч, но, черт возьми, md должен быть более подробным об этих ошибках!
источник
printf '%#x\n' $(( (259072+4294708224 )*512 ))
есть0x20000000000
, что, очевидно, не случайно. (Это точно 2TB. Я подозреваю, что некоторые махинации из grub-install или что-то вроде MBR). Я бы не заметил этого, если бы просто искал смещения на устройстве MD, чтобы найти поврежденный файл. (Кстати,%#x
формат добавляет0x
префикс для вас.)xfs_db
просто говоритmust run blockget first
, хотя я только что сделал (точно так же, как я написал в вопросе), после следования вашему примеру. Даже если я использую,blockget -v -n -b 12884124672
чтобы дать ему определенный блок. Я использовалdd
иhexdump
обнаружил, что на самом деле в этом блоке есть несоответствие. Все три равны нулю, а четвертый имеет один однобитный бит 1 кБ в полосу 512 Кбайт. (Очень удобно, что мне не пришлось искать способ на самом деле блокировать XOR, чтобы проверить избыточность.)daddr
сначала (перед blockget), я не получаю сообщение об ошибке, просто не выводить вообще изblockget -v -n
иblockuse -v -n
. В случае, если это имеет значение, мой xfsprogs - 3.2.1ubuntu1, и я использую Linux 4.2.0-36-generic (не мое исправленное ядро -rc). Моя ФС используетcrc=1 isize=512
,naming =version 2 bsize=4096 ascii-ci=0 ftype=1
find -exec xfs_bmap -vpl {} +
поиск файла, содержащего известный блок.