从python线程启动时,FreeBSD Jail无法启动

时间:2011-12-07 22:08:59

标签: python multithreading freebsd cherrypy

以下作品:

ezjail-admin create -f default test 10.0.0.1
ezjail-admin start test

或者在Python中:

import subprocess, shlex
command = 'ezjail-admin create -f default test 10.0.0.1'
subprocess.Popen(shlex.split(command)).wait()
command = 'ezjail-admin start test'
subprocess.Popen(shlex.split(command)).wait()

但是当在一个线程中执行时(在CherryPy下),jail安装正常但它从未正确启动:

root    15231  0.0  0.0  8296  2056   1  I+    4:52PM   0:00.01 /bin/sh /usr/local/etc/rc.d/ezjail.sh start content
root    15240  0.0  0.0  8296  2120   1  I+    4:52PM   0:00.06 sh /etc/rc.d/jail onestart content
root    15407  0.0  0.0  8296  2016   1  I+J   4:52PM   0:00.01 /bin/sh /etc/rc
root    15467  0.0  0.0  8296  2060   1  I+J   4:52PM   0:00.00 /bin/sh /etc/rc
root    15474  0.0  0.0  6920  1224   1  I+J   4:52PM   0:00.00 /usr/sbin/syslogd -ss

jail启动,但/etc/rc似乎在启动syslogd后冻结。

不知何故,当在线程中执行时,jail rc失败。我怀疑某些环境设置缺失(可能是一个pty?),jexec正常运行。

使用jexecezjail-admin console尝试附加控制台也会失败(实际上会启动jail的单独副本)。 /var/log jail没有内容(除了在syslogd启动时创建的空日志文件),主机日志文件也没有。

有人知道为什么在非线程应用程序中执行工作命令有效,但是只要它在一个线程下运行,就会出现严重问题吗?

TLDR:当尝试从python线程启动jail时,rc在syslogd启动后挂起。相同的命令将在非线程应用程序中成功启动jail。

编辑:fork工作......它与线程有关。

以下内容对ezjail-admin start无效。 ezjail-admin create完美无缺。

class TestThread(threading.Thread):
  def run(self):
    command = 'ezjail-admin create -f content content 10.0.254.33'
    os.system(command)
    command = 'ezjail-admin start content'
    os.system(command)    

tt = TestThread()
tt.start()

可以在https://github.com/masom/Puck/tree/master/client看到实际代码 当前的实现使用早期的fork,但线程会更清晰。

2 个答案:

答案 0 :(得分:-1)

你真的想在那里使用popen吗?你期望阅读stdout或stderr,还是写入stdin?从.wait()看起来不像它。如果是这样,为什么要使用popen?

我不是特别了解Python,所以我假设subprocess.Popen是用popen(3)实现的。

在内部,popen必须fork / exec,所以我怀疑你确实有一个线程问题。因为您正在使用popen,所以更有可能的是阻止尝试将其中一个管道用于父进程。添加线程将改变Python处理I / O的方式,这可能会暴露问题。

因此,要测试它,您可以尝试相同的命令,但使用stdin,stdout和stderr重定向到/ dev / null。使用此命令:

sh -c 'ezjail-admin start test < /dev/null > /dev/null 2> /dev/null'

ezjail文档可能会告诉您它是否对标准I / O句柄做了任何事情。如果没有,底层的jail(2)调用将使用继承的句柄,并且给定你的代码我很确定你想要关闭它们,或者将它们重定向到有用的地方。

更新

如果该命令与重定向到/ dev / null的标准句柄一起使用,那么问题与您如何处理标准I / O句柄而不是线程有关。你需要决定你希望这些句柄去哪里,并在你启动jail时正确设置它们。如果您要读取和/或写入连接到监狱子级的管道,您需要了解注释中提到的文档页面上的大红色警告,以避免死锁。这几乎肯定是你所看到的问题。

你谈论ssh和服务器进程;不清楚你到底在做什么。您正在创建一个jail,然后在jail中执行/ etc / rc。该进程从其父进程继承标准I / O句柄,并设置系统环境。组成系统环境的进程也将继承这些句柄并使用它们。系统的行为会有所不同,具体取决于它们指向的位置。在jail中调用/ etc / rc的不同方法会改变这些句柄。要使其与“线程”一起使用,只需正确设置句柄。

答案 1 :(得分:-1)

os.system不等待命令完成。所以你的创建和开始并行运行导致由于竞争条件而开始失败。在调用之后调用sleep来创建或放置subprocess.Popen调用.wait()

我所说的是等待不起作用,因为ezjail-admin是一个不等待结果的shell脚本。

为了证明我是对还是错,请尝试运行相同的命令,中间睡眠时间为1秒。

监狱创建不需要pty。实际上你可以运行一个虚拟监狱内存只有静态链接的进程,根本没有文件系统(虽然现在很难在网络上找到这个fu ...)

睡眠很笨,但通过jls检查运行jail是一种方式(ezjail在那里注册以及统一)。