Rozważ 100-procentowe urządzenie blokowe jako prosty przykład. To jest 204800 bloków po 512 bajtów każdy w sumie 102760448 bajtów.
Wyzwaniem jest przesunięcie pierwszych 98 MB (200704 bloków), aby przed nimi była przerwa 2 MB (4096 bloków). Wykonanie tego w miejscu wymaga, aby nic nie zostało zapisane w sektorze, który nie został odczytany. Jednym ze sposobów osiągnięcia tego jest wprowadzenie bufora:
$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 | dd of=/dev/sdj2 seek=4096
Oczekuje się, że mbuffer
zapisze 4096 bloków przed przekazaniem czegokolwiek do programu piszącego, zapewniając w ten sposób, że nic nie zostanie zapisane w obszarze, który nie został odczytany, a program piszący opóźnia czytnik o wielkość bufora. Bufor powinien umożliwiać czytelnikowi i pisarzowi działanie tak szybko, jak to możliwe w obrębie tych elementów stałych.
Jednak wydaje się, że nie działa niezawodnie. Próbowałem używać prawdziwych urządzeń, ale to nigdy nie działa na nich, podczas gdy eksperymenty z plikiem działały na moim 64-bitowym pudełku, ale nie na moim 32-bitowym pudełku.
Najpierw trochę przygotowania:
$ dd if=/dev/sdj2 count=200704 | md5sum
0f0727f6644dac7a6ec60ea98ffc6da9
$ dd if=/dev/sdj2 count=200704 of=testfile
To nie działa:
$ 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
Działa to w systemie 64-bitowym, ale nie w systemie 32-bitowym:
$ 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
Jak można to zrobić niezawodnie?
notatki
Czytałem inne pytania dotyczące buforowania i spojrzał pv
, buffer
a mbuffer
. Mogłem tylko sprawić, aby ten drugi działał z wymaganym rozmiarem bufora.
Korzystanie z pamięci międzystanowej jest oczywistym rozwiązaniem problemu, który zawsze działa, ale nie jest praktyczne, gdy nie ma wystarczającej wolnej pojemności.
Platformy testowe z systemem Arch Linux w mbuffer
wersji 20140302.
mbuffer
Powinny rzeczywiście zmusić drugi dd
w tyle za pierwszy i trzeba tylko wystarczającej ilości pamięci RAM do buforowania wielkość przesunięcia. Szkoda, dd
że nie obsługuje odczytu i zapisu bloków w kolejności wstecznej, ponieważ wyeliminowałoby to problem!
-H
argument włącza tę funkcję).
mbuffer
co w ogóle korzystać? Dlaczego zamiast tego niedd
przeczytać całej zawartości urządzenia blokowego za jednym razemdd bs=102760448
? Oczywiście w ten czy inny sposób jest buforowany w pamięci RAM.