[英]How to find the owner process of an opened inode in Linux kernel?
给定一个 inode 号(一个打开的套接字),我想找到打开套接字的进程,这可能吗?
有什么我可以使用的功能吗?
有执行此操作的 lsof 工具,您也可以使用 /proc/ filsystem 看到这一点,如此处所回答。 如何在 C/C++ 应用程序中使用 lsof(List Opened Files)?
查看/proc
两种方法,您可以找到它,但您需要使用您想知道的 inode 进行 grep。 在下面的情况下,检查 inode 的最后一列。
$ cat /proc/net/tcp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
方括号中指定的值又是inode。
$ls -l /proc/5267/fd/10
lrwx------ 1 esunboj egi 64 Feb 18 12:07 /proc/5267/fd/10 -> socket:[19950]
我查看了ss
工具实现,以了解当我们使用-p
命令行选项时它们如何获取信息。
事实是,他们使用以下函数读取用户条目并生成相应的地图。 然后在显示套接字列表时,他们检查映射以查看是否可以找到 inode,如果可以,则他们有 PID。
注意下面的函数需要root用户才能找到所有的inode。 它检测名称为socket:[<inode>]
形式的文件( /proc/<pid>/fd/<number>
是软链接,尝试使用ls -l ...
列出它们以查看特殊套接字& FIFO 条目)。
static void user_ent_hash_build(void)
{
const char *root = getenv("PROC_ROOT") ? : "/proc/";
struct dirent *d;
char name[1024];
int nameoff;
DIR *dir;
char *pid_context;
char *sock_context;
const char *no_ctx = "unavailable";
static int user_ent_hash_build_init;
/* If show_users & show_proc_ctx set only do this once */
if (user_ent_hash_build_init != 0)
return;
user_ent_hash_build_init = 1;
strlcpy(name, root, sizeof(name));
if (strlen(name) == 0 || name[strlen(name)-1] != '/')
strcat(name, "/");
nameoff = strlen(name);
dir = opendir(name);
if (!dir)
return;
while ((d = readdir(dir)) != NULL) {
struct dirent *d1;
char process[16];
char *p;
int pid, pos;
DIR *dir1;
char crap;
if (sscanf(d->d_name, "%d%c", &pid, &crap) != 1)
continue;
if (getpidcon(pid, &pid_context) != 0)
pid_context = strdup(no_ctx);
snprintf(name + nameoff, sizeof(name) - nameoff, "%d/fd/", pid);
pos = strlen(name);
if ((dir1 = opendir(name)) == NULL) {
free(pid_context);
continue;
}
process[0] = '\0';
p = process;
while ((d1 = readdir(dir1)) != NULL) {
const char *pattern = "socket:[";
unsigned int ino;
char lnk[64];
int fd;
ssize_t link_len;
char tmp[1024];
if (sscanf(d1->d_name, "%d%c", &fd, &crap) != 1)
continue;
snprintf(name+pos, sizeof(name) - pos, "%d", fd);
link_len = readlink(name, lnk, sizeof(lnk)-1);
if (link_len == -1)
continue;
lnk[link_len] = '\0';
if (strncmp(lnk, pattern, strlen(pattern)))
continue;
sscanf(lnk, "socket:[%u]", &ino);
snprintf(tmp, sizeof(tmp), "%s/%d/fd/%s",
root, pid, d1->d_name);
if (getfilecon(tmp, &sock_context) <= 0)
sock_context = strdup(no_ctx);
if (*p == '\0') {
FILE *fp;
snprintf(tmp, sizeof(tmp), "%s/%d/stat",
root, pid);
if ((fp = fopen(tmp, "r")) != NULL) {
if (fscanf(fp, "%*d (%[^)])", p) < 1)
; /* ignore */
fclose(fp);
}
}
user_ent_add(ino, p, pid, fd,
pid_context, sock_context);
free(sock_context);
}
free(pid_context);
closedir(dir1);
}
closedir(dir);
}
因此,换句话说,事实是内核中似乎没有 PID 函数的 inode(或者最终用户无法访问它)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.