Розглянемо блок простого блоку на 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
. Я міг змусити останнього працювати лише з необхідним розміром буфера.
Використання інтерметіатів для зберігання є очевидним рішенням проблеми, яка завжди працює, але це не практично, коли недостатня запасна ємність недоступна.
Тестові платформи під управлінням Linux Linux з mbuffer
версією 20140302.
mbuffer
слід змусити другий dd
відставати на першому, і вам потрібно лише достатня оперативна пам’ять, щоб захистити розмір зсуву. Дуже погано dd
не підтримує читання та запис блоків у зворотному порядку, оскільки це усуне проблему!
-H
аргумент дозволяє цю функцію).
mbuffer
взагалі використовувати ? Чому б замість цього не змусити за один разdd
прочитати весь вміст блокового пристроюdd bs=102760448
? Звичайно, так чи інакше він буферизований в оперативній пам'яті.