ozawa
2020年11月18日 19時53分
お世話になります。小澤と申します。
Armadillo-IoT G3Lにおいて、microSDを外部ストレージとして使う場合について教えてください。
microSDを挿入し、ある条件のときファイルを保存するように
組込んでいますが、microSDにファイルが保存ができません。
microSDはFAT32でフォーマットしています。
下記のように、/media にマウントし、ディレクトリ(aaa)を作成し
ここにrenameしてファイルを移動するようにしています。
system("mount -t vfat /dev/mmcblk0p1 /media");
system("mkdir /media/aaa/);
Teratermで、ディレクトリ(/media/aaa/)をlsコマンドで確認したところ、ファイルが存在していましたが、
ArmadilloからmicroSDを取り外し、Windows上でmicroSDの内容確認すると、何も保存されていませんでした。
何かやり方が間違っているのでしょうか?
ちなみにArmadilloからmicroSDを取り外すとき
umount /media をすると、
”umount: /media: not mounted” と表示されました。
うまくマウントができてないのでしょうか?
ご教授のほど、よろしくお願いいたします。
コメント
ozawa
お世話になります。小澤です。
古関様、ご返信ありがとうございます。
以下のように、mountコマンドやmkdirコマンドができているか、処理を追加して確認してみました。
~~~
LOG_INFO("===== start =====");
static string BASE_DIR = "/media/unsent/";
struct stat statBuf;
if( system("mount -t vfat /dev/mmcblk0p1 /media") ){
LOG_INFO("mount NG");
}else{
LOG_INFO("mount OK");
}
static string cmd = "mkdir " + BASE_DIR;
if( system(cmd.c_str()) ){
LOG_INFO("mkdir NG");
}else{
LOG_INFO("mkdir OK");
}
auto file_name = get_file_name(unsent_files);
auto moved_file = BASE_DIR + file_name;
if(rename(unsent_files.c_str(), moved_file.c_str()) == 0){
LOGF_INFO("moved file path:%s -> %s", unsent_files.c_str(), moved_file.c_str());
}else{
LOG_ERROR(strerror(errno));
}
~~~
上記の処理を実行すると、以下のログ出力となりました。
>>>>>>>>>>>>>>>>
[info] ===== start =====
[info] mount OK
[info] mkdir OK
[error] Invalid cross-device link
<<<<<<<<<<<<<<<<
mount、mkdirはできているが、renameコマンドができてなくて
エラー出力されているように見えます。
ちなみにこの後、umountができました。
(前回はおそらくmountがうまくできてなかったのかと思います)
このエラー「Invalid cross-device link」は
何が原因で発生しているのでしょうか?
推測ですが、
mountできてないときは、ファイル移動ができるがmicroSDに保存できない。
mountできているときは、このエラーが発生しファイル移動ができなくなる、と思われます。
ご教授のほど、よろしくお願いいたします。
もし情報が不足していましたら、ご指摘ください。
at_ohsawa
> mount、mkdirはできているが、renameコマンドができてなくて
> エラー出力されているように見えます。
そのrenameはコマンドではなくてシステムコールですね。
renameシステムコールは異なるマウントポイント間で動作しません。
Invalid cross-device linkのerrnoはEXDEVですが
(strerroで説明の文字列に変えると却ってわかりづらいですね)
man 2 renameとコマンド打ってEXDEVの説明を見ると、
そう書いてあるのがわかると思います。
(参考: rename の日本語訳)
https://linuxjm.osdn.jp/html/LDP_man-pages/man2/rename.2.html
恐らくmount した microSD と armadilloのeMMC間でrenameしようとしたので
上のエラーになっているのでしょう。
(microSD から microSD へrename等同じマウントポイントなら問題ないです)
こういう場合は下記の方法があります。
元々systemでコマンド呼んでいるのでとくに事情なければcで良いと思いますが…
a. 元、先ともにopen() して read() write()で転記して元ファイルを削除
b. sendfile()関数を使う(POSIX準拠にこだわりが無い限りaではなくbで良いです)
c. system()でmvコマンドを呼ぶ
ozawa
at_koseki
2020年11月18日 21時33分
古関です。
頂いている情報だけだと判断が難しいのですが、
考えられること記載します。
■ コマンドの戻り値チェック
C言語からsystem関数を実行しているものと思いますが、
mountコマンドやmkdirコマンドの戻り値チェックはしているでしょうか?
mountコマンド自体がエラーになっていないのにもかかわらず、
umount: /media: not mountedが出る状況でしょうか。
■ syncの実行
mkdir からumountの間にsyncコマンド は実行しているでしょうか?