4月8日の午後7時11分,東京航空交通管制部のRDP(航空路レーダー情報処理)のメイン・システムがダウンした。原因は,レーダー画面上で航空機を非表示にするプログラムのバグ。実行判定ロジックにミスがあり,実行されてはならない条件で動いて,不正なデータを書き込んだ。

 RDPシステムは,レーダー画面に航空機の「便名」や「高度情報」などを表示する。国内の管制エリアは16個の「セクター」に分けてあり,管制官は担当セクターのレーダー画面に表示された航空機を受け持つ。

図1●RDPシステムのトラブルはプログラム・ミスが原因
4月8日の午後7時11分,東京航空交通管制部のRDP(航空路レーダー情報処理)のメイン・システムがダウンに追い込まれた。「非表示プログラム」にコーディング・ミスがあり,本来は実行されてはいけないタイミングで動いた。その結果,「不正なデータ」がテーブルに書き戻され,そのデータにアクセスした別のアプリケーションが異常終了。自動的にリカバリに入ったが,異常終了と再起動を繰り返したため,サブ・システムへの切り替えを余儀なくされた
図2●ワークエリアの「不正なデータ」を書き戻す
本来,レーダー画面の初期化中はいかなるコマンドも受け付けてはならない。ところが,このタイミングで呼び出された「非表示プログラム」には,初期化中か否かを判定するロジックに不備があった。意図せずに実行されたこのプログラムは,ワークエリアに存在した「不正なデータ」をテーブル領域に書き戻した。その後,このデータにアクセスしたアプリケーション(アプリ-B)が異常終了した
表1●メインとサブ・システムの機能の違い

 問題が発生したのは4月8日の午後7時,レーダー画面を分割する命令を入力したタイミングである。それまで,隣接する「播磨」「山陽」の2つのセクターは「播磨&山陽セクター」として,一つのレーダー画面にまとめて表示していた。このセクターを通過する航空機の数が増えてきたので,「播磨セクター」と「山陽セクター」に分割しようとした(図1[拡大表示]の左)。

 分割の指示を受けたレーダー画面では,初期化処理が実行される。通常,処理にかかる時間は約2秒である。今回,この処理中に「山陽セクター」の管制官が,そのレーダー画面では取り扱わない航空機を非表示にする命令を入力した。ここで呼び出された「非表示プログラム」にバグがあり,障害を引き起こした。このCOBOLプログラムはNTTデータが開発。「1997年に性能向上を図った際に,バグが紛れ込んだと思われる」(国土交通省 航空局 管制保安部 保安企画課 管制情報処理システム室 調査官 北村智氏)。

不正なデータを書き戻す

 RDPシステムの仕様では,レーダー画面の初期化中にはいかなるコマンドも受け付けない。ところが「非表示プログラム」の実行判定ロジックに記述ミスがあった。“初期化中”の場合,本来は処理を中止すべきところを,「ワークエリア」にあったデータを「テーブル」に書き戻す処理を実行した。

 ワークエリアとテーブルは,NEC ACOS内のメモリー領域を指す(図2[拡大表示])。RDPシステムは,FDP(飛行計画情報処理)システムから受け取った「飛行計画情報」データをハードディスクに格納した後に,メモリー内のテーブルに展開する。このデータを操作するには,テーブルからワークエリアに読み込む必要がある。

 今回,非表示プログラムは,「飛行機の位置を照会するアプリケーション」(図2のアプリ-A)がワークエリアに読み込んだデータを,勝手にテーブルへ書き戻した。このアプリケーションは,飛行計画とレーダーの情報を照合する機能を持つ。頻繁に実行されるため,「高速に処理する必要性から,ワークエリアに読み込む一方で,テーブルへは書き戻さない」(北村氏)。

 しかも,このアプリケーションはワークエリアをクリアしていない。そのため,ワークエリア内には,整合性が取れていない「不正なデータ」が生じる可能性がある。実際に今回,データには,航空機の経由地として「BIZEN(備前)」が2重に書き込まれていた(図2の上)。ある便(図2ではCAB001便)の飛行情報を照会した際,それ以前に実行した別の便の照会処理の結果がワークエリアの中に残っていた。その「BIZEN(備前)」が残った状態に,CAB001便の照会結果が書き加えられてしまった。

 非表示プログラムは,この「不正なデータ」をテーブルに書き戻した。

実行判定後の飛び先に誤り

 前述のように,ワークエリアには「不正なデータ」が存在する可能性がある。そのためデータ変更を伴うアプリケーションは,(1)ワークエリアをクリアした後に,(2)必要なデータをテーブルからワークエリアに読み込み,(3)処理を実行して,(4)テーブルにデータを書き戻す,という流れで処理を進める。

 「非表示プログラム」もこのルールに沿っていた。ただし,処理の冒頭「レーダー画面が初期化中か否か」の判定で“初期化中”だった場合,本来は「非表示プログラム」終了とすべきところが,いきなり(4)の書き戻し処理に飛んでいた。この記述ミスにより,午後7時に呼び出された際,「不正なデータ」をテーブルに書き戻した。

 午後7時11分,別のアプリケーション(図2のアプリ-B)がこのデータにアクセスして異常終了した。データのなかにある2つ目の「BIZEN(備前)」が通常は“あり得ない”情報だったからだ。CUE(大津)など経由地の情報には,それが格納されているテーブルの索引番号が付いている。この番号は“1”から始まるが,2つ目の「BIZEN(備前)」には“0”が付いていた。

サブ・システムは機能が少ない

 異常終了したアプリケーションは,リカバリのために自動的に再起動された。しかし,テーブルには「不正なデータ」が再現されるため,何度リカバリしてもアプリケーションは異常終了する。やむなく,サブ・システムに切り替え,航空管制業務を継続した。

 ただし,サブ・システムはメイン・システムに比べ機能を絞り込んである(表1[拡大表示])。例えば,レーダー画面間で航空機を引き継ぐ処理。メイン・システムは,コマンドを使った「自動引き継ぎ機能」を備える。

 この機能が無いサブ・システムでは,電話などを使い口頭で引き継ぐ必要がある。管制官の負荷が高まるため,「安全を見て,エリア内の航空機の数を,メイン・システムよりも減らして運用した」(国土交通省 航空局 管制保安部 管制情報処理システム室長 近藤信行氏)。その結果,午後8時12分から同9時22分にかけて,計130便に30分以上の遅れが生じた。

データを読み直して復旧

 メイン・システムが復旧したのは午後9時30分。ダウン直後から調査を進めた結果,「“飛行計画情報データを触った処理がおかしい”というところまで突き止めた」(国土交通省 航空局 管制保安部 保安企画課 管制情報処理システム室 調査官 小林市郎氏)。

 そこで,RDPシステムを手動で再起動し,飛行計画情報をハードディスクから読み直した。これにより,不正な情報が取り除かれた。障害発生後,すぐにシステムを再起動すれば復旧時間は短縮できた。しかし,「処理とデータ,どちらが間違っているのか分からない状態で,データを初期化するわけにはいかなかった」(小林氏)。

 再発防止策として,初期化中に非表示コマンドを入力しても重複処理しないよう改修する。併せて,実行判定といった類似の機能を見直した。該当する機能はシステムに185個あったが,問題は一つも無かった。

(森山 徹=tmoriyam@nikkeibp.co.jp)