Ubuntu再起動時にSDカードが認識されない問題の対処
背景
我が家ではMELE quieter3cというファンレスPCにUbuntuを入れて自宅サーバとして稼働させている。同PCをファイルサーバとしても使おうと、安価な1TBのMicroSDカードを挿入してそこを参照する形でSambaを構成した。
構築直後は正常に動いていたが、サーバを再起動するとSDカードが認識されず、ファイル共有が動かない。SDカードを抜いて挿せば再び認識されるが、ずっと挿しっぱなしで運用したいので解決法を調べた。
参照したサイト
結局ここの方法に従った。MELE quieter 3qという姉妹製品の事例だったから再現性高いかと思って採用したけど、ハードウェアやBIOSというよりはOSレベルの問題だったんじゃないかと思っている。 unix.stackexchange.com
全てが終わった後で見つけた記事。試してないがこれで十分だったんじゃないかという気がしている。 qiita.com
調査結果と今回の対応方法
調査結果
- LinuxにおいてSDカードはmmcというドライバによって認識される
echo 1 > /sys/class/mmc_host/mmc0/device/remove
によってmmc0(mmcによって認識されている0番目のデバイス)を切断し、物理的にデバイスを取り出したのと同じ状態を作ることができるecho 1 > /sys/class/pci_bus/0000\:00/rescan
によってPCIバス上の全てのデバイスを再スキャンし、物理的に接続されているデバイスを認識させることができる- MELE quieter3cには128GBのeMMCストレージ(最近の小型PCによく搭載されているマザーボード上に組み込まれたストレージ)があり、その名の通りこれもmmcによって制御される
- eMMCとSDカードが読み込まれる順序は一定でなく、SDカードがmmc0になったりmmc1になったりする
- mmcの読み込み順によってパーティションを指定するときのパスが変わり、
/dev/mmcblk0p1
になったり/dev/mmcblk1p1
になったりする - mmcデバイスとして接続されているが中身が読み込まれていない状態は
/sys/class/mmc_host/mmc#
配下にmmc#:0001
のようなフォルダが存在するか否かによって見分けられる
今回の対応
以下のようなシェルスクリプトを作り、OS起動後に実行するようにした。
本当はメタデータ的なものを参照して該当のMMCデバイスがSDカードであることを確認したかったが、やり方が分からなかった&自分の環境だとこれで問題なく動くのでこれで運用している。
echo '+ checking mmc devices' mmcdev=nodevice while read -r line; do # ヒアストリングで指定しているmmcデバイス(/sys/class/mmc_host/配下)でループを回す echo " - checking $line" ls /sys/class/mmc_host/$line | egrep -v 'device|power|subsystem|uevent' # mmc#:0001が存在すれば$?が0になる = 該当のmmcデバイスが認識されている if [ $? -ne 0 ]; then mmcdev=$line break fi done<<EOF # ls | while read line ...とするとループの外の変数が見えなくなるため普段使わない書き方になった $(ls /sys/class/mmc_host) EOF if [ $mmcdev = 'nodevice' ]; then echo ' - no empty mmc devices found' exit 0 else echo " - sdcard should be recognized at $mmcdev" fi mmcnum=${mmcdev:3} echo '+ rescanning sdcard' echo 1 > /sys/class/mmc_host/${mmcdev}/device/remove echo 1 > /sys/class/pci_bus/0000\:00/rescan echo ' - waiting for 10 seconds...' sleep 10 echo '+ checking device status' fdisk -l | grep /dev/mmcblk${mmcnum} if [ $? -eq 0 ]; then echo ' - sdcard was found' else echo ' - failed to recognize sdcard' exit 1 fi echo '+ mounting sdcard' mount ${devpath} /mnt/sdcard status=$? if [ $status -eq 0 ]; then echo " - success. ${devpath} -> /mnt/sdcard" else echo " - mount failed with status $status" exit $status fi echo '+ starting smbd' systemctl start smbd status=$? if [ $status -eq 0 ]; then echo ' - success' else echo ' - failed to start smbd' exit $status fi