無停電プロセスとは何ですか?


155

Linuxでプログラムを作成し、なんらかのバグが原因でクラッシュする場合はいつでも、無停止のプロセスになり、コンピューターを再起動するまで(ログアウトした場合でも)永久に実行し続けます。私の質問は:

  • プロセスが中断されない原因は何ですか?
  • それを防ぐにはどうすればよいですか?
  • これはおそらく馬鹿げた質問ですが、コンピュータを再起動せずに中断する方法はありますか?

TASK_UNINTERUPTIBLEシステムがアイドル状態でないときにいつでも状態になるプロセスを開始するプログラムを作成して、スーパーユーザーが終了すると強制的にデータを収集し、送信を待機することは可能ですか?これは、ハッカーが情報を取得し、ゾンビ状態に戻り、アイドル時にネットワークを介して情報を送信するための金鉱となります。これはBlackdoor、必要に応じてシステムに出入りするための権限を作成する1つの方法であると主張する人もいます。この抜け穴は、 `TASK_UNINTERUPTIB
Nuuwski

2
コードを共有していただけますか?
再び

回答:


197

割り込み不可能なプロセスとは、シグナルによって割り込みできないシステムコール(カーネル関数)にあるプロセスです。

これが何を意味するのかを理解するには、割り込み可能なシステムコールの概念を理解する必要があります。典型的な例はread()です。これは、ハードドライブのスピンアップやヘッドの移動を伴う可能性があるため、長い時間(数秒)かかるシステムコールです。この時間のほとんどの間、プロセスはスリープ状態になり、ハードウェアでブロックされます。

システムコールでプロセスがスリープしている間、プロセスはUnix非同期シグナル(たとえば、SIGTERM)を受信でき、次のことが起こります。

  • システムコールは途中で終了し、-EINTRをユーザー空間に返すように設定されています。
  • シグナルハンドラが実行されます。
  • プロセスがまだ実行中の場合は、システムコールから戻り値を取得し、同じ呼び出しを再度行うことができます。

システムコールから早期に戻ると、ユーザー空間コードは信号に応答してその動作をすぐに変更できます。たとえば、SIGINTまたはSIGTERMに反応してクリーンに終了します。

一方、一部のシステムコールは、この方法で割り込みを許可されていません。システムが何らかの理由でストールを呼び出すと、プロセスはいつまでもこの強制不能状態のままになる可能性があります。

LWNはこのトピックに触れた素晴らしい記事を7月に掲載しました。

元の質問に答えるには:

  • これを防ぐ方法:問題の原因となっているドライバーを特定し、使用を停止するか、カーネルハッカーになって修正します。

  • 再起動せずに無停止のプロセスを強制終了する方法:どういうわけかシステムコールを終了させます。電源スイッチを押すことなくこれを行う最も効果的な方法は、電源コードを抜くことです。LWNの記事で説明されているように、カーネルハッカーになり、ドライバにTASK_KILLABLEを使用させることもできます。


31
ラップトップの電源コードを抜いたところ、残念ながら動作しません。;-)
thecarpy 2014

1
EAGAINではなくEINTRではありませんか?また、read()は-1を返し、errnoにエラーが設定されます。
リーサルマン2015年

2
@デクスター:あなたは確かにポイントを逃しています。LWNの記事を読みます:lwn.net/Articles/288056。これらの問題は遅延デバイスドライバープログラマーによって引き起こされ、デバイスドライバーコードで修正する必要があります。
ddaa 2015年

4
@ddaa「Unixの伝統(つまり、ほとんどすべてのアプリケーション)は、ファイルストアの書き込みは信号の割り込みができないと信じています。この保証を変更することは安全でも実用的でもありません。」->これは、このすべてのIMOの中で最も間違っている部分です。ドライバーの読み取り/書き込み要求を中断するだけで、実際のデバイス(ハードディスク/ネットワークカードなど)がデータを配信するときは無視してください。OSカーネルは、開発者がそれを台無しにできないように作成する必要があります。
デクスター2017年

2
@ddaa私のコメントのどの部分がそれに関係しているのかはわかりませんが、Linuxがマイクロカーネルではないことはわかっています...そして、あなたのコメントは、マイクロカーネルOSがこれらの「中断できない」プロセスに問題がないことを意味しますか?もしそうでなければ、多分私がマイクロカーネルのファンになる時がきたので...:D
デクスター

49

プロセスがユーザーモードの場合、いつでも中断できます(カーネルモードに切り替えます)。カーネルがユーザーモードに戻ると、保留中のシグナル(SIGTERMandのようなプロセスを強制終了するために使用されるシグナルを含む)があるかどうかを確認しますSIGKILL。これは、ユーザーモードに戻ったときにのみプロセスを強制終了できることを意味します。

カーネルモードでプロセスを強制終了できないのは、同じマシン内の他のすべてのプロセスで使用されているカーネル構造を破壊する可能性があるためです(スレッドを強制終了すると、同じプロセス内の他のスレッドで使用されているデータ構造が破損する可能性があります)。 。

カーネルが長い時間を必要とする何かを行う必要がある場合(別のプロセスによって書き込まれたパイプで待機したり、ハードウェアが何かを実行するのを待機したりするなど)、それ自体をスリープとしてマークし、スケジューラを呼び出して別のスケジューラに切り替えます。プロセス(非スリーププロセスがない場合、「ダミー」プロセスに切り替わり、CPUに少しスローダウンしてループ(アイドルループ)に入るように指示します)。

シグナルがスリープ中のプロセスに送信された場合、ユーザー空間に戻って保留中のシグナルを処理する前に、シグナルを起こさなければなりません。ここでは、2つの主なタイプの睡眠の違いがあります。

  • TASK_INTERRUPTIBLE、割り込み可能なスリープ。タスクがこのフラグでマークされている場合、タスクはスリープ状態ですが、シグナルによって起こされる可能性があります。これは、タスクをスリープ状態としてマークしたコードがシグナルの可能性を期待しており、ウェイクアップした後、それをチェックしてシステムコールから戻ることを意味します。シグナルが処理された後、システムコールは自動的に再起動される可能性があります(その仕組みについては詳しく説明しません)。
  • TASK_UNINTERRUPTIBLE、途切れない睡眠。タスクがこのフラグでマークされている場合、簡単に再起動できないか、プログラムがシステムコールがアトミックであることをプログラムが期待しているため、待機しているもの以外のものによって起こされることを期待していません。これは、非常に短いことがわかっている睡眠にも使用できます。

TASK_KILLABLE (ddaaの回答でリンクされているLWNの記事で言及されている)は新しいバリアントです。

これはあなたの最初の質問に答えます。2番目の質問については、中断のないスリープを回避することはできません。これらは正常な状態です(たとえば、プロセスがディスクに対して読み取り/書き込みを行うたびに発生します)。ただし、それらはほんの一瞬しか続かないはずです。それらがはるかに長く続く場合、それは通常、ハードウェアの問題(またはカーネルに同じように見えるデバイスドライバーの問題)を意味し、デバイスドライバーはハードウェアが決して起こらない何かを実行するのを待っています。また、NFSを使用していて、NFSサーバーがダウンしていることも意味します(サーバーが回復するのを待っています。「intr」オプションを使用して問題を回避することもできます)。

最後に、回復できない理由は、カーネルがユーザーモードに戻って信号を送信するかプロセスを強制終了するまで待機するのと同じ理由です:カーネルのデータ構造が破損する可能性があります(割り込み可能なスリープで待機しているコードは、それを通知するエラーを受け取る可能性がありますプロセスが強制終了される可能性があるユーザー空間に戻る場合;中断のないスリープで待機しているコードはエラーを予期していません)。


1
ファイルシステムのロックのバグも考えられる原因です、IME。
東武

3
全部分かりません。「無停止のスリープを回避することはできません」-無停止のスリープが単に状態として存在しないような方法でOSを作成することはできませんか?次に、破損に関する部分-プロセス自体のカーネルモード部分(または破損を引き起こす可能性があるもの)を終了できないか、メモリ内のコードを変更するだけで復帰できませんか?なぜこれがLinuxでさえできないほど難しい/不可能であるのか説明してください。(この問題はWindowsでのみ発生すると思っていました)
デクスター

私は考えることができる唯一の場合は、(安全に)それらのプロセス強制終了になるだろう、本当に(非常に難しい、とだけではなく、聞かせての言う)不可能をハードウェア自体が破損を引き起こすことができればです。ハードウェアは制御できません。カーネルはできます。しかし、ハードウェアからデータを取得してメモリを変更するのはカーネルです(そのため、プロセスがユーザーモードに戻る前に解放してはならず、破損が発生する可能性があります)...メモリ内のカーネルコードを変更すれば、問題は発生しなくなります。
デクスター

@Dexterは、カーネルを単一のマルチスレッドプロセスであるかのように考えます。各プロセスのカーネルモードの部分はカーネル内のスレッドです。あなたの提案は、マルチスレッドプログラムでシングルスレッドを強制終了するのと同じぐらい悪いことになります。ダングリングロック、一時的に変更されたデータ構造、または変更中のデータ構造などが残る可能性があります。
CesarB 2016

@CesarBスレッドを強制終了するのは正解です...しかし、「メイン」スレッド(OSカーネルで、他のスレッドはドライバーになるなど)はどうにかして処理できませんか?「変更中」の構造は本当に難しい問題のように見えますが、無停止のプロセスが不可能なOSを見ることはないでしょう:(
Dexter

23

通常、割り込み不可能なプロセスは、ページフォールトに続くI / Oを待機しています。

このことを考慮:

  • スレッドは、コアにないページ(デマンドロードされる実行可能ファイル、スワップアウトされた匿名メモリのページ、またはデマンドロードされるmmap() 'dファイル)にアクセスしようとします。同じこと)
  • カーネルは現在それを(ロードしようとしている)
  • ページが利用可能になるまで、プロセスは続行できません。

シグナルを処理できないため、この状態ではプロセス/タスクを中断できません。そうした場合、別のページ違反が発生し、元の場所に戻ります。

私が「プロセス」と言うとき、私は本当に「タスク」を意味します。これは、Linux(2.6)では、おおまかに「スレッド」に変換され、/ procに個別の「スレッドグループ」エントリがある場合とない場合があります。

しばらくお待ちいただく場合があります。この典型的な例は、実行可能ファイルまたはmmapされたファイルが、サーバーに障害が発生したネットワークファイルシステム上にある場合です。I / Oが最終的に成功した場合、タスクは続行されます。最終的に失敗すると、タスクは通常SIGBUSまたは何かを取得します。


1
最終的に失敗すると、タスクは通常SIGBUSまたは何かを取得します。待って、カーネルを作成して、「中断できない」プロセスを強制終了したときに、I / O操作が失敗したことを単にTELLSするようにできないのでしょうか。その後、プロセスはユーザーモードに戻り、なくなってしまいますか?これらの「D」状態のプロセスを安全に強制終了する方法が必要です。それは簡単ではないと思います。そのため、WindowsもLinuxもその可能性はまだありません。反対に、私はそれらのプロセスを少なくとも安全ではなく殺すことができるようにしたいと思います。システムクラッシュの可能性などは気にしません...
デクスター

@Dexterうーん、私はWindowsでこの問題を経験したことがありません。そこでそれを再現する方法は何ですか?少なくともこの投稿によると、すべてのI / O要求がWindowsで中断される可能性があります。
ルスラン

1

3つ目の質問:を実行することで、中断できないプロセスを強制終了できると思います sudo kill -HUP 1。実行中のプロセスを終了せずにinitを再起動し、実行後、中断できないプロセスがなくなりました。


-3

「ゾンビ」プロセス(ps出力では「ゾンビ」と指定されている)について話している場合、これはプロセスリスト内の無害なレコードであり、誰かが戻りコードを収集するのを待っているため、無視しても安全です。

「中断のないプロセス」とは何ですか?それは「キル-9」を生き延びて、幸せに一緒に食べますか?その場合は、一部のシステムコールで停止しており、一部のドライバーで停止しており、再起動するまで(そして、場合によってはすぐに再起動する方がよい場合があります)、または関連するドライバーのアンロード(発生する可能性が低い)まで、このプロセスで停止します。 。"strace"を使用して、プロセスがどこに行き詰まっているのかを調べ、将来それを回避することができます。


プロセスを強制終了するのと同じ方法で、ドライバーを強制的にアンロードできませんか?カーネルモードにはユーザーモードよりも特権アクセスがあることを知っていますが、オペレーティングシステム自体よりも特権を与えることはできません。カーネルモードで実行されているものは、常にカーネルモードで実行されている他のものを改ざんすることができます。
デクスター
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.