linux系统 自带光驱弹出异常问题记录

问题: 在linux系统下,使用插件挂载与卸载光驱。 在按下物理设备自带光驱的弹出按钮后,光驱正常弹出,但lsblk下挂载点还在,且目录可看。

自己的机器不复现,问题机器不在身边 调试起来有些不方便。

对问题分析、排查、定位过程:

 首先简单的加日志替换 挂载插件udevil--devmon shell脚本 查看日志。 发现按弹出按钮后无日志更新,也就是说没有触发正常的devmon流程。

  阅读源码分析开源挂载插件流转。发现devmon进程,实际是一个while 一直在read -u ${COPROC[0]};  这里的${COPROC[0]} 是协同进程的管道的文件描述符。 可以通过echo打印COPROC_PID来看 pid找到向他发送数据的进程。 这里我看到的就是 udevli这个插件进程。
通过日志,可以判断 在执行弹出操作时,一直是阻塞到read -u ${COPROC[0]}; 也就是说udevil进程没有向他发送数据。再继续阅读udevil的源码,整理了一下他的设计。

  在插件源码 udevil.c中,通过调用 udev库函数,新建了一个 socket(PF_NETLINK, SOCK_DGRAM|SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT);  这里PF_NETLINK是linux特殊的socket可以建立内核与用户的通信。 查阅资料看大多usb光驱等事件都是这样搞得。

  建立完成后,再将fd 通过g_io_channel_watch检测G_IO_IN(需读取消息事件),如有事件就进入cb处理,cb中通过 udev_device_get_action等函数判断设备执行了什么操作。最后调用printf,devmon中的read就可以收到。 这里对于printf的使用还没有弄太懂。

 在源码中整个流程中间可能会影响接收的地方都加了日志,在udevil.c中使用printf会发送到devmon中 所以临时封装一个log_func 将我的日志重定向到指定文件。 编译源码。 替换到异常机器,发现没有进入错误逻辑,就是在弹出操作后,一直没有进入 cb也就是说没有收到内核的G_IO_IN。 

  这就奇怪了,同一操作系统iso 在别的设备上都是正常的,此异常设备用移动光驱也没有问题。就是自带光驱弹出有问题。这个udevil插件还是依靠的udev机制,查阅了一下资料,了解了下udev。

  使用udevadm monitor -p命令可以监测 内核消息与udev事件,测试了一下。正常的信息为:
先会收到:

KERNEL[65601.889278] change   /devices/pci0000:00/0000:00:02.0/0000:03:00.0/usb1/1-3/1-3:1.0/host4/target4:0:0/4:0:0:0/block/sr0 (block)

这是kernel到的设备变动。  

紧接着通过netlink 套接字会发给 UDEV:

UDEV  [65593.698640] change   /devices/pci0000:00/0000:00:02.0/0000:03:00.0/usb1/1-3/1-3:1.0/host4/target4:0:0/4:0:0:0/block/sr0 (block)、

果然第二条及时UDEV开头的事件,再后面就是我插件干的事了。

这里的"change"是光驱读盘与弹出事件;
还有“add”新设备插入事件;
“remove”设备拔出事件; 

在异常设备上 弹出时没有收到第一条KERNEL信息;也就是说内核都没检测到设备动作。 自然无法向下流转,到不了我的插件执行卸载挂载点操作。/var/log/message 与dmesg也没有异常日志。

总结: 分析定位后是设备问题,因为装不装我的挂载插件, KERNEL都检测不到设备变动,UDEV也没法拿到。 

了解了一下linux下 UDEV机制,博大精深。

udevadm monitor命令非常好用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值