Pertimbangkan perangkat blok mentah 100MB sebagai contoh sederhana. Itu adalah 2.048.000 blok masing-masing 512 byte untuk total 102760448 byte.
Tantangannya adalah untuk menggeser 98MB pertama (200704 blok) sehingga ada celah 2MB (4096 blok) di depannya. Untuk melakukan ini di tempat mengharuskan tidak ada yang ditulis untuk sektor yang belum dibaca. Salah satu cara untuk mencapai ini adalah dengan memperkenalkan buffer:
$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 | dd of=/dev/sdj2 seek=4096
Harapannya adalah bahwa mbuffer
akan menyimpan 4.096 blok sebelum menyerahkan apa pun kepada penulis, sehingga memastikan bahwa tidak ada yang ditulis ke area yang belum dibaca dan bahwa penulis tertinggal pembaca dengan ukuran buffer. Buffer harus memungkinkan pembaca dan penulis beroperasi secepat mungkin dalam konstanta-konstanta itu.
Namun, sepertinya itu tidak berfungsi dengan baik. Saya sudah mencoba menggunakan perangkat nyata tetapi tidak pernah berhasil pada mereka, sedangkan percobaan dengan file bekerja pada kotak 64-bit saya tetapi tidak pada kotak 32-bit saya.
Pertama, beberapa persiapan:
$ dd if=/dev/sdj2 count=200704 | md5sum
0f0727f6644dac7a6ec60ea98ffc6da9
$ dd if=/dev/sdj2 count=200704 of=testfile
Ini tidak berfungsi:
$ 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
Ini berfungsi pada sistem 64-bit tetapi tidak pada sistem 32-bit:
$ 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
Bagaimana ini bisa dilakukan dengan andal?
catatan
Saya telah membaca pertanyaan lain tentang buffering dan melihat pv
, buffer
dan mbuffer
. Saya hanya bisa mendapatkan yang terakhir untuk bekerja dengan ukuran buffer yang diperlukan.
Menggunakan penyimpanan intermetiate adalah solusi yang jelas untuk masalah yang selalu berhasil tetapi tidak praktis ketika kapasitas cadangan yang memadai tidak tersedia.
Platform uji yang menjalankan Arch Linux dengan mbuffer
versi 20140302.
sumber
mbuffer
sama sekali? Mengapa tidak malahdd
membaca seluruh isi perangkat blok dalam sekali pakaidd bs=102760448
? Tentu saja, satu atau lain cara itu buffered dalam RAM.mbuffer
harus benar-benar memaksa keduadd
tertinggal untuk pertama dan Anda hanya perlu cukup RAM untuk penyangga ukuran shift. Sayang sekalidd
tidak mendukung membaca dan menulis blok dalam urutan terbalik karena itu akan menghilangkan masalah!-H
argumennya memungkinkan fitur ini).Jawaban:
Tanpa buffer, Anda bisa mundur, satu blok pada satu waktu.
Harap perhatikan bahwa contoh ini berbahaya karena kurangnya pemeriksaan kesalahan.
Ini juga lambat karena jumlah
dd
panggilan. Jika Anda memiliki memori yang tersisa, Anda dapat menggunakan ukuran blok yang lebih besar.Dengan penyangga, berhati-hatilah dengan perangkap . Hal ini tidak cukup untuk menjamin 100% Prefill. Yang Anda butuhkan adalah pengisian minimum selama seluruh proses. Buffer tidak boleh pernah jatuh di bawah ini
2M
karena jika tidak Anda akan menimpa data Anda yang belum dibaca lagi.Jadi sementara secara teori Anda bisa melakukannya tanpa buffer dan hanya rantai
dd
:Dalam praktiknya ini tidak bekerja dengan andal karena tidak ada jaminan yang pertama
dd
mengelola untuk terus membaca data, sedangkan yang terakhirdd
(dengan2M
"buffer" di antaranya) sudah menulis.Anda dapat meningkatkan peluang Anda secara signifikan dengan membuat di antara buffer jauh lebih besar, tetapi meskipun demikian, itu tidak dapat diandalkan.
Sayangnya saya tidak tahu program buffer yang baik dengan properti isi minimum. Anda memerlukan satu yang menghentikan output selama ada kurang dari margin keamanan Anda di dalam buffer.
sumber
dd
bisa digunakan. Saya pikir, bagaimanapun, bahwa solusi sebenarnya adalah tidak menggunakandd
tetapi memilih untuk sesuatu yang dirancang untuk berjalan mundur sepertiddrescue
. Saya telah menjelaskan cara untuk melakukan itu dalam sebuah jawaban.ddrescue
sini. Tidak jika itu diharapkan dapat bekerja pada perangkat yang berbeda, dan Anda harus mengelabui agar menerima argumen Anda. Mungkin tidak memiliki properti "isi buffer minimum" secara internal (karena dengan perangkat yang berbeda itu tidak diperlukan), jadi sekali lagi itu dapat merusak data Anda. Anda harus memeriksa dalam kode sumber apakah itu benar-benar dirancang untuk kasus penggunaan Anda.Anda membaca 4096 blok, dan kemudian menulis 4096 blok ke 4096 blok berikutnya dari disk, sehingga menimpa blok 4096 kedua sebelum mereka dapat dibaca. Anda perlu membaca 8129 blok untuk mendapatkan yang kedua 4096 sebelum memulai penulisan apa pun, dan kemudian Anda hanya perlu menulis 4096 blok sebelum membaca 4096 berikutnya.
Anda tidak menyebutkan jenis filesystem apa ini. Jika ext [234], dan Anda memiliki versi terbaru dari e2fsprogs, maka Anda dapat menggunakannya
e2image -ra -O 512 /dev/sdj2
. Ini juga memiliki manfaat tambahan karena cukup pintar untuk melewati ruang kosong dalam volume.sumber
ext4
tetapi untuk salinan perangkat blok, sistem file apa pun harus tidak relevan.dd
tidak dilakukan.Solusi yang andal mengharuskan Anda memastikan bahwa tidak ada yang menulis ke area yang mungkin belum dibaca dan satu-satunya cara nyata untuk mencapai itu adalah dengan melakukan salinan dalam arah sebaliknya.
The
ddrescue
alat dapat bekerja dalam arah sebaliknya tetapi menolak untuk menjalankan dengan input dan output menjadi sama. Namun dimungkinkan untuk mengelabunya dengan menduplikasi node perangkat.Saya telah melakukan beberapa percobaan cepat dan tampaknya berhasil. Baris perintah adalah:
Argumennya adalah
-f
diperlukan untuk memaksanya menulis ke perangkat output yang ada-R
menyuruhnya bekerja ke arah sebaliknya-s
memberitahu berapa banyak input untuk disalin (saya menggunakans
akhiran untuk menentukan jumlah sektor)-o
memintanya untuk mencari ke depan dalam perangkat output sebelum menulis (ditentukan dalam sektor lagi dengans
akhiran)/dev/sdj11
adalah perangkat blok untuk dibaca/dev/sdj11_copy
adalah perangkat blok untuk menulisSaya buat
/dev/sdj11_copy
denganmknod
untuk mencocokkan parameter/dev/sdj11
.Saya hanya melakukan beberapa tes yang sangat cepat tetapi ini tampaknya berfungsi baik untuk menyalin perangkat mentah. Itu tidak bekerja pada file (saya tidak bisa mengelabui untuk melampaui file yang sama)
Ini tidak menjawab pertanyaan awal saya yang menanyakan bagaimana mencapainya,
dd
tetapi saya pikir, setelah membaca jawaban yang lain, jawabannya adalahdd
tidak bisa melakukannya.sumber
ddrescue
menemukan blok buruk dalam skenario ini? Jika lompatan ke area lain dari disk (untuk menghindari blok buruk), dan terus menyalin dari sana, itu lagi akan menimpa belum menyalin bagian data Anda. Jika tidak berharap untuk bekerja dengan perangkat yang sama, tidak memiliki alasan untuk mengambil tindakan khusus untuk mencegah berbagai kemungkinan kasus korupsi data.ddrescue
opsi untuk membatasi upayanya untuk memulihkan data yang buruk, tetapi saya belum melihat untuk menggunakannya.