You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用inotify检测USB插入后opendir遇权限拒绝问题排查

问题原因

核心是USB挂载的时序与inotify事件触发时机不匹配:

Linux系统挂载USB设备的流程是分步执行的:

  1. 先创建/media/michel/MYUSB挂载点目录
  2. 将USB设备的文件系统挂载到该目录
  3. 调整挂载点的权限/归属,确保当前用户可访问

你通过IN_CREATE|IN_ISDIR监控到的事件,是在第一步完成后就触发的——此时USB文件系统还没挂载,你访问的只是系统临时创建的空目录,这个目录的权限通常是root所有,普通用户调用opendir自然会返回权限拒绝错误。

而提前插入USB时,整个挂载流程已经完成,目录的权限和归属都已调整为当前用户可访问,所以opendir能正常执行。

解决办法

1. 延迟重试访问

收到inotify事件后,不要立即调用opendir,而是短暂等待后重试(挂载操作通常在几百毫秒内完成),示例代码如下:

// 收到事件后的处理逻辑
DIR *usbdir = NULL;
int retry_count = 5;
const int retry_delay_ms = 200;

while (retry_count-- > 0 && usbdir == NULL) {
    usbdir = opendir(folders);
    if (usbdir == NULL) {
        // 等待后重试,usleep单位为微秒
        usleep(retry_delay_ms * 1000);
    }
}

if (usbdir == NULL) {
    perror("Failed to open USB directory after retries");
} else {
    // 执行目录扫描逻辑
    // ...
    closedir(usbdir);
}

2. 监控挂载完成的属性变化

除了IN_CREATE,额外监控IN_ATTRIB事件——当USB文件系统挂载完成后,挂载点的文件属性(如文件系统类型、权限)会发生变化,触发该事件。此时再调用opendir,就能确保访问的是挂载后的USB文件系统。

修改inotify_add_watch的事件参数:

evtfd = inotify_add_watch(notifyfd, folders, IN_CREATE|IN_ISDIR|IN_ATTRIB);

然后在事件处理时,优先响应IN_ATTRIB事件(或同时处理,确保挂载完成后再操作)。

3. 结合挂载状态验证

可以读取/proc/mounts文件,检查目标目录是否已经完成挂载,确认后再执行目录扫描。比如通过解析/proc/mounts的内容,查找是否有/media/michel/MYUSB对应的挂载条目。

内容的提问来源于stack exchange,提问作者Michel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 14:50:03