実際のサイズはほんの数MBしかありませんが、「見かけのサイズ」には約1GBのシステムイメージスパースファイルがあります。 (バグなしで)ブロックデバイスに効率的に書き込もうとしています。私が試したがうまくいかなかったいくつかの回避策は次のとおりです。
dd if=sparse_file of=/dev/some_dev
穴を含むファイル全体を処理すると、最終的に次のような結果が表示されます。1007869952 bytes (1,0 GB) copied, 22,0301 s, 45,7 MB/s
cp --sparse=always sparse_file /dev/some_dev
数MBが長い時間(〜13秒)かかるため動作しないようです。ddrescue --sparse --force sparse_file /dev/some_dev
メッセージで失敗するddrescue: Only regular files can be sparse.
(注:対処する内容と反対の方向に機能する)ここ)。
他に2つの方法がありますここしかし、私は単にLinuxディストリビューションの標準ツールを使用したいと思います。
それでは、ブロックイメージにスパースファイルを書き込んで穴をスキップする方法はありますか?
答え1
このツールCで書かれた内容が役に立ちます。標準的なツールではありませんが、非常にシンプルでコンパイルしやすいです。
そうですね。cp
ブロックデバイスへのスパース出力はサポートされていません(マンページで確認済み)。
答え2
このスレッドに関連する問題が発生しました。完全性を備えたLUKS暗号化ブロックデバイスを作成しました。データを読み取る前にセクタの整合性を確認できるように、各セクタ(論理ブロックなど)を消去したいと思います。 "luksFormat"では、cryptsetup(8)はデフォルトですべてのセクタを消去します。セクタを上書きすると、そのセクタの整合性ビットも上書きされるため、以前に整合性チェックを受けたかどうか気にする必要はありません。ただし、部分書き込みにより、カーネルがページサイズ内の隣接セクタと一緒にそのセクタを読み込み、関連する整合性を確認できない場合、書き込みは失敗します。残念ながら、mke2fsはいくつかのセクターを書いています。したがって、削除されていないデバイスでは mke2fs を使用できません。だから私はこの "sparseblk"ユーティリティを書いた。通常のファイルにfsイメージを作成し、通常のファイルをデバイスに書き込むことができます。 "sparseblk"ユーティリティはlseek(fd、offset、SEEK_DATA)を介して入力から穴をスキップし、書き込み時にセクタ境界にデータを埋めます。ファイルシステムがマウントされると、カーネルはセクタ全体を書き込みます。
仮想シナリオ:https://gitlab.com/cryptsetup/cryptsetup/issues/335#note_270050959
truncate -s 1G /tmp/1.img /tmp/2.img
truncate -s 980M /tmp/1.img /tmp/2.img
mke2fs /tmp/2.img
cryptsetup luksFormat \
--key-file /etc/motd \
--sector-size $(getconf PAGESIZE) \
--cipher chacha20-plain \
--integrity poly1305 \
--integrity-no-wipe \
/tmp/1.img
cryptsetup open --key-file /etc/motd /tmp/1.img dm-0
argv[0] < /tmp/2.img > /dev/mapper/dm-0
mount /dev/mapper/dm-0 /mnt/1
e2fsckやresize2fsなどでテストしていません。
それにもかかわらず、セキュリティが重要な場合は、デバイス全体を消去します。
この「sparseblk」ユーティリティは他の目的に使用できます。この「sparseblk」ユーティリティを他の目的に使用する場合は、「論理ブロックサイズがページサイズの倍数ではありません」という警告を無視できます。
posixはSEEK_DATA SEEK_HOLEを採用しています。http://austingroupbugs.net/view.php?id=415
「レアブロック」:https://gist.github.com/insulsa/18b7d31bd82ddade14db07f413c0b2d2
答え3
私はLinuxディストリビューションの標準ツールを使いたいだけです。
たとえば、基本的に何がインストールされていますか?
あなたが考えているように、2つの可能な答えがあります。
conv=sparse
ddはフラグとしてサポートされています。対象機器がすべて消去されたことを知っている限り、dd if=sparse_file conv=sparse of=/path/to/device
qemu-img は、ほとんどの標準配布リポジトリからインストールでき、希少なフォーマットと書き込みを理解します。ターゲットブロックデバイスがTRIMをサポートしている場合は、ターゲットにまれに書き込まれ、バージョン4から(私の考えでは?)パラメータを使用して強制的にまれに書き込むことができます
--target-is-zero
。
qemu-img convert -O raw sparse_file /path/to/device
それとも強制的にさせたか
qemu-img convert -O raw --target-is-zero sparse_file /path/to/device