イメージをディスクに書き込みますが、ソースイメージのセクタにはすべてゼロが含まれていませんか?

イメージをディスクに書き込みますが、ソースイメージのセクタにはすべてゼロが含まれていませんか?

128GBのディスクがあるとしましょう。ディスクは12GBのみを使用します。 116GBのディスクはすべて0(0x00)を含む空き容量です。

ディスクの正確なスナップショットを撮って、後で現在と同じように再構成できるようにしたいと思います。圧縮された画像のスペースを節約するために、またはなどの高速圧縮アルゴリズムを使用してlz4画像を配信しますzstd

次のような同様のツールを使用してこれを実行できますddpv

pv /dev/sdb | lz4 > disk.image.lz4

これでサイズは約10 GBですが、実際にはゼロを含むフル128 GBのイメージを含むディスクイメージファイルがあります。 0は圧縮されています。

これで、このイメージをディスクに書き直したいと思います。当然私はこれを行うことができます:

lz4 -d -c disk.image.lz4 > /dev/sdb

しかし、ここで問題は、イメージをディスクに書き換える作業はすべて、ゼロまでディスクに書き換えるために時間がかかることです。

2つのうちの1つを想定します。レプリカで一時的にゼロだったブロックがまだゼロであるかどうか気にしない場合、またはSSDの場合は、文字通りblkdiscard数秒で画像を書き込む前にSSDのすべてのブロックを削除できます。数分でディスクを消去します。

質問:ソース画像をブロック単位で読み取り、ゼロ点を検出し、簡単に飛び越える出力デバイスにこのブロックを書きますか?

たとえば、1MB チャンクを使用する場合、理想的なツールは 1MB のデータを読み取り、すべて 0x00 であることを確認し、そうでない場合はターゲットの同じ場所に書き込みます。ブロックが実際にすべて0x00の場合、書き込みは完全にスキップされます。

これが利点になる理由は次のとおりです。

  • すべてのブロックをターゲットディスクに書き込むのに時間がかかることがあります。特に、サイズが2TBを超えるが比較的少量の実際のデータのみを含むロータリーハードドライブを使用する場合には、さらにそうです。
  • ドライブの比較的小さな部分にのみ関心のあるデータを含めることができます。
  • イメージが書き込まれると解凍されるため、ソースデバイスに追加の読み取りI / Oは適用されません。

これを行うための簡単なツールがまだ存在しない場合は、作成しようとしています。しかし、これを行う方法がすでにある場合は何ですか?

編集:より詳細な情報を提供するために、アクティブなソフトウェアライセンスを含むハードドライブパーティションをバックアップするユースケースを例に挙げます。アクティベーションスキームによっては、単純なファイルコピーまたはファイルシステム対応パーティションイメージも正しく復元されない場合があります。 (たとえば、認証スキームが割り当てられていない領域にデータを格納する場合、ファイルテーブルのセクタは不良セクタではなくても意図的に不良としてマークされるか、NTFSのMFT自体などが表示されます。)生成するには、すべてゼロ以外のすべての項目をビット単位でコピーする必要があります。

ベストアンサー1

圧縮されていない(まれに可能な)ソースファイルの場合は(GNU)のみを使用してcp --sparse=always sourcefile /dev/sdXください。

--sparse=WHEN

スパースファイルの生成を制御します。下記をご覧ください

デフォルトでは、スパースソースファイルはおおよそのヒューリスティックによって検出され、対応するターゲットファイルもスパースされます。これは選択された動作です--sparse=auto--sparse=alwaysSOURCEファイルにゼロバイトの長いシーケンスが含まれるたびにスパースDESTファイルが生成されることを指定します。--sparse=neverスパースファイルの生成を無効にするために使用されます。

希少ファイルの生成は、書き込みではなく検索によって簡単に行われます。ブロックデバイスではこれがまさにOPが探しているものです(慌てた意図)。

lz4リーンなサポートもあります。

--[no-]sparse

スパースモードのサポート(デフォルト:ファイルでは有効、stdoutでは無効)

lz4 -d -c --sparse disk.image.lz4 > /dev/sdX

この方法も機能しますが(指定する必要さえありません--sparse)、最初にファイルの上書きについて警告します。

lz4 -d --sparse /tmp/src.img.lz4 /dev/sdX

最後に、他の場合(GNU?)の場合、ddスパースはデフォルトでサポートされています。

sparseすべてNUL出力ブロックを作成する代わりに検索してみてください。

lz4 -d -c disk.image.lz4 | dd conv=sparse of=/dev/sdX

(おそらくSSD削除ブロックサイズと同じサイズを設定します。bs=デフォルトの512バイトをそのままにするのではなく、約1M程度になります。)

おすすめ記事