实现FUSE文件系统时,如何获取mkdir调用时的当前目录及跟踪cd操作后的工作目录?
解决FUSE文件系统中获取当前目录与跟踪cd变化的问题
首先得说清楚:FUSE用户态进程的getcwd()返回根目录是正常的——因为FUSE进程本身的工作目录就是挂载点(甚至可能是其他无关目录),它没法直接拿到发起请求的用户进程的当前工作目录。下面分两种场景给你具体解决方案:
一、在mkdir时获取用户执行命令的当前目录
当用户执行mkdir时,你没法直接从FUSE的mkdir回调参数里拿到用户的原始工作目录,但可以通过以下步骤精准获取:
- 在
mkdir回调中,调用fuse_get_context()获取请求上下文,其中包含发起请求的用户进程PID(ctx->pid)。 - 构造路径
/proc/<pid>/cwd,这是一个指向该进程当前工作目录的符号链接。 - 使用
readlink()函数读取这个符号链接的目标路径,就能得到用户执行mkdir时所在的宿主系统绝对路径;你可以截取挂载点之后的部分,得到相对于FUSE文件系统根的路径。
举个简单的代码片段示例:
#include <fuse.h> #include <unistd.h> #include <stdio.h> #include <string.h> static int my_mkdir(const char *path, mode_t mode) { struct fuse_context *ctx = fuse_get_context(); char proc_path[PATH_MAX]; char proc_cwd[PATH_MAX]; // 拼接目标进程的cwd符号链接路径 snprintf(proc_path, sizeof(proc_path), "/proc/%d/cwd", ctx->pid); ssize_t len = readlink(proc_path, proc_cwd, sizeof(proc_cwd)-1); if (len != -1) { proc_cwd[len] = '\0'; printf("User ran mkdir from: %s\n", proc_cwd); // 假设挂载点是/mnt/fuse,截取相对路径 char *fuse_rel_path = strstr(proc_cwd, "/mnt/fuse"); if (fuse_rel_path) { fuse_rel_path += strlen("/mnt/fuse"); printf("Relative to FUSE root: %s\n", fuse_rel_path); } } // 你的mkdir核心逻辑... return 0; }
注意事项:
- 这个方法依赖
/proc文件系统,如果是没有/proc的嵌入式环境,该方法不可用。 - 要注意权限:FUSE进程需要有读取
/proc/<pid>/cwd的权限,普通用户发起的请求一般没问题,但跨用户进程可能会有权限限制。
另外还有个折中的办法:如果用户用相对路径执行mkdir(且路径不含../),FUSE收到的path参数是解析后的绝对路径(相对于FUSE根),此时目标目录的父目录就是用户执行命令时的当前目录。但这个方法无法处理带../的相对路径场景,通用性有限。
二、跟踪用户的cd命令变化
这里必须明确:cd是shell的内置命令,它不会触发任何FUSE文件系统操作——因为cd只是修改用户进程自身的工作目录,不会对文件系统进行创建、读取、修改等操作,所以没法通过FUSE回调直接捕获cd事件。
你可以通过以下间接方式实现跟踪:
- 复用上面的
/proc/<pid>/cwd方法:在用户执行任何其他FUSE操作(比如ls、touch、rm等)时,获取并记录该进程的当前工作目录,间接感知用户在FUSE文件系统中的位置变化。 - 如果是你自己的应用程序使用该FUSE文件系统,可以在应用层添加逻辑,调用
chdir时主动通知FUSE进程。 - 针对特定shell(比如bash),可以修改shell配置(比如
PROMPT_COMMAND变量),让shell在每次cd后执行一个小脚本,向FUSE进程发送位置变化通知。但这个方法通用性不强,只适用于定制化的shell环境。
总结一下:要精确获取用户操作时的当前目录,/proc/<pid>/cwd是最可靠的方案;而跟踪cd只能通过间接手段,因为cd本身不会触发FUSE请求。
内容的提问来源于stack exchange,提问作者bobthesnob
相关产品推荐
相关产品推荐

