(57)【要約】【課題】主記憶が不揮発であるシステムを前提とし、システムが突然の電源切断に直面した場合にも、主記憶，ＣＰＵ，周辺デバイスの状態を、一貫性を維持しつつ復元可能とする。【解決手段】コンピュータ・システムは、カーネル（ＯＳ）２１０、各周辺デバイス１４２〜１４４に対応した、カーネルとデバイスとのインターフェースであるデバイス・ドライバ２２０，２３０，２４０、および、ＯＳ２１０上でユーザ・レベルで実行されるアプリケーション・プログラム２６２，２６４，２６６等の要素により構成されている。デバイス１４２，１４３，１４４との依存関係が発生する要素であるデバイス・ドライバ２２０，２３０，２４０に注目し、個々のデバイスとデバイス・ドライバの間で一貫性を維持することにより、突然の電源切断から復元可能としている。【選択図】図２
2005107573.tif 000002
【特許請求の範囲】
【請求項１】
電源切断時のシステムの実行状態を復元できるコンピュータ・システムであって、
不揮発性メモリである主記憶と、
システム実行中に電源切断を検出して電源切断割り込みを発生する電源切断割り込み手段と、
前記電源切断割り込みにより、ＣＰＵの状態を保存するＣＰＵ状態保存手段と、
周辺デバイスへのアクセスごとにログをとるか、デバイスアクセス前にチェックポインティングを行うデバイスアクセス保存手段と、
デバイスへ発行された要求を保存するデバイス要求保存手段と、
電源が投入され、システムが立ち上がるときに、直前にシステム実行中に電源切断となったことを検出する直前電源切断検出手段と、
直前にシステム実行中に電源切断となったとき、前記デバイスアクセス保存手段およびデバイス要求保存手段により保存された情報により、周辺デバイス状態および該デバイスへのアクセス状態を復帰してＣＰＵが復帰するポイントを決定する復帰手段と、
決定されたＣＰＵの復帰ポイントからシステム実行を再開する実行再開手段と
を備えることを特徴とするコンピュータ・システム。
【請求項２】
周辺デバイスへのアクセスごとにログをとるか、デバイスアクセス前にチェックポインティングを行うデバイスアクセス保存手段と、
デバイスへ発行された要求を保存するデバイス要求保存手段と、
直前にシステム実行中に電源切断となったとき、前記デバイスアクセス保存手段およびデバイス要求保存手段により保存された情報により、周辺デバイス状態および該デバイスへのアクセス状態を復帰してＣＰＵが復帰するポイントを決定する復帰手段と
をコンピュータ・システムに構築させるプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、主記憶に不揮発メモリを用いたコンピュータ・システムの実行状態復元に関するものである。
【背景技術】
【０００２】
突然の電源切断に面した時にも、その実行状態が復元可能なシステムを構築することは、広く一般に普及するコンピュータ・システムの信頼性や利便性を大きく向上させる。さらに現在、「ユビキタス電源」と呼ばれ、様々な形でコンピュータ・システムに対して電力を供給する試みが盛んに行なわれている。これらの電源は基本的に不安定であり、システムへの電力供給は断続的にならざるを得ない。このような環境下で動作するコンピュータ・システムには、電源切断時のシステムの実行状態を即座に回復するような能力が求められる。電源が失われる毎にＯＳやアプリケーションの再起動を必要とするようでは、大きくその利便性を損なう。
システムが突然の電源切断に面した時に、その実行状態を復元するためには、電源切断前のシステム全体の状態が保存されており、システム再起動（リカバリ）時にそれらが復元可能である必要がある。また、復元される状態はシステム全体で一貫性が保証される必要がある。システムの実行状態には、ＣＰＵや主記憶と共に周辺デバイスが保持する状態が含まれる。耐故障性の向上を目的として、fail-stopモデルでの故障に対し、システム状態の復元をするための研究が多く行われている（非特許文献１〜３参照）。しかし、主にＣＰＵと主記憶の状態を対象としており、システムに接続される周辺デバイスの状態についてはあまり考慮がなされてこなかった。例えば、libckpt（非特許文献４参照）では、デバイスについてはオープンしているファイル・ディスクリプタ及びファイル上の注視点 の情報を復元するのみであり、デバイス自体が持つ状態については考慮されていない。
【０００３】
ＡＰＭ（非特許文献５参照）やＡＣＰＩ（非特許文献６参照）などのシステムの電源管理仕様では、周辺デバイスの状態も含めたシステムの実行状態復元(サスペンド／レジュームやハイバネーション)を実現する。これらの実装では、システムの電源状態の遷移要求が通知された際に、周辺デバイスを含めたシステムの状態を保存／復元する。しかし、状態の保存処理は電力が十分に残されている間に行われることを前提とするため、突然電力が失われるような場合や保存処理に必要な電力が十分に残されていないような場合には対応できない。さらに、現在までの技術は、そのほとんどが主記憶の内容は電源切断と共に失われるものとし、主記憶の大部分の状態の保存を必要とした。また、保存先にはディスク等の低速なデバイスが利用されていた。一方、現在主記憶として用いることが可能な不揮発性メモリの実用化がなされてきている。電源切断時に不揮発である主記憶に残る状態と共に、適切なＣＰＵや周辺デバイスの状態が復帰されれば、ほぼ実行時そのままのシステム実行状態を高速に復元可能となる。
【０００４】
【非特許文献１】Elnozahy, M., Alvisi, L., Wang, Y.-M. and Johnson, D.B.: A Survery of Rollback-Recovery Protocols in Message-Passing Systems, Technical Report CMU-CS-99-148, Carnegie Mellon University (1999).
【非特許文献２】Joe, D., Glasco, D. and Flynn, M.: Fault Tolerance: Methods of Rollback Recovery, Technical Report CSL-TR-97-718, Stanford University (1997)
【非特許文献３】Morin, C. and Puaut, I.: A Survey of Recoverable Distributed Shared Memory Systems, IEEE Trans. on Parallel and Distributed Systems, Vol. 8, No. 9, pp. 959〜969 (1997)
【非特許文献４】Plank, J. S., Beck, M. and Kingsley, G.: Libckpt: Transparent Checkpointing under Unix, USENIX Winter 1995 Technical Conference, pp. 213〜223 (1995)
【非特許文献５】Intel and Microsoft: Advanced Power Management BIOS Interface Specification Rev.1.2 (1996) http://www.microsoft.com/hwdev/archive/BUSBIOS/apm 12.asp.
【非特許文献６】Corporation, C. C., Corporation, I., Corporation, M., Ltd., P. T. and Corporation,T.: Advanced Configuration and Power Interface Specification Rev. 2.0a (2002)  http://www.acpi.info
【発明の開示】
【発明が解決しようとする課題】
【０００５】
本発明の目的は、主記憶が不揮発であるシステムを前提とし、システムが突然の電源切断に面した場合にも、主記憶，ＣＰＵ，周辺デバイスの状態を、一貫性を維持しつつ復元可能とすることである。
【課題を解決するための手段】
【０００６】
本発明の目的を達成するために、本発明は、電源切断時のシステムの実行状態を復元できるコンピュータ・システムであって、不揮発性メモリである主記憶と、システム実行中に電源切断を検出して電源切断割り込みを発生する電源切断割り込み手段と、前記電源切断割り込みにより、ＣＰＵの状態を保存するＣＰＵ状態保存手段と、周辺デバイスへのアクセスごとにログをとるか、デバイスアクセス前にチェックポインティングを行うデバイスアクセス保存手段と、デバイスへ発行された要求を保存するデバイス要求保存手段と、電源が投入され、システムが立ち上がるときに、直前にシステム実行中に電源切断となったことを検出する直前電源切断検出手段と、直前にシステム実行中に電源切断となったとき、前記デバイスアクセス保存手段およびデバイス要求保存手段により保存された情報により、周辺デバイス状態および該デバイスへのアクセス状態を復帰してＣＰＵが復帰するポイントを決定する復帰手段と、決定されたＣＰＵの復帰ポイントからシステム実行を再開する実行再開手段とを備えることを特徴とする。
周辺デバイスへのアクセスごとにログをとるか、デバイスアクセス前にチェックポインティングを行うデバイスアクセス保存手段と、デバイスへ発行された要求を保存するデバイス要求保存手段と、直前にシステム実行中に電源切断となったとき、前記デバイスアクセス保存手段およびデバイス要求保存手段により保存された情報により、周辺デバイス状態および該デバイスへのアクセス状態を復帰してＣＰＵが復帰するポイントを決定する復帰手段とをコンピュータ・システムに構築させるプログラムも本発明である。
【発明の効果】
【０００７】
本発明は、基本的にソフトウェア・ベースのアプローチであり、補助的な電源を仮定しない。このため、小型化や軽量化などの要求から、補助的な電源の利用が困難なシステムにも適用可能である。また、不安定な電源環境下で、補助電源に十分な容量の電力が残されていなかった場合など、前述の電源管理仕様を補うことができる。
【発明を実施するための最良の形態】
【０００８】
本発明の実施形態を、図を用いて説明する。
図１に本発明の実施形態のハードウェア構成を、図２にシステムのソフトウェア構成を示す。本発明では、図１に示すように、主記憶１２０が不揮発性メモリで構成されたシステムを対象とする。現在、ＭＲＡＭやＦｅＲＡＭなど、主記憶に用いられるメモリと同様の方法で読込／書込アクセスが可能な不揮発性メモリが実用化されている。これらは速度や容量の面においても、現状の主記憶の代替として十分な能力を持つことができる。
また、電源切断時のＣＰＵ１１０の状態は復帰可能とする。電源１５２を監視する電源監視ＩＣ１５６を用い、システムに供給される電源１５２が一定値以下になった場合にＣＰＵ１１０に対して、割込線１５８により割り込みをかける。この割り込みにより、割り込み処理（図２の割り込みハンドラ２１２）で特定の領域にＣＰＵ１１０の状態を保存する。必要であれば、キャパシタ等によってＣＰＵの状態を保存する処理時間分、電源の減衰を鈍らせることも可能である。この保存されたＣＰＵの状態は、リカバリ時にブート・リカバリ処理２１４によって利用される。
周辺デバイス１４２〜１４４には、以下のような前提を設ける。デバイスが動作していない時の状態（アイドル状態）は、再初期化および必要な情報の設定を行えば復元可能とする。また、電源切断前のデバイスの状態を復元し、同じデバイスへのアクセス（コマンド）を再実行すれば、デバイスは停止前と同一の動作をするものとする。そして、システム上の各デバイスはそれぞれ独立に動作するものとする。デバイスが電源切断によって損傷する場合は考えない。
【０００９】
＜システムモデル＞
本発明の実施形態のソフトウェアのシステム構成を図２に示す。図２に示されるように、カーネル（ＯＳ）２１０、各周辺デバイス１４２〜１４４に対応した、カーネルとデバイスとのインターフェースであるデバイス・ドライバ２２０，２３０，２４０、ＯＳ２１０上でユーザ・レベルで実行される、アプリケーション・プログラム２６２，２６４，２６６等の要素により構成されている。
このような複数の要素で構成されるシステムにおいて、各要素間に依存関係が発生しなければ、各要素が独立に状態を復元し、システム全体の一貫性を維持することが可能である。
このシステムでは、主記憶１２０は不揮発性であり、状態を復元する必要はない。また、ＣＰＵ１１０の状態も上述したように復元できる。
よって、まず、デバイス１４２〜１４４との依存関係が発生する要素であるデバイス・ドライバ２２０，２３０，２４０に注目する。そして、個々のデバイスとデバイス・ドライバの間で一貫性を維持するリカバリ手法を確立する。その手法をシステムに接続される各デバイス・ドライバにそれぞれ適用することによって、システム全体の状態を回復することができる。
本発明の実施形態では、デバイス・ドライバにコードを追加し、デバイス・ドライバやデバイスの情報を保存／復元する。追加されるコードでは、デバイス・ドライバとデバイスの間で一貫性を維持するように、必要となる情報を保存する。
【００１０】
＜モデルの説明＞
本実施形態を、メッセージパッシング・システムのモデルを用いて説明する。メッセージパッシング・システムのモデルでは、図３に示すようにシステムを成するプロセスの実行を横矢印で表し、それらの間で取り交わされるメッセージを斜めの矢印で表す。各プロセスは通常実行中、その実行状態を保存する。この時点は「チェックポイント」と呼ばれる。また、あるプロセスが故障により停止した後、リカバリ作業によって各プロセスが復元されるポイントを「リカバリポイント」と呼ぶ。リカバリポイントは各プロセスのチェックポイントから選ばれる。また、各リカバリポイントを結んだ線を「リカバリライン」と呼ぶ。このリカバリラインがメッセージを横切る場合に、回復後のシステム状態の一貫性が維持できない場合があることが知られている。
説明する実施形態では、デバイスを、システムを構成する１プロセスとみなす。なぜなら、メッセージパッシング・システムにおける各プロセスと同じく、通常各デバイスはＣＰＵと並列に実行するためである。同様に、デバイス・ドライバの実行を１プロセスとみなし、また、デバイス・ドライバ内の割り込み処理についても非同期に起動されるため、単独のプロセスとみなす。そして、割り込みを含むデバイスとのやり取り（アクセス）をメッセージとみなす。デバイスとのやりとりによって、デバイス・ドライバとデバイスが保持する状態に依存関係が発生することも、メッセージパッシング・システムでのモデルに類似するためである。
このようにモデル化したとき、システムの一貫性を保つためには、各アクセスを横切らないリカバリラインを発見すればよいこととなる。
このことから、まずデバイス状態の復元可能なポイント、つまりデバイスのアイドル状態を基準として、適切なリカバリラインを発見する。そして、デバイス・ドライバやその割り込み処理について、電源切断時点の状態を利用することができない場合には、デバイス・ドライバの状態を保存するようにし、リカバリポイントを作り出す。この方針を基にして、デバイスとデバイス・ドライバ間で整合性を維持するための要件を抽出する。
【００１１】
＜解析＞
図３と同様な図を用いて、要件を抽出するために、デバイス・ドライバの動きを解析する。
（デバイスへの要求発行）
図４に、モデル化したデバイス・ハンドリング時の様子を示す。横の矢印は時間の経過と各要素の実行状態を表し、線が細い部分はその要素が実行されていないことを表す。これは、デバイスについてはアイドル状態を意味する。縦の矢印はデバイスへのアクセスを表す。読み込み及び書き込みのアクセスが混在する場合が多いため、上下両方を指す矢印として示してある。
図４のＰ１において、デバイス・ドライバはデバイスへの要求を発行し始める。デバイスが持つレジスタの設定や読み込みを複数回行った後、Ｐ２においてその要求の発行が終了する。そして、デバイスは要求に対応する実行を開始する。
Ｐ１以前にシステムの電源切断が生じた場合、デバイスはアイドル状態である。よって、図４のリカバリラインはＬ１のようになり、電源切断の時の状態がそのまま復元可能である。
【００１２】
図４において、Ｐ１とＰ２の間で電源切断が生じた場合、復元可能なデバイスの状態はＰ１での状態である。そのままデバイス・ドライバの電源切断時の状態を復元したとすれば、この時のリカバリラインはＬ２で示される点線となる。
この場合、Ｐ１から電源切断までのアクセスに依存するデバイスの状態は失われ、デバイスは要求を正確に実行できなくなる。これは、図３においてリカバリラインＬがメッセージを横切るとき、リカバリ後のシステム状態の一貫性が維持できない、ということに対応する。
この解決には２通りの方法が考えられる。一つは、Ｐ１でのＣＰＵ，主記憶，デバイスの状態を復元し、実行を再びＰ１から開始する方法である。これは、リカバリラインをＰ１での垂直線にすることである。もう一つは、実行中に各アクセスのログを保存し、Ｐ１でのデバイス状態を復元した後に、Ｐ１から電源切断までのログを用いてアクセスをもう一度行う方法である。それぞれ、メッセージパッシング・システムでのチェックポインティング手法、ロギング手法に相当し、デバイス・ドライバの製作者がＰ１からＰ２に行われる処理内容に応じて選択すれば良い。
【００１３】
Ｐ２以降、デバイスが動作を開始した後に電源切断が生じた場合には、リカバリラインはＬ３のようにすれば良い。Ｐ１におけるデバイスの状態を復元し、Ｐ１からＰ２に行われるデバイスへのアクセスを再度実行できれば、Ｐ２でのデバイスの状態を復元可能である。よって、Ｐ１からＰ２間のアクセスを「デバイスへの要求」として保存し、リカバリ時に再実行することにより、Ｐ２でのデバイス状態を復元するようにする。このとき、デバイス・ドライバはデバイスとは無関係に動作するので、Ｐ２以降電源切断が生じた場合には、ＣＰＵや主記憶の状態は電源切断時の状態をそのまま使用し、システムを復帰すればよい。
【００１４】
（割り込み処理）
非同期に動作するデバイスの動作の完了は、通常割り込みを用いて行われる。また、マウスやキーボードなど、デバイス側から発生するイベントも同様に割り込みを用いてＣＰＵに通知される。それぞれの場合をモデル化した図を、図５及び図６に示す。各図中
において、割り込みは周辺デバイスから生じる太い上向きの矢印で表されている。
図５は、Ｐ１からＰ２にかけて発行された要求の完了通知（割り込み）がＰ３において発生した場合である。割り込みに応じて、対応するデバイス・ドライバの割り込みサービス処理（ＩＳＲ：Interrupt Service Routine）が、カーネルの割り込みハンドラ２１２（図２参照）より呼び出される。ＩＳＲの処理では、デバイスの制御やデバイスからのデータの取得などのためのアクセスが発生する（以降、このような処理を「要求の後処理」と呼ぶ）。
Ｐ３からＰ４において、デバイスからデータを取得するための処理が行われるとすると、Ｐ４にてこの処理が完了する以前に電源切断が生じた場合、デバイスから取得されるデータは不完全なものとなる。このため、システムの再起動時Ｐ１からＰ２で発行される要求を再度実行し、デバイスが同じデータを保持するようにする必要がある。これは、前述したように、保存された「デバイスへの要求」をリカバリ時に再実行することにより行われる。ここからＬ１に示すリカバリラインが導き出される。このため、ＩＳＲでは電源切断までに行われた処理を無効化し、状態を割り込み発生以前（Ｐ３以前）のものにする必要がある。つまり、ＩＳＲではＰ３での状態を保存しておき、リカバリ時に復元する必要がある。
Ｐ４以降ＩＳＲ内においてデバイスアクセスが終了した後には、処理はＣＰＵと主記憶の間で完結するため、電源切断時点からシステムを再実行させることが可能となる。このためリカバリラインはＬ２のようになる。このときもはやデバイスの状態をＰ２に戻す必要はなくなるので、保存された「デバイスへの要求」はＰ４の時点で破棄可能となる。
【００１５】
図６は、Ｐ１においてキーボードの入力やパケットの到着などのイベントが発生し、Ｐ２においてＣＰＵに対して割り込みが発生した場合である。Ｐ１とＰ２は等しくても構わない。
Ｐ２とＰ３の間で電源切断が生じた場合、デバイスが保持するデータはまだ取得されていない。また、デバイスの状態は失われＰ１時点のものしか復元できない。この時のリカバリラインはＬ１となり、前述の議論と同様にＩＳＲの状態はＰ２以前に戻す必要がある。
Ｐ１以降のデバイスの状態を回復するための情報は、ＣＰＵ側からは取得および保存する術がないため、この時生じた割り込みはシステムのリカバリ後完全に失われることとなる。しかし、このようなイベントは、もともと生じるかどうか不確定であるため、無視できる場合が多い。キーボードやマウスの入力がこれにあたる。
【００１６】
（共有領域のアクセス）
前述では、ＩＳＲの状態はロールバックされる必要がある場合があることについて述べた。ロールバックされる要素が存在する場合、その要素に依存して他の要素もロールバックしなければならない可能性について考慮しなければならない。
図７は、ＩＳＲがロールバックされる時において、この状況が発生する場合である。ＩＳＲ内でデバイスへのアクセスが終了する（Ｐ５）以前に、Ｐ３においてＩＳＲが共有領域にある共有データに対して書き込みを行い、かつＰ４においてデバイス・ドライバがそのデータの読み込みを行ったとする。この時、ＩＳＲとデバイス・ドライバの状態に依存関係が発生する。そして、Ｐ４とＰ５の間で電源切断が生じた場合、ＩＳＲの状態はＰ２にロールバックされるため、デバイス・ドライバの状態もＰ４以前に戻さなければならなくなる。
問題の解決には、ＩＳＲがロールバックされる範囲内でＩＳＲとデバイス・ドライバの間に依存関係が発生しないようにすれば良い。このことから、一つの解決策は、ＩＳＲから共有領域への書き込みアクセスはデバイスへのアクセスが終了した後に行うように、ＩＳＲをプログラムすることである。それが困難な場合、ＩＳＲが共有領域に関連する同期プリミティブのロックを、デバイスのアクセスが終了するまで保持し続けるようにしても良い。これによって、デバイス・ドライバからの共有領域への書込アクセスをＰ５以降まで行われないようにすれば良い。なお、ＩＳＲとデバイス・ドライバが並行もしくは並列に実行されないことが自明の場合、これらの対応は必要ない。
【００１７】
＜解析のまとめ＞
上述した解析をまとめると以下のようになる。
（１）デバイスへのアクセスは、各アクセス毎にログをとるか、デバイスアクセス前にチェックポインティングを行う。
（２）デバイスへ発行される要求を保存する。
（３）保存されたデバイスへの要求は、対応する割り込みが生じ、その要求の後処理が終了した時点で破棄可能となる。
（４）ＩＳＲ内で要求の後処理等のためのデバイスアクセスが完了する前に電源切断が生じた場合、その状態は割り込み発生以前にロールバックさせる。
（５）ＩＳＲ内で他の要素との共有領域へ書込アクセスを行う場合、デバイスアクセス終了後に行うようにするか、ＩＳＲがデバイスアクセス終了後までロックを保持し続けるようにする。
【００１８】
＜デバイス・ドライバへの適用＞
ここでは、表１に示す擬似コード例を用い、前述の事項のデバイス・ドライバへの適用方法について述べる。なお、表１中、read，write，ioctlの各メソッドの役割は、ＰＯＳＩＸで規定される同名のＡＰＩの機能と同一である。また、interruptメソッドは割り込み発生時に実行されるＩＳＲである。
【００１９】
［表１］
1            void write(void* request){
2                 if(idle == get_device_state()){
3                     DEV_ACCESS_START();
4                     tell_device_request(request);
5                     DEV_REQUEST_SAVE(request_log,request);
6                     DEV_ACCESS_END();
7                 }else{
8                     lock(request_queue);
9                     enqueue(request_queue,request);
10                     request_count++;
11                    unlock(request_queue);
12                 }
13             }
14             void read(void* return_buf){
15                 lock(event_buf);
16                while(event_buf_count){
17                     unlock(event_buf);
18                     sleep(read_wait);
19                     lock(event_buf);
20                }
21                memcpy(return_buf,event_buf);
22                 event_buf_count--;
23                 unlock(event_buf);
24             }
25             void ioctl(void* new_state){
26                 dev_state = *new_state;
27                 device_state_change(new_state);
28             }
29             void interrupt(){
30                 do{
31                 if(request_done & interrupt_reason()){
32                     ISR_STATE_SAVE();
33                    post_processing_for_request();
34                    ISR_STATE_DISCARD();
35                    DEV_REQUEST_DISCARD(request_log);
36                     lock(request_queue);
37                     if(request_count){
38                         request = dequeue(request_queue);
39                         DEV_ACCESS_START();
40                         tell_device_request(request);
41                         request_count--;
42                         DEV_REQUEST_SAVE(request_log,request);
43                         DEV_ACCESS_END();
44                     }
45                     unlock(request_queue);
46 }
47                if(event_arose & interrupt_reason()){
48                     ISR_STATE_SAVE();
49                     lock(event_buf);
50                     data = get(event_buf);
51                     post_processing_for_event(&data);
52                     event_buf_count++;
53                     ISR_SATE_DISCARD();
54                     unlock(event_buf);
55                     if(someone_is(read_wait))
56                        wakeup(read_wait);
57                }
58                 }while(interrupt_reason());
59             }
【００２０】
上述の擬似コード例において、各デバイスアクセスに関する関数の役割については、表２のデバイスアクセスに関する関数を参照されたい。
【表２】
2005107573.tif 000003
また、状態復帰に関する処理および状態復帰に関連する変数は、表３の状態復帰に関する処理，表４の状態復帰に関連する変数を参照されたい。
【表３】
2005107573.tif 000004
【表４】
2005107573.tif 000005
【００２１】
（アイドル状態の復帰）
まず、アイドル時のデバイスの状態を復元できるようにしなければならない。これは基本的にはデバイスの初期化作業を行えば良い。しかし、ioctlシステムコールのように、明示的なデバイスの動作要求とは別に、デバイスの状態を変化させる場合がある。例えばＵＡＲＴデバイスのボーレート設定などが該当する。
これらの設定を復元するため、デバイスの状態を変更する際に、変更後のデバイスの状態をリカバリ時に参照可能な領域へ保存しておく必要がある（表１中２６行）。リカバリ時には、この情報を参照し、デバイスの状態の初期化と再設定を行うようにする。なお、要求の実行などがデバイスのアイドル状態に影響する場合も、同様にリカバリ時に参照可能な領域へその情報を保存し対応する。
【００２２】
（デバイスアクセス）
デバイスへの要求を発行するためのアクセスは、チェックポインティング手法もしくはロギング手法によって対応することを述べた。
チェックポインティング手法の場合には、デバイスへのアクセス開始時にデバイス・ドライバの主記憶状態，ＣＰＵ状態の保存を行う。そして、アクセスが終了した時点でそれらの情報を破棄する。リカバリ時には、これらの情報が存在するかどうかを調べる。存在する場合には、保存された主記憶状態の復元を行った後、この時のＣＰＵ状態を用いてシステムの実行を再開すればよい。
このとき、主記憶状態の保存については、デバイス・ドライバ内全ての領域を保存する必要はない。デバイスアクセス開始時の状態が復元できれば良いため、デバイスアクセスが終了するまでに変更され、かつ復元が必要となる主記憶の状態を保存すれば良い。
ロギング手法を用いる場合には、各デバイスアクセス毎に、どのようなアクセスが行われるかを示すログをとる。そしてデバイスアクセスが終了した時点でこれらのログを破棄する。リカバリ時には、ログの存在を確認し、存在する場合には、それらのログを実行する。そして、電源切断時のＣＰＵ状態を用いてシステムの実行を再開すれば良い。
表１中DEV_ACCESS_START およびDEV_ACCESS_END（３，６，３９，４３行）は、それぞれ、デバイスへのアクセスの開始とデバイスへのアクセスの終了に対応する。ロギング手法ではDEV_ACCESS_STARTにおいて何も行う必要はなく、tell_device_request関数内でログをとるための変更を加える。
【００２３】
（デバイスへの要求の保存）
デバイスへの要求は、デバイスへのアクセスが終了した後、アクセスを復元するための情報の破棄(DEV_ACCESS_END) が行われる前に、保存する必要がある。アクセスの情報を破棄した後、要求を保存したとする。これらの処理の間で電源切断が生じたとすると、アクセスを再実行するための情報は失われ、かつデバイスへの要求もまだ保存されていないこととなる。このため、デバイスの実行状態を復元できなくなってしまう。
また、前述したように、この情報が破棄されるのはＩＳＲ内となる。破棄作業の注意点については、次で説明する。
前に、デバイス・ドライバのコンテキスト内で要求が発行される場合を述べたが、デバイスへの要求はＩＳＲの中でも発行される場合がある。デバイスがビジー状態の時に新たなデバイスへの要求が発行された場合、デバイス・ドライバのコンテキストではその要求をキューイングすることがある。キューイングされた要求は、実行中の要求が終了したとき、ＩＳＲの中でデバイスに発行される。しかし、ＩＳＲ内で実行されたとしても、ロールバックされる範囲でなければ、まえに述べた議論と同一となる。つまり、通常実行時と同じ対応をＩＳＲ内で行えば良い。このことは表１中、７〜１１行および３６〜４４行に対応する。表１中、要求のログをとる処理に対応するのがDEV_REQUEST_SAVE（５，４２行） である。また、ログの破棄に対応するのはDEV_REQUEST_DISCARD（３５行）である。
【００２４】
（ＩＳＲのロールバック）
ＩＳＲの中で要求の後処理等のためのデバイスアクセスが終了する以前に電源切断が生じた場合、ＩＳＲ の状態をロールバックしなければならない。このため、ＩＳＲ の実行が開始する時に、ＩＳＲの主記憶状態を保存する必要がある。そして、デバイスへのアクセスが終了した時点で、破棄可能となる。
表１中、ＩＳＲの状態保存を行う処理に対応するのがISR_SATE_SAVE（３２行，４８行）、保存された情報を破棄する処理がISR_STATE_DISCARD（３４行，５３行）である。
これらの処理は、デバイスアクセスをチェックポインティング手法で復元させる場合の対応と類似するが、復帰後ＩＳＲを再実行する必要はないため、ＣＰＵの状態を保存する必要はない。リカバリ時には、カーネルが割り込み受け付けた時に保存したＣＰＵ状態(割り込み時に実行されていたコンテキスト) を用いてシステムを再開させれば良い。
再実行が必要な「デバイスへの要求」について、ＩＳＲがロールバックされる時に失われないようにする必要がある。このため、ＩＳＲの情報が破棄された後、この情報の破棄を行うようにする（３５行）、もしくは、ＩＳＲの状態がロールバックされた時に、破棄された要求も復元するようにする必要がある。
【００２５】
ＩＳＲは複数の要因で起動されることが多い。例えば、ネットワークに対する送信終了割り込みと受信割り込みは同一のＩＳＲで処理されることがある。この場合、ＩＳＲでは、割り込み要因の特定を行い対応する割り込みを処理する。また、ＩＳＲ実行中に割り込みが発生する場合がある。このため、ＩＳＲの処理は割り込み要因が無くなるまでループする場合がある。
ＩＳＲがロールバックされる範囲はそれぞれの割り込み要因の特定がなされてからのものとする必要がある。例えば、要求の終了とイベントによる割り込みが同時に発生したとする。このとき表１に示す擬似コードでは、ＩＳＲが起動され、要求に対応する処理終了に続いて、イベントの処理が行われることになる。要求に対応する処理が終り、５０行目の処理中に電源切断が生じたとすれば、この場合ロールバックされなければならない内容はイベント処理に関するもののみである。要求に対応する処理までロールバックする必要はない。よって、ISR_STATE_SAVEとISR_STATE_DISCARDは表１の擬似コードのようにそれぞれ別々に挿入される（３２と３４行目及び４８と５３行目）。
また、ＩＳＲ内で割り込み要因を特定する時に、「現在の状態」を確認する必要がある。同上の例において、３８行目で電源切断が生じたとする。リカバリ後３９行目以降の処理が継続されるが、デバイスの状態は失われているため電源切断前のイベントの処理を続けて行うことはできない。このため、復帰後には３１、４７行目や５８行目でその時点の割り込み要因の特定がなされるようにする必要がある。
４９行目と５４行目のロックの操作は前に述べた「共有領域へのアクセス」の説明に対応するものである。５１行目でreadメソッドとの共有領域であるevent_bufをアクセスする。このため、４９行目で取得したロックは５４行目まで保持される。ただし、ＩＳＲとデバイス・ドライバのコンテキストが同時に実行しないことが解っている場合には、これらの操作は必要ない。
【００２６】
＜リカバリ＞
デバイス状態の復帰は、コールバック関数により行われる。コールバック関数の例を表５に示す。
［表５］コールバック関数の例（模擬コード）
1            int recovery_call_back(CPU_t **cpu_state){
2                 initialize_device(dev_state);
3                 recover_memory_area();
4                 replay_request();
5                 return flag;
6             }
表５の関数は、システム全体のリカバリ処理時にカーネル内のブート・リカバリ処理２１４（図２）から呼び出される。これまでの説明からわかるように、この関数では主に、デバイスの再初期化、主記憶状態の復元、デバイスへの要求の再実行を行うことになる。まず、前に述べたように、デバイスの再初期化は、通常実行中保存された情報を元に、アイドル時のデバイス状態を復元する（２行）。次に、DEV_ACCESS_START(チェックポインティング手法の場合) 、ISR_STATE_SAVEで保存された主記憶状態が存在する場合には、それぞれを復元する（３行）。そして、再実行すべきデバイスアクセスのログ（ロギング手法の場合）や再実行すべきデバイスへの要求が存在する場合にはこれらを実行する（４行）。また、リカバリ時にはISR_STATE_SAVEで保存された情報の破棄を行う必要があり、これは、ＩＳＲの状態を復元した後に行えば良い。DEV_ACCESS_STARTでの主記憶状態やログについては、リカバリ後の通常動作によって破棄されるため、この関数内では何も行う必要はない。
前に述べたように、ロールバックが必要となる範囲で電源切断が生じた場合、システムを再開させるためのＣＰＵ状態をカーネルが把握する必要がある。このため、このメソッドは例えば表５に示すように、ＣＰＵ状態構造体へのポインタを参照受け渡しするようにし、DEV_ACCESS_STARTで保存されたＣＰＵ状態をカーネルに返せるようにする。また、ＩＳＲ内で電源切断が生じた場合には、割り込み発生時に保存されたＣＰＵ状態を用いる必要があるので、このことを示せるように、返戻値として値を返す等を行う。これらの各デバイス・ドライバのコールバック関数から返される情報を元に、カーネルのブート・リカバリ処理はシステムの再実行に用いるＣＰＵの状態を決定し、システムを復帰する。
【００２７】
＜電源切断およびリカバリ処理のまとめ＞
上述の電源切断とリカバリのときのカーネルにおける処理をまとめると、以下の通りである。
（電源切断の処理）
１．電源切断が起こると、電源監視ＩＣ１５６等によってＣＰＵ１１０に割り込みが通知される。
２．カーネルの割り込みハンドラ２１２が、ＣＰＵ１１０の状態をある特定の主記憶領域に保存する。
３．システム停止
（リカバリの処理）
１．システムに電源が投入される。
２．カーネルのブート・リカバリ処理２１４によって、直前にシステム実行中電源切断が生じたことを判断し、リカバリ・モードに入る。
３．リカバリ処理によって、各デバイス・ドライバ２２０，２３０，２４０のコールバック関数２２２，２３２，２４２が呼び出される。
４．各デバイス・ドライバのコールバック関数２２２，２３２，２４２は、各対応するデバイスの状態及びデバイス・ドライバの状態を復帰する（表５の擬似サンプルコード中recovery 関数）。
５．各コールバック関数から返される情報を元に、ブート・リカバリ処理２１４はＣＰＵが復帰するポイントを決定する。
６．決定されたポイントにおけるＣＰＵの状態を復帰し、システムの実行を再開する。
なお、これまでの説明は基本的な場合について述べたものである。例えば、要求の再実行が必要ないようなデバイスでは、リカバリ時に要求を再実行しなくとも良い。また、デバイスへの要求自体を保存しなくてもかまわない。これまでの議論をもとに、対象となるデバイスの特徴に応じてこれまで述べた方法を応用し、実際のデバイス・ドライバに適用すればよい。
【実施例】
【００２８】
本発明の手法をlinux 2.4.4 カーネルを用いて実施した。ＣＰＵはモトローラ社のＭＰＣ８６０（４０ＭＨｚ動作)を用いた。またＦｅＲＡＭを用いた不揮発ＲＡＭ ボードを作成し、これを主記憶として用いた。デバイスとしては、オンチップ上に存在するＵＡＲＴ及びEthernet（１０Ｍｂｐｓ）コントローラを用いた。まず、上述の手法を実装したシステムにおいて、実行状態の復元が可能であるかどうかを調べた。システム上でＵＡＲＴデバイスに対して出力を続けるプロセスを実行し、電源を切断した。そして電源を再度入れシステムを再起動した際に、走行していたプロセスの実行が復元され、再びＵＡＲＴデバイスに出力を開始することを確認した。
次に、提案手法が適切に動作しているかどうかを調べた。ＵＡＲＴデバイスから電源切断直前の文字が出力される場合があることを確認した。これは、ＵＡＲＴデバイスに対して、要求の再実行が適切に行われた結果だと考えることができる。また、デバイスアクセスの復元やＩＳＲの状態復元が適切に動作しているかを調べるため、システム上の最も高いレベルの割り込みにプッシュボタンを取りつけ、この割り込みを仮想的な電源切断として、この時のＣＰＵ状態を保存するようにした。そして、システムの実行中にこの割り込みを発生させた。割り込み発生時のアドレスを確認し、一度システムの電源を切断した後、再度システムの電源を投入してシステムを再起動させた。ＵＡＲＴデバイス、Ethernetデバイス両方について、デバイスアクセス中及びＩＳＲ処理中に割り込みが発生した場合でも、電源切断時に実行中だった処理が継続することを確認した。この事により、デバイスへのアクセスの復帰や、ＩＳＲの状態復元処理が適切に行なわれていると考えることができる。
そして、実装したシステム上での提案手法によるオーバヘッドの測定をおこなった。提案手法を用いない場合(通常実行)、提案手法においてデバイスのアクセスに対しチェックポインティング手法を用いた場合、同じくロギング手法を用いた場合について２つのタスクを実行した。タスクＡは、ＵＡＲＴデバイスに対し１文字を出力する動作を10000回繰り返すプロセスを実行し、time コマンドによってその実行時間を測定した。ＵＡＲＴのボーレート設定は９６００ｂｐｓ  である。タスクＢはリモートのマシンに対し２ＭｂｙｔｅのＮＦＳ上ファイルをcp コマンドによりコピーした。コピー先も同様にＮＦＳ上とした。それぞれの結果を図８に示す。
通常実行に対し、チェックポインティング手法、ロギング手法いずれを用いた場合にも、実行時間の増加がほとんどないことがわかる。
【図面の簡単な説明】
【００２９】
【図１】実施形態のハードウェアの構成例を示す図である。
【図２】実施形態のソフトウェアの構成例を示す図である。
【図３】メッセージパッシング・システムでのモデルとリカバリラインを説明する図である。
【図４】基本的なデバイスへの要求発行処理を示す図である。
【図５】要求に対応する割り込み処理を示す図である。
【図６】外部イベントに対する割り込み処理を示す図である。
【図７】共有領域のアクセスを含む処理を示す図である。
【図８】各実装手法による実行時間を比較するための図である。
【図１】
2005107573.tif 000006
【図２】
2005107573.tif 000007
【図３】
2005107573.tif 000008
【図４】
2005107573.tif 000009
【図５】
2005107573.tif 000010
【図６】
2005107573.tif 000011
【図７】
2005107573.tif 000012
【図８】
2005107573.tif 000013