admin管理员组

文章数量:1558091

openwrt下U盘自动挂载

文章目录

  • openwrt下U盘自动挂载
    • 1 背景介绍
    • 2 实验环境
    • 3 软件改动
    • 4 测试现象

1 背景介绍

openwrt默认配置下不支持U盘的自动挂载,需要使用mount命令来手动挂载。为了更方便用户的使用,有必要在插入U盘后让系统自动完成挂载。

网上搜的很多方法不可行,所以自己实验成功后想分享给大家正确的方法。本人实验了两种方法:

  • 修改/etc/config/fstable文件,将其中的anon_mount置1(不可行)

    插入U盘后,/mnt文件夹下自动生成sda1文件夹;拔出U盘, sda1文件夹消失;

    但是reboot后会失效,于是尝试在源码中修改anon_mount为1,还是失败,原因:相应文件在编译时每次从openwrt/dl/文件夹下解压,dl/中默认anon_mount为0,所以不成功。

  • 修改openwrt/package/system/fstools/files/mount.hotplug文件(可行)

    使用第二种方法可行,并且reboot后仍然有效,接下的实验会详细讲解如何更改配置和源代码。

2 实验环境

  • 使用的是Banana Pi BPI-R64开发板,上面的主控芯片是联发科的MT7622,其上有一个USB接口。使用的是openwrt开源系统。
  • USB 3.0 大容量存储设备(U盘)。

3 软件改动

  • 在openwrt menuconfig中配置block-mount,lsblk,ntfs-3g。


    Note: 本文重点讲自动挂载方案,本文默认USB storage相关配置、exFAT/FAT/NTFS/ext4文件系统支持等已经选上,配置可参考: openwrt U盘热插拔自动挂载

    增加lsblk命令是为了给后面修改的脚本使用。通过“lsblk -f"命令可以输出未挂载设备的真实文件系统格式。

    本人最初尝试过"fdisk -l"命令,但其显示的文件系统不准确,比如会把exFAT格式的U盘显示为HPFS/NTFS格式。

    也尝试过“df -T"命令,但其只能显示已挂载设备的文件系统格式,而本文是想在挂载设备之前就识别出文件系统格式。
    配置ntfs-3g是为了解决NTFS只能读不能写的问题

    在linux内核5.15之前的版本中,对NTFS缺乏功能齐全的读/写支持。内核5.15版本添加了对NTFS的完整支持。我使用的是5.10内核版本,默认情况下,在挂载了NTFS文件系统后,只能读取移动硬盘的内容,而不能写。openWRT的menuconfig里面提供了ntfs-3g这个插件的配置,默认情况下不安装ntfs-3g。选中这个配置后,能解决NTFS只读的问题。

  • 更改源码文件openwrt/package/system/fstools/files/mount.hotplug内容如下:

    #!/bin/ash
    
    case "$ACTION" in
        add)
            for i in $(ls /dev/ | grep 'sd[a-z][1-9]')
            do
                filetype=ext4
                lsblk -f | grep exfat
                if [ $? -eq 0 ]; then
                    filetype=exfat
                fi
    
                lsblk -f | grep ntfs
                if [ $? -eq 0 ]; then
                    filetype=ntfs-3g
                fi
    
                lsblk -f | grep vfat
                if [ $? -eq 0 ]; then
                    filetype=vfat
                fi
    
                mkdir -p /mnt/$i
                mount -t $filetype -o iocharset=utf8,rw /dev/$i /mnt/$i
            done
            ;;
        remove)
            MOUNT=`mount | grep -o '/mnt/sd[a-z][1-9]'`
            for j in $MOUNT
            do
                umount $j
            done
    
            DIR=`ls /mnt | grep -o 'sd[a-z][1-9]'`
            for k in $DIR
            do
                rm -r /mnt/$k
            done
            ;;
    esac
    

    本人实验了网上别人提供的修改,但多多少少都有些问题。经过多次完善,形成了上面的修改方法。

    上面脚本首先通过lsblk命令来判断未挂载设备的文件系统格式,然后再mount并带上filetype参数。如果mount时不带上filetype参数,系统会尝试不同的文件系统直到最终挂载。这种尝试会导致许多“/dev/sda: Can’t open blockdev”输出,影响用户体验。
    mount时带上“iocharset=utf8”是为了解决U盘中中文文件名或者中文内容在openwrt下乱码的问题。

    拔出U盘时,上面脚本会进行umount并删除残留文件夹。

    这里需要说明很重要的一点:linux系统下拔出U盘之前一定要手动umount,不然刚更改的内容可能会丢失。原因:linux系统下,向U盘写内容,并不会直接把内容写到U盘,而是先写到文件系统的buffer,拔出U盘之前的手动umount会触发把buffer里面的内容同步到U盘。若拔出U盘之前没有手动umount,buffer里面的内容就不会同步到U盘,从而导致最新的更改丢失。

    同时,不先手动umount情况下拔出U盘会有错误输出:

    上面脚本在拔出U盘时进行umount,看着好像没啥作用,毕竟U盘已经拔出,但实际测试发现并没有什么影响,就当做一种保护措施吧。脚本中的umount并不能代替手动umount,拔U盘之前一定要先手动执行umount!!!

4 测试现象

完成上述配置和修改后,编译并运行系统,插入U盘后,会自动完成挂载,在/mnt/目录下增加了一个sda1/目录;手动umount,拔出U盘,/mnt/下的sda1目录消失。

本文标签: OpenWRT