組込みファイルシステムの電源断について

つぶつぶコラム

はじめに

今回は組込みファイルシステムでたまに聞く電源断対応について書いていきます。

なお、はじめに書いておきますが、当社の自社開発製品であるGR-FILEは電源断には対応していません。(弱点を晒すようで心苦しいですが…)

電源断とは

ここで言う電源断とは、ファイルシステムがメディア(電子記録媒体)に情報を書き込んでいる間にシステムの電源が失われることを指します。
予期せぬ停電や操作ミスなどで電源断が発生すると、メディアの情報に矛盾が生じたり、情報が壊れるようなことが発生します。

電源断に対応しているというのは、

  • メディアへの書き込み順序を矛盾が生じにくい順序で書き込むこと
  • 書き込み時にどこのセクタにどんな情報を書き込んだのか分かるログを残すこと
  • メディアに確実に書き込まれた際にログを削除すること
  • メディアのマウント時にメディアの整合性をチェックし、ログに従って修復すること

これらの機能が実装されている必要があります。
また、電源断に似た状態として、書き込み中にメディアを取り外すことがあります。
この場合はシステム側に情報が残っていれば、再度メディアを接続することで復旧を試みれるファイルシステムもあります。

電源断でファイルシステムが壊れる原因

電源断が発生するとメディアの情報に矛盾が生じると書きました。
ここでは、どんな矛盾が生じるのかをFATファイルシステムを例に書いていきます。

FATファイルシステムの情報

FATファイルシステムでは、FAT(File Allocation Table)と呼ばれるチェイン情報と、ファイルの長さや名称といった情報、ファイルの中身そのものの情報の3つがあります。この3つの情報が矛盾なく連動してファイルシステムが動作しています。
この3つの情報は離れたセクタに保存されており、ファイルの更新時には3つの情報を更新する必要があります。
この更新の途中で電源断が生じると更新された情報と、更新されずに以前の情報のままの状態が発生し、矛盾が生じる場合があります。

矛盾が生じる例

例えば、既存のファイルに情報を追記する場合を考えてみます。

情報を追記するということはファイルの長さが大きくなるということです。ファイルの長さは変わりますし、追記する情報そのものを記録するクラスタを新たに割り当てる場合もあります。クラスタを割り当てた場合はFATチェインの更新も必要になります。つまりFATチェインの更新、ファイル長の更新、追記データの書き込み、という3つの情報の更新が発生します。

この時、素直に処理を考えると、「追記するためのクラスタの割り当て」、「ファイル長の変更」、「追記情報の書き込み」といった順になるかと思います。ですが、例えば、「追記するためのクラスタの割り当て」、「ファイル長の変更」の間で電源断が生じると「FATチェインの更新は出来ているが、ファイル長の更新は出来ていない」という状態ができます。

この状態で、さらにファイルの追記を行ってしまうと、「ファイル長としてはクラスタの割り当てを行う必要があるが、FATチェインではすでに割り当てられている」といった矛盾が起きているため、ファイルシステムとしてはFATチェインとファイル長のどちらを信用して動作してよいか分からなくなります。

電源断対応機能

電源断に対応するには、メディアへの書き込み順序を矛盾が生じにくい順序で書き込むこと、書き込み時にどこのセクタにどんな情報を書き込んだのか分かるログを残すこと、メディアに確実に書き込まれた際にログを削除すること、メディアのマウント時にメディアの整合性をチェックし、ログに従って修復すること、と書きました。

ここでは、これらについて書いていきます。

矛盾が生じにくい書き込み順序とログ

既存のファイルに情報を追記する場合、FATチェインの更新、ファイル長の更新、追記データの書き込み、という3つの情報の更新が必要ですが、これらは矛盾の生じにくい書き込み順序があります。ただし生じにくいだけで、ここで紹介する順序を守れば矛盾が生じなくなるということではないので注意してください。

順序としては、追記データの書き込み、FATチェインの更新、ファイル長の更新、の順になるかと思います。

最初に、追記データの書き込みを行いますが、これにはあらかじめクラスタの割り当てが必要です。この割り当ては仮に割り当てておくことで、FATチェインを更新せずに追記データを書き込めます。もしこの時点で電源断が発生しても、FATチェインは更新されていないため、仮に割り当てたクラスタに追記情報を書いたのみとなります。ですがFATチェインは更新されていないのでファイルシステムとしては矛盾の無い状態となります。

次に、FATチェインの更新を行います。これは仮に割り当てていたクラスタをFATチェインに繋ぐ処理になります。この時、FATチェインの書き込み情報のログを保存しておきます。ログはFATチェインの書き込みの前に残します。この時点で電源断が発生した場合、FATチェインとファイル長に矛盾が生じます。ですが、ログにFATチェインを更新した情報があるため、マウント時にログを見て修復(FATチェインを元に戻す)が可能になります。修復することでファイルシステムとしては矛盾が無い状態に戻すことができます。

最後に、ファイル長の書き込みを行います。この書き込みが完了できれば一連の書き込みが完了し矛盾がない状態になりますが、ここでもファイル長の書き込み前にログを保存します。その後、ファイル長を書き込み、FATチェインの更新のログとファイル長のログを削除します。この時点で電源断が発生した場合は、ログの残り方で修復が可能です。FATチェインと、ファイル長の両方のログが残っている場合、ファイル長の更新ができていない可能性がありますので、FATチェインとファイル長を元に戻します。両方のログがない場合は書き込みが完了しているものとして修復はせずに済みます。

箇条書きにすると以下のようになります。

ファイルの更新時

  • 割り当てたクラスタに追記データ(ファイルの内容そのもの)を書き込む
  • FATチェインの更新ログをログに書き込む
  • FATチェインの更新を書き込む
  • ファイル長など(ディレクトリエントリの更新)のログを書き込む
  • ファイル長などを書き込む

マウント時のチェック

  • もし、FATチェインとファイル長などのログの両方が残っていた場合は、ファイル書き込みが完了していないものとして、FATチェインとファイル長などを元に戻す。
  • もし、FATチェインのログだけ残っていた場合は、ファイル書き込みが完了していないものとして、FATチェインを元に戻す。
  • 両方のログが無い場合は、追記データの書き込みのみ行われたか、ファイル書き込みが完了しているものとして何もしない。

電源断機能使用時の注意点

電源断機能は対応していると便利な機能ですが、使用する場合に注意しなければいけないことがあります。

他のシステムで書き込まない

同じシステムであれば、残されたログによる処理ができるので問題ないですが、異なるシステムで書き込んでしまうと、ログの状態とメディアの状態が異なる状態になってしまうため、ファイルシステムを壊す可能性があります。

例えば電源断が発生しログが残されたメディアを、PCなどで修復してしまうと、ファイルシステムは正常修復されてもログが残るため、次に電源断対応の組込みシステムで使用した場合に、ログに従って修復しようとします。この処理を行うとPCで修復した情報が壊される可能性があります。

電源断対応時の書き込み

電源断に対応する場合、ファイルシステムのプログラム順で確実にメディアに書き込まれることが大前提になります。ですので、読み込みキャッシュは利用できますが、遅延書き込みキャッシュは利用しない方が良いと思われます。これは実際のメディアへの書き込みタイミングとプログラム上の書き込みタイミングがずれるほか、ログの書き込みが行われない場合、修復のための情報が残らないため正しい修復ができなくなるためです。

まとめ

いかがでしたでしょうか。

今回書いた電源断の修復方法はログを用いた簡単なものです。実際にはクロスリンクなどを検出・修復するなどいくつかの修復機能が無いと実用には耐えられないと思います。ですが、これらの機能をまじめに実装しようとするとメモリなどのリソースが多く必要になってしまいます。また、メディアのサイズが大きくなると処理時間も多くかかってしまいます。

世の中には電源断対応のファイルシステムが存在しますが、それぞれメリットデメリットがあると考えています。GR-FILEは中途半端な修復機能を実装するよりは、その分を高速・高機能に割り振った設計思想になっていますので、メディアが壊れた際はPCなどのチェックツールを使用していただくようにお願いしています。

もし、電源断への対応について懸念点がございましたら、一度ご相談ください。