diff options
| author | Yun Mao <yunmao@gmail.com> | 2012-03-13 16:15:19 -0400 |
|---|---|---|
| committer | Yun Mao <yunmao@gmail.com> | 2012-03-14 16:49:23 -0400 |
| commit | caf25ef8d3bdb49a6f23ee9789342558c53b9172 (patch) | |
| tree | 2cdefe0850a23efbd9549b62d633ea114b5d1a4e | |
| parent | f40357574245d2e3b8cb7995cb27adc8e9b99175 (diff) | |
nonblocking libvirt mode using tpool
Add an option libvirt_nonblocking (disabled by default) to use a thread
pool to execute all libvirt API calls. Previously all the calls except
one in firewall.py are blocking in the eventlet thread model.
Change-Id: I665ed7a629bb029011b181e8d2844fc2276502d9
| -rw-r--r-- | etc/nova/nova.conf.sample | 2 | ||||
| -rw-r--r-- | nova/virt/libvirt/connection.py | 15 | ||||
| -rw-r--r-- | nova/virt/libvirt/firewall.py | 8 |
3 files changed, 23 insertions, 2 deletions
diff --git a/etc/nova/nova.conf.sample b/etc/nova/nova.conf.sample index 1ff6ec357..afdedfbd3 100644 --- a/etc/nova/nova.conf.sample +++ b/etc/nova/nova.conf.sample @@ -740,6 +740,8 @@ # libvirt_disk_prefix=<None> ###### (BoolOpt) Inject the admin password at boot time, without an agent. # libvirt_inject_password=false +###### (BoolOpt) Use a separated OS thread pool to realize non-blocking libvirt calls. Disabled by default. +# libvirt_nonblocking=false ###### (StrOpt) Libvirt domain type (valid options are: kvm, lxc, qemu, uml, xen) # libvirt_type="kvm" ###### (StrOpt) Override the default libvirt URI (which is dependent on libvirt_type) diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index 5603b1e26..58154c4a4 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -50,6 +50,8 @@ import time import uuid from eventlet import greenthread +from eventlet import tpool + from xml.dom import minidom from xml.etree import ElementTree @@ -154,6 +156,10 @@ libvirt_opts = [ help='Number of seconds to wait for instance to shut down after' ' soft reboot request is made. We fall back to hard reboot' ' if instance does not shutdown within this window.'), + cfg.BoolOpt('libvirt_nonblocking', + default=False, + help='Use a separated OS thread pool to realize non-blocking' + ' libvirt calls') ] FLAGS = flags.FLAGS @@ -249,9 +255,16 @@ class LibvirtConnection(driver.ComputeDriver): def _get_connection(self): if not self._wrapped_conn or not self._test_connection(): LOG.debug(_('Connecting to libvirt: %s'), self.uri) - self._wrapped_conn = self._connect(self.uri, + if not FLAGS.libvirt_nonblocking: + self._wrapped_conn = self._connect(self.uri, self.read_only) + else: + self._wrapped_conn = tpool.proxy_call( + (libvirt.virDomain, libvirt.virConnect), + self._connect, self.uri, self.read_only) + return self._wrapped_conn + _conn = property(_get_connection) def _test_connection(self): diff --git a/nova/virt/libvirt/firewall.py b/nova/virt/libvirt/firewall.py index 04b3cf42a..dd491ea5f 100644 --- a/nova/virt/libvirt/firewall.py +++ b/nova/virt/libvirt/firewall.py @@ -144,7 +144,13 @@ class NWFilterFirewall(base_firewall.FirewallDriver): if callable(xml): xml = xml() # execute in a native thread and block current greenthread until done - tpool.execute(self._conn.nwfilterDefineXML, xml) + if not FLAGS.libvirt_nonblocking: + # NOTE(maoy): the original implementation is to have the API called + # in the thread pool no matter what. + tpool.execute(self._conn.nwfilterDefineXML, xml) + else: + # NOTE(maoy): self._conn is a eventlet.tpool.Proxy object + self._conn.nwfilterDefineXML(xml) def unfilter_instance(self, instance, network_info): """Clear out the nwfilter rules.""" |
