使用内核命名空间 PID 从全局范围中杀死进程

Posted

技术标签:

【中文标题】使用内核命名空间 PID 从全局范围中杀死进程【英文标题】:Killing a process from the global scope using its kernel namespace PID 【发布时间】:2013-12-01 01:01:01 【问题描述】:

今天在使用 Linux kernel namespaces 时遇到了一些困难,特别是将 unique PID namespace 内的 PID 与全局 PID 命名空间内的 PID 相关联

我需要能够执行以下操作之一:

a) 使用命名空间分配的 PID 从全局范围杀死进程

b) 将命名空间特定的 PID 转换为全局 PID,这样我就可以从全局范围中杀死 PID

c) 启用 PID 命名空间内的进程向我报告其全局 PID,以便我可以从全局范围中终止 PID

有一些关于在命名空间场景here 中包含 PID 信息的进程结构的讨论。我不确定如何/是否可以从用户级应用程序访问这些结构,或者我是否需要通过内核 hack 添加支持。

为什么? 我有一个当前使用网络命名空间的应用程序。我正在添加对 PID 命名空间的支持。以下是它目前的工作方式:

在引入 PID 命名空间之前: 主应用程序当前在另一个网络命名空间中启动一个 bash 控制台。然后它使用该 bash 控制台启动程序并让这些程序报告它们当前的 PID。当主应用程序想要杀死该网络命名空间中的子进程时,它只是告诉操作系统杀死返回的 PID。

使用 PID 命名空间(中断状态): 主应用程序当前在另一个网络和 PID 命名空间中启动一个 bash 控制台。然后它使用该 bash 控制台启动程序并让这些程序报告它们当前的 PID。但是,返回的当前 PID 在全局 PID 命名空间中无效(可能是 10,当全局命名空间中的 PID 为 56000 时)。结果,主应用程序无法杀死该网络+ PID命名空间中的子进程

一如既往,感谢任何指导

【问题讨论】:

除非您在内核中,否则如何在命名空间之间转换 pid 绝对不明显。但是既然你可以让你的 bash 控制台启动程序,为什么不让它启动kill -9 pid 程序,其中pid 是受害者在 bash 控制台的 pid 命名空间中的 pid? bash 控制台已经被交互式地用于显示正在执行的应用程序。我在这里破解了一个开源软件,所以我可以改变一些东西,但我在某种程度上受到了限制 我不完全确定我是否完全理解您的问题域,但是 afaik,可以禁用 pid 命名空间并仅使用网络命名空间,在这种情况下,由新 bash shell 创建的进程不会无效,您可以从那里杀死它。 @rakib 是的——以前的状态只是使用网络命名空间。现在我也想使用 PID 命名空间(我正在添加这个功能)。 @BSchlinker 使用 PIDNS 的整个概念是将其与主机的 PIDNS 隔离,如果有人试图从主机中杀死它,我认为它不应该允许这样做,或者也可能存在安全问题。如何纠正将访问 shell 并终止进程的脚本。就好像你可以从 shell 运行脚本一样。 【参考方案1】:

一种方法可以是在 pid 队列中搜索与目标 pid 匹配的进程描述符,如果报告 shell 在同一个工作区上,它可以进行系统调用以获取其他进程的“进程描述符”并进行某种for循环在/proc/

中查找进程描述

您可能还想看看这里:http://lkml.indiana.edu/hypermail/linux/kernel/0707.0/1701.html 特别是这部分:

/*
 * the helpers to get the pid's id seen from different namespaces
 *
 * pid_nr() : global id, i.e. the id seen from the init namespace;
 * pid_vnr() : virtual id, i.e. the id seen from the namespace this pid
 * belongs to. this only makes sence when called in the
 * context of the task that belongs to the same namespace;
 * pid_nr_ns() : id seen from the ns specified.
 *
 * see also task_xid_nr() etc in include/linux/sched.h
 */

static inline pid_t pid_nr(struct pid *pid)

pid_t nr = 0;
if (pid)
-    nr = pid->nr;
+    nr = pid->numbers[0].nr;
return nr;

希望对你有帮助!

最好的问候!

【讨论】:

以上是关于使用内核命名空间 PID 从全局范围中杀死进程的主要内容,如果未能解决你的问题,请参考以下文章

理解Docker容器的进程管理

命名空间中的类并使用模板类型作为返回类型时的全局范围友元运算符声明

名称空间

并行运行多个子进程 - python 2.7

Docker的底层原理实现(二十)

在全局范围内声明命名空间错误