Solaris Resource Manager 1.1 のシステム管理

第 10 章 問題の解決

この章では、Solaris Resource Manager の操作で問題が発生したときの診断方法について説明します。

詳しくは、ご購入先にお問い合わせください。

ユーザー関連の問題

ユーザーがログインできない

Solaris Resource Manager の上記の制限は、いずれもスーパーユーザーには適用されません。

制限に達したことがユーザーに通知されない

Solaris Resource Manager の通常の操作では、制限に達すると、ログインしているユーザーに通知メッセージが送られます。ユーザーがこれらのメッセージを見ていないと、発生している問題の原因が分からず、システムの様子がおかしいと思います。ただし、システム管理者には通知されます。

通知メッセージの送信は、Solaris Resource Manager のデーモンプログラム limdaemon によって行われます。通知メッセージがユーザーに送信されない場合、管理者は次の点について調べてください。

ユーザーのグループを変更できない

Solaris Resource Manager は、スケジューリングツリーにおける l ノードの親を sgroup 属性で判定します。そして、この階層を使って資源の使用を規制し、CPU のスケジューリングを行います。そのため、sgroup 属性の修正に対しセキュリティ保護のための措置をいくつか設けることによって、変更上の不注意なエラーを防ぎ Solaris Resource Manager の制限が適用されるようにします。

sgroup 属性を変更するためには、次のいずれかの特権がユーザーに必要です。

親のない l ノードを他の l ノードの親にすることはできません。「親のない l ノード」を参照してください。

ユーザーが制限値をしばしば超過する

次の条件で問題が発生していないか調べてください。

予期しない通知メッセージ

制限値に達したユーザーには通知メッセージが送信されます。そのため、グループ制限値に達すると、グループヘッダーと、スケジューリング階層でその下のすべてのユーザーが通知メッセージを受け取ります。

ユーザーが別の l ノードに接続され、制限値を超過する場合があります。そのユーザーは通知メッセージを受け取りませんが、影響を受けるその他のすべてのユーザーが通知メッセージを受け取ります。影響を受けるグループにとって、問題の原因が明らかでない場合があります。

端末接続時間が更新されない

この問題の原因として第一に考えられるのは、limdaemon プログラムが動作していないことです。limdaemon は、ログイン済みのすべてのユーザーに対し、端末デバイスカテゴリの usage 属性と accrue 属性を定期的に更新します。通常 limdaemon は、Solaris Resource Manager の init.d スクリプトから起動します。

性能上の問題

root l ノードに接続されたプロセス

システム管理のために、root l ノードに接続されるプロセスには、要求するほとんどすべての CPU 資源が与えられます。したがって、root l ノードに CPU 使用量の多いプロセスを接続すると、このプロセスによって CPU が占有されるため、他の l ノードのプロセスが遅くなるか停止します。

これを避けるために、次の予防措置をとることができます。

setuid-root として動作するプログラムは、root l ノードに自動的に接続しません。通常、プロセスは、それを作成した親の l ノードに接続されたままで、実効ユーザー ID だけが変更されます。

CPU 資源が Solaris Resource Manager によって制御されない

Solaris Resource Manager は、SHR スケジューリングクラスのプロセスによる CPU の使用だけを制御します。他のスケジューリングクラス、特にリアルタイム (RT) とシステム (SYS) から高い優先順位で過度の要求があると、SHR は残りの CPU 資源でプロセスのスケジューリングを行います。

RT クラスの使用は、Solaris Resource Manager のシステムを制御する能力と対立するものです。リアルタイムプロセスはシステムをいつでも使用できるので、応答をリアルタイムに (通常、数百マイクロ秒で) 返すことができます。定義によって SHR クラスで動作するプロセスは、リアルタイムで動作するどれよりも低い優先順位を与えられます。Solaris Resource Manager は、RT プロセスを制御できません。したがって、使用可能なすべての資源をリアルタイムプロセスが使用したために、Solaris Resource Manager が他のプロセスに割り当てる資源がなくなることもあります。

SYS クラスだけで動作する重要なシステムに NFS サーバーがあります。NFS デーモンは SYS クラスで動作するため、Solaris Resource Manager はこれを制御できません。NFS サービスがよく使われるシステムでは、Solaris Resource Manager がプロセッサ資源を割り当てる余地は少なくなります。

プロセスがシステムコールの中でカーネルコードを実行している間は、通常のタイムスライス横取り規則は適用されません。ほとんどのシステムコールは、横取り点に達するほどの作業量をしません。しかし、システムがそれより強力なシステムコールによる高い負荷のもとにあると、全体的な応答性が低下することがあります。これはスケジューリングクラスによる制御の範囲外です。

システムの実メモリーが十分でないと、ページフォルト率が増加し、プロセススワップが増加するため入出力のボトルネックが生じ、カーネルがより多くの CPU を使用します。入出力待ちの時間が多くなることは、CPU の処理能力が失われていることを示します。これもまたスケジューリングクラスによる制御の範囲外です。

SHR スケジューリングクラスはタイムシェアリング (TS) スケジュールです。このクラスは、TS や対話式 (IA) スケジューラと同じ大域優先順位範囲を使用します。すべてのプロセスを SHR クラスに移行したり、そこから他のクラスへ移行する期間を除き、SHR と TS、IA を混在して使用するのは適切ではありません。SHR クラスと TS クラスのプロセスが混在した状態でシステムを操作すると、両方のクラスでスケジューリングの質が低下します。そのため、Solaris Resource Manager は、root 以外のプロセスが自らのプロセスや他のプロセスを TS や IA クラスに移すのを防止します。RT クラスは別の優先順位範囲を使用します。RT クラスは TS や IA クラスとともに使用できますが、SHR クラスとも一緒に使用できます。

root が実行するプロセスに、setpriority(3C) ライブラリルーチンの代わりに priocntl(2) システムコールを直接使って優先順位を調整するコードが入っている場合には、それらのプロセスがターゲットプロセスを別のスケジューリングクラス (通常は TS) に移動することがあります。setpriority ライブラリルーチンコードは、SHR への priocnt1 インタフェースが TS のインタフェースとバイナリ互換であるという事実を考慮に入れるため、問題が避けられます。ps(1)-c オプションか priocntl(1)-d オプションを使用すれば、プロセスのスケジューリングクラスを表示できます。

root 特権を持つプロセスが priocntl(2) を明示的に使ってプロセスのスケジューリングクラスのメンバーを管理する場合にも、同じ問題が生じます。

親のない l ノード

「親のない l ノード」とは、存在しない親 l ノードを持つ l ノードです。これは管理者にとって問題です。親のない l ノードや、スケジューリングツリーにおいて親のない祖先を持つ l ノードにはプロセスを接続できません。

カーネルは、スケジューリンググループの親に対する無効な変更によって親のない l ノードが作成されないように、sgroup 属性の変更をチェックします。

l ノードが親のない状態になったときの主な問題は、この l ノードにはプロセスを接続できなくなるということです。この l ノードにはプロセスを接続できないので、この l ノードを使ってログインすることはできません。したがって、対応するアカウントを使ってログインしても失敗します。

親のない l ノードを簡単に検出するには limreport コマンドに組み込まれている親なし識別子を指定します。

% limreport orphan - uid sgroup lname

このコマンドによって、親のない l ノードを持つユーザーのユーザー ID、スケジューリンググループ親、およびログイン名が表示されます。sgroup 属性を使えば、ツリーの親のない部分の一番上の l ノードがどれかがわかります。

親のない l ノードが見つかったら、管理者は、まずスケジューリングツリーの親のない部分の一番上を見つける必要があります。この l ノードを再接続する必要があるからです。親のない部分の一番上を正しく識別しないと、親のない部分の一部だけがツリーに接続されてしまいます。

親のない部分の一番上が判定できたら、適切な特権を持つ管理者であれば、limadm を使って、一番上の親のない l ノードの sgroup 属性にスケジューリングツリー内の有効な l ノードを設定できます。これによって、親のない l ノードは、有効な l ノードが一番上にあるグループのメンバーとしてツリーに再接続されます。limadm を実行すると、新しいスケジューリンググループが動作中になるかどうか検査されます。これによって、変更した l ノードが親のない状態ではないことがわかります。

一方、親のない l ノードの sgroup 属性のユーザー ID と等しいユーザー ID を持つユーザーを新たに作成することもできます。これによって、ツリーの親のない部分が自動的に再接続されます。

グループループ

l ノードを動作中にすると、root l ノードに至るまでそのすべての親が動作中になります。この過程でいずれかの l ノードの親がすでに見つけられているものと同じ場合、カーネルは「グループループ」があるものとみなします。

リミットデータベースが壊れていると、l ノードの親のどれかが同時にその l ノードの子の 1 つとなって、グループループになることがあります。カーネルはグループループを発見すると、ループを任意に断ち切り、root l ノードの下にグループとして接続することによって、ループをスケジューリングツリーに (メッセージなしに) 自動的に接続します。ループには始めも終わりもないので、カーネルはどれが一番上の l ノードか判定できません。したがって、ループをスケジューリングツリーに接続した点の l ノードが一番上のグループのグループヘッダーになります。このグループのメンバーは、特権や本来より高い制限値を継承することがあります。

原因

スケジューリンググループの親を設定するときには、limadm がグループループが起こらないようにします。グループループは、リミットデータベースが壊れていることが原因で起こります。リミットデータベースは Solaris Resource Manager の操作の基本です。これが壊れていると、あらゆる問題の原因となります。

修正

カーネルが l ノードを root l ノードに接続するので、スケジューリングツリーの構造の問題は自動的に修正されます。この接続にはループ内の任意の点が使用されるため、管理者は、この l ノードをどこに接続するかを判定するだけでなく、ループ内の他のメンバーの接続点もチェックする必要があります。

グループループが自動的に修復された結果は、root l ノードの子の l ノードを一覧表示すると参照できます。

% limreport 'sgroup==0' - uid lname

このコマンドでは、root l ノードを親に持つすべての l ノードが表示されます。root l ノードの子ではない l ノードが表示される場合は、その l ノードが root l ノードの下に接続されたグループループの一番上と考えられます。

グループループが検出された場合は、リミットデータベースが損傷しているということなので、もっと重大な問題が起こる可能性があるということに管理者は注意する必要があります。リミットデータベースが壊れている可能性がある場合は、ファイルを検査して壊れているかどうかを判定し、壊れていたら修正する必要があります。リミットデータベースが壊れているかどうかの判定とその修正方法については、「クラッシュの回復」を参照してください。

ユーザー ID の重複の解決

srmidlesrmlost、および srmother にシステムが割り当てるユーザー ID が、既存のユーザー ID と重複していないか検証するため、次のように実行してください。

# /usr/bin/egrep 41¥|42¥|43 /etc/passwd

重複している場合、パスワードファイルとシャドウファイル (/etc/passwd/etc/shadow) を編集してユーザー ID を変更してください。

クラッシュの回復

Solaris システムが異常終了したら、管理者はいろいろなことを考慮しなければなりません。Solaris Resource Manager システムを使用する場合には、次の点にも考慮が必要です。

次の各項では、これらについて詳しく説明し、必要に応じてその対処法を示します。

リミットデータベースの損傷

Solaris Resource Manager のリミットデータベースの保守は信頼性があるため、損傷することはほとんど考えられません。ただし、このデータベースは Solaris Resource Manager の操作にとって基本的なものであるため、損傷が実際に起きた場合には、大きな問題です。損傷の可能性がある場合は調査し、損傷が見つかったら修正する必要があります。

症状

リミットデータベースが壊れていることを的確に判定できる唯一の症状はないので、いくつかの症状から判断する必要があります。

リミットデータベースの損傷を検出する最もよい方法は、limreport を使って l ノードを一覧表示することです。ある範囲内にあるはずの属性の値がその範囲外にあることがあります。範囲外の値があると、損傷があったことが分かります。flag.real が消去されている l ノードも表示できます。この l ノードが表示される場合には、l ノードが存在しないアカウントがパスワードマップにあることを示します。

処置

損傷を検出したら、管理者は、リミットデータベースを損傷していない状態に戻す必要があります。リミットデータベースの一部分だけが壊れている場合には、他のすべての l ノードの内容を保存し、limreportlimadm を使って新しいリミットデータベースに再読み込みできることがあります。このリミットデータベースには、最新の usage 属性と accrue 属性が含まれているので、リミットデータベースの最新のコピーがない場合は、この方法が必要です。リミットデータベースの保存と復元のための手順は、第 5 章「l ノードの管理」を参照してください。l ノードがなくなっているだけのような場合は、limadm コマンドを使うだけで作成し直すことができます。

limdaemon による接続時間の喪失

limdaemon コマンドが何らかの理由で停止すると、ログイン済みのすべてのユーザーに接続時間使用量を負担させなくなります。さらに、limdaemon コマンドを再起動すると、ログイン済みのユーザーは同じ端末を無料で使用し続けます。これは、デーモンが、login のログイン通知を使って、接続時間使用量を計算するための Solaris Resource Manager ログインセッションレコードを内部構造に設定するからです。したがって、デーモンを起動しても、デーモンが最初の通知を受け取るまでは、Solaris Resource Manager ログインセッションは確立されません。

通常、limdaemon がシステムクラッシュのために停止する場合には、他のプロセスも停止するので、これは問題とはなりません。ログインセッションは、システムが再起動されるまで再開できないからです。

limdemon が他の理由で停止する場合には、管理者は次の 2 つの方法を実行します。

  1. デーモンを直ちに再起動し、ログイン済みのユーザーに対し、失われた端末接続時間の課金を無視する。この場合、このユーザーを見つけてログアウトさせるまで、端末は永久に無料で使用されます。

  2. システムをシングルユーザーモードにしてから、マルチユーザーモードに戻す。現在のすべてのログインセッションは停止され、ユーザーは、デーモンが再起動されるまでログインできません。