Эмпирический подход. Я решил провести тест. Краткий ответ: тест не показал, что процедура небезопасна.
Testbed
uname -a
:
Linux foobar 3.2.0-4-amd64 #1 SMP Debian 3.2.86-1 x86_64 GNU/Linux
Выдержка из smartctl -a /dev/sdc
:
Model Family: Western Digital Caviar Blue EIDE
Device Model: WDC WD5000AAKB-00H8A0
Firmware Version: 05.04E05
User Capacity: 500,107,862,016 bytes [500 GB]
Sector Size: 512 bytes logical/physical
Также SMART показывает, что диск здоров.
Он был подключен через USB-мост (к концентратору USB 2.0). lsusb | grep SATA
:
Bus 001 Device 003: ID 152d:2509 JMicron Technology Corp. / JMicron USA Technology Corp. JMS539 SuperSpeed SATA II 3.0G Bridge
Один раздел, практически нет нераспределенного пространства. fdisk -l /dev/sdc
:
Disk /dev/sdc: 465,8 GiB, 500107862016 bytes, 976773168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x202b0b89
Device Boot Start End Sectors Size Id Type
/dev/sdc1 2048 976773167 976771120 465,8G 83 Linux
Здоровая файловая система ext4, размонтирована. file -s /dev/sdc1
:
/dev/sdc1: Linux rev 1.0 ext4 filesystem data, UUID=… (extents) (large files) (huge files)
Использование файловой системы составило около 20%, но:
- он широко использовался, поэтому свободное место точно не было нулями;
- В любом случае я не собирался полагаться на файловую систему, я рассчитал
md5sum
для всего устройства (см. Ниже).
тестирование
Сначала я сохранил контрольную сумму всего содержимого устройства:
md5sum -b /dev/sdc > sdc.before.md5
# the throughput was about 24 MB/s
Фактический dd
-инг:
dd if=/dev/sdc of=/dev/sdc
# took 800 minutes, 10,4 MB/s
dd if=/dev/sdc of=/dev/sdc bs=128M conv=sync
# 630 minutes, 13,2 MB/s
dd if=/dev/sdc of=/dev/sdc bs=512 conv=sync
# 795 minutes, 10,5 MB/s
После каждого dd
я запускаю sync
, затем md5sum -b /dev/sdc
. Все контрольные суммы соответствуют sdc.before.md5
.
Мне также понравился strace dd if=/dev/sdc of=/dev/sdc
и он залил мой терминал парами строк:
read(0, "]\203\0\0]\203\1\0]\203\2\0]\203\3\0]\203\4\0]\203\f\0]\203\r\0]\203\30\0"..., 512) = 512
write(1, "]\203\0\0]\203\1\0]\203\2\0]\203\3\0]\203\4\0]\203\f\0]\203\r\0]\203\30\0"..., 512) = 512
или (для больших bs
)
read(0, "A\260_4\245\316\273\321p\203\331\250\3022\354\303\6\30\233\366\345\237\303\244\fx\10@=0\221+"..., 134217728) = 134217728
write(1, "A\260_4\245\316\273\321p\203\331\250\3022\354\303\6\30\233\366\345\237\303\244\fx\10@=0\221+"..., 134217728) = 134217728
Выводы и ответы
- Безопасно ли это независимо от файловой системы?
Контрольная сумма остается неизменной, и здесь нет ничего специфичного для файловой системы. Перезапись данных теми же данными должна быть безопасной.
Примечание: это верно для магнитных приводов, которые перезаписывают сектора напрямую. С другой стороны, твердотельные накопители (и я не уверен, что все они) должны стереть сектор (или несколько секторов одновременно), прежде чем его можно будет записать снова. Один и тот же логический сектор может быть записан в другую физическую "ячейку" и т.д. В случае сбоя питания это может привести к повреждению данных (или нет, я мало знаю о мерах предосторожности в твердотельных накопителях). Вы упомянули магнитный поток, так что я полагаю, что твердотельные накопители в любом случае находятся вне области применения.
- Делает ли этот процесс то, что я ожидаю, то есть, читает сектор, а затем сразу же переписывает его?
strace
показывает, что это именно то, что происходит. Буферы могут задерживать запись, но кажется, что каждый читаемый сектор будет перезаписан рано или поздно.
Я могу подумать об "оптимизации" (в ОС или в прошивке жесткого диска), которая сравнивала бы запрос на запись с кэшированным чтением и могла бы отбросить запись как ненужную, если данные уже есть. Это может сделать вашу процедуру бессмысленной. Тем не менее, это кажется маловероятным, потому что:
- матч будет происходить редко, если вы не хотите, чтобы это произошло преднамеренно;
- недостаточно большой кэш-память не будет иметь значения для больших значений
bs
.
Так что, если сомневаетесь, просто используйте большие bs
. Большой bs
хорош для производительности.
- Дает ли это желаемый практический эффект, или предотвращает некоторые формы гниения змеиным способом?
Я согласен с одним из комментариев:
Он переписывает каждый сектор, так что, по-видимому, это "лекарство" от предполагаемой гнили.
Тем не менее, чтобы подтвердить это на практике, нам нужен статистический анализ многих дисков (некоторые "омолодились", некоторые нет) в течение длительного времени. Мой единственный тест не может ответить на это.