【发布时间】:2012-11-14 05:44:50
【问题描述】:
Python 中是否支持系统调用 clone(2)(not os.fork)?我想在 Python 下使用 Linux 命名空间,但似乎没有太多关于它的信息。
编辑:
我认为带有 libc 的 ctypes 是答案,但我仍然没有任何成功。 fork 没有任何问题,因为它没有任何参数,那么这段代码就可以工作:
from ctypes import *
libc = CDLL("libc.so.6")
libc.fork()
使用克隆我正在尝试这个:
from ctypes import *
def f():
print "In callback."
return 0
libc = CDLL("libc.so.6")
f_c = CFUNCTYPE(c_int)(f)
print libc.getpid()
print libc.clone(f_c)
print get_errno()
克隆实际上有这个签名:
int clone(int (*fn)(void *), void *child_stack, int 标志,无效 arg,... / pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
我仍然需要传递 *child_stack 和标志,但不知道该怎么做。有什么帮助吗?
更多编辑:
我现在明白了:
from ctypes import *
def f():
print "In callback."
return 0
libc = CDLL("libc.so.6")
f_c = CFUNCTYPE(c_int)(f)
stack = c_char_p(" " * 1024 * 1024)
libc.clone(f_c, c_void_p(cast(stack, c_void_p).value + 1024 * 1024), 0)
这确实有效,但我想我用堆栈在我的系统中打了一个大洞,有更清洁的方法吗?
编辑:
几乎完成,为 newpid 添加正确的标志:
from ctypes import *
libc = CDLL("libc.so.6")
def f():
print libc.getpid()
return 0
f_c = CFUNCTYPE(c_int)(f)
stack = c_char_p(" " * 1024 * 1024)
libc.clone(f_c, c_void_p(cast(stack, c_void_p).value + 1024 * 1024), 0x20000000)
这不能只为 root 运行,并打印一个不错的 1。
在这篇文章之后,堆栈似乎很好:http://code.google.com/p/chromium/wiki/LinuxPidNamespaceSupport
【问题讨论】:
-
如果您只使用
CLONE_NEWPID标志(0x000200000),子进程将立即重新成为父进程的init,因此父进程将无法等待子进程.如果您想在父进程中等待子进程,您可能想要使用signal.SIGCHLD|0x000200000。 (你必须指定一些信号,SIGCHLD是明显的候选者。)
标签: python