Рассмотрим простое блочное устройство объемом 100 МБ в качестве простого примера. Это 204800 блоков по 512 байт каждый на общую сумму 102760448 байт.
Задача состоит в том, чтобы переместить первые 98 МБ (блоки 200704), чтобы перед ним был разрыв в 2 МБ (4096 блоков). Для этого требуется, чтобы ничего не было записано в сектор, который не был прочитан. Одним из способов достижения этого является введение буфера:
$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 | dd of=/dev/sdj2 seek=4096
Предполагается, что mbuffer
перед передачей чего-либо записывающему устройству будет сохранено 4096 блоков, что гарантирует, что ничего не будет записано в область, которая не была прочитана, и что записывающее устройство отстает от читателя по размеру буфера. Буфер должен позволять читателю и записывающему устройству работать как можно быстрее в пределах этих констант.
Однако, это, кажется, не работает надежно. Я пытался использовать реальные устройства, но они никогда не работают на них, тогда как эксперименты с файлом работали на моем 64-разрядном компьютере, но не на моем 32-разрядном устройстве.
Сначала немного подготовки:
$ dd if=/dev/sdj2 count=200704 | md5sum
0f0727f6644dac7a6ec60ea98ffc6da9
$ dd if=/dev/sdj2 count=200704 of=testfile
Это не работает:
$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 -H | dd of=/dev/sdj2 seek=4096
summary: 98.0 MiByte in 4.4sec - average of 22.0 MiB/s
md5 hash: 3cbf1ca59a250d19573285458e320ade
Это работает на 64-битной системе, но не на 32-битной системе:
$ dd if=testfile count=200704 | mbuffer -s 512 -b 4096 -P 100 -H | dd of=testfile seek=4096 conv=notrunc
summary: 98.0 MiByte in 0.9sec - average of 111 MiB/s
md5 hash: 0f0727f6644dac7a6ec60ea98ffc6da9
Как это можно сделать надежно?
заметки
Я прочитал другие вопросы о буферизации и посмотрел pv
, buffer
и mbuffer
. Я мог только заставить последний работать с требуемым размером буфера.
Использование промежуточного хранилища является очевидным решением проблемы, которая всегда работает, но не практична, когда не хватает достаточной резервной емкости.
Тестовые платформы под управлением Arch Linux с mbuffer
версией 20140302.
mbuffer
Должны фактически заставить второй dd
отстать для первого и вам нужна только достаточно оперативной памяти для буферизации размера сдвига. Жаль, dd
что не поддерживается чтение и запись блоков в обратном порядке, поскольку это устранит проблему!
-H
аргумент включает эту функцию).
mbuffer
вообще использовать ? Почему бы вместо этого не сделатьdd
чтение всего содержимого блочного устройства за один разdd bs=102760448
? Конечно, так или иначе он буферизируется в оперативной памяти.