ddで作成されたimgファイルのサイズを変更するには?


19

2つのパーティションがある4GB SDカードのDDイメージがあります。これらの2つのパーティションは約800 MBしか使用していないため、imgファイルのサイズを小さくしたいと考えています。

imgファイルから「空き領域」を削除する方法を知っている人はいますか?


希望する結果を追加することもできます。つまり、画像をカードに戻し、CDに保存します。
ウェイン

回答:


8

最初に、空き領域が実際に空であり、削除されたファイルの残りが含まれていないことを確認します。これを実現する最も簡単な方法は、nullバイトのみを含む巨大なファイルをディスク上に作成してから削除することです。

# losetup --find --partscan foo.img
# lsblk
NAME      MAJ:MIN RM    SIZE RO TYPE MOUNTPOINT
loop0       7:0    0   4096M  0 loop 
├─loop0p1 259:0    0   2048M  0 loop 
└─loop0p2 259:1    0   2048M  0 loop 
# for part in /dev/loop0p*; do
    mount $part /mnt
    dd if=/dev/zero of=/mnt/filler conv=fsync bs=1M
    rm /mnt/filler
    umount /mnt
  done
dd: error writing ‘/mnt/filler’: No space left on device
dd: error writing ‘/mnt/filler’: No space left on device
# losetup --detach /dev/loop0

次に、gzipまたはのようなツールで圧縮しxzます。最低の圧縮レベルでも、ゼロの長いシリーズは十分に圧縮されます。

# ls -s
4096M foo.img
# gzip foo.img
# ls -s
11M foo.img.gz

ディスクに書き戻すときは、イメージを解凍する必要があることに注意してください。これにより、「ライブ」で解凍されます。

# cat foo.img.gz | gunzip | dd of=/dev/sda

出力デバイス(sda)元の画像に合わせて十分なサイズでなければなりません。そうしないと、データが失われたり破損したりします。


イメージを引き続き使用する場合(仮想マシンなど)の代替方法は、生のイメージを仮想化ソフトウェアで使用されるイメージ形式のいずれかに変換することです。たとえば、Qemuのqcow2、VirtualBoxのVDI、またはVMwareのVMDK。

このことに注意してくださいまだ、上記の方法を使用して空き領域を洗浄することにより、画像を準備する必要があります。

# qemu-img convert -f raw -O qcow2 foo.img foo.qcow

# qemu-img convert -f raw -O vmdk foo.img foo.vmdk

ただし、実際のディスクに再度書き込む場合は、元のイメージに変換する必要があります。


1
パーティションに現在保存されているすべてのファイルがディスク上に物理的に散らばっていないことをどのようにして確認できますか?
ヴァレリオサンティネッリ14年

ファイルはディスク上に順番に書き込まれず、ファイルがストレージの最後にある場合、サイズを小さくすると、そのファイルの内容が失われるためです。
ヴァレリオサンティネッリ14年

OPはデータを失うことなくディスクイメージを縮小する方法を求めているためです。特定のサイズで画像を切り捨てると、データが保持されるかどうかを確認できません。
ヴァレリオサンティネッリ14年

@ValerioSantinelli:どこで画像を切り捨てることを正確に提案するのですか?
user1686 14年

1
@ValerioSantinelli:ファイルシステム、例えばのために良いと考え、ファイルシステムサイズ変更ツールを使用して、resize2fsまたはntfsresizeより小さなデバイスに書き込む前に、(LinuxはFATのためのツールを持っていない)、または新鮮なファイルシステムを作成し、オーバーだけでファイルをコピーすることによって。
user1686 14年

22

使用resize2fsははるかに簡単です

resize2fs -M xxx.img

最初にe2fsckを要求されます-そのため:

e2fsck -f -y xxx.img

(イメージをマウントしてはいけません!)

注:これは、イメージが単一のパーティションの場合にのみ機能します。複数のパーティションを持つブロックデバイス全体の場合、上記の回答を参照してください...


注:複数のパーティションについてはlosetup --find --partscan xxx.img、イメージファイルをループデバイスとして設定するために使用します。次にlsblk、ループデバイスのパーティションを見つけます。
Yihui Xiong

オペレーティングシステムを含むISOイメージでは機能しないようです。システムのサイズを変更した後、起動しません。
SR

@SR Linuxオペレーティングシステム?
ロルフ

1
これは非常に良い答えですresize2fsが、extNタイプパーティション専用です。他のタイプのパーティションには、他のツールが必要です。
ロルフ

2

また、qemu-imgで試してみましたが、それは魅力的なものでした:

qemu-img resize test.img 2G

サイズを変更しtest.img2G(2GB)にします。

私にとって完璧に働いた。


1
素晴らしい、私にとっても完璧に働き、Raspbianイメージを圧縮しました。完全に動作しています!
ffleandro

まあ、すべてが動作していますが、起動後、実行df -hすると元のサイズが表示されます。これはどのように可能ですか?
ffleandro

どうやら、qemu-imgはパーティションテーブルではないので、.imgをどのように圧縮しますか?
ffleandro

.imgディスクのサイズを1Mに変更すると、ディスクイメージが確実に破損します。サイズ変更をより安全にするためのアイデアはありますか?
レスカ

1

Ubuntu 16.10コンピューターでgpartedアプローチを使用しました。

1)losetup上記の前の投稿で説明したように、imgファイルを次に使用可能なループパーティションにマップします。

2)lsblk画像ファイルがどのループドライブにマップされているかを確認します。例えば/dev/loop0

3)実行 sudo gparted /dev/loop0

4)適切と思われるループパーティションを縮小します。これらのパーティションをアンマウントしてください。

5)実行してfdisk /dev/loop0からを入力するpと、さまざまなパーティションのブロックサイズと終了ブロック番号が表示されます。

6)実行しdd if=/dev/loop0 of=shrunk_image_file.img、そのコマンドにオプションbs=[BlockSize]を適用するとcount=[EndBlockNumberOfLastLoopPartition+1]、縮小されて権限のあるイメージファイルが作成されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.