Armadilloフォーラム

[Armadillo-640]USBの自動マウント手順について(ご質問)

miyamoto

2018年9月19日 9時57分

お世話になっております。宮本と申します。
USBをArmadilloに挿入した際に自動でマウントする方法についてご教示ください。

自動マウントする方法として、udevを使用しています。
USB挿抜時にマウント、アンマウントするようにrules、実行シェルを作成しましたが、マウントされない状況です。
udevでのUSB挿入時の自動マウント手順、または、それ以外の方法でUSBを自動マウントさせる手順の
ご教示のほどお願いいたします。

作業の詳細について以下に示します。

【作業環境】
 製品:Armadillo-640
 OS:Debian stretch
 Linux:4.14-at4(atmark@atde7)(gcc version 6.3.0 20170516(Debian 6.3.0-18))

【やりたいこと】
 USB挿抜時に、自動でマウント、アンマウントしたい。
 (マウント先:/mnt/usb)

【作業内容・手順】
1.事前に/mnt配下にusbディレクトリを作成
2./etc/udev/rules.d配下に以下の内容のrulesファイルを作成
  KERNEL=="sd*[0-9]*",SUBSYSTEMS=="usb",ACTION=="add",RUN+="/etc/config/usb_auto_mount.sh %k"
  KERNEL=="sd*[0-9]*",DEVPATH=="*usb*",ACTION=="remove",RUN+="/etc/config/usb_auto_umount.sh %k"
3.rulesのリロード
  [armadillo ~]# udevadm control --reload-rules
4./etc/config配下に2.で指定したシェルファイルを作成
  usb_auto_mount.sh
   #!/bin/sh
   echo device:$1 > /dev/ttymxc0
   sudo mount -t vfat /dev/$1 /mnt/usb
   echo result:$? > /dev/ttymxc0
  usb_auto_umount.sh
   #!/bin/sh
   sudo umount -l /mnt/usb
   echo result:$? > /dev/ttymxc0
5.4.のシェルに対して実行権限を付与
  [armadillo ~]# chmod 777 usb_auto_mount.sh
  [armadillo ~]# chmod 777 usb_auto_umount.sh
6.USBを挿入
  シェルに記述した終了ステータスは「0」でコンソールに表示。
7.dfコマンド実行
  /dev/sd*は表示されず、マウントされていないことを確認。

rules、shファイル、実行時の画面ハードコピーを添付させていただきます。

以上です。よろしくお願いいたします。

ファイル ファイルの説明
20180919_資料.zip
コメント

中村です。

mountコマンドは実行されているようですので、
原因とは関係はないと思いますが、

>    sudo mount -t vfat /dev/$1 /mnt/usb
のsudoは不要だと思います。

> rules、shファイル、実行時の画面ハードコピーを添付させていただきます。

添付の画面キャプチャにあった
FAT-fs (sda1): Volume was not properly unmounted......
はwarningであってマウント自身は成功している、
という経験があります。(今ぐぐってみても、それで正しいみたいです)
(echoで表示しているresultは0になっているので成功していると思われます)

> 7.dfコマンド実行
>   /dev/sd*は表示されず、マウントされていないことを確認。

cat /etc/mtab
をやってみてもらえますか?

また、
ls -l /mnt/usb
もやってみてください。
(そのUSBメモリには何かファイルが入ってますよね?)

それから、udevのルールを一旦削除して、
・USBメモリ挿入
・手動でmountコマンドを実行
・dfコマンドを実行
などを試してみると、何かわかるかもしれません。

--
なかむら

中村です。

追加です。

> > 7.dfコマンド実行
> >   /dev/sd*は表示されず、マウントされていないことを確認。
>
> cat /etc/mtab
> をやってみてもらえますか?

df -a

df /mnt/usb
は、どうなりますか?

--
なかむら

お世話になります。宮本です。
早速のご返信ありがとうございます。

> cat /etc/mtab
> df -a
> df /mnt/usb
dfと同じ結果で、/mnt/usbへのマウントはありませんでした。

> ls -l /mnt/usb
total 0 で中身は見れない状態です。

実行結果をテキストに貼り付けましたので添付いたします。

> それから、udevのルールを一旦削除して、
> ・USBメモリ挿入
> ・手動でmountコマンドを実行
> ・dfコマンドを実行
問題なくmountされます。dfコマンド結果にも表示されます。
(Filesystemに/dev/sda1、Mounted onに/mnt/usb)

udevではなく、上記のように手動でmountコマンド実行や、作成したシェルを手動で実行
した場合には問題ないようです。

取り急ぎご報告させていただきます。

> 中村です。
>
> 追加です。
>
> > > 7.dfコマンド実行
> > >   /dev/sd*は表示されず、マウントされていないことを確認。
> >
> > cat /etc/mtab
> > をやってみてもらえますか?
>
> df -a
> や
> df /mnt/usb
> は、どうなりますか?
>
> --
> なかむら
>

ファイル ファイルの説明
コマンド実行結果.txt

宮本さん、
中村です。

いろいろ試していただいて、ありがとうございます。

とすると、先ほど書いた
>> 添付の画面キャプチャにあった
>> FAT-fs (sda1): Volume was not properly unmounted......
>> はwarningであってマウント自身は成功している、
>> という経験があります。(今ぐぐってみても、それで正しいみたいです)
>> (echoで表示しているresultは0になっているので成功していると思われます)
は、今回はそうじゃない、ということのようですね。

整理すると・・・

> udevではなく、上記のように手動でmountコマンド実行や、作成したシェルを手動で実行
> した場合には問題ないようです。
udevルールで呼び出すスクリプトは問題なし。

udevルールの記述(udevからこのスクリプトの呼び出し)も問題なし。
mountコマンドも実行されている。
mountコマンドの終了ステータスも問題なさそう。
でもマウントされていない。

USBメモリを別なものに変更するとどうなりますか?
複数お持ちであれば、いろいろ試してみるとか。

udevルールファイルは実行スクリプトを具体的に書いていただいているので、
同じ設定で私自身で試せるといいのですが、いまは出先のため、
できるとしても今日の夜になってしまいます。

--
なかむら

中村です。

> udevではなく、上記のように手動でmountコマンド実行や、作成したシェルを手動で実行
> した場合には問題ないようです。
のとき、udevのときに表示されていた
FAT-fs (sda1): Volume was not properly unmounted......
というメッセージは表示されますか?

それから、udevを使ったとき、
syslogに何か手がかりは残っていないでしょうか?

--
なかむら

中村様

お世話になります。宮本です。
こちらこそお忙しい中ご確認ありがとうございます。
返信が遅れまして、すみません。

> USBメモリを別なものに変更するとどうなりますか?
別のUSBでも同様です。マウントされません。

>> udevではなく、上記のように手動でmountコマンド実行や、作成したシェルを手動で実行
>> した場合には問題ないようです。
> FAT-fs (sda1): Volume was not properly unmounted......
> というメッセージは表示されますか?
表示されます。
別のUSBを使用した際に初回は表示されませんでしたが(マウントもされてません)
2回目以降では表示されるようになりました。
表示されたり、しなかったり…というような動きです。

> syslogに何か手がかりは残っていないでしょうか?
特にエラー等は出力されていませんでした。
画面に表示される内容のみのようです。
(FAT-fs (sda1): Volume was not properly unmounted......など)

念のためUSB挿抜時のsyslogを添付いたします。

以上です。よろしくお願いいたします。

ファイル ファイルの説明
syslog.txt

中村です。

> 念のためUSB挿抜時のsyslogを添付いたします。

ありがとうございます。

自分でも試してみました。
udevを使ったとき、udevを使わずに手動で実行したとき、とも、
同じような結果になりました。

もう少し調べてみます。

スクリプトで気になった部分を書いておきます。
これは問題の原因ではなく、単純なミスや、
気にしなくても大丈夫な部分ですが。。。

usb_auto_umount.shのリダイレクト
echo "result:"$? > ttymxc0
とありますが、これは /dev/ttymxc0。

usb_auto_mount.shとusb_auto_umount.shのどちらもですが、
echoのダブルクォートは引数全体を囲った方がいいと思います。
上のumountのを例にすると、
echo "result:$?" > /dev/ttymxc0
です。

--
なかむら

中村です。

> 自分でも試してみました。
> udevを使ったとき、udevを使わずに手動で実行したとき、とも、
> 同じような結果になりました。

動くようになりました。

参考にしたwebサイト:
https://unix.stackexchange.com/questions/330094/udev-rule-to-mount-disk…
http://hardwareandsoonlab.blogspot.com/2018/04/raspberry-pi-zero.html
https://unix.stackexchange.com/questions/152485/mount-is-not-executed-w…
など

それなりのキーワードで検索するとたくさん見つかります。
どうやら Debian/stretch 全般で発生している問題のようです。

新規に /etc/systemd/system/systemd-udevd.service を作ります。

.include /lib/systemd/system/systemd-udevd.service
[Service]
MountFlags=shared

やることはこれだけです。

ただ、この変更をして再起動すると、syslogや
systemctl status systemd-udevd.service の表示に
systemd-udevd[134]: could not open moddep file '/lib/modules/4.14-at2/modules.dep.bin'
が出てました。
この表示(ログ)が出ていても問題はなさそうですが、
起動後に手動で
systemctl restart systemd-udevd.service
systemctl status systemd-udevd.service
すると、この表示はなくなります。

/var/logに残っていた古いsyslogを見ると
Armadillo-640が届いた直後に起動したときのログにも残っていました。
Apr 13 03:08:49 armadillo systemd-udevd[129]: could not open moddep file '/lib/modules/4.14-at2/modules.dep.bin'
Apr 13 03:08:49 armadillo systemd-udevd[129]: could not open moddep file '/lib/modules/4.14-at2/modules.dep.bin'
(4/13は640が届いた日でこのタイムスタンプはUTCです)

以下は、今回の調査でわかったことです。

Armadillo-IoTG3/M1も同じ設定になっていて、
実際に試してみたところ、同じ問題が発生しました。

systemd-udevd.serviceのデフォルト設定は
/lib/systemd/system/systemd-udevd.service

MountFlags=slave
になっています。
jessieではこの設定(MountFlags)はなかったようです。

元の MountFlags=slave の状態で動かして、
udevから呼び出されてUSBメモリをマウントするスクリプトで、
mountの直後にdfを実行するようにしてみました。

#!/bin/sh
 
echo device:$1 > /dev/ttymxc0
mount -v -t vfat /dev/$1 /mnt/usb > /dev/ttymxc0 2>&1
echo result:$? > /dev/ttymxc0
df /mnt/usb > /dev/ttymxc0
sleep 10
df /mnt/usb > /dev/ttymxc0

udevから呼び出されたスクリプトの中では、
dfコマンドでUSBメモリがマウントされています。

ところが、このスクリプトがsleepしている間に
別端末でdfを実行するとマウントされていません。
「なぜだ~?」と調べてわかった解決策が、
MountFlags=shared にすることでした。

MountFlagsの説明は SYSTEMD.EXEC(5) にあります。
$ man systemd.exec
からその部分を引用しておきます。

MountFlags=
Takes a mount propagation flag: shared, slave or private, which
control whether mounts in the file system namespace set up for this
unit's processes will receive or propagate mounts or unmounts. See
mount(2) for details. Defaults to shared. Use shared to ensure that
mounts and unmounts are propagated from the host to the container
and vice versa. Use slave to run processes so that none of their
mounts and unmounts will propagate to the host. Use private to also
ensure that no mounts and unmounts from the host will propagate
into the unit processes' namespace. Note that slave means that file
systems mounted on the host might stay mounted continuously in the
unit's namespace, and thus keep the device busy. Note that the file
system namespace related options (PrivateTmp=, PrivateDevices=,
ProtectSystem=, ProtectHome=, ProtectKernelTunables=,
ProtectControlGroups=, ReadOnlyPaths=, InaccessiblePaths=,
ReadWritePaths=) require that mount and unmount propagation from
the unit's file system namespace is disabled, and hence downgrade
shared to slave.

MOUNT(2)には次の記述があります。
$ man 2 mount
から引用しておきます。

MS_SHARED
Make this mount point shared. Mount and unmount events immedi-
ately under this mount point will propagate to the other mount
points that are members of this mount's peer group. Propagation
here means that the same mount or unmount will automatically
occur under all of the other mount points in the peer group.
Conversely, mount and unmount events that take place under peer
mount points will propagate to this mount point.

MS_PRIVATE
Make this mount point private. Mount and unmount events do not
propagate into or out of this mount point.

MS_SLAVE
If this is a shared mount point that is a member of a peer group
that contains other members, convert it to a slave mount. If
this is a shared mount point that is a member of a peer group
that contains no other members, convert it to a private mount.
Otherwise, the propagation type of the mount point is left
unchanged.

When a mount point is a slave, mount and unmount events propa-
gate into this mount point from the (master) shared peer group
of which it was formerly a member. Mount and unmount events
under this mount point do not propagate to any peer.

A mount point can be the slave of another peer group while at
the same time sharing mount and unmount events with a peer group
of which it is a member.

--
なかむら

中村です。

余談ですが・・・

> それなりのキーワードで検索するとたくさん見つかります。
> どうやら Debian/stretch 全般で発生している問題のようです。

Ubuntu 16.04 では、systemd-udevd.serviceから
MountFlags=slave が削除されているみたいです。
https://askubuntu.com/questions/1019865/why-does-ubuntu-16-04-remove-mo…

Why does Ubuntu 16.04 delete MountFlags=slave
from systemd-udevd.service which is different
from systemd upstream?

--
なかむら

中村様

お世話になります。宮本です。

詳細な回答いただきましてありがとうございます。
内容を確認の上、動作を確認いたします。

取り急ぎ、確認のご報告です。

中村様

お世話になります。宮本です。

回答いただいた内容にて問題なくUSB自動マウント、アンマウントされることを確認いたしました。
検索が足りてませんでした…
遅くまでご対応ありがとうございました。
本件については完了とさせてください。

宮本さん、
中村です。

> 回答いただいた内容にて問題なくUSB自動マウント、アンマウントされることを確認いたしました。

確認、ありがとうございます。

> 検索が足りてませんでした…

今回の場合、症状(udevで起動したスクリプト内では
マウントされた状態になっているが、外部からは
マウント状態には見えない)がわかって、解決策も
判明したあとに、その対処方法をキーワードにして
検索したらたくさん見つかった、というものですので、
最初から検索で原因や対策を探すのは難しかったと思います。

> 遅くまでご対応ありがとうございました。

対応というより、自分にも関係するので調べました。
まだArmadillo-640の開発案件はありませんが、
今後640案件があったときに同じ問題にあうかもしれません。
また、すでに開発案件としてかかわっている同じユーザランドの
G3系でも発生するのでは?と不安になりました。

開発にかかわっているG3では、
udevでUSBメモリを自動マウントしてスクリプトを実行し、
そのスクリプトでアプリケーションを更新しています。
旧G3(Debian/jessie)で開発が始まった案件ですが、
G3/M1対応と、旧G3でもDebian/stretch対応が必要になり、
すでにDebian/stretchへの移行はほぼ終わっていて、
USBメモリでのアプリの自動更新も動作の確認ができているのですが、
今回の問題には気付かないままでした。

udevから起動したスクリプトの中で
mount→更新処理→umountをしていたので、
今回の問題の影響はなかったようです。

> 本件については完了とさせてください。

アットマークテクノのご担当者さま、
もし可能でしたら、このスレッドの対象ハードウェアに
G3系Armadillo(G3,G3L,X1)を加えていただけますでしょうか?

--
なかむら

溝渕です。

何時も有難うございます。

> もし可能でしたら、このスレッドの対象ハードウェアに
> G3系Armadillo(G3,G3L,X1)を加えていただけますでしょうか?

追加しました。

中村です。

> 追加しました。

溝渕さん、ありがとうございます。

--
なかむら