5

ファイルシステムに関連するすべてのシステムコールをインターセプトし、代わりに独自のコードを実行することに興味があります。たとえば、creat、write、close、lseek、getcwdなどの呼び出し。私の目標は、生成されたプログラムから呼び出しプロセスによって管理されるメモリ内ファイルシステムへのすべてのファイルI/Oをキャプチャするexecveのような関数を作成することです。このようにして、呼び出し側プログラムはファイルシステムのオーバーヘッドなしで出力を検査できます。

私のユースケースは、APIやライブラリを持たない大規模な数値シミュレーションプログラムを使用しています。これらのプログラムは、入力ファイルと出力ファイルを介してのみ通信します。これらのファイルが大きい場合、I/Oを実行するためだけにランタイムの大部分を占める可能性があります。一部のコンピューターでは、スーパーユーザーのアクセス許可があれば、RAMに存在するファイルシステム(Linuxのtmpfsなど)をセットアップできますが、スーパーユーザーのアクセス許可がない場合、または特定の方法で構成されたマシンでは、これは不可能です。 。

LD_PRELOADを使用すると、libcの関数の代わりにカスタムコードを呼び出すことができることを理解しています。ただし、これは動的にリンクされたプログラムに対してのみ機能し、呼び出し元のプログラム(メモリ内のファイルシステムをホストしたい)と呼び出し先の間でIPCをどのように実行するかという質問には答えません。このアプローチの問題は、IPCを最適に実行する方法です。パイプ、UNIXドメインソケット、またはいくつかの共有メモリを使用する必要がありますか?

また、システムコールを傍受する方法としてptraceを見てきました。これはうまくいくようですが、このアプローチについて2つの質問があります。まず、実際のシステムコールが発生しないようにするにはどうすればよいですか(いくつかの例で見たように、システムコールの引数を変更するだけではありません)。第二に、ptraceは、呼び出し先のメモリ空間の高性能な読み取りを可能にしますか?

4

1 に答える 1

2

を使用LD_PRELOADすると、呼び出し先のメモリ空間でインターセプトコードを実行できます。ライブラリコンストラクター関数(__attribute__((constructor)))を使用すると、ライブラリを最初に起動するときに、選択したコードを実行できます。たとえばmmap、仮想ファイルシステムを初期化することができます。

次に、プリロードされたライブラリで呼び出しをインターセプトすると、ライブラリの関数がターゲットプロセスで実行され、構築されたファイルシステムにアクセスできます。IPCは必要ありません。

呼び出し元のプロセスがファイルシステムを管理する必要がある場合は、ファイルシステムとの通信にオーバーヘッドが発生します。子プロセスでファイルシステムの重要な部分をマッピングし(おそらく共有メモリ領域として)、代わりに子でリスナーを使用して親からのファイルシステムの変更を監視することをお勧めします(ファイルシステム操作を適切にロックします)。帯域幅の要件が低いため、単純なパイプで変更通知を行うことができます。

また、変更されたGlibcを提供することでファイルシステムアクセスをサンドボックス化する準仮想化システムであるPlashもチェックしてください。

于 2012-09-17T03:18:20.710 に答える