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.
źródło
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.mbuffer
Powinny rzeczywiście zmusić drugidd
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ę).Odpowiedzi:
Bez bufora możesz cofać się o jeden blok na raz.
Należy pamiętać, że ten przykład jest niebezpieczny z powodu braku sprawdzania błędów.
Jest również powolny ze względu na liczbę
dd
połączeń. Jeśli masz wolną pamięć, możesz użyć większego rozmiaru bloku.Za pomocą bufora strzeż się pułapek . To nie wystarczy, aby zagwarantować 100% Prefill. To, czego potrzebujesz, to minimalne wypełnienie podczas całego procesu. Bufor nigdy nie może spaść poniżej,
2M
ponieważ w przeciwnym razie ponownie nadpisane zostaną dane, które należy jeszcze przeczytać.Tak więc teoretycznie można obejść się bez bufora i łańcucha
dd
:W praktyce nie działa to niezawodnie, ponieważ nie ma gwarancji, że pierwszemu
dd
uda się nadal odczytywać dane, podczas gdy ostatnidd
(z2M
„buforem” pomiędzy nimi) już zapisuje.Możesz znacznie zwiększyć swoje szanse, znacznie zwiększając odstęp między buforem, ale mimo to nie jest wiarygodny.
Niestety nie znam dobrego programu buforującego z minimalną właściwością wypełnienia. Potrzebujesz takiego, który zatrzymuje wyjście, o ile w buforze jest mniej niż margines bezpieczeństwa.
źródło
dd
można go użyć. Myślę jednak, że prawdziwym rozwiązaniem nie jest użycie,dd
ale wybór czegoś, co jest zaprojektowane tak, aby działało wsteczddrescue
. Opisałem sposób na to w odpowiedzi.ddrescue
. Nie, jeśli spodziewa się, że będzie działać na różnych urządzeniach, a ty musisz oszukać go, aby zaakceptował twoje argumenty. Może również nie mieć wewnętrznej właściwości „minimalnego zapełnienia bufora” (ponieważ w przypadku różnych urządzeń nie jest to konieczne), więc ponownie może uszkodzić dane. Będziesz musiał sprawdzić w kodzie źródłowym, czy rzeczywiście jest on zaprojektowany dla twojego przypadku użycia.Czytasz 4096 bloków, a następnie zapisujesz te 4096 bloków do następnych 4096 bloków dysku, zastępując w ten sposób drugie 4096 bloków, zanim będą mogły zostać odczytane. Musisz przeczytać 8129 bloków, aby uzyskać drugie 4096 przed rozpoczęciem pisania, a następnie musisz tylko napisać 4096 bloków przed odczytaniem następnego 4096.
Nie wspomniałeś, jaki to system plików. Jeśli jest to ext [234] i masz najnowszą wersję e2fsprogs, możesz użyć
e2image -ra -O 512 /dev/sdj2
. Ma to również tę dodatkową zaletę, że jest wystarczająco inteligentny, aby pominąć wolne miejsce w woluminie.źródło
ext4
samo dotyczy kopii urządzenia blokowego, każdy system plików powinien być nieistotny.dd
nie działa.Niezawodne rozwiązanie wymaga upewnienia się, że nic nie zapisuje w obszarze, który mógł nie zostać odczytany, a jedynym prawdziwym sposobem na osiągnięcie tego jest wykonanie kopii w odwrotnym kierunku.
ddrescue
Narzędzie może pracować w odwrotnym kierunku, ale odmawia pracy z wejścia i wyjścia są takie same. Można go jednak oszukać, duplikując węzeł urządzenia.Przeprowadziłem kilka szybkich eksperymentów i wydaje się, że działają. Wiersz polecenia to:
Argumenty są
-f
jest wymagane, aby wymusić zapis na istniejącym urządzeniu wyjściowym-R
każe mu działać w odwrotnym kierunku-s
informuje, ile danych wejściowych należy skopiować (użyłems
sufiksu, aby określić liczbę sektorów)-o
każe szukać dalej w urządzeniu wyjściowym przed zapisem (ponownie w sektorach zs
sufiksem)/dev/sdj11
to urządzenie blokowe do odczytu/dev/sdj11_copy
jest urządzeniem blokowym do pisaniaUtworzyłem za
/dev/sdj11_copy
pomocą,mknod
aby dopasować parametry/dev/sdj11
.Zrobiłem tylko kilka bardzo szybkich testów, ale wydaje się, że to działa dobrze, aby skopiować surowe urządzenie. Nie działa na pliku (nie mogłem go oszukać, aby wyjść poza pliki, które są takie same)
To nie odpowiada na moje pierwotne pytanie
dd
, które brzmiało, jak to osiągnąć, ale myślę, że po przeczytaniu innych odpowiedzi odpowiedź na to jestdd
niemożliwa.źródło
ddrescue
odkryje zły blok w tym scenariuszu? Jeśli przeskoczy na inny obszar dysku (aby uniknąć złych bloków) i kontynuuje kopiowanie z tego miejsca, ponownie zastąpi jeszcze nie skopiowane części danych. Jeśli nie spodziewa się, że będzie działać z tym samym urządzeniem, nie ma powodu, aby podejmować specjalne środki, aby zapobiec różnym możliwym przypadkom uszkodzenia danych.ddrescue
opcje ograniczenia prób odzyskania złych danych, ale nie zastanawiałem się nad ich wykorzystaniem.