FUSE 파일 시스템을 구현하는 프로세스 찾기

FUSE 파일 시스템을 구현하는 프로세스 찾기

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

15007과 15031 중 어느 것이 dir1이고 어느 것이 dir2인지 어떻게 알 수 있나요? 이상적으로는 이를 자동화하고 싶습니다. 즉, 실행하여 somecommand /home/gilles/net/dir115007(또는 15031 또는 경우에 따라 "FUSE 마운트 지점이 아님")을 표시하도록 합니다.

프로세스가 연결된 호스트 및 포트 추적, 서버 측 프로세스에서 열리는 파일 추적 등 SSHFS에만 국한된 것이 아니라 일반적인 답변을 찾고 있습니다. sshfs이는 전혀 불가능할 수도 있습니다. 연결 공유로 인해.

저는 주로 Linux 답변에 관심이 있지만 모든 FUSE 지원 시스템에 적용되는 일반적인 답변이 이상적입니다.

궁금한 이유: 작업을 추적하고, 문제가 발생하면 종료합니다.

답변1

나는 이것이 불가능하다고 생각한다. 이유는 다음과 같습니다. ./dev/fusestruct 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

커널을 시작하고 sshfs를 마운트한 후 mount를 실행했습니다.

[email protected]:/tmp on /root/tmp type fuse.sshfs (rw,nosuid,nodev,relatime,pid=1549,user_id=0,group_id=0)

성공? 불행하게도:

root      1552  0.0  0.0  45152   332 ?        Ssl  13:39   0:00 sshfs [email protected]:/tmp tmp                                                                

그런 다음 나머지 sshfs 프로세스는 마운트를 생성한 프로세스의 하위 프로세스라는 것을 깨달았습니다. fd에서 상속됩니다. 퓨즈를 구현하면 fd를 상속하는 여러 프로세스를 가질 수 있습니다. 원래 프로세스 트리에서 완전히 벗어난 UNIX 소켓에 fd를 전달할 수 있습니다.

소켓에 이 메타데이터가 있고 /proc를 구문 분석하면 이를 알 수 있기 때문에 "이 TCP 포트를 소유한 사람" 정보를 얻을 수 있습니다. 불행하게도 퓨즈 fd 는 일반 fd 입니다 /dev/fuse. 해당 fd가 특별해지지 않는 한 어떻게 구현해야 할지 모르겠습니다.

답변2

pslsof원하는 정보를 얻기 위해 및 의 조합을 사용할 수 있다고 생각합니다 .

사용자 공간 애플리케이션은 항상 마운트 지점 매개변수를 인수로 사용하는 것 같습니다. 마운트 지점을 인수로 사용하는 명령(예: )을 찾기 위해 프로세스 목록을 살펴보는 경우 ps -ef | egrep ' <mount>( |$)'모든 FUSE 프로세스를 가져와야 합니다. 물론 마운트 지점을 매개변수로 사용하는 다른 프로세스도 얻을 수 있습니다(예: ls <mount>). 결과 목록을 가져와 실행 lsof하고 열린 연결과 관련된 프로세스를 찾으면 /dev/fuse마운트 지점 FUSE와 관련된 프로세스를 찾을 수 있습니다.

예를 들어, 내 시스템에 gvfs FUSE 프로세스가 있습니다.

gvfsd-fuse on /run/user/1000/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000)

ps모든 작업을 수행하기 위해 간단한 쉘 명령을 실행하면 lsof다음과 같은 결과가 나타납니다.

~$ for pid in \
     $(ps -ef | egrep ' /run/user/1000/gvfs( |$)' | awk '{print $2}')
   do 
     ps -f -p $(lsof -p "$pid" | fgrep /dev/fuse | awk '{print $2}')
   done
UID        PID  PPID  C STIME TTY          TIME CMD
username  2241  1997  0 Apr25 ?        00:00:00 /usr/lib/gvfs/gvfsd-fuse /run/user/1000/gvfs -f -o big_writes

이것은 당신이 원하는 것을하는 것 같습니다. PID 또는 파일 핸들과 마운트 지점 간의 매핑을 알려주는 FUSE 수준 커널 인터페이스가 있으면 좋겠지만 존재하지 않는 것 같습니다.

관련 정보