Armadilloフォーラム

電源喪失への対処について

minaba

2023年5月26日 10時43分

Armadillo-IoT G4についての質問です。
下記を参照したうえでの投稿となります。
https://armadillo.atmark-techno.com/howto/power-off-measures

前提:
1.rootfsはoverlayfsを使用する。(デフォルト)
2.logs, appパーティションはext4を使用する。(デフォルト)
3./var/logはlogsパーティションをマウントする。(デフォルト)

想定
1.対象製品の遠隔監視用にG4を用いる。
2.電源喪失に備えてバッテリー(UPS)からG4へ電源供給をする。
3.対象製品の試運転などを行なう際、UPSとG4間の接続を突然切断する可能性がある。
4.G4上のアプリケーションは、データ永続化のためにコンテナ外(appパーティション)にデータを書込む。

課題:
突然の電源断による破壊が課題です。(データ欠落、システム停止は許容する)
 データ破壊、ファイルシステム破壊の両方を回避したいのですが、データ破壊は最悪許容します。

質問:
1.前提に間違いはないでしょうか。
2.G4ではG3までと異なる電源断に対する特別な対策が取られているでしょうか。(rootfsのoverlayfs採用以外で)
3.vintrigger は周期指定(秒単位)となっています。突然の電源断には対応できなさそうです。0も指定できるようですが、この場合の振る舞いはOFFでしょうか。それともポーリングではなく割込み(シグナル)対応のような事ができるのでしょうか。
4.logs, appパーティションにファイルシステム破壊があってもブート時のfsckで修復されるでしょうか。
5.logs、appパーティションの修復ができなかった場合、rootfsが破壊されていなければ通常起動するでしょうか。それとも、セーフモードのようなモードで起動するでしょうか。あるいは、起動せず停止するでしょうか。

コメント

at_dominique.m…

2023年5月26日 12時52分

minabaさん、

お世話になっています、
アットマークテクノのマルティネです。

説明が少し長くなって、分からなかったところがございましたらお手数ですがまた聞いてください。

> 質問:
> 1.前提に間違いはないでしょうか。

大きくは間違ってませんが、一つだけ訂正させてください。
app は ext4 ではなく btrfs を使っています。二重化のために btrfs の snapshot 機能に頼っているのは一番の理由ですが、btrfs は copy-on-write(CoW)という仕組みで電源断にとても強い書き込み方しています(後でもう少し説明します)。
また、この btrfs パーティションでは metadata を二重書き込みしていて(metadata=DUP)、チェックサムも有効になっています。どちらも新しい btrfs バージョンではデフォルトになっています。

> 2.G4ではG3までと異なる電源断に対する特別な対策が取られているでしょうか。(rootfsのoverlayfs採用以外で)

rootfs の overlayfs と log,app を noatime でマウントして書き込みを抑えている程度ですね。

> 3.vintrigger は周期指定(秒単位)となっています。突然の電源断には対応できなさそうです。0も指定できるようですが、この場合の振る舞いはOFFでしょうか。それともポーリングではなく割込み(シグナル)対応のような事ができるのでしょうか。

vintrigger はブログに書いてあるとおりに、 Armadillo G3/A6 シリーズの機能であって、Armadillo IoT G4 で実装していません。
AD converter から電源電圧を取得するハードウェアの実装を行っていませんので、ソフト上で対応できないようになっています。

電源が切断した場合には特に不具合にならないと考えていますが、電源が不安定な場合(電圧が低すぎる場合など)に不具合になりえますが、搭載されている DC/DC converter が広い範囲の電圧を受けてくれて、Under Voltage Lockout Protection等の機能もありますので故障する前に切断してくれると思います。(その心配もあればもう少し確認しますので聞いてください)

> 4.logs, appパーティションにファイルシステム破壊があってもブート時のfsckで修復されるでしょうか。

/var/at-log にマウントされている、最低限のログが記載されているパーティションだけに fsck をかけて、故障の場合に予備の gp2 パーティションにコピーして再作成しますが、/var/log と app については何もしません。
fsck を下手に実行すれば復帰できるデーターをなくすこともありますので、at-log の様な予備パーティションがない以上何もしない方がいいと判断しました。
そこは Armadillo の使い方それぞれにメリットとデメリットがありますので、データーの保存よりどうにかしてまた動かせることを優先する場合は fsck よりカスタムなサービスでパーティションを作り直した方がいいと思います。

そこで btrfs についてもう少し詳しい説明が必要だと思います:
- btrfs にも一応 fsck コマンドがありますが、それで問題が発生した場合の復帰は難しいと考えています。
なお、fsck は btrfs のチェックサムも確認してません。チェックサムはデーターを読む時に確認されて、必要な場合に「scrub」と言うコマンドで強制的に確認できます。Armadillo IoT G4 に使われている eMMC は データー化けにくい industrial品を使っているため今のところは scrub もデフォルトで行っていません。

データー化けがあった場合の現象は以下のとおりです:
- metadata に問題があった場合はチェックサムで自動的に検知されて、二重のコピーから自動的に復帰されます。(二つのコピーが故障された場合は IO エラーになって、場合によってリカバリがかなり難しくなります)
- data のチェックサムにエラーがあった場合は IO エラーで読み取りできませんが、書き込み(上書き)は可能なままです。

この説明で不安になったかもしれませんが、先ほど話していた Copy on write の仕組みのおかげで電源断の際にこういう問題が絶対に起きません(ソフトウェアの不具合や、ハードウェアが flush を無視する場合に可能ですので絶対は言いすぎましたが、使っている物をよく試して信用しています。)
新しいデーターを書き込む時は何もないところに新しい部分を書いて、sync の際か定期的にその新しいデーターを反映するために metadata を更新します。metadata を書き込んだ時に data が eMMC に書き込み終わったことを確認していますし、metadata の更新は atomic で行われているためそこで電源断があっても前のデータか新しいデーターのどれかを読み取れます。
なので、一般的には書き込み中の最後の数秒を失うことになるだけで、ファイルシステム全体の故障はとても考えにくいです。
(失いたくないデーターがあれば fsync を使ってください。sync しない場合は sysctl vm.dirty_expire_centisecs で管理されて、デフォルトでは書き込んだ 30秒後に必ず書き込まれています。)

> 5.logs、appパーティションの修復ができなかった場合、rootfsが破壊されていなければ通常起動するでしょうか。それとも、セーフモードのようなモードで起動するでしょうか。あるいは、起動せず停止するでしょうか。

マウントできなかった場合は overlay になってしまいますので、/var/log の場合に永続化できなくなりますが機能としては動きます。

app がマウントできなくなった場合はコンテナを当然起動できなくなりますが、btrfs の仕様としてはありえないと考えています。その場合でも Base OS の部分が動いていて、hawkBit サーバーや管理サービスを用意していた場合にそれを監視してリモート復帰は可能です。
(まだ開発の段階ですが、弊社の管理サービスができたらそれでも可能になります)

よろしくお願いします。

minaba

2023年5月29日 10時14分

マルティネさん、

minabaです。
ご回答ありがとうございます。

勉強させていただきました。ファイルシステムの進化でかなり堅牢になっているのですね。
CoWにてデータの破壊は防がれる。
メタデータの二重化とアトミックアクセスでファイルシステムの破壊は防がれると理解しました。

確認のための質問になります。下記理解で合っているでしょうか。
1.前提の修正。appはbtfs, logsはext4がデフォルト。
2.セクタ不良などデバイス要因を除けば、btrfsでは電源断による破壊は原理的には起こらない。
ただし、btrfs自体の不具合があれば別だが。

3.仮にapp,logsが破壊されていれば、マウントは失敗するが、システムは通常起動する。
4.logsが破壊されている場合、/var/logはrootfs上となるため、ログは永続化されないが動作する。

以下は新たな質問になります。
5.appのマウント失敗によりコンテナ起動ができないという事ですが、appのマウント位置はどこでしょうか?
6.podmanはrootfs上にあるのだろうと思いますが、imageがapp上に置かれるという事でしょうか。
7.一部の主要コンテナをrootfs上に配置する事は可能でしょうか。

以上、よろしくお願い致します。

at_dominique.m…

2023年5月29日 11時48分

minabaさん、

マルティネです。

> 1.前提の修正。appはbtfs, logsはext4がデフォルト。

はい。

> 2.セクタ不良などデバイス要因を除けば、btrfsでは電源断による破壊は原理的には起こらない。
> ただし、btrfs自体の不具合があれば別だが。

はい、btrfs 自体のバグやハードウェアの故障はどうしようもないですね…
それ以外は原理的に壊れません。

> 3.仮にapp,logsが破壊されていれば、マウントは失敗するが、システムは通常起動する。
> 4.logsが破壊されている場合、/var/logはrootfs上となるため、ログは永続化されないが動作する。

3/4, はい。

> 5.appのマウント失敗によりコンテナ起動ができないという事ですが、appのマウント位置はどこでしょうか?

/etc/fstab を拝見すればマウント箇所がいくつかあります。
btrfs のサブボリュームを直接に /var/app/volumes 等にマウントしていますので、いくつかのマウント位置がありますが、故障したとすればどれもマウントできないようになると思います。
「subvolume 一つだけマウントできなくなりました」様な不具合は metadata の二つのコピーの特定なディレクトリを壊して一応可能ではありますが、故障としてはあまり考えられません。

> 6.podmanはrootfs上にあるのだろうと思いますが、imageがapp上に置かれるという事でしょうか。

はい、デフォルト状態では /var/lib/containers/storage_readonly に置かれています。その subvolume は強制的に読み取り専用になっていますので、運用では固定されています。アップデートの場合でも subvolume を「snapshot」コピーしてそのコピーを更新していますので、更新中でも「間違って化けました」がありません。(これも btrfs に不具合があればそこまでですが、それは何でもありですね)
開発用の abos-ctrl podman-storage --disk の場合は /var/lib/containers/storage の追加のマウントポイントにあります。そこは btrfs/ハードウェアの問題ではなく、podman の仕様として不具合が出ている歴史がありますので、開発以外に使わないようにお願いしています。

> 7.一部の主要コンテナをrootfs上に配置する事は可能でしょうか。

そうですね、あまり考えてませんでしたが、podman の "additional image store" を足せば appfs の読み取り専用のパーティションと同じ仕組みを使えます。

コンテナをそこに入れるのは少し大変です…
気になって以下のでできましたが、これで何かトラブルがあったらサポートできない可能性がありますのでご了承ください。btrfs の読み取り専用のコードで充分と考えていますので、Armadillo Base OS としてではなくただの好奇心で書きました。

# podman は overlayfs に直接にかけませんので仮に /var/tmp にイメージを書きます。
armadillo:~# podman --root /var/tmp/storage pull docker.io/alpine
armadillo:~# mv /var/tmp/storage /root/
# ディレクトリを移動したので、podman のチェックを無効にします
armadillo:~# rm /root/storage/libpod/bolt_state.db
# 永続化
armadillo:~# persist_file -r /root/storage
# コンテナに場所を設定します
armadillo:~# vi /etc/atmark/containers/test.conf
set_image docker.io/alpine
set_command sleep infinity
add_args --storage-opt additionalimagestore="/root/storage"
# 必要な場合は --storage-opt additionalimagestore=/var/lib/containers/storage_readonly も
armadillo:~# podman image list
# イメージがないの確認
armadillo:~# podman_start test
armadillo:~# podman ps #等の確認

よろしくお願いします。

minaba

2023年5月29日 14時28分

マルティネさん、

minabaです。
ご回答ありがとうございます。
よくわかりました。(と思います)

パーティション内をサブボリュームに分割して、サブボリューム単位でマウントできるのですね。
metadataがサブボリューム毎に分離されているのであれば、これで十分に思えます。そもそも原理的に破壊がないわけですし。

ここまで教えていただいた内容から、電源断に備えてUPS及びUPSからの信号によるpower-offを使用する必要性が無いのではないかと考え始めました。
変な質問になりますが、G4の電源供給にUPSを使用するメリットは何か考えられるでしょうか。

at_dominique.m…

2023年5月29日 16時02分

minabaさん、

マルティネです。

> パーティション内をサブボリュームに分割して、サブボリューム単位でマウントできるのですね。
> metadataがサブボリューム毎に分離されているのであれば、これで十分に思えます。そもそも原理的に破壊がないわけですし。

はい、基本的にサブボリュームの metadata が分離されています。
例外は:
* マウントする時は root subvolume に各subvolume のパスを探します。root subvolume は更新の時以外マウントされてませんが、そこに問題が発生すれば appfs 全体に影響します。
* A/B面のためで snapshot を使っているため、A/B面のデーター/メタデーターは一時的に共有されます。ただし、CoW の仕組みで変更の際にそのツリーを変更せずに新しいノードを作ってますので、理論上は snapshot に変更を加えることで元のサブボリュームに影響はないです。(これも、snapshot の部分は通常に同時にマウントされてませんので、アップデートの時だけですね)

> ここまで教えていただいた内容から、電源断に備えてUPS及びUPSからの信号によるpower-offを使用する必要性が無いのではないかと考え始めました。

ありがとうございます、このつもりで設計していますのでそう言っていただけると嬉しいです。

> 変な質問になりますが、G4の電源供給にUPSを使用するメリットは何か考えられるでしょうか。

そうですね、ファイルシステムの故障の面ではなくてもいいと考えていますが、それでもメリットはいくつかあります:

1. サービスとして電源が落ちたことの知らせを送信する必要がある場合は何かのバッテリが必要になりますね。知らせの必要がなくても、電源がよく落ちる場合に自分のサービスに影響があるかもしれませんので、長く運用したい場合でも有効かもしれません。
2. 最初の返事で説明した、書いたばかりのデーターがなくなる可能性がありますので、重要なデーターでしたら UPS あった方がいいです。fsync を使えば安全に保存できますが、パフォーマンス的にはよろしくないので database などのワークロードの場合に fsync 無しで UPS を使った方がいいかもしれません。
3. 過去に故障の実績はありませんが、LTE モデムのメーカーから正しい手順で電源を切るように推奨されていますので、UPS があればその推奨を実施できます。

よろしくお願いします。

minaba

2023年5月29日 16時25分

マルティネさん、

minabaです。
本件、丁寧なご回答ありがとうございました。