如何获取 FUSE 文件系统驱动程序的进程 ID?
例如,我目前在 Linux 机器上安装了两个 SSHFS 文件系统:
$ grep sshfs /proc/mounts
host:dir1 /home/gilles/net/dir1 fuse.sshfs rw,nosuid,nodev,relatime,user_id=1000,group_id=1000 0 0
host:dir2 /home/gilles/net/dir2 fuse.sshfs rw,nosuid,nodev,relatime,user_id=1000,group_id=1000 0 0
$ pidof sshfs
15031 15007
Run Code Online (Sandbox Code Playgroud)
我怎么知道 15007 和 15031 中哪个是 dir1,哪个是 dir2?理想情况下,我想自动化,即运行somecommand /home/gilles/net/dir1并让它显示 15007(或 15031,或“非 FUSE 挂载点”,视情况而定)。
请注意,我正在寻找一个通用的答案,而不是特定于 SSHFS 的答案,例如跟踪sshfs进程连接到哪个主机和端口,以及服务器端进程打开了哪些文件——这甚至可能根本不可能由于连接共享。
我主要对 Linux 答案感兴趣,但适用于所有支持 FUSE 的系统的通用答案将是理想的。
为什么我想知道:跟踪它的操作,在出现问题时杀死它等。
我认为这是不可能的。原因如下。我采取了简单的方法,即将打开的进程的 pid 添加/dev/fuse到 fusion 在挂载时创建的元数据中struct fuse_conn。pid=然后,我使用该信息在 mount 命令中显示一个字段。该补丁非常简单:
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 7354dc1..32b05ca 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -402,6 +402,9 @@ struct fuse_conn {
/** The group id for this mount */
kgid_t group_id;
+ /** The pid mounting process */
+ pid_t pid;
+
/** The fuse mount flags for this mount */
unsigned flags;
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index e8799c1..23a27be 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -554,6 +554,7 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root)
struct super_block *sb = root->d_sb;
struct fuse_conn *fc = get_fuse_conn_super(sb);
+ seq_printf(m, ",pid=%u", fc->pid);
seq_printf(m, ",user_id=%u", from_kuid_munged(&init_user_ns, fc->user_id));
seq_printf(m, ",group_id=%u", from_kgid_munged(&init_user_ns, fc->group_id));
if (fc->flags & FUSE_DEFAULT_PERMISSIONS)
@@ -1042,6 +1043,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
fc->release = fuse_free_conn;
fc->flags = d.flags;
+ fc->pid = current->pid;
fc->user_id = d.user_id;
fc->group_id = d.group_id;
fc->max_read = max_t(unsigned, 4096, d.max_read);
def@fractal [6:37] ~/p/linux -- master
Run Code Online (Sandbox Code Playgroud)
我启动了内核,安装了 sshfs,然后运行了 mount:
root@192.168.1.1:/tmp on /root/tmp type fuse.sshfs (rw,nosuid,nodev,relatime,pid=1549,user_id=0,group_id=0)
Run Code Online (Sandbox Code Playgroud)
成功?不幸的是,没有:
root 1552 0.0 0.0 45152 332 ? Ssl 13:39 0:00 sshfs root@192.168.1.1:/tmp tmp
Run Code Online (Sandbox Code Playgroud)
然后我意识到:剩余的 sshfs 进程是创建挂载的进程的子进程。它继承自fd。随着熔丝的实现,我们可以有多个继承自 fd 的进程。我们可以让 fd 在 UNIX 套接字中传递,完全脱离原始进程树。
我们可以获得“谁拥有这个 TCP 端口”信息,因为套接字具有此元数据,并且只需解析 /proc 即可告诉我们该信息。不幸的是,fuse fd 是 上的常规 fd /dev/fuse。除非那个 fd 变得特别,否则我不知道如何实现它。