如何在libvirt中设置超时(使用Python)
我想在我的Python程序中使用libvirt时,设置一个短的连接超时时间(只要几秒钟),而不是默认的较长时间。
我在C语言的libvirt API中找到了一个函数:virEventAddTimeoutFunc()
,可以在这里查看:
http://libvirt.org/html/libvirt-libvirt.html#virEventAddTimeoutFunc
还有在libvirt.py
大约第150行的eventInvokeTimeoutCallback(timer, callback, opaque)
,但我不知道怎么使用它。网上没有找到任何示例。
我试过这个,但出现了段错误: :-(
import libvirt
def timeout_cb_d():
print 'Timeout !'
try:
# try to set the libvirt timeout to 2 seconds:
t = libvirt.eventInvokeTimeoutCallback(2, timeout_cb_d, "from dom0_class")
except:
...
有没有人能给我一个能用的示例呢?
3 个回答
0
我经常使用一种叫做“猴子补丁”的方法来修改一个库,让它的网络连接有超时设置。通常,你只需要找到一个调用了 select
或 poll
的方法,然后把它替换成你修改过的版本。有时候,你还需要设置一个“尝试-捕获”的机制,来捕捉到 socket.timeout 这个错误,并做一些处理,让这个错误能够传递到你的代码中,而不会在传递的过程中引发其他错误。比如,有一次我就不得不创建一个有效的响应对象,而不是返回 None。
0
我假设libvirt是通过标准的套接字进行通信的。如果是这样的话,你可以使用 socket.settimeout
来设置整个应用程序的超时时间。
这并不是说libvirt的Python绑定不会自己调用这个函数,但试试看也是值得的。
1
我们终于找到了一种简单的方法,可以使用Python的报警和信号处理器来实现:http://docs.python.org/library/signal.html#example
补充:
这里是这个想法:
import string, time, sys, signal
class Host:
# (...)
def timeout_handler(self, sig_code, frame):
if 14 == sig_code: sig_code = 'SIGALRM'
print time.strftime('%F %T -'), 'Signal handler called with signal:', sig_code
raise Exception('Timeout!')
def libVirtConnect(self):
try:
# Enable the timeout with an alarm:
signal.signal(signal.SIGALRM, self.timeout_handler)
signal.alarm(self._libvirt_timeout_in_seconds)
self._virt_conn = libvirt.open('xen+tcp://'+self._ip)
signal.alarm(0) # Disable the alarm
except Exception, e:
signal.alarm(0) # Disable the alarm