Воздействовать на физическом уровне на устройства - задача нетривиальная. Но мне кажется, что можно действовать по-другому и получить схожий результат. Показываю по шагам свой эксперимент.
1️⃣ Для ускорения проведения экспериментов предлагаю всё делать на маленьких разделах диска. Покажу на примере mdadm raid1:
# apt-get install mdadm# mdadm --create /dev/md0 -l 1 -n 2 /dev/sdb /dev/sdс# mkfs.ext4 /dev/md0# mount /dev/md0 /mnt2️⃣ Заполняем весь раздел файлом:
# dd if=/dev/urandom of=/mnt/testfileКоманда остановится с ошибкой, как только на диске закончится место.
3️⃣ Вычисляем хэш файла:
# md5sum /mnt/testfile4b1f1e62670849f08c975e9cab8cfd10 /mnt/testfile4️⃣ Запишем что-нибудь напрямую на блочное устройство. Чтобы точно попасть в созданный файл, я и сделал его во весь объём раздела.
# dd if=/dev/urandom of=/dev/sdb seek=10000000 count=1 bs=10 conv=notruncЗаписали 1 блок размером 10 байт, отступив от начала 10 МБ или 100 МБ. Не помню точно, считается этот отступ в байтах или в размере блока.
5️⃣ Ещё раз проверяем хэш:
# md5sum /mnt/testfile4b1f1e62670849f08c975e9cab8cfd10 /mnt/testfileНа удивление, он остался тем же. Я ожидал, что изменится.
6️⃣ Запускаем проверку целостности данных в массиве и когда закончится, смотрим результат:
# echo 'check' > /sys/block/md0/md/sync_action# cat /sys/block/md0/md/mismatch_cnt 128У нас 128 несинхронизированных секторов. Точную причину проблем не посмотреть, но мы в данном случае знаем, что причина в том, что мы напрямую изменили часть данных.
7️⃣ Запускаем исправление ошибок:
# echo 'repair' > /sys/block/md0/md/sync_actionЖдём по логу ядра окончание ремонта и смотрим ещё раз на количество ошибок:
# cat /sys/block/md0/md/mismatch_cnt0Проверяем исходный файл:
# md5sum /mnt/testfile4b1f1e62670849f08c975e9cab8cfd10 /mnt/testfileХэш не поменялся.
Я проводил несколько подобных экспериментов, меняя разные участки на блочном устройстве. Не всегда один repair приводил к исчезновению ошибок синхронизации, но после 2-х, 3-х раз они пропадали. И хэш файла всё время был один и тот же. Но если я через dd писал напрямую в md0:
# dd if=/dev/urandom of=/dev/md0 seek=10000000 count=1 bs=10 conv=notruncТо хэш неизменно менялся. Этот способ изменения файлов реально их меняет, хэш становится другим.
То же самое пробовал делать с массивом с включённым dm-integrity. Как и ожидается, массив получает ошибку хэша в определённом секторе:
device-mapper: integrity: dm-0: Checksum failed at sector 0xe88b8А вот дальше я сталкивался в разных экспериментах с разным результатом. Это может не приводить ни к каким ошибкам, возникающие на некоторое время ошибки синхронизации через несколько минут сами пропадают без запуска принудительной синхронизации через repair. Хэш файла не меняется.
Но один раз я получил ошибку чтения файла, а в логе было следующее:
device-mapper: integrity: dm-0: Checksum failed at sector 0x2b4f8
md/raid1:md0: dm-0: rescheduling sector 175144
device-mapper: integrity: dm-0: Checksum failed at sector 0x2b4f8
device-mapper: integrity: dm-1: Checksum failed at sector 0x2b4f8
md/raid1:md0: redirecting sector 175144 to other mirror: dm-1
device-mapper: integrity: dm-1: Checksum failed at sector 0x2b4f8И так далее по кругу. То есть сектор был определён как повреждённый. Шла попытка взять его с другого диска, но там он тоже был с изменённой checksum. Не знаю, с чем это связано. Как-будто мое изменение успело синхронизироваться на второй диск и блока с правильным хэшем просто не осталось. В итоге файл вообще перестал открываться (Input/output error), его хэш нельзя было посмотреть.
Методику для тестов я вам показал. Можете помучать свои хранилища перед внедрением в эксплуатацию.
❗️Если заметка вам полезна, не забудьте 👍 и забрать в закладки.
#mdadm #backup
