web-dev-qa-db-ja.com

Linuxカーネルは、どのプロセスがシステムコールを行ったかをどのようにして知るのですか?

プロセスがファイルを開くためのシステムコールを行ったとします。Linuxカーネルがこのシステムコールを実行すると、Linuxカーネルは開いたファイルのfdをプロセスfdに追加します。システムコール。

システムコールに渡された引数にPIDが含まれていない場合、Linuxカーネルはどのプロセスがこのシステムコールを行ったかをどのように知るのですか?

3
user230989

カーネルシステムコールは、呼び出しプロセスのコンテキスト内で、異なる特権レベルで、異なるサポートインフラストラクチャで実行されます。 Linuxカーネルには、現在のプロセスを追跡するCPUごとの変数があります current_task ;現在のプロセスが何であるかを知る必要があるときはいつでもそれを使用します。特定のCPUでは、現在のタスクはスケジューラーが決定したときにのみ変更され、コンテキストスイッチは必要なすべての情報を保存して、カーネルがどこで何が起こっているかを追跡できるようにします。

LWNには、syscallに関する有用な記事がいくつかあります システムコールパート1の構造 および パート2 。システムコールの定義方法と実行方法について説明しますが、ユーザースペースからカーネルスペースへの移行について詳しく説明していないため、実際に質問に答えるには十分な詳細がない可能性があります。しかし、それは、CPUで利用可能なトラップベースの遷移サポートが何であれ「ただ」です。

6
Stephen Kitt

あなたの質問は、アプリケーションがそれ自身のPIDを知っていて管理していることを示唆しており、カーネルがその仕事をする方法を知るためにそれをカーネルに渡す必要があります。これはよくある誤解です。この情報が流れる方法は、実際には逆です。プロセスは、プロセスID、ファイル記述子テーブルなどを認識または保存する必要はありません。それらに関する情報を取得したい場合は、getpidioctlなどのシステムコールを使用してカーネルから情報を取得する必要があります。

カーネルは大量のソースコード行で構成されていますが、その側で実行されている単一のプログラムではありません。ユーザーランドプログラムは反対側にあり、Webブラウザがリクエストを送信しているようにカーネルにリクエストを送信します。 Webサーバー。システムコールパラメータと戻り値は、アプリケーションとカーネル間を流れる一意の情報ではなく、状態(実行中、待機中、スリープ中...)がカーネルメモリに格納されているすべてのスレッドとプロセスに関するすべての低レベルの情報です。

大きなライブラリのようにカーネルコードの大部分が表示され、システムで実行されているすべてのプロセスにリンクされているはずです。プロセス(実際にはスレッド)がシステムコールを実行すると、その特別なライブラリに飛び込んで、短時間だけ超能力を獲得します。ただし、それでもまったく同じスレッドであるため、カーネルは正確にカーネル(ここではスケジューラー)であるため、実行中のスレッドを識別および管理するために必要なすべての情報(所有者、グループ、pid、ファイル記述子テーブルなど)を備えています。使用可能な(v)CPUにスレッドを割り当てます。

2
jlliagre