ファイルを意図的に断片化する方法

ファイルを意図的に断片化する方法

いくつかのツールのパフォーマンスを評価するために、既存のファイルを断片化する方法を探しています。NTFSファイルシステム用のソリューションを見つけました。マイフラグメントこのしかし、ext2/3/4用のものは見つかりません...独自のファイルフラグメンターを開発することはできますが、時間の制約があるため、より高速なソリューションを見つけたいと思います。次のようなツールを見つけました。HJスプリットファイルを小さなビットに分割しますが、これでファイルの断片化がシミュレートされるかどうかは疑問です。

私の問題に対する解決策はありますか?

答え1

あなたがしたい場合は確保する断片化ではなく防ぐ(つまり、何が起こるかについて部分的な制御しかできない)断片化の詳細を気にしない場合は、ここで手っ取り早く簡単な方法を紹介します。

n少なくとも 2 つのフラグメントでブロックのファイルを作成するには:

  1. 同期書き込みでファイルを開き、m < n ブロックを書き込みます。
  2. 別のファイルを開きます。ディスク上の空きブロックが最大で n - m ブロックになるまで追加します。誤ってスパースにしないでください。
  3. 残りの n - m ブロックを最初のファイルに書き込みます。
  4. unlink2番目のファイルを閉じます。

より多くのファイルをインターレースすることで、より多くの部分に断片化できます。

これは、ファイルシステムがこの種の拷問に使用できることを前提としています。つまり、マルチユーザーまたはミッションクリティカルな環境ではありません。また、ファイルシステムに予約ブロックがないか、予約ブロックが UID または root 用に予約されていることを前提としています。

ありません直接Unix システムはファイルシステムの抽象化を採用しているため、生のファイルシステムと通信することはなく、断片化を確実に行う方法ではありません。

また、ファイルシステム レベルの断片化を確認しても、下位レベルで何が起きるかはわかりません。LVM、ソフトウェアおよびハードウェア RAID、ハードウェア レベルのセクター再マッピング、その他の抽象化レイヤーは、期待値 (および測定値) を台無しにする可能性があります。

答え2

Linux 上で、連続したファイルよりも書き込みスループットを犠牲にする汎用ファイル システムに出会ったことはありません。つまり、特にスパース ファイルの場合、断片が非連続的な順序で書き込まれると、すべてのファイル システムが断片化します。

簡単な方法: ファイルを Torrent クライアントで実行します。できれば、ファイルを事前に割り当てないクライアントがよいでしょう。BitTornado または rtorrent が適しています。(前者には設定可能な割り当てモードがあります)

難しい方法: ソース ファイルを数 KB のサイズに分割し、シャッフルします。宛先ファイルを開きます。各部分について、正しい位置を探して書き込みます。

これを実行する Perl スクリプトは次のとおりです。

#!/usr/bin/perl

use List::Util qw/shuffle/;
use IO::Handle;

use constant BLOCK_SIZE => 4096;

my ($src, $dst) = @ARGV;

my $size = (stat($src))[7];
my @blocks = shuffle(0 .. ($size / BLOCK_SIZE));

my ($srcfh, $dstfh);
open $srcfh, "<", $src or die "cannot open $src: $!";
open $dstfh, ">", $dst or die "cannot open $dst: $!";
truncate $dstfh, $size; # undefined behaviour

my $buf;
for my $blockno (@blocks) {
  seek $_, $blockno * BLOCK_SIZE, 0 for ($srcfh, $dstfh);
  read $srcfh, $buf, BLOCK_SIZE;
  print $dstfh $buf;
  $dstfh->flush;
}

close $dstfh;
close $srcfh;

filefrage2fsprogs パッケージに含まれるコマンドを使用して断片化をチェックできます。

トレントが行うことの例を次に示します。

# ls -sh amd64memstick-5.1.2.fs.gz
239M amd64memstick-5.1.2.fs.gz
# filefrag amd64memstick-5.1.2.fs.gz
amd64memstick-5.1.2.fs.gz: 585 extents found

私のスクリプトで得られた結果は次のとおりです (ext3 上):

$ ls -sh source.tar
42M source.tar
$ perl fragment.pl source.tar fragmented.tar
$ md5sum fragmented.tar source.tar
f77fdd7ab526ede434f416f9787fa9b3  fragmented.tar
f77fdd7ab526ede434f416f9787fa9b3  source.tar
# filefrag fragmented.tar
fragmented.tar: 395 extents found

編集:気にしないでください。結局のところ、かなり大きなファイル (1.5 GB のファイル フラグメントは確実) を除いて、それほどうまく機能しないようです。

VM システムはおそらくキャッシュを行っており、小さすぎる書き込みを延期/並べ替えています。これが、Torrent クライアントが断片化 (通常は 10MB/秒を超えるダウンロードは行わないため) する理由ですが、私のスクリプトでは断片化しません。VM しきい値を下げることで調整できると思います。/proc/sys/vm/dirty_*

答え3

Linux ext4で断片化されたファイルを生成する必要がある状況に遭遇しました。私は次のようにして実行しました。ファロケートは、ファイルに穴を開けるのに使用できますが、穴は使用可能なディスク領域として再利用されるため、フラグメントが発生します。ここ断片化されたファイル (および添付されたストーリー) を生成するスクリプト。この方法では、数千の断片 (またはエクステント) を簡単に作成できます。

関連情報