FUSEファイルシステムドライバのプロセスIDを取得するには?
たとえば、現在私のLinuxシステムには2つの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/dir1
15007(または15031、または場合によっては「FUSEマウントポイントではありません」)を表示するようにします。
プロセスが接続されているホストとポートの追跡、サーバー側のプロセスで開かれるファイルの追跡など、SSHFSに限定されていない一般的な答えを探しています。sshfs
これはまったく不可能かもしれません。接続共有のため。
私は主にLinuxの答えに興味がありますが、すべてのFUSEサポートシステムに適用される一般的な答えが理想的です。
気になる理由:タスクを追跡し、問題が発生した場合は終了します。
答え1
これは不可能だと思います。理由は次のとおりです。/dev/fuse
その後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
カーネルを起動して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
ps
lsof
必要な情報を得るために、およびの組み合わせを使用できると思います。
ユーザー空間アプリケーションは常にマウントポイントパラメータを引数として使用しているようです。マウントポイントを引数として使用するコマンド(例:)を見つけるためにプロセスのリストを調べる場合は、すべての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レベルのカーネルインタフェースがあればいいのですが、存在しないようです。