masahide
2019年5月15日 18時29分
お世話になっております。赤坂と申します。
Armadillo640で開発を行ってます。
ルートファイルシステム上にアプリケーションの設定ファイル(800byteほど)を置いており、
Armadillo起動中にアプリケーションから設定変更(設定ファイルの書き換え)を行った場合、
その後に電源をOFF→ON(電源を遮断して起動)すると、設定ファイルの中身が空(0byte)になる事象が
1/4回程度の頻度で発生します。
(電源をOFFする前に、ls, catコマンドで中身のあるファイルが存在することを確認済み)
マニュアルの「20.4. ルートファイルシステムへの書き込みと電源断からの保護機能」を見ると、
「RAM上に残ったキャッシュがeMMCに書き込まれずに、ファイルシステムの破綻やファイルの内容が古いままになる状況が発生します。」
とあるので、その様な状況が発生しているのが原因ではないかと推定しています。
そこで、ルートファイルシステム上のファイルの書き換えを実行した場合に、キャッシュを使用せずに
eMMCに書き込み実行するarmadilloの設定はありますでしょうか?
また、アプリケーションから設定ファイルの書き換えを実行した後に、eMMCに書き込み実行するlinuxコマンドまたは、
C言語関数がありますでしょうか?
よろしくお願いします。
コメント
y.nakamura
中村です。
> .... sync コマンドを3回入力する ....
懐かしすぎ!
このあたり(↓)も参考に。
[Linux: ディスクキャッシュをストレージへ書き出す方法]
https://users.atmark-techno.com/blog/53/2466
--
なかむら
masahide
masahide
tyoshida1970
masahide
追加で質問させて下さい。
電源OFFする前に更新したファイルを確認した際には中のデータがあり、
電源OFF→ON後にファイルの中身が空になっていたので、電源OFFする前に確認していたデータは
RAMのバッファデータだったという事になります。
そこで、ファイル更新後にsync()を実行してRAMのバッファデータをeMMCへ書き込み、
その後、更新したファイルを再度読み込んだ場合(fopenでfreadする)には、
そのデータはRAMのバッファデータでなく、eMMCに書き込まれたデータと考えて良いでしょうか?
sync()によりRAMバッファデータが消えるのであれば、その後に確認するデータは
eMMCに書き込まれたデータである事が保障されると考えるからです。
at_koseki
古関です。
■ ディスクキャッシュの無効化について
> 念のための確認ですが、OSの設定としてキャッシュを使用しない設定は無いでしょうか?
O_DIRECTや以下のパラメータ調整、カーネルコンフィグ設定でできるかもしれませんが、
こちらでは試してないです。
/proc/sys/vm/dirty_background_ratio、/proc/sys/vm/dirty_ratio・・・
キャッシュを無効にする目的は何でしょうか?
(以下の理由によりおすすめできないかなと。)
例えば、「データ書き込み中の電源断によって発生するデータ不整合」の防止が目的だとすると、
これはキャッシュを無効にしたとしても防ぎきれないと思います。
Write要求はファイルシステム ... ブロックデバイス .... といき、最終的にはeMMC内の生NAND まで行くわけですが、
キャッシュを無効にしても書き込みが0秒で終わることはないため、
デバイスへの書き込み中に電源断が起きればデータの不整合は発生しえます。
書き込むデータサイズが大きくなったり、データが小さくても生NAND上の複数のブロックにまたがったりすると
単純に時間がかかりその発生確率は上がります。
試してないので推測ですが、キャッシュの有効時と無効時の以下2つの書き込みオペレーションにおける、
電源断をしてはいけない(不整合が発生しうる)時間ですが、
実運用上でメリットが得られるほどの差は出ないと思います(むしろ悪くなるかも・・)。
・キャッシュ有効時: write要求、sync
・キャッシュ無効時: write
キャッシュを無効にして得られるメリットよりも、発生するデメリットの方が多そうです。
※ I/Oなどの動きがもろもろ遅くなるとか
もし、電源断に対して非常にデリケートなデータを扱う必要があるのであれば、
バッテリバックアップしたり、UPSをつけたり、別のアプローチもアリかもしれません。
(これはかけられるコスト次第ですか)
■ sync後のReadはどこから読まれるか
> そこで、ファイル更新後にsync()を実行してRAMのバッファデータをeMMCへ書き込み、
> その後、更新したファイルを再度読み込んだ場合(fopenでfreadする)には、
> そのデータはRAMのバッファデータでなく、eMMCに書き込まれたデータと考えて良いでしょうか?
write/sync/read/compareがしたいということでしょうかね。
syncはeMMCへの吐き出し要求は行いますが、その後のRead動作に対してはキャッシュヒット(DRAM)するのか、
ちゃんと物理ストレージ(eMMC)から読むのはわからないですね。
不安ならsyncとreadの間に、drop cacheしてみたらどうでしょうか。
https://futuremix.org/2009/09/clear-linux-memory-cach
よろしくお願いいたします。
masahide
izawa
access.mihara
2019年5月15日 18時41分
三原と申します。
Armadillo 独自ではなく Linux 全体に適用される範囲で話をいたします。
Linux で、ファイルに書き込んだデータが物理ディスクに書き込まれる前にバッファリングされるのは、2レベルあります。
- C言語標準ライブラリでユーザ空間にバッファリングされている
- Linux カーネル空間にバッファリングされている
C言語標準ライブラリでバッファされているデータをフラッシュするには、C言語プログラムでは fflush() という関数があります。他の言語のプログラムの場合は、使用している言語のマニュアルを参照願います。
fflush()
https://linuxjm.osdn.jp/html/LDP_man-pages/man3/fflush.3.html
Linux カーネル空間にバッファリングされているデータをフラッシュするには、C言語プログラムでは sync() や fsync() という関数があります。
sync()
https://linuxjm.osdn.jp/html/LDP_man-pages/man2/sync.2.html
fsync()
https://linuxjm.osdn.jp/html/LDP_man-pages/man2/fsync.2.html
ならびにシェルから実行するコマンドとして sync があります。かつて Unix(Linux に限らず) でシャットダウンする際にディスク内容が反映されないという噂から sync コマンドを3回入力するといいという都市伝説が流布したことがあり、その起源を考察した記事が下記 URL にあります。
https://qiita.com/tboffice/items/9c6092278ccaab88e71e