Linuxディスクイメージをスパースファイルに変換するにはどうすればよいですか?


12

EXTパーティションにddrescueで作成された多数のディスクイメージがあり、マウント可能な状態でデータを失うことなくサイズを縮小したいと考えています。

画像のファイルシステムの空きスペースをゼロで埋めてから、ファイルをスパースファイルに変換して、この空きスペースが実際にディスクに保存されないようにするにはどうすればよいですか?

例えば:

> du -s --si --apparent-size Jimage.image 
120G Jimage.image
> du -s --si Jimage.image 
121G Jimage.image

ただし、実際には50Gの実際のデータしかありませんので、2番目の測定はもっと小さくする必要があります。

これはおそらく空のスペースをゼロで埋めます:

cat /dev/zero > zero.file
rm zero.file

しかし、スパースファイルが透過的処理されると、仮想ディスクに何も書き込まずに実際にスパースファイルが作成され、皮肉なことに仮想ディスクイメージをスパースファイルに変換できなくなります。:)それは?

注:何らかの理由で、マウントされたディスクイメージ上ではsudo dd if=/dev/zero of=./zero.file機能しcatません。


2
ファイルにゼロを書き込んでも、スパースファイルは作成されません。それは別の概念です。OSがデータブロックが実際に存在しないことを発見したときにスパースファイルをシーク/読み取りすると(その領域のデータのブロックリストは空です)、(OS)は自動的に読み取りバッファーをゼロバイトで埋めます。
布袋

注:コマンドをsudo cat /dev/zero > zero.file実行する前に、bash(rootではなくユーザーとして実行)がリダイレクトを行うため、機能しませんsudounix.stackexchange.com/questions/1416/を
フリッツ

回答:


19

まず、スパースファイルは、ゼロを書き込む場合ではなく、シークする場合にのみ透過的に処理されます。

より明確にするために、ウィキペディアの例

dd if=/dev/zero of=sparse-file bs=1k count=0 seek=5120

ゼロを書き込みません。出力ファイルを開き、5MBをシーク(ジャンプ)し、ゼロゼロを書き込みます(つまり、何も書き込みません)。このコマンド(ウィキペディアからではありません

dd if=/dev/zero of=sparse-file bs=1k count=5120

5MBのゼロを書き込み、スパースファイルを作成しません!

結果として、すでにスパースではないファイルは、魔法のように後でスパースになることはありません。

第二に、多くのゼロがまばらなファイルを作成するには、それをcpする必要があります

cp --sparse=always original sparsefile

または、tarまたはrsyncの--sparseオプションも使用できます。


1
ウィキペディアによると、ddでゼロを書き込むとスパースファイルが作成されます。「探求」の意味を説明できますか?
エンドリス

1
では猫はどうですか?スパースファイルに関するマニュアルページには何もないので、cat /dev/zero > zero.file空のスペースをゼロで埋めても問題ないと思いますか?
ルートヴィヒワインツィール

2
@endolith:使用することの違いを明確にするために私の回答を更新しました ddゼロの書き込みまたはシーク。
mihi

2
@Ludwig Weinzierl:はい、そのcatコマンドはディスク全体(または少なくともルートまたはクォータによって予約されていない量)を「実際の」ゼロで満たし、スパースファイルを作成しません。
mihi

1
@endolithには余分なスペースが必要です、はい。ただし、tarballを圧縮できるため、必要なのは元のファイル用のスペースと圧縮ファイルの圧縮バージョンだけです。
ミヒ

12

ファイルを適切にスパース化する最も簡単な方法はfallocate、次のようにユーティリティを使用することです。

fallocate -v --dig-holes {file_name}

fallocate(1)Debianのutil-linuxパッケージで提供されます


1
何らかの理由で、fallocate --dig-holesオリジナルの299GiBから103GiBファイルが生成されましたが、93GiBが提供されました。cp --sparse=alwaysすべて同じSHA1合計(du -B1Gvsでチェックされたサイズdu --apparent-size -B1G)でした。そのfallocateため、結果は劣っているようです。
ルスラン

3

完全を期すために回答を編集する:

  1. ゼロのバルーン空のFSスペース(警告:これによりディスクイメージが変更されます):

losetup --partscan --find --show disk.img

ディスクとして/ dev / loop1を指定し、パーティションが1つしかない場合は、マウント可能なFSを持つすべてのパーティションに対してこれを繰り返す必要があります(スワップパーティションなどは無視してください)。

mkdir -p /mnt/tmp mount /dev/loop1p1 /mnt/tmp dd if=/dev/zero of=/mnt/tmp/tempfile

ENOSPCで失敗するまで終了させます。

/bin/rm -f /mnt/tmp/tempfile umount /mnt/tmp losetup -d /dev/loop1

  1. スパースイメージにコピーします。

'dd'には、ゼロを含むファイルをスパースファイルに変換するオプションがあります。

dd if=disk.img of=disk-sparse.img conv=sparse



1
はい、このオプションはOPが尋ねた時からではありません。これは、「他の検索者のためにパン粉を残す」というものでした... :
)

1
ファイルシステムのタイプに応じて、ファイルシステムにzerofreeゼロをマウントして書き込むよりも高速であり、すでに多数のゼロが含まれている場合はディスクイメージの成長を小さくすることができます。
ミヒ

2

ddrescueで作成されたイメージは、たとえば50 GBであり、実際にはもっと少ないもので十分だということですか?

その場合、最初にddで新しいイメージを作成することはできませんでした:

dd if=/dev/zero of=some_image.img bs=1M count=20000

そして、その中にファイルシステムを作成します:

mkfsofyourchoice some_image.img

次に、イメージをマウントし、古いイメージから新しいイメージにすべてをコピーしますか?それはあなたのために働くでしょうか?


2

PartImageは、ファイルシステムの使用済みブロックのみを保存するディスクイメージを作成できるため、未使用のブロックを無視することで必要なスペースを大幅に削減できます。結果のイメージを直接マウントできるとは思わないが、行く:

image -> partimage -> image -> cp --sparse=alway

必要なものを作成する必要があります(最後のステップを実行することさえ可能かもしれませんが、試していません)。


1
残念ながら、partimageで作成されたイメージは、再度展開しないとマウントできないため、アーカイブ目的にのみ適しています。
パーキンス

0

これを行うvirt-sparsifyというツールがあります。空のスペースをゼロで埋めてから、画像をスパースファイルにコピーします。ただし、多くの依存関係をインストールする必要があります。


-2

それが本当にあなたがしたいことであるならば、あなたはその仕様に書かれたカスタムプログラムを必要とすると思う。でも…?

実際にすべてゼロの領域が多数ある場合、優れた圧縮ツールを使用すると、大幅に低下します。また、スパースファイルを記述しようとしても、すべての場合に機能するとは限りません。正しく思い出せば、スパースファイルでさえ、入力ブロックにゼロ以外のビットが含まれる出力ストレージの最小1ブロックを占有します。たとえば、512バイトブロックあたり平均1個の非ゼロビットを持つファイルがあるとします-「まばらに」書き込むことはできません。ちなみに、zip、bzip、bzip2、またはp7zipでファイルを圧縮しても、データを失うことはありません。これらは、損失の多いmpegまたはjpeg圧縮とは異なります。

一方、ファイルへのランダムシークリードを行う必要がある場合、圧縮はそれが価値があるよりも厄介である可能性があり、スパース書き込みに戻ります。有能なCまたはC ++プログラマは、そのようなものを1時間以内に書くことができるはずです。


おもしろい-ダウン票ですが、私が書いたものに反論がないことに気付きました。正確であるが役に立たない場合、それは投票する理由にはなりません。正確でなく、役に立たない場合は、それに値します。
布袋

OPには、圧縮されたイメージのマウントに関連する質問があったことが他の場所でわかります。これはそのスレッドの続きだと思います。圧縮の提案が受け入れられなかった理由がわかりました。単純なCプログラムは、スパースファイルを作成する簡単な方法です。しかし-(指定されていない)OSは、まばらなISOをマウントさせます。Ubuntu ISOマウンターのようにうるさいので、それがうまくいくかどうかは100%確信できません...しかし、いずれにしても幸運を祈ります。
布袋

4
なぜ車輪を再発明するのですか?cp --sparse=alwaysうまくいく
-mihi

@mihi:それはいい考えです。BSDフレーバー(freebsd.org/cgi/…)では利用できないため、スパースオプションについては知りませんでした。また、cpのLinux manページを見る必要はありませんでした(今日まで)。
布袋

圧縮イメージを作成してマウントする1つの方法は、ネイティブ圧縮をサポートするファイルシステムに単純に保存することです。ドライブがクラッシュした場合、データ復旧がひどくなりますが、それがバックアップの目的ですよね?
パーキンス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.