速度が重要で圧縮が不要な場合は、を使用しtarて使用するsyscallラッパーをフックしLD_PRELOAD、変更tarして計算してください。私たちのニーズに合わせて、これらの機能のいくつかを再実装することにより(電位出力タールデータのサイズを計算する)、我々は多くのを排除することができますreadし、writeそれは、通常の操作で行われますtar。これによりtar、コンテキストスイッチを前後にカーネルに前後に切り替える必要がなくなりstat、実際のファイルデータではなく、要求された入力ファイル/フォルダーのみをディスクから読み取る必要があるため、はるかに高速になります。
コードは以下の実装含みclose、readおよびwritePOSIX機能を。このマクロOUT_FDはtar、出力ファイルとして使用するファイル記述子を制御します。現在、標準出力に設定されています。
readcount実際のデータが読み取られなかった場合、bufに圧縮を渡すための有効なデータが含まれていないため、bufにデータを入力する代わりに、バイトの成功値を返すように変更されました。サイズ。
write入力countバイトをグローバル変数に合計し、ファイル記述子が一致する場合のみバイトtotalの成功値を返すように変更されました。そうでない場合は、経由で取得した元のラッパーを呼び出して同じ名前のsyscallを実行します。countOUT_FDdlsym
closeそれでも元の機能はすべて実行されますが、ファイル記述子がOUT_FDと一致する場合、tartarファイルへの書き込みの試行が完了したことを認識しているため、total番号は最終的なものであり、stdoutに出力されます。
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include <errno.h>
#include <dlfcn.h>
#include <string.h>
#define OUT_FD 1
uint64_t total = 0;
ssize_t (*original_write)(int, const void *, size_t) = NULL;
int (*original_close)(int) = NULL;
void print_total(void)
{
printf("%" PRIu64 "\n", total);
}
int close(int fd)
{
if(! original_close)
{
original_close = dlsym(RTLD_NEXT, "close");
}
if(fd == OUT_FD)
{
print_total();
}
return original_close(fd);
}
ssize_t read(int fd, void *buf, size_t count)
{
return count;
}
ssize_t write(int fd, const void *buf, size_t count)
{
if(!original_write)
{
original_write = dlsym(RTLD_NEXT, "write");
}
if(fd == OUT_FD)
{
total += count;
return count;
}
return original_write(fd, buf, count);
}
読み取りディスクアクセスと通常のtar操作のすべてのsyscallsがLD_PRELOADソリューションに対して実行されるソリューションを比較するベンチマーク。
$ time tar -c /media/storage/music/Macintosh\ Plus-\ Floral\ Shoppe\ \(2011\)\ \[Flac\]/ | wc -c
332308480
real 0m0.457s
user 0m0.064s
sys 0m0.772s
tarsize$ time ./tarsize.sh -c /media/storage/music/Macintosh\ Plus-\ Floral\ Shoppe\ \(2011\)\ \[Flac\]/
332308480
real 0m0.016s
user 0m0.004s
sys 0m0.008s
上記のコード、上記を共有ライブラリとしてビルドするための基本的なビルドスクリプト、およびLD_PRELOADそれを使用する「テクニック」を備えたスクリプトがレポジトリで提供されています:https :
//github.com/G4Vi/tarsize
LD_PRELOADの使用に関する情報:https : //rafalcieslak.wordpress.com/2013/04/02/dynamic-linker-tricks-using-ld_preload-to-cheat-inject-features-and-investigate-programs/
--totalsオプションでいろいろ試してみてください。いずれにせよ、ディスクがいっぱいになった場合、アーカイブ、imhoを削除するだけです。利用可能なすべてのオプションを確認するには、を実行できますtar --help。