美文网首页
使用udev实现插入U盘自动挂载的一些记录

使用udev实现插入U盘自动挂载的一些记录

作者: 苍蝇的梦 | 来源:发表于2019-06-23 12:02 被阅读0次

    2019-06-10 遇到的一点小问题
    新需求是在U盘插入设备时实现自动挂载功能,一般都是推荐使用udev。记录一下第一次使用出现的问题。

    .

    刚开始先按网上找的方法
    ,在/etc/udev/rules.d/创建个.rules文件,再根据插入动作调用.sh文件来执行mount操作:

    KERNEL=="sd[a-z]*",ACTION=="add",RUN+="/srv/wannoo.sh %k"
    

    语法挺简单的,就是容易遇坑:有一次KERNELACTION顺序弄反,然后就执行失败;还有一U盘只能读到sdd,所以KERNEL=="sd[a-z][1-9]"读不到,为了兼容只能改成KERNEL=="sd[a-z]"*;然后换行也要注意;还有就是一行命令数限制五个,多了后面的不生效。
    不过虽然把语法弄懂了,但mount还是出错了:

    mount: /tmp/sdc1: permission denied.
    echo $? == 32    #分区不支持挂载是返回这个,随便输个地址也返回这个,服了。
    
    FUSE exfat 1.3.0    #在命令行mount也有提示这句,返回值为0,能正常mount。
    fusermount: mount failed: Operation not permitted
    echo $? ==  1    #这边多了上面那句返回,然后返回值是1,挂载失败。
    
    WARN: volume was not unmounted cleanly.    #偶尔出现这句,可以忽略了。
    
    .

    测了几次,依然没有解决。只好再到ArchLinux的wiki上面仔细看看udev (简体中文)。按说明修改了/etc/systemd/system/systemd-udevd.service文件,也按要求把挂载动作放在 udev 规则内部,可惜测试了还是不行。也按这篇Auto-mounting USB storage with udev的示例试了一下,依旧失败返回fusermount: mount failed: Operation not permitted

    KERNEL=="sd[a-z]*",ACTION=="add",RUN+="/bin/mkdir /tmp/%k",RUN+="bin/mount -r /dev/%k /tmp/%k"
    
    .

    因为udev (简体中文)写的翻译时间是2017-10-19,有点旧了,所以又仔细看了看udev英文文档。发现里面使用的示例不是bin/mount而是使用/usr/bin/systemd-mount去挂载。

    ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode /media"
    

    在控制台试了下systemd-mount命令

    [root@archlinux ~]# /usr/bin/systemd-mount /dev/sdb2 /media/sdb2
    Failed to start transient mount unit: Unit media-sdb2.mount already exists.    #之前未卸载
        # echo $? == 1
    [root@archlinux ~]# systemd-mount -u /media/sdb2
    Stopped unit media-sdb2.mount for mount point: /media/sdb2    #卸载成功
        # echo $? == 0
    [root@archlinux ~]# systemd-mount /dev/sdb2 /media/sdb2
    Started unit media-sdb2.mount for mount point: /media/sdb2    #任务执行成功,不一定mount成功。
        # echo $? == 0
    [root@archlinux ~]# systemctl status media-sdb2.mount
    * media-sdb2.mount - /media/sdb2
       Loaded: loaded (/run/systemd/transient/media-sdb2.mount; transient)
    Transient: yes
       Active: active (mounted) since Tue 2019-06-11 08:55:28 UTC; 32s ago
        Where: /media/sdb2
         What: /dev/sdb2
        Tasks: 1 (limit: 4915)
       Memory: 2.5M
       CGroup: /system.slice/media-sdb2.mount
               `-10153 /usr/bin/mount.exfat /dev/sdb2 /media/sdb2 -o rw
    
    Jun 11 08:55:27 archlinux systemd[1]: Mounting /media/sdb2...
    Jun 11 08:55:28 archlinux systemd[1]: Mounted /media/sdb2.
      # echo $? == 0
    

    测试中发现加上--automount=yes选项之后,如果使用umount 命令去卸载,df能看出成功,但是再cd进入之前挂载的文件夹又会自动挂载起来,所以卸载动作需要使用systemd-umount 命令systemd-mount -u 命令去卸载。

    最后,在.rules文件里使用systemd-mount命令试一下挂载U盘。

    ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", RUN{program}+="/bin/mkdir /media/%k" ,RUN{program}+="/usr/bin/systemd-mount --no-block --collect $devnode /media/%k"
    

    有一个U盘成功了,但有一个U盘一直没看到挂载成功,所以又用控制台试了一下。

    [root@archlinux ~]# /usr/bin/systemd-mount --no-block --collect /dev/sdb2 /media/sdb2
    Started unit media-sdb2.mount for mount point: /media/sdb2    #任务执行成功,不一定mount成功。
    [root@archlinux ~]# systemd-mount /dev/sdb2 /media/sdb2
    Job for media-sdb2.mount failed.    #不使用--no-block选项能等到结果出现
    See "systemctl status media-sdb2.mount" and "journalctl -xe" for details.    #根据提示去看状态
    [root@archlinux media]# systemctl status media-sdb2.mount
    * media-sdb2.mount - /media/sdb2
       Loaded: loaded (/run/systemd/transient/media-sdb2.mount; transient)
    Transient: yes
       Active: failed (Result: exit-code) since Tue 2019-06-11 08:48:38 UTC; 5s ago
        Where: /media/sdb2
         What: /dev/sdb2
    
    Jun 11 08:48:38 archlinux systemd[1]: Mounting /media/sdb2...
    Jun 11 08:48:38 archlinux mount[5851]: mount: /media/sdb2: unknown filesystem type 'exfat'.
    Jun 11 08:48:38 archlinux systemd[1]: media-sdb2.mount: Mount process exited, code=exited, status=32/n/a
    Jun 11 08:48:38 archlinux systemd[1]: media-sdb2.mount: Failed with result 'exit-code'.
    Jun 11 08:48:38 archlinux systemd[1]: Failed to mount /media/sdb2.
    [root@archlinux ~]# pacman -Sy exfat-utils
    ...     #成功安装 exfat-utils
    

    加上--no-block可以异步等待结果,但现在并不需要,所以去掉后重试。马上返回失败信息了,然后根据提示使用systemctl status media-sdb2.mount查看状态及记录,才知道是缺少exfat支持,这个问题之前在其他设备上monut时有遇到过,使用pacman -Sy exfat-utils安装后,重新拔插U盘再试了一次:

    [root@archlinux media]# systemctl status media-sdb2.mount
    * media-sdb2.mount - /media/sdb2
       Loaded: loaded (/run/systemd/transient/media-sdb2.mount; transient)
    Transient: yes
       Active: activating (mounting) since Tue 2019-06-11 08:50:36 UTC; 93ms ago
        Where: /media/sdb2
         What: /dev/sdb2
    Cntrl PID: 7177 (mount)
        Tasks: 2 (limit: 4915)
       Memory: 2.5M
       CGroup: /system.slice/media-sdb2.mount
               |-7177 /usr/bin/mount /dev/sdb2 /media/sdb2
               `-7178 /usr/bin/mount.exfat /dev/sdb2 /media/sdb2 -o rw
    
    Jun 11 08:50:36 archlinux systemd[1]: Mounting /media/sdb2...
        # echo $? == 3
    

    不懂为什么返回值是3。使用df看了下,已经正常挂载了。先不理会。

    .

    网上随便搜了几篇文章参考,这边记录一下:

    使用 udev 高效、动态地管理 Linux 设备文件
    在 Linux 中如何编写基本的 udev 规则
    An introduction to Udev: The Linux subsystem for managing device events
    udev学习笔记汇总

    关于udevadm命令,有用到几个先记录一下:

    #实时监听U盘拔插,在控制台显示动态:
    udevadm monitor
    #模拟插拔动作:
    udevadm test --action="add" /devices/pci0000:00/0000:00:14.0/usb1/1-2/1-2.3/1-2.3:1.0/host3/target3:0:0/3:0:0:0/block/sdd
    #规则修改后,重载生效:
    udevadm control --reload
    

    然后有几个会用到的位置也记一下:

    /usr/lib/udev/rules.d    #系统定义的规则
    /etc/udev/rules.d/    #自定义的规则
    /usr/lib/systemd/system/systemd-udevd.service    #系统定义的配置文件
    /etc/systemd/system/systemd-udevd.service    #将系统定义的配置文件复制过来修改
    

    https://wiki.archlinux.org/index.php/Udisks_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)

    相关文章

      网友评论

          本文标题:使用udev实现插入U盘自动挂载的一些记录

          本文链接:https://www.haomeiwen.com/subject/ukctfctx.html