如何在libvirt中设置超时(使用Python)

1 投票
3 回答
1645 浏览
提问于 2025-04-16 15:21


我想在我的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

我经常使用一种叫做“猴子补丁”的方法来修改一个库,让它的网络连接有超时设置。通常,你只需要找到一个调用了 selectpoll 的方法,然后把它替换成你修改过的版本。有时候,你还需要设置一个“尝试-捕获”的机制,来捕捉到 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

撰写回答