Good afternoon,
I have a project where the SD card may become momentarily disconnected due to a weak contact on the SD Detect pin. I want to be able to check if it has been unmounted and remount it in software.
My SD card partition is /dev/mmcblk1p1
It is originally mounted automatically when Linux boots up
If I execute a umount /mnt/storage command, then remove the SD card, I can re-insert it, and perform a mount /dev/mmcblk1p1 /mnt/storage without issues
However, if I remove the SD card first, without umount, executing mount /dev/mmcblk1p1 /mnt/storage results in
mounting /dev/mmcblk1p1 on /mnt/storage failed: No such device or address
I tried running
umount /mnt/storage
rmdir /mnt/storage
mkdir /mnt/storage
This error always comes up when the SD card is removed without unmounting
I'm using a Yocto distribution running on Imx6.
If the SD card is written to by a C++ application, it can be forcefully removed, but it cannot be umount(ed) until that application closes the file descriptors. The application itself does not need to close.
This solution is for mechanical applications, where the SD card (or other flash media) may become momentary disconnected, and needs to be resumed writing to by an application:
Answer:
Forcefully remove the SD card
Detect that the SD card is disconnected
Simplest way to do this is check the SD cards' mount size
read file "/sys/block/mmcblk1/size" and check it's > 0
Note that it's not necessary to close these before the card is removed. Linux is robust enough to write to a non-existing file. But this needs to be done before the SD card is umount'ed, otherwise umount will fail, and this is what was causing my problem. Umount also cannot be ran when the SD card is already re-inserted.
Umount the SD card
system("umount /mnt/storage");'
Now re-insert the SD card
Detect the Card has been reinserted
Mount the card again
system("mount /dev/mmcblk1p1 /mnt/storage")
If you have udev running on your system you can let udev's mount script auto-unmount your devices if they are removed.
Therefore add something like the following in /etc/udev/scripts/mount.sh:
UMOUNT="/bin/umount"
if [ "$ACTION" = "remove" ] && [ -x "$UMOUNT" ] && [ -n "$DEVNAME" ]; then
for mnt in `cat /proc/mounts | grep "$DEVNAME" | cut -f 2 -d " " `; do
$UMOUNT $mnt
done
fi
Furthermore you have to tell udev to run that mount script on added and removed devices. Therefore I've created /etc/udev/rules.d/autounmount.rules:
SUBSYSTEM=="block", ACTION=="remove" RUN+="/etc/udev/scripts/mount.sh"
This works fine for me using Yocto "Daisy" on an armv7 platform.