0

現在、単純な「マルチキャスト」モジュールを作成しています。

書き込み用に proc ファイルシステム ファイルを開くことができるプロセスは 1 つだけであり、残りのプロセスは読み取り用に開くことができます。これを行うには、inode_operation .permission コールバックを使用します。操作をチェックし、誰かが書き込み用にファイルを開いていることを検出したら、フラグをオンに設定します。

書き込み用にファイルを開いたプロセスがファイルを閉じることを決定したかどうかを検出する方法が必要です。これにより、フラグをオフに設定して、他の誰かが書き込み用に開くことができます。

現在、誰かが書き込みのために開いている場合に備えて、そのプロセスの current- >pidを保存し、.close コールバックが呼び出されたときに、そのプロセスが以前に保存したプロセスであるかどうかを確認します。

それを行うより良い方法はありますか?pidを保存せずに、おそらく現在のプロセスが開いているファイルとその許可を確認しています...

ありがとう!

4

2 に答える 2

2

いいえ、安全ではありません。いくつかのシナリオを考えてみましょう:

  • プロセス A が書き込み用にファイルを開き、次にfork()s がプロセス B を作成します。これで、A と B の両方が書き込み用にファイルを開きます。プロセス A がフラグを閉じると、フラグが 0 に設定されますが、プロセス B はまだ書き込み用に開いています。

  • プロセス A には複数のスレッドがあります。スレッド X はファイルを書き込み用に開きますが、スレッド Y はファイルを閉じます。現在、フラグは 1 のままです (->pidカーネル空間では、実際にはユーザー空間のスレッドID であることを思い出してください)。

i ノード レベルで処理を行うのではなく、構造体のメソッド.open.releaseメソッドで処理を行う必要がありますfile_operations

i ノードのプライベート データには、struct file *current_writer;に初期化された が含まれている必要がありますNULLfile_operations.openメソッドで、書き込み用に開かれている場合は、 ; を確認してくださいcurrent_writer。NULL の場合は、開いているものに設定します。struct file *それ以外の場合は、で開くのに失敗しEPERMます。file_operations.releaseメソッドで、解放されている が inode と等しいかどうかを確認しstruct file *ます。等しい場合はcurrent_writer、にcurrent_writer戻しNULLます。

PS: Bandan もロックが必要であることは正しいですが、i ノードの既存のものを使用するi_mutexことでcurrent_writer.

于 2010-05-12T05:01:59.210 に答える
0

あなたの質問が正しく理解できたことを願っています。誰かがあなたの proc ファイルに書き込みたい場合、flag という変数を 1 に設定し、current->pid をグローバル変数に保存します。次に、close() エントリ ポイントが呼び出されたときに、close() インスタンスの current->pid を確認し、それを保存した値と比較します。それが一致する場合は、フラグをオフにします。右 ?

次の状況を考えてみましょう: プロセス A が proc リソースに書き込みたいので、パーミッション コールバックをチェックします。フラグが 0 であることを確認すると、プロセス A のフラグを 1 に設定できます。しかし、その時点で、スケジューラはプロセス A がタイム シェアを使い果たしたことを検出し、実行する別のプロセスを選択します (フラグはまだ o!)。しばらくすると、プロセス B があなたの proc リソースにも書き込もうとして現れ、フラグが 0 であることを確認し、それを 1 に設定してから、ファイルへの書き込みを開始します。残念ながら、この時点で、プロセス A は再び実行するようにスケジュールされているため、フラグが 0 であると見なされ (スケジューラーがプリエンプトする前はフラグが 0 だったことを思い出してください)、それを 1 に設定してファイルへの書き込みを開始します。最終結果: proc リソースのデータが破損します。

このタイプの操作には、カーネルが提供する適切なロック メカニズムを使用する必要があります。要件に基づいて、RCU が最適だと思います。RCU ロック メカニズムをご覧ください。

于 2010-05-11T19:56:43.203 に答える