dd pada seluruh disk, tetapi tidak ingin bagian yang kosong

33

Saya memiliki disk, katakan / dev / sda.

Berikut ini adalah fdisk -l:

 Disk /dev/sda: 64.0 GB, 64023257088 bytes
255 heads, 63 sectors/track, 7783 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0000e4b5

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          27      209920   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              27         525     4000768    5  Extended
Partition 2 does not end on cylinder boundary.
/dev/sda5              27         353     2621440   83  Linux
/dev/sda6             353         405      416768   83  Linux
/dev/sda7             405         490      675840   83  Linux
/dev/sda8             490         525      282624   83  Linux

Saya perlu membuat gambar untuk disimpan di server file kami untuk digunakan dalam mem-flash perangkat lain yang kami produksi jadi saya hanya ingin ruang yang digunakan (hanya sekitar 4gb). Saya ingin menyimpan mbr dll ... karena perangkat ini harus siap boot segera setelah salinan selesai.

Ada ide? Saya sebelumnya telah menggunakan dd if=/dev/sda of=[//fileserver/file], tetapi pada saat itu, salinan master saya menggunakan ide flash 4GB.

Jonathan Henson
sumber
2
Semua jawaban di bawah ini salah kecuali untuk @sudoer. Jawaban yang benar adalah menggunakan dd conv=sparse.
bahamat
@ Bahahamat, tidak, gzip lebih baik karena akan memampatkan data.
psusi
1
Itu tidak sama dengan jarang.
bahamat
@ Bahahamat, pertanyaannya bukan menanyakan sprase secara spesifik; hanya bagaimana membuat gambar membutuhkan lebih sedikit ruang.
psusi

Jawaban:

37

Kembali pada hari saya mengalami masalah yang sama dengan distribusi Linux tertanam - singkirkan semua sampah sebelum mengompresi gambar.

dd if=/dev/zero of=asdf.txt. Tunggu sampai mati. Hapus asdf.txt.

Anda baru saja menulis nol untuk semua ruang kosong di perangkat.

Sekarang ambil gambar disk dan jalankan melalui gzip. Voila, gambar yang jarang.

Mungkin skalanya tidak terlalu baik dan dapat menyebabkan masalah jika Anda benar-benar perlu menulis ke disk, tapi hei.

Anda bisa mengambil snapshot rsync disk ke volume lain, nol itu, dan kemudian mengambil gambar disk.

Catatan: Bisa berbahaya untuk SSD, pengguna harus mempertimbangkan operasi ini sebelum melakukan.

Rob Bos
sumber
jika saya menjalankannya melalui gzip, apakah saya harus membuka zipnya sebelum menggunakannya? Dan dengan menjalankannya melalui gzip, apakah saya hanya pipa itu selama proses dd?
Jonathan Henson
3
Iya nih. dd if=sda2.gz | gunzip > /dev/sda2dandd if=/dev/sda2 | gzip > sda2.gz
Rob Bos
3
"Anda baru saja menulis nol untuk semua ruang kosong di perangkat". Maksud Anda partisi, bukan perangkat, saya pikir. Jadi, Anda harus menjalankan perintah itu dengan ofjalur untuk setiap partisi.
jiggunjer
Jika media fisik adalah SSD, sekarang mungkin berpikir setiap sektor pada perangkat telah digunakan. Ini akan memberi SSD lebih sedikit sektor cadangan untuk bekerja dan mungkin menurunkan kinerja sebagai hasilnya. Jika driver dan firmware memiliki dukungan TRIM kondisi itu hanya akan berlaku sampai Anda menghapus file lagi. Jika Anda menyimpan file di tempat saat Anda membuat gambar, Anda harus menghapus file lagi setelah mengembalikan gambar. Itu mungkin berguna jika gambar dikembalikan ke SSD.
kasperd
Ada beberapa kekhawatiran tambahan yang perlu diingat. Karena metode ini mengharuskan sistem file untuk dipasang baca-tulis, ada risiko bahwa perubahan pada sistem file yang mendasarinya saat penyalinan sedang berlangsung akan mengarah pada gambar yang tidak konsisten. Pada satu kesempatan saya telah melihat salinan yang dihasilkan sangat tidak konsisten sehingga fsck akan benar-benar segfault ketika mencoba untuk memperbaiki ketidakkonsistenan pada salinan. Mengisi perangkat juga dapat menyebabkan proses lain yang gagal untuk menulis ke media.
kasperd
17

Dengan asumsi Anda ingin menyimpan /dev/sdXNuntuk /tgtfs/image.rawdan Anda root:

  1. mkdir /srcfs && mount /dev/sdXN /srcfs

  2. Gunakan zerofill atau just: dd if=/dev/zero of=/srcfs/tmpzero.txtuntuk mengisi blok yang tidak digunakan dengan nol (tunggulah sampai penuhi sistem file rm /srcfs/tmpzero.txt)

  3. Ambil gambar dengan dd dan gunakan conv = jarang untuk meninju nol saat bepergian: dd conv=sparse if=/dev/sdxn of=/tgtfs/image.raw

Jika Anda ingin menggunakan kompresi, Anda tidak perlu memukul nol dengan dd karena nol blok sangat kompresibel:

dd if=/dev/sdxn | gz -c | dd of=/tgtfs/image.raw

PS: Anda harus mencatat bahwa ini bukan ide yang baik pada media penyimpanan berbasis memori flash (yaitu sistem file sumber Anda menjadi SSD)

Sudoer
sumber
5
Ini jawaban yang benar. Gunakan dd conv=sparse.
bahamat
1
Apa yang salah dengan melakukan ini pada penyimpanan flash?
Dan
2
@Dan (tergantung pada desain dan konfigurasi perangkat keras dan perangkat lunak) dapat menyebabkan penulisan yang luas ke SSD Anda dan mengurangi masa pakainya. dan secara umum, tidak apa-apa untuk memindahkan data dari disk lama ke yang baru (atau apa yang OP ingin lakukan), tetapi cadangan tingkat disk / partisi bukanlah solusi yang baik untuk pencadangan dan pemulihan rutin, bahkan pada HDD. cadangan tingkat file (yaitu mengatasi file dari satu sistem file ke sistem lainnya), atau cadangan tingkat sistem file (dengan sistem file seperti BTRFS dengan btrfs snapshotdan btrfs sendalat) adalah solusi IMHO yang lebih baik.
Sudoer
Petunjuk: Jika Anda tidak memiliki gzpada Anda PATH(seperti yang saya lakukan tidak, pada GParted Hidup), Anda dapat menggunakan gzip -csebagai gantinya.
XtraSimplicity
11

Gunakan dd, dengan opsi hitung.

Jika Anda menggunakan fdisk, maka saya akan mengambil pendekatan itu. "Sudo fdisk -l" Anda menghasilkan:

    Disk /dev/sda: 64.0 GB, 64023257088 bytes
    255 heads, 63 sectors/track, 7783 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x0000e4b5

    Device Boot      Start         End      Blocks   Id  System
    /dev/sda1   *           1          27      209920   83  Linux
    Partition 1 does not end on cylinder boundary.
    /dev/sda2              27         525     4000768    5  Extended
    Partition 2 does not end on cylinder boundary.
    /dev/sda5              27         353     2621440   83  Linux
    /dev/sda6             353         405      416768   83  Linux
    /dev/sda7             405         490      675840   83  Linux
    /dev/sda8             490         525      282624   83  Linux

Dua hal yang harus Anda perhatikan adalah 1) ukuran unit, dan 2) kolom "Akhir". Dalam kasus Anda, Anda memiliki silinder yang sama dengan 8225280 Bytes. Pada kolom "End" sda8 berakhir pada 525 (yaitu 525 [unit] * 16065 * 512 = ~ 4.3GB)

dd dapat melakukan banyak hal, seperti memulai setelah offset, atau berhenti setelah sejumlah blok tertentu. Kami akan melakukan yang terakhir menggunakan opsi hitung di dd. Perintah akan muncul sebagai berikut:

    sudo dd if=/dev/sda of=/your_directory/image_name.iso bs=8225280 count=526

Di mana -b adalah ukuran blok (paling mudah untuk menggunakan unit yang digunakan fdisk, tetapi unit apa pun akan melakukannya selama opsi penghitungan dideklarasikan dalam unit-unit ini), dan hitungan adalah jumlah unit yang ingin kita salin (perhatikan bahwa kami menambah hitungan dengan 1 untuk menangkap blok terakhir).

Tom Looby
sumber
FYI: untuk menunjukkan unit dalam silinder, gunakanfdisk -l -u=cylinders /dev/sda
xinthose
3
Mengapa ini bukan jawaban yang diterima? Tampaknya menjadi opsi yang paling tidak mengganggu karena tidak mengubah sumbernya.
user33326
@ user33326 karena jawaban ini baik untuk tidak menyalin ruang yang tidak dipartisi pada drive, bukan ruang yang tidak digunakan di dalam partisi, yang menjadi perhatian OP.
GDorn
8

Sementara /dev/zeroruang disk kosong dan penggunaan dd conv=sparse/ gz -cdimungkinkan, pada disk besar dengan ruang kosong yang berjalan dalam 100-an GB, /dev/zeroprosesnya sangat lambat - belum lagi seperti yang dicatat oleh jawaban lain, /dev/zerogunakan SDD hingga EOF.

Inilah yang saya lakukan ketika saya mengalami situasi ini:

  • Pada live CD lubuntu, digunakan gparteduntuk 'mengecilkan' disk ke ukuran seminimal mungkin, meninggalkan sisa ruang yang tidak terisi

  • Digunakan
    dd bs=1M count=<size_in_MBs> if=/dev/sdX | gzip -c --fast| dd of=/path/to/image.gz untuk membuat gambar yang dikompresi cepat (tidak perlu dikatakan, Anda mungkin ingin melewatkan kompresi jika Anda memiliki ruang yang cukup untuk menyimpan data mentah (atau sebaliknya cenderung mengurangi pemuatan CPU)

  • Digunakan
    dd if=/path/to/image.gz | gunzip -c | dd bs=1M of=/dev/sdY untuk menyalin data kembali ke disk yang berbeda
  • Digunakan gpartedlagi untuk 'memperluas' partisi

Saya belum mencobanya untuk beberapa partisi tapi saya percaya proses di atas dapat disesuaikan untuk menyalin 'partisi' jika partisi-tabel pada disk tujuan dibuat terlebih dahulu dan hanya data yang terkandung dalam partisi yang disalin melalui dd- baca / tulis offset ( skip/ seekOpsi dd, masing-masing) akan diperlukan sesuai kebutuhan.

Ashish Chopra
sumber
1
ini adalah jawaban yang sebenarnya, cukup gunakan countparameter
Gordy
7

Kamu tidak bisa ddadalah alat tingkat yang sangat rendah dan tidak memiliki alat untuk membedakan antara file dan ruang kosong.

Di sisi lain ruang kosong akan memampatkan sangat, sangat baik jadi jika Anda hanya peduli tentang ruang penyimpanan, bukan misalnya waktu menulis, maka cukup pipa melalui gzip.

c2h5oh
sumber
7
Dengan asumsi ruang kosong sebelumnya tidak pernah digunakan. Anda dapat nol mengisi ruang kosong terlebih dahulu untuk memastikan kompresi berfungsi seperti yang diharapkan.
Sirex
1
Benar. Dan itu hanya mempersulit proses dan membuatnya butuh waktu lebih lama.
c2h5oh
6

Dengan asumsi sisa drive kosong (semua nol) Anda dapat menyalurkan DD Anda melalui gzip, yang akan memampatkan ruang kosong dengan cukup baik. Anda dapat menggunakan alat seperti zerofree untuk memastikan ruang kosong Anda benar-benar kosong sehingga dapat dikompres dengan baik.

Jika Anda menggunakan alat seperti partimage , clonezilla atau beberapa alat kloning linux lainnya, mereka akan menangani sebagian besar untuk Anda secara otomatis.

Sakit kepala
sumber
partimage dan clonezilla sebenarnya cukup pintar untuk melewatkan membaca ruang kosong, daripada mengandalkan Anda untuk menulis nol padanya, dan kemudian memiliki dd atau gzip menjatuhkan atau kompres nol setelah membacanya.
psusi
2

Jawaban yang diterima tidak benar. Saya setuju dengan komentar di atas. Saya menggunakan dd dengan parameter hitung untuk membuat cadangan disk saya pada basis reguler. Cukup ganti BACKUP_FOLDER dan huruf perangkat Anda dengan "X":

Tentukan blok disk yang terakhir digunakan:

ct=$(fdisk -l | awk '$1 == "/dev/sdX" { print $3 }')

Kemudian kloning disk (tidak termasuk ruang kosong itu):

dd if=/dev/sdX bs=512 count=$ct | gzip > BACKUP_FOLDER/sdX_$(date +"%Y-%m-%d").img.gz >>"$LOG"
Aloha D
sumber