(57)【特許請求の範囲】
【請求項１】
カーネルおよび該カーネルの修正部分に対応するモジュールである１つまたは複数のプラグが格納された記憶部と、
対称型マルチプロセッシング構成による複数のＣＰＵを有しプログラムを実行する制御部と
を有する情報処理装置上で実行する、前記プラグを前記カーネルに導入するカーネル更新方法であって、
前記制御部において、
前記プラグを前記カーネルの空き領域に書き込むステップと、
前記プラグを前記空き領域に書き込んだ後、前記プラグを導入するための手順を除く前記カーネルの実行を前記制御部上に存在する全てのＣＰＵに対して、プラグイン用スレッドのみを動作させることで、全ＣＰＵの処理を停止させるステップと、
一部を除く前記カーネルの実行を停止させた後、前記修正部分のコードを、前記修正部分において前記プラグに手順をジャンプさせるためのジャンプコードに書き換えるステップと、
を実行することを特徴とするカーネル更新方法。
【請求項２】
カーネルおよび該カーネルの修正部分に対応するモジュールである１つまたは複数のプラグが格納された記憶部と、
対称型マルチプロセッシング構成による複数のＣＰＵを有しプログラムを実行する制御部とを有する情報処理装置上で実行する、前記プラグを前記カーネルで無効化するカーネル更新方法であって、
前記制御部において、
前記プラグを無効化するための手順を除く前記カーネルの実行を前記制御部上に存在する全てのＣＰＵに対して、プラグイン用スレッドのみを動作させることで、全ＣＰＵの処理を停止させるステップと、
一部の手順を除く前記カーネルの実行を停止させた後、前記修正部分の処理を有効にするために、前記プラグの処理を実行可能にするために書き込まれたジャンプコードを前記修正部分のコードに書き戻すステップと、
を実行することを特徴とするカーネル更新方法。
【請求項３】
カーネルおよび該カーネルの修正部分に対応するモジュールである１つまたは複数のプラグが格納された記憶部と、
前記プラグを前記カーネルに導入する場合、該プラグを該カーネルの空き領域に書き込み、該プラグを導入するための手順を除く前記カーネルの実行を停止させた後、前記修正部分で前記プラグに手順をジャンプさせるためのジャンプコードに前記修正部分のコードを書き換え、また、前記プラグを前記カーネルで無効化する場合、該プラグを無効化するための手順を除く前記カーネルの実行を停止させた後、前記修正部分の処理を有効にするために前記ジャンプコードを前記修正部分のコードに書き戻す制御部と、
を有する情報処理装置であって、
前記制御部には対称型マルチプロセッシング構成による複数のＣＰＵを有すること
を特徴とする情報処理装置。
【請求項４】
請求項１または２に記載のカーネル更新方法に記載された各ステップを情報処理装置に実行させるためのプログラム。
【請求項５】
請求項１または２に記載のカーネル更新方法に記載された各ステップを情報処理装置に実行させるためのプログラムを記録した、情報処理装置に読み取りが可能な記録媒体。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、高信頼性を要求されるネットワークサービスを提供するための、プログラムを修正するモジュールであるプラグをＯＳ（Operating System）の基本機能を備えたソフトウェアプログラムであるカーネルにロード、またはカーネルからアンロードするためのプログラム更新方法、情報処理装置、その方法をコンピュータに実行させるためのプログラム、および、コンピュータに読み取り可能な記録媒体に関する。
【背景技術】
【０００２】
ネットワークサービスを提供するシステムには極めて高い信頼性、すなわち長期間にわたって連続して稼動し続けるという性能（これを可用性という）が要求される。具体的に説明すると、ネットワークサービスでは２４時間３６５日連続してサービスを提供し、典型的に年間のサービス可用性が９９．９９９％以上であることが要求される。
【０００３】
このため、従来は専用システムを用いて可用性を確保してきた。しかし、専用システムはコストが高く、安価にサービスの提供ができないという問題があった。
【０００４】
そこで、ｘ８６アーキテクチャのハードウェアやオープンソースＯＳであるＬｉｎｕｘ（登録商標）など、汎用のハードウェアや汎用のＯＳがシステムに用いられるようになってきた。そのため、汎用のハードウェアや汎用のＯＳを用いたシステムで可用性を確保することが課題になっている。
【０００５】
一般に、多くのソフトウェアにはバグが存在する。バグ修正の際にはプロセスの再起動が必要なため、バグ修正の度にサービスを停止せざるを得ず、これが可用性を低下させる原因になっていた。そこで、プロセスのバグ修正を、サービスを停止することなく行い得ることが必要となっている。
【０００６】
従来の専用ＯＳは、プロセスのメモリ上のコードを直接修正する技術（以下では、この技術をライブパッチ技術、または、単にライブパッチと称する）を有していた。汎用ＯＳであるＬｉｎｕｘでも、非特許文献１に示すように、アプリケーションのプロセスを終了・再起動させることなく、バグ修正を可能にするライブパッチ技術が開発されるに至っている。
【０００７】
Ｌｉｎｕｘでは、カーネルと、カーネルの管理の下で動作するアプリケーションとからなる。非特許文献１はアプリケーションに関するプラグのライブパッチ技術を開示している。
【０００８】
アプリケーションに対してライブパッチを行うには、ライブパッチを実行する管理プロセス（プロセスＡ）と修正ターゲット（プロセスＢ）が必要である。ライブパッチは、システム管理者がプロセスＡにプラグ情報やプロセスＢの情報を入力し、プロセスＢのメモリ空間に適切なタイミングでアクセスし、コードを修正する方法で行われる。
【０００９】
この方法を実現するには、
（１）修正ターゲット（プロセスＢ）のメモリ空間へのアクセスができること、
（２）修正ターゲット（プロセスＢ）のメモリ空間上のコードが修正できること、
（３）修正ターゲット（プロセスＢ）のメモリ空間へ適切なタイミングでアクセスできること、
が必要になる。
【００１０】
Ｌｉｎｕｘにおいては、カーネルがプロセスのメモリ空間を管理し、実際の物理的なメモリアドレスを個々のプロセス固有のメモリ領域に割り振っている。これにより、個々のプロセスは自プロセスに割り振られたメモリ空間へ仮想アドレス番地でアクセスが可能になると共に、他のプロセスが持つアドレス空間へのアクセスが制限される。
【００１１】
そこで、プロセスＡがプロセスＢのメモリ空間にアクセスできるようにするため、カーネルのメモリ管理を変更し、カーネルに新たな任意のメモリ空間へのアクセスを許容するインターフェイスを定義することで実現している（上記（１）を実現）。
【００１２】
コードの修正は、分岐命令上書きによる変更を用いることで実現している（上記（２）の実現）。呼び出される関数を修正する場合、修正する関数の先頭番地に新たな分岐命令を書き込めば、新規領域にロードされた修正後の関数へ分岐させることができる。
【００１３】
修正するタイミングは、修正対象の関数および変数へのアクセスが修正対象のプロセス・スレッドから行われていないタイミングで行うことが必要である。そこで、修正対象プロセス・スレッドをライブパッチで行う直前に、スケジューリングの対象外とし、プロセスの状態がライブパッチ可能かどうかを判断した上で行うことで、修正するタイミングを確保している（上記（３）の実現）。
【００１４】
以上、説明したように、Ｌｉｎｕｘにおいても、アプリケーションのバグ修正を、サービスを停止することなく行い得る。
【非特許文献１】池辺  他、「ネットワークサービス提供に向けたＬｉｎｕｘＯＳの高可用化ライブパッチ技術」、信学技報  ＮＳ２００５−５０  ｐ．４９−５２（２００５）電子情報通信学会
【発明の開示】
【発明が解決しようとする課題】
【００１５】
上記した方法は、カーネルによって管理されているアプリケーションについてのライブパッチにのみ適用可能であって、カーネルのバグ修正のライブパッチには適用できないという問題があった。
【００１６】
本発明は上述したような従来の技術が有する問題点を解決するためになされたものであり、カーネルに対してもバグ修正のプラグインをライブパッチで実現することを可能にしたプログラム更新方法、情報処理装置、プログラム、および、コンピュータに読み取りが可能な記録媒体を提供することを目的とする。
【課題を解決するための手段】
【００１７】
上記目的を達成するための本発明のプログラム更新方法は、情報処理装置上で動作するプログラム更新方法であって、
前記情報処理装置はカーネルおよび該カーネルの修正部分に対応するモジュールである１つまたは複数のプラグが格納された記憶部と、
１つまたは複数のＣＰＵを有しプログラムを実行する制御部とを有し、
前記プログラム更新方法は前記プラグを前記カーネルに導入するためのプログラム更新方法であって、
前記プラグを前記カーネルの空き領域に書き込むステップと、
前記プラグを前記空き領域に書き込んだ後、前記プラグを導入するための手順を除く前記カーネルの実行をシステム上に存在する全てのＣＰＵに対して、プラグイン用スレッドのみを動作させることで、全ＣＰＵの処理を停止させるステップと、
一部を除く前記カーネルの実行を停止させた後、前記修正部分のコードを、前記修正部分において前記プラグに手順をジャンプさせるためのジャンプコードに書き換えるステップと、
を有するものである。
【００１８】
本発明では、新たにプラグをロードしてそれを有効にするための専用スレッドをカーネルに設けていれば、その専用スレッドのみを実行可能とし、他のスレッドを停止する。これにより、専用スレッド以外の修正部分を含むカーネルが一時停止することになるため、メモリの書き換え中に該当部分が実行されることがない。
【００１９】
また、本発明のプログラム更新方法は、情報処理装置上で動作するプログラム更新方法であって、
前記情報処理装置はカーネルおよび該カーネルの修正部分に対応するモジュールである１つまたは複数のプラグが格納された記憶部と、
１つまたは複数のＣＰＵを有しプログラムを実行する制御部とを有し、
前記プログラム更新方法は前記プラグを前記カーネルで無効化するためのプログラム更新方法であって、
前記プラグを無効化するための手順を除く前記カーネルの実行をシステム上に存在する全てのＣＰＵに対して、プラグイン用スレッドのみを動作させることで、全ＣＰＵの処理を停止させるステップと、
一部の手順を除く前記カーネルの実行を停止させた後、前記修正部分の処理を有効にするために、前記プラグの処理を実行可能にするために書き込まれたジャンプコードを前記修正部分のコードに書き戻すステップと、
を有するものである。
【００２０】
本発明では、カーネル中の修正対象部分が実行されないようにバイパスを設けている。バイパスに該当するプラグとジャンプコードをカーネルの空き領域に書き込み、ジャンプコードを介してプラグに手順をジャンプさせるための割り込み命令を修正部分に書き込んでいる。そのため、仮に修正対象部分が実行されそうになっても、バイパス先のプラグが実行される。この場合、カーネルを一時停止しなくてもよい。
【発明の効果】
【００２１】
本発明によれば、動作中のカーネルに対して再起動せずに動作を変更することができる。また、処理内容の変更対象となるカーネル側に準備が必要でないことから、既存のカーネルに適用できる。さらに、カーネルの停止時間を最小限または停止時間なしで、プラグをロードして有効化することができる。
【発明を実施するための最良の形態】
【００２２】
本実施形態において、カーネルのプラグインとはカーネルのメモリ空間にアクセスし、その内容の読み込み、書き換えを行うことをいう。プラグインには、プラグをロードすること、ロードしたプラグをアンロードすることを含むものとする。本実施形態では、プラグの導入先となる側を「ターゲット」、プラグインによって導入される要素を「プラグ」と称する。
【００２３】
Ｌｉｎｕｘのカーネルはカーネル本体とカーネルモジュールの二種類に分類される。カーネルモジュールはカーネル本体起動後に動的にカーネル内にロードされ、組み込まれる。したがって、プラグは、カーネル本体とカーネルモジュールが投入された後に、カーネルモジュールとして導入することとする。
【００２４】
カーネルに対してプラグインをライブパッチで行うための困難性は、アプリケーションでのようにプロセスを一時的に停止することができない点にある。したがって、メモリ書き換えの処理途中で書き換え箇所が実行されることによる処理矛盾を発生させないようにすることが必要となる。
【００２５】
そのための１つの方法として、ＣＰＵ（Central Processing Unit）にプラグイン用スレッドのみを動作させ、本来のスレッドの実行を停止させる方法を案出した。これにより、実効的にＣＰＵは停止状態になり、メモリ書き換えの処理途中で書き換え箇所が実行されることによる処理矛盾が発生しないようにできる。また、複数のＣＰＵを使用する対称型マルチプロセッシング（ＳＭＰ；Ｓｙｍｍｅｔｒｉｃ  ＭｕｌｔｉＰｒｏｃｅｓｓｏｒ）でも、全ＣＰＵでプラグイン用スレッドを生成・実行すればよい。この方法は、プラグインの間、全ＣＰＵの動作を実質上一時的に停止することになることから、この方法をストップマシンラン法と呼ぶ。
【００２６】
もう１つの方法として、カーネルへのプラグインにおいて、書き換え箇所が実行されることによる処理矛盾が生じなければよいことから、書き換え箇所が実行されないように、書き換え箇所にバイパスを作成する方法を案出した。この方法では、書き換えに係わるＣＰＵ以外のＣＰＵは停止する必要がない。この方法を、バイパス法と呼ぶ。
【００２７】
以下に、本発明の実施例について、図面を参照して詳細に説明する。
【実施例１】
【００２８】
図１は、本発明によるカーネルプラグインを実現する方法を概念的に説明するための図である。図１は、カーネルがメモリに格納された場合のメモリの領域を示すカーネルメモリ領域の一例を示している。本実施例は、ストップマシンラン法と呼ぶ方法を使用した場合である。
【００２９】
カーネルメモリ領域１０は、コード領域１１、データ領域１２、および空き領域１３からなる。空き領域１３にプラグイン対象であるパッチモジュール２２をロードし、カーネルを一時停止し、パッチモジュールへの分岐命令を修正対象関数２１のエントリポイントに上書きすることでパッチモジュールであるプラグをアクティブ化する。プラグのアクティブ化とは、プラグを有効化することを意味し、ＣＰＵがそのプラグを実行し得る状態にあることをいう。プラグの非アクティブ化とは、プラグを無効化することを意味し、ＣＰＵがそのプラグを実行しない状態にあることをいう。
【００３０】
図２は、本発明によるカーネルプラグインを行うための、本実施例のネットワーク装置の一構成例を示すブロック図である。
【００３１】
ネットワーク装置２００は、サーバおよびワークステーション等の情報処理装置である。ネットワーク装置２００は、カーネルが格納された記憶部２１２と、制御部２１０と、操作者が指示を入力するための操作部２１６と、制御部２１０の実行状況を操作者が確認するための表示部２１６とを有する。また、記憶部２１２には、カーネルにロードされる前のプラグが格納されている。プラグにはそれぞれ異なる識別子が付与されている。以下では、この識別子をプラグ番号と称する。
【００３２】
図３は、図２に示した制御部の構成例を示すブロック図である。
【００３３】
制御部２１０は、状態管理部２０１と、ロード機能部２０２と、パッチ機能部２０３と、ファイル化機能部２０４とを有する。ロード機能部２０２、パッチ機能部２０３およびファイル化機能部２０４のそれぞれは状態管理部２０１と接続されている。制御部２１０には、プログラムにしたがって処理を実行するＣＰＵ（不図示）と、プログラムを格納するためのメモリ（不図示）とが設けられている。ここでいうプログラムは、プラグをロードして有効にし、またはプラグをアンロードして元の処理を有効にするための専用スレッドに相当する。ＣＰＵがこのプログラムを実行することで、状態管理部２０１と各機能部が仮想的にネットワーク装置２００内に構成される。制御部２１０に設けられるＣＰＵは単体であってもよく、複数であってもよい。以下に、各機能部の構成を簡単に説明する。
【００３４】
ロード機能部２０２は、操作部２１４を介してロード対象のプラグが指定されると、プラグの正当性とその状態を確認し、対象のプラグをロードする。また、操作部２１４を介してアンロード対象のプラグが指定されると、プラグの正当性とその状態を確認し、対象のプラグをアンロードする。
【００３５】
状態管理部２０１は、各機能部からの依頼にしたがって、プラグの状態遷移に必要な情報であるプラグ情報をカーネルのメモリ空間内に保持してプラグを管理するとともに、プラグ情報を読み書きする。プラグ情報は、プラグ番号、プラグの状態、各種コード、書き換え位置のアドレス、および、書き換えるバイト数などの情報を含む。プラグの状態とは、プラグを実行可能な状態にある「アクティブ」状態か、プラグを実行可能な状態にはない「非アクティブ」状態であるかのいずれかの状態のことである。また、状態管理部２０１は、プラグ情報の読み込みとその書き換え要求があった場合、対象のプラグ情報を検索して取り出し、要求にしたがってプラグ情報を書き換える。
【００３６】
パッチ機能部２０３は、プラグのロードの場合には、新たにロードされたプラグを有効化して変更後の新しい処理に遷移させる。この一連の処理がアクティブ化に相当する。アクティブ化の処理は、プラグ状態の確認、カーネルの動作抑止、処理の書き換え・書き戻しの処理からなる。カーネルの動作抑止とは、新たにプラグを導入するための手順を実行可能にしたまま、その他のカーネルの動作を停止させることである。導入したプラグをアンロードする際には、プラグを無効化するための手順を除くカーネルの動作を停止させることである。そのための方法の一つとして、プラグインに関連する動作を可能にするための専用のスレッドをカーネルに設けてもよい。
【００３７】
処理の書き換えの際、新たにロードされたプラグに処理手順をジャンプさせるために、旧処理コードの上にジャンプコードを上書きする。ジャンプコードは、新たにロードされたプラグの処理にジャンプさせるためのコードである。ジャンプコードは、ＣＰＵによる処理がジャンプコードに達すると、ＣＰＵの処理を新たにロードされたプラグの先頭アドレスにジャンプさせる。書き換え用のジャンプコードを書き込む際、書き戻しの処理を行う場合を考慮して、旧処理コードを状態管理部２０１のプラグ情報に保存する。
【００３８】
また、パッチ機能部２０３は、プラグのアンロードの場合には、プラグを無効化して変更前の処理に戻す。この一連の処理が非アクティブ化に相当する。非アクティブ化の処理は、プラグ状態の確認、カーネルの動作抑止、処理の書き換え・書き戻しの処理からなる。
【００３９】
ファイル化機能部２０４は、プラグ再投入のためのスクリプトを生成して出力する。
【００４０】
以下に、プラグのロードとプラグのアンロードのそれぞれの場合についての動作手順を説明する。はじめに、プラグをロードする場合の動作手順を説明する。
【００４１】
図４はプラグをロードする場合の動作手順を示すフローチャートである。なお、以下では、処理手順を示す「ステップ」の用語を省略して「Ｓ」で表記する。図４から図８についても同様である。
【００４２】
操作者が操作部２１４を介してロード対象のプラグを指定すると、ロード機能部２０２は対象となるプラグのプラグ番号を記憶部２１２から読み出す。そして、プラグが適切な状態にあるか否かを確認するために、読み出したプラグ番号と同じ番号のプラグが既にカーネル内のターゲットにないか状態管理部２０１に問い合わせる（Ｓ３０１）。状態管理部２０１からの回答により（Ｓ３０２）、同じ番号のプラグがターゲット内にあると判断すると、適切な状態になっていないエラーとして処理を中断する（Ｓ３０３）。
【００４３】
ロード機能部２０２は、ロード対象のプラグと同じ番号のプラグがターゲット内になければ、Ｓ３０２でプラグが適切な状態になっていると判断し、ロード対象のプラグを記憶部２１２から読み出してカーネルの空き領域に書き込むロード処理を実行する（Ｓ３０４）。ロード処理が完了すると（Ｓ３０５）、ロードしたプラグのプラグ情報のうち、プラグの状態を「非アクティブ」状態に変更するように状態管理部２０１に指示する（Ｓ３０６）。状態管理部２０１は、ロード機能部２０２からの指示にしたがって、ロードされたプラグの状態を「非アクティブ」状態に書き換える。
【００４４】
続いて、パッチ機能部２０３が、プラグ状態の確認、カーネルの動作抑止、処理の書き換え・書き戻しの処理からなるアクティブ化の処理を、次のようにして行う。プラグ状態の確認では、対象のプラグ番号のプラグの状態が正当であるかどうかを確認する（Ｓ３１１）。プラグのアクティブ化は、プラグの状態が「非アクティブ」状態である場合のみに実行可能であるため、「非アクティブ」状態であるか否かを状態管理部２０１に確認する（Ｓ３１２）。プラグが「非アクティブ」状態であれば、プラグを有効化する（Ｓ３１３）。
【００４５】
なお、図４には示していないが、複数のプラグに対応する場合には、シンボル間の依存関係を次のようにチェックする。アクティブ化時に、プラグ情報内の参照先プラグ番号に対応するプラグの状態をチェックし、非アクティブ状態のプラグがあった場合はエラーとする。複数のプラグのうち１つでも非アクティブ状態のプラグがあると、実行できなくなるからである。
【００４６】
パッチ機能部２０３は、Ｓ３１３でプラグを有効化すると、プラグインに関連する手順を除くカーネルの動作を停止する動作抑止を行う（Ｓ３１５）。カーネルの動作抑止が完了したら（Ｓ３１６）、処理を切り替えるための処理コードの書き換えを行う（Ｓ３２１〜Ｓ３２５）。
【００４７】
具体的に説明すると、カーネル処理を新しい処理に切り替えるための、書き換え用のジャンプコードを状態管理部２０１のプラグ情報より読み出す（Ｓ３２１）。続いて、書き戻し用の旧処理コードをカーネルから読み出して状態管理部２０１のプラグ情報に保存する（Ｓ３２２）。そして、旧処理コードの先頭（関数のパッチの場合は旧関数の先頭アドレス）に、読み出したジャンプコードを上書きする（Ｓ３２３）。その後、プラグの状態を「アクティブ」状態に更新する旨を状態管理部２０１に指示する（Ｓ３２４）。状態管理部２０１は、パッチ機能部２０３からプラグの状態の更新の依頼を受けると、対象となるプラグ情報のプラグの状態を更新する。
【００４８】
なお、書き換えに必要な新コード（ここでは、ジャンプコードに相当する）、旧処理コードの先頭アドレス（書き換えアドレスに相当する）、および旧処理コードの情報はプラグ情報に含まれ、これらの情報を状態管理部２０１に読み出し依頼を行って取得する。
【００４９】
ファイル化機能部２０４は、新たなプラグの処理を有効にするプラグ再投入のためのスクリプトを生成して出力する（Ｓ３２５〜Ｓ３２６）。ここでは、生成対象プラグ情報の取得、スクリプトファイルの出力、シンボリックリンクの作成を行う。スクリプト生成対象となるプラグは、指定されたプラグが「アクティブ」状態である場合に限られる。
【００５０】
ＣＰＵがスクリプトを実行すると、対象プラグの全てがロードされ、アクティブ化され、スクリプト実行時に指定されるプロセス全てに対し、実行され、プラグの投入がアクティブ化順、および生成時の指定順に行われる。
【００５１】
本実施例では、新たにプラグをロードしてそれを有効にするための専用スレッドをカーネルに設けていれば、その専用スレッドのみを実行可能とし、他のスレッドを停止する。これにより、専用スレッド以外の修正部分を含むカーネルが一時停止することになるため、メモリの書き換え中に該当部分が実行されることがない。そのため、メモリ書き換えの処理途中で書き換え箇所が実行されることによる処理矛盾が発生しないようにでき、カーネルに対してもバグ修正のプラグインが実現できる。
【００５２】
次に、プラグをアンロードする場合の動作手順を説明する。図５はプラグをアンロードする場合の手順を示すフローチャートである。
【００５３】
操作者が操作部２１４を介してアンロード対象のプラグを指定すると、パッチ機能部２０３は、対象のプラグを無効化して変更前の処理に戻す非アクティブ化を行う。この処理は、プラグ状態の確認、カーネルの動作抑止、処理の書き換え・書き戻しの処理からなる。
【００５４】
プラグ状態の確認では、対象のプラグ番号のプラグの状態が正当であるかどうかを確認する（Ｓ４０１）。そのため、「アクティブ」状態であるか否かを状態管理部２０１に確認する（Ｓ４０２）。プラグの非アクティブ化は、プラグの状態が「アクティブ」状態である場合のみに実行可能である。
【００５５】
なお、図５には示していないが、複数のプラグに対応する場合には、シンボル間の依存関係を次のようにチェックする。非アクティブ化時に、アクティブ状態となっているプラグを全てチェックし、非アクティブ化対象外のプラグ情報内のシンボル参照先プラグ番号に非アクティブ化対象のプラグが含まれている場合はエラーとする。
【００５６】
パッチ機能部２０３は、プラグの状態が正当であることを状態管理部２０１で確認すると（Ｓ４０２）、カーネルの動作抑止を行う（Ｓ４０３）。カーネルの動作抑止が完了したら（Ｓ４０４）、処理を切り替えるための処理コードの書き換え、書き戻しを次のように行う。
【００５７】
プラグの非アクティブ化時には、カーネルをプラグ導入前に戻すための、書き戻し用の旧処理コードをプラグ情報より読み出す（Ｓ４１１）。旧処理コードの先頭（関数のパッチの場合は旧関数の先頭アドレス）に上書きされたジャンプコードを状態管理部２０１のプラグ情報に保存し（Ｓ４１２）、カーネルのジャンプコードに旧処理コードを上書きする（Ｓ４１３）。そして、プラグ情報内のプラグの状態を「非アクティブ」状態に更新する旨を状態管理部２０１に指示する（Ｓ４１４）。状態管理部２０１は、パッチ機能部２０３からプラグの状態の更新の依頼を受けると、対象となるプラグ情報のプラグの状態を更新する。
【００５８】
なお、プラグのロードの場合と同じように、書き換え、書き戻しに必要な新コード（ジャンプコードに相当する）、旧処理コードの先頭アドレス（書き換えアドレスに相当する）、および旧処理コードの情報はプラグ情報に含まれ、これらの情報を状態管理部２０１に読み出し依頼を行って取得する。
【００５９】
次に、ロード機能部２０２がプラグのアンロードを行うが、アンロード時にはプラグが「非アクティブ」状態になっている必要がある。ロード機能部２０２は、プラグが適切な状態になっているかを確認するために、対象のプラグの状態を状態管理部２０１に問い合わせる（Ｓ４２１）。プラグが「非アクティブ」状態になっていなければ、プラグが適切な状態になっていないエラーとして、処理を中断する（Ｓ４２２）。
【００６０】
Ｓ４２１でプラグが「非アクティブ」状態になっていれば、ロード機能部２０２は、プラグをカーネルから削除するアンロード処理を行い（Ｓ４２４）、アンロード後にはプラグ情報を「アンロード」状態に変更する旨を状態管理部２０１に指示する（Ｓ４２５）。
【００６１】
なお、本実施例では、カーネルからプラグを削除してプラグを実行できないようにしているが、プラグの読み出しをできない状態にするのであれば他の方法であってもよい。例えば、プラグがロードされているメモリ領域を開放すること（どのプログラムからも参照・使用されていない状態にする）、または、実際にメモリ領域を開放しなくても、プラグ機能からは該当プラグ番号に対する管理情報を削除することで、プラグの読み出しができないようにしてもよい。後者の場合、不要な情報がメモリ領域に残存するが、今日のオペレーティングシステムでは長期間使用されないメモリ領域は、メモリ不足時にハードディスクにスワップアウトされるため、実用上の問題は少ない。
【００６２】
上述した方法により、メモリ書き換えの処理途中で書き換え箇所が実行されることによる処理矛盾が発生しないように、カーネルからプラグをアンロードできる。
【００６３】
次に、本実施例の効果を説明する。
【００６４】
効果を確認するために用いた情報処理装置は、ＣＰＵ：Ｘｅｏｎ３．４ＧＨｚ（ＥＭ６４Ｔ）×２、メモリ：１ＧＢ、ＯＳ：Ｒｅｄｈａｔ  Ｅｎｔｅｒｐｒｉｓｅ  Ｌｉｎｕｘ  ＡＳ４（×８６＿６４）、Ｌｉｎｕｘカーネルバージョン：２．６．９−５．ＥＬ（ＳＭＰ有効、カーネルプリエンプション無効）を有している。そして、この装置を使用し、アプリケーションに見立てた１個のプロセスが起動した状態で本実施例の効果を測定した。
【００６５】
プロセスは無限ループによってＣＰＵに１００％の負荷をかけ、ＬＴＰ（Ｌｉｎｕｘ  Ｔｅｓｔ  Ｐｒｏｊｅｃｔ）におけるｇｒｏｗｆｉｌｅｓの負荷をかけた。１００秒間カーネルパッチのアクティブ化／非アクティブ化を連続して繰り返し、ＣＰＵ使用率の低下から、停止時間の平均値と、起こりうる最大値を求めた。
【００６６】
その結果、計測回数：約６０，０００回、停止時間の平均：０．０６２（ｍＳ）、起こりうる最大値：１１７．０（ｍＳ）であった。停止時間は、約１００ｍｓと短いという効果があった。
【実施例２】
【００６７】
本実施例は、バイパス法と呼ぶ方法を使用した場合である。なお、本実施例の方法を実行するための装置の構成については、パッチ機能部２０３を除いて、実施例１と同様であるため、その詳細な説明を省略する。本実施例では、パッチ機能部２０３を中心に説明する。
【００６８】
本実施例のパッチ機能部２０３は、バイパスコードを生成し、処理の書き換えを行う。バイパスコードとは、カーネルにある修正部分の処理の代わりに、新たにロードするプラグを実行させるためのコードである。
【００６９】
はじめに、プラグをロードする場合の動作を説明する。図６はプラグをロードする場合の動作手順を示すフローチャートである。
【００７０】
パッチ機能部２０３は、次のようにして、プラグ状態の確認、処理の書き換えを行う。プラグ状態の確認では、対象のプラグ番号が指定されると、指定されたプラグがプラグの状態が正当であるかどうかを状態管理部２０１に問い合わせて確認する（Ｓ５１１）。プラグのアクティブ化では、プラグが「非アクティブ」状態である場合のみに実行可能である（Ｓ５１２）。
【００７１】
なお、図６には示していないが、複数プラグに対応する場合、シンボル間の依存関係をアクティブ化時には参照先プラグの状態のチェックで行う。すなわち、アクティブ化時の参照先プラグの状態のチェックでは、プラグ情報内の参照先プラグ番号に対応するプラグの状態をチェックし、そのプラグの状態が「非アクティブ」状態であった場合はエラーとする。パッチ機能部２０３は、対象プラグの状態、ならびに参照先および参照元プラグの状態を状態管理部２０１に問い合わせ、状態管理部２０１からこれらの情報を取得し、それを解析することによりプラグの状態を判定する。
【００７２】
Ｓ５１２の後、パッチ機能部２０３は、処理の書き換えを次のようにして行う。プラグのアクティブ化時には、書き戻し用の旧処理コードをカーネルから読み出し、プラグ情報に保存する（Ｓ５１３）。コマンドファイルで指定された長さのバイパスコードを生成してカーネルの空き領域に確保し、バイパスを使用できるようにする（Ｓ５１４）。
【００７３】
具体的には、割り込み命令となるｉｎｔ３命令を、修正部分の命令コードの先頭に上書きし、ｉｎｔ３割り込みハンドラとしてバイパスコードを実施させる。ｉｎｔ３命令はブレークポイントに使用される割り込み命令であり、容量がきわめて小さいサイズの命令であるため、排他制御なしに設定することが可能である。このため、アクティブ化時にカーネル処理を停止することなく、バイパスコードに処理を遷移することが可能である。また、この時点でカーネルは、バイパスコードを介して、新たなプラグ側の修正処理を実施可能である。ここでのｉｎｔ３命令は、バイパスコードの読み出し命令となる。
【００７４】
上述したように、バイパスに該当するプラグとバイパスコードをカーネルの空き領域に書き込み、バイパスコードを介してプラグに手順をジャンプさせるための割り込み命令を修正部分に書き込んでいる。そのため、仮に修正部分が実行されそうになっても、バイパス先のプラグが実行される。
【００７５】
一方、バイパスコードを介して常にプラグ側の処理を実施させる場合、常に割り込みが生じるため、性能が優れない。そのため、最終的にはジャンプコードを旧処理コード上に上書きする。このために、以下の処理を行う。
【００７６】
パッチ機能部２０３は、カーネルの修正対象部分をプラグの処理に切り替えるための、書き換え用のジャンプコードを状態管理部２０１のプラグ情報より読み出す（Ｓ５１５）。旧処理コードの先頭（関数のパッチの場合は旧関数の先頭アドレス）に、読み出したジャンプコードを上書きする（Ｓ５１６）。その際、ｉｎｔ３命令部分の上書きを最後に行うために、ｉｎｔ３命令部分のうしろ側の旧処理コードの部分をジャンプコードに先に書き換え、最後にｉｎｔ３命令部分をジャンプコードに書き換える。その後、プラグ状態を「アクティブ」状態に更新する旨を状態管理部２０１に指示する（Ｓ５１７）。状態管理部２０１は、パッチ機能部２０３からプラグの状態の更新の依頼を受けると、対象となるプラグ情報のプラグの状態を更新する。
【００７７】
なお、書き換え、書き戻しのために必要な新コード（ジャンプコードに相当する）、旧処理コードの先頭アドレス（書き換えアドレスに相当する）、および旧処理コードの情報はプラグ情報に含まれ、これらの情報を状態管理部２０１に読み出し依頼を行って取得する。
【００７８】
本実施例では、カーネル中の修正対象部分が実行されないようにバイパスを設けている。バイパスに該当するプラグをカーネルの空き領域に書き込み、修正部分にはそのプラグに手順をジャンプさせるためのコードを書き込むことで、仮に修正対象部分が実行されそうになっても、バイパス先のプラグが実行される。そのため、カーネルを一時停止しなくてもよい。複数のＣＰＵが設けられている場合には、カーネルの書き換えに使用されているＣＰＵ以外のＣＰＵの動作を止めることなくカーネルにプラグをロードすることができる。
【００７９】
次に、プラグをアンロードする場合の動作を説明する。図７はプラグをアンロードする場合の動作手順を示すフローチャートである。本実施例では、図５に示したＳ４０１〜Ｓ４１４の処理の替わりに図７に示す処理が行われる。
【００８０】
パッチ機能部２０３は、次のようにして、プラグ状態の確認、処理の書き換えを行う。プラグ状態の確認では、対象のプラグ番号が指定されると、指定されたプラグがプラグの状態が正当であるかどうかを状態管理部２０１に問い合わせて確認する（Ｓ６１１）。プラグの非アクティブ化では、プラグが「アクティブ」状態である場合のみに実行可能である（Ｓ６１２）。
【００８１】
なお、図７には示していないが、複数プラグに対応する場合、シンボル間の依存関係をアクティブ化時には参照先プラグの状態のチェックで行う。非アクティブ化時の参照元プラグ存在チェックでは、アクティブ状態となっているプラグを全てチェックし、非アクティブ化対象外のプラグ情報内の、各プラグが参照するシンボルのプラグ番号に非アクティブ化対象のプラグ番号が含まれていた場合はエラーとする。パッチ機能部２０３は、対象プラグの状態、ならびに参照先および参照元プラグの状態を状態管理部２０１に問い合わせ、状態管理部２０１からこれらの情報を取得し、それを解析することによりプラグの状態を判定する。
【００８２】
Ｓ６１２の後、パッチ機能部２０３は、処理の書き換えを次のようにして行う。コマンドファイルで指定された長さのバイパスコードを生成してカーネルの空き領域に確保し、バイパスを使用できるようにする（Ｓ６１４）。具体的には、プラグをロードする場合と同様に、ジャンプコードの先頭にｉｎｔ３命令を上書きする。
【００８３】
Ｓ６１４の後、パッチ機能部２０３は、処理の書き換えを次のようにして行う。カーネルの処理を以前の処理に戻すために、書き戻し用の旧処理コードを状態管理部２０１のプラグ情報より読み出す（Ｓ６１５）。続いて、旧処理コードの先頭（関数のパッチの場合は旧関数の先頭アドレス）に記述されているジャンプコードに、読み出した旧処理コードを上書きする（Ｓ６１６）。その際、プラグをロードする場合と同様に、以下のように行う。Ｓ６１４で説明したように旧処理コードをバイパスコード（既にカーネルに書き込まれたジャンプコードとは異なる）で準備し、カーネル中のジャンプコードの読み出しに処理手順が達すると、ｉｎｔ３命令とバイパスコードで旧処理コードの読み出しにジャンプさせるようにする。その後、カーネル本体の旧処理コードの部分に上書きされていたジャンプコードを、旧処理コードに書き戻す。
【００８４】
その後、パッチ機能部２０３は、プラグ状態を「非アクティブ」状態に更新する旨を状態管理部２０１に指示する（Ｓ６１７）。状態管理部２０１は、パッチ機能部２０３からプラグの状態の更新の依頼を受けると、対象となるプラグ情報のプラグの状態を更新する。
【００８５】
なお、書き換え、書き戻しのために必要な新コード（ジャンプコードに相当する）、旧処理コードの先頭アドレス（書き換えアドレスに相当する）、および旧処理コードの情報はプラグ情報に含まれ、これらの情報を状態管理部２０１に読み出し依頼を行って取得する。
【００８６】
上述した方法によると、カーネルの書き換えに使用されているＣＰＵ以外のＣＰＵの動作を止めることなくカーネルのプラグをアンロードすることができる。
【実施例３】
【００８７】
本実施例は、実施例２の割り込み命令を用いた方法について具体的に説明するものである。本実施例では、プラグをロードする場合で説明する。
【００８８】
図８は、実施例２におけるバイパスコード書き込みおよびジャンプコード書き込み方法を示すフローチャートである。図９は図８の各ステップでのコードイメージを示す図である。
【００８９】
パッチ機能部２０３は、カーネルの空き領域にバイパスコードの領域を確保し、そこにジャンプコードを書き込み、また、カーネルの空き領域にプラグ関数を書き込む（Ｓ７０１）。そして、修正対象関数のエントリポイントの先頭１バイトに、ｉｎｔ３コードを書き込み、処理がバイパスコードを通過するようにする（Ｓ７０２）。この処理は、１バイトの書き換えであることから、他のＣＰＵの動作を停止させることなくアトミックにできる。
【００９０】
続いて、パッチ機能部２０３は、修正対象関数のうちｉｎｔ３コード以外の部分にジャンプコードの先頭１バイトを除いた部分を書き込む（Ｓ７０３）。このとき、書き換え箇所のコードを通過するスレッドはないため、アトミックに行わなくてもよい。その後、ｉｎｔ３コードの位置にジャンプコードの先頭１バイトを書き込む（Ｓ７０４）。このようにして、ジャンプコードの処理をアトミックに有効化することができる。
【００９１】
なお、プラグをアンロードする場合には、ジャンプコードを書き込んだ部分に元の修正対象関数を上書きする。この場合、プラグをロードする際に、修正対象関数を予め記憶部２１２に保存しておく。
【００９２】
本実施例では、１バイトの割り込み命令を書き込むことにより、１バイトの書き換えで処理変更がすむことからアトミックに処理できる。
【００９３】
次に、本実施例の効果を説明する。
【００９４】
ＣＰＵ：Ｘｅｏｎ３．４ＧＨｚ×２、メモリ：１ＧＢ、ＯＳ：Ｒｅｄｈａｔ  Ｅｎｔｅｒｐｒｉｓｅ  Ｌｉｎｕｘ  ＡＳ４（×８６＿６４）、Ｌｉｎｕｘカーネルバージョン：２．６．１４．３＋ｄｊｐｒｏｂｅ（ＳＭＰ有効、カーネルプリエンプション無効）を有する情報処理装置において、アプリケーションに見立てた１個のプロセスが起動した状態で測定を行った。
【００９５】
プロセスは無限ループによってＣＰＵに１００％の負荷をかけ、ＬＴＰ（Ｌｉｎｕｘ  Ｔｅｓｔ  Ｐｒｏｊｅｃｔ）におけるｇｒｏｗｆｉｌｅｓの負荷をかけた。
【００９６】
１００秒間カーネルパッチのアクティブ化／非アクティブ化を連続して繰り返し、ＣＰＵ使用率の低下から、停止時間の平均値と、起こりうる最大値を求めた。
【００９７】
計測回数：約４０，０００回、停止時間の平均：０（ｍＳ）、起こりうる最大値：０（ｍＳ）で、他プロセスを停止することがない効果があった。
【００９８】
なお、本発明のプログラム更新方法をコンピュータに実行させるためのプログラムに適用してもよく、そのプログラムをコンピュータに読み取りが可能な記録媒体に格納してもよい。
【産業上の利用可能性】
【００９９】
本発明は、高信頼性を要求されるネットワークサービスの分野で利用できる。
【図面の簡単な説明】
【０１００】
【図１】本発明によるカーネルプラグインを実現する方法を概念的に説明するための図である。
【図２】実施例１のネットワーク装置の一構成例を示すブロック図である。
【図３】図２に示した制御部の構成例を示すブロック図である。
【図４】実施例１においてプラグをロードする場合の動作手順を示すフローチャートである。
【図５】実施例１においてプラグをアンロードする場合の動作手順を示すフローチャートである。
【図６】実施例２においてプラグをロードする場合の動作手順を示すフローチャートである。
【図７】実施例２においてプラグをアンロードする場合の動作手順を示すフローチャートである。
【図８】バイパスコード書き込みおよびジャンプコード書き込み方法を示すフローチャートである。
【図９】図８に示したフローチャートの各ステップでのコードイメージを示す図である。
【符号の説明】
【０１０１】
２００
２０１    状態管理部
２０２    ロード機能部
２０３    パッチ機能部
２０４    ファイル化機能部
２１０    制御部
２１２    記憶部
【図１】
0004931711.tif 000002
【図２】
0004931711.tif 000003
【図３】
0004931711.tif 000004
【図４】
0004931711.tif 000005
【図５】
0004931711.tif 000006
【図６】
0004931711.tif 000007
【図７】
0004931711.tif 000008
【図８】
0004931711.tif 000009
【図９】
0004931711.tif 000010