[libvirt] Supporting vhost-net and macvtap in libvirt for QEMU
by Anthony Liguori
Disclaimer: I am neither an SR-IOV nor a vhost-net expert, but I've CC'd
people that are who can throw tomatoes at me for getting bits wrong :-)
I wanted to start a discussion about supporting vhost-net in libvirt.
vhost-net has not yet been merged into qemu but I expect it will be soon
so it's a good time to start this discussion.
There are two modes worth supporting for vhost-net in libvirt. The
first mode is where vhost-net backs to a tun/tap device. This is
behaves in very much the same way that -net tap behaves in qemu today.
Basically, the difference is that the virtio backend is in the kernel
instead of in qemu so there should be some performance improvement.
Current, libvirt invokes qemu with -net tap,fd=X where X is an already
open fd to a tun/tap device. I suspect that after we merge vhost-net,
libvirt could support vhost-net in this mode by just doing -net
vhost,fd=X. I think the only real question for libvirt is whether to
provide a user visible switch to use vhost or to just always use vhost
when it's available and it makes sense. Personally, I think the later
makes sense.
The more interesting invocation of vhost-net though is one where the
vhost-net device backs directly to a physical network card. In this
mode, vhost should get considerably better performance than the current
implementation. I don't know the syntax yet, but I think it's
reasonable to assume that it will look something like -net
tap,dev=eth0. The effect will be that eth0 is dedicated to the guest.
On most modern systems, there is a small number of network devices so
this model is not all that useful except when dealing with SR-IOV
adapters. In that case, each physical device can be exposed as many
virtual devices (VFs). There are a few restrictions here though. The
biggest is that currently, you can only change the number of VFs by
reloading a kernel module so it's really a parameter that must be set at
startup time.
I think there are a few ways libvirt could support vhost-net in this
second mode. The simplest would be to introduce a new tag similar to
<source network='br0'>. In fact, if you probed the device type for the
network parameter, you could probably do something like <source
network='eth0'> and have it Just Work.
Another model would be to have libvirt see an SR-IOV adapter as a
network pool whereas it handled all of the VF management. Considering
how inflexible SR-IOV is today, I'm not sure whether this is the best model.
Has anyone put any more thought into this problem or how this should be
modeled in libvirt? Michael, could you share your current thinking for
-net syntax?
--
Regards,
Anthony Liguori
11 months, 3 weeks
[libvirt] [PATCH] qemu: add PCI-multibus support for ppc
by Olivia Yin
Signed-off-by: Olivia Yin <hong-hua.yin(a)freescale.com>
---
src/qemu/qemu_capabilities.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 7bc1ebc..7d7791d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2209,6 +2209,11 @@ virQEMUCapsInitHelp(virQEMUCapsPtr qemuCaps, uid_t runUid, gid_t runGid)
virQEMUCapsClear(qemuCaps, QEMU_CAPS_NO_ACPI);
}
+ /* ppc support PCI-multibus */
+ if (qemuCaps->arch == VIR_ARCH_PPC) {
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS);
+ }
+
/* virQEMUCapsExtractDeviceStr will only set additional caps if qemu
* understands the 0.13.0+ notion of "-device driver,". */
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE) &&
@@ -2450,6 +2455,11 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
virQEMUCapsSet(qemuCaps, QEMU_CAPS_NO_ACPI);
}
+ /* ppc support PCI-multibus */
+ if (qemuCaps->arch == VIR_ARCH_PPC) {
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS);
+ }
+
if (virQEMUCapsProbeQMPCommands(qemuCaps, mon) < 0)
goto cleanup;
if (virQEMUCapsProbeQMPEvents(qemuCaps, mon) < 0)
--
1.6.4
10 years, 7 months
[libvirt] JNA Error Callback could cause core dump.
by Benjamin Wang (gendwang)
Hi,
When I changed code as following:
public class Connect {
// Load the native part
static {
Libvirt.INSTANCE.virInitialize();
try {
ErrorHandler.processError(Libvirt.INSTANCE);
} catch (Exception e) {
e.printStackTrace();
}
+ Libvirt.INSTANCE.virSetErrorFunc(null, new ErrorCallback());
}
The server will generate the following core dump:
Program terminated with signal 6, Aborted.
#0 0x0000003f9b030265 in raise () from /lib64/libc.so.6
(gdb) where
#0 0x0000003f9b030265 in raise () from /lib64/libc.so.6
#1 0x0000003f9b031d10 in abort () from /lib64/libc.so.6
#2 0x0000003f9b06a84b in __libc_message () from /lib64/libc.so.6
#3 0x0000003f9b07230f in _int_free () from /lib64/libc.so.6
#4 0x0000003f9b07276b in free () from /lib64/libc.so.6
#5 0x00002aaaacf46868 in ?? ()
#6 0x0000000000000000 in ?? ()
The problem was caused that when JNA call setErrorFunc, it will create ErrorCallback object. But when GC is executed, the object is GCed. But even I change code as following.
When GC is excuted, the callback object will be moved. Then C can't find this object. Both of scenarios will cause core dump. It seems that JNA mustn't provide ErrorCallback Class,
Because nobody can use this.
Please correct me.
public class Connect {
+ private static final ErrorCallback callback = new ErrorCallback();
// Load the native part
static {
Libvirt.INSTANCE.virInitialize();
try {
ErrorHandler.processError(Libvirt.INSTANCE);
} catch (Exception e) {
e.printStackTrace();
}
+ Libvirt.INSTANCE.virSetErrorFunc(null, callback);
}
B.R.
Benjamin Wang
10 years, 10 months
[libvirt] configuring a disconnected <interface>
by Dan Kenigsberg
Hi List,
Like most of us, I've bought my actual computer with an Ethernet
interface card, that I can connect to a wall jack at will. It's quite
easy to disconnect the Ethernet cable from the wall, as well.
I would like to expose this behavior to virtual computers, too. Via
libvirt, of course. That's useful, since an admin may need to disconnect
a running VM from a network temporarily, without resorting to
hot-unplugging its nic.
How should the domxml represent this situation? An interface that is
connected to a specific LAN1 bridge is
<interface type='bridge'>
<source bridge='LAN1'>
<target dev='vnet1'/>
<model type='virtio'/>
</interface>
Would the following make sense for an interface with no bridge at the
source?
<interface type='bridge'>
<source/>
<target dev='vnet1'/>
<model type='virtio'/>
</interface>
And how about the recommended config for <interface>s, which is
type='network'? Would it make sense to predefine
<network>
<name>null-bridge-network</name>
<forward mode='bridge'>
<bridge/>
</network>
so that
<interface type='network'>
<source network='null-bridge-network'/>
</interface>
means "keep this interface dangling out there"?
Regards,
Dan.
11 years, 1 month
[libvirt] [PATCH] python: return dictionay without value in case of no blockjob
by Guannan Ren
Currently, when there is no blockjob, dom.blockJobInfo('vda')
still reports error because it didn't distinguish return value 0 from -1.
libvirt.libvirtError: virDomainGetBlockJobInfo() failed
virDomainGetBlockJobInfo() API return value:
-1 in case of failure, 0 when nothing found, 1 found.
And use PyDict_SetItemString instead of PyDict_SetItem when key is
string type. PyDict_SetItemString increments key/value reference
count, so calling Py_DECREF() for value. For key, we don't need to
do this, because PyDict_SetItemString will handle it internally.
---
python/libvirt-override.c | 54 ++++++++++++++++++++++++++++++++++-------------
1 file changed, 39 insertions(+), 15 deletions(-)
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index fd9ebb8..c1e8661 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -4354,33 +4354,57 @@ libvirt_virDomainGetBlockJobInfo(PyObject *self ATTRIBUTE_UNUSED,
unsigned int flags;
virDomainBlockJobInfo info;
int c_ret;
- PyObject *ret;
+ PyObject *type = NULL, *bandwidth = NULL, *cur = NULL, *end = NULL;
+ PyObject *dict;
if (!PyArg_ParseTuple(args, (char *)"Ozi:virDomainGetBlockJobInfo",
&pyobj_domain, &path, &flags))
return NULL;
domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
-LIBVIRT_BEGIN_ALLOW_THREADS;
+ if ((dict = PyDict_New()) == NULL)
+ return NULL;
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
c_ret = virDomainGetBlockJobInfo(domain, path, &info, flags);
-LIBVIRT_END_ALLOW_THREADS;
+ LIBVIRT_END_ALLOW_THREADS;
- if (c_ret != 1)
+ if (c_ret == 0) {
+ return dict;
+ } else if (c_ret < 0) {
+ Py_DECREF(dict);
return VIR_PY_NONE;
+ }
- if ((ret = PyDict_New()) == NULL)
- return VIR_PY_NONE;
+ if ((type = libvirt_intWrap(info.type)) == NULL ||
+ PyDict_SetItemString(dict, "type", type) < 0)
+ goto error;
+ Py_DECREF(type);
- PyDict_SetItem(ret, libvirt_constcharPtrWrap("type"),
- libvirt_intWrap(info.type));
- PyDict_SetItem(ret, libvirt_constcharPtrWrap("bandwidth"),
- libvirt_ulongWrap(info.bandwidth));
- PyDict_SetItem(ret, libvirt_constcharPtrWrap("cur"),
- libvirt_ulonglongWrap(info.cur));
- PyDict_SetItem(ret, libvirt_constcharPtrWrap("end"),
- libvirt_ulonglongWrap(info.end));
+ if ((bandwidth = libvirt_ulongWrap(info.bandwidth)) == NULL ||
+ PyDict_SetItemString(dict, "bandwidth", bandwidth) < 0)
+ goto error;
+ Py_DECREF(bandwidth);
- return ret;
+ if ((cur = libvirt_ulonglongWrap(info.cur)) == NULL ||
+ PyDict_SetItemString(dict, "cur", cur) < 0)
+ goto error;
+ Py_DECREF(cur);
+
+ if ((end = libvirt_ulonglongWrap(info.end)) == NULL ||
+ PyDict_SetItemString(dict, "end", end) < 0)
+ goto error;
+ Py_DECREF(end);
+
+ return dict;
+
+error:
+ Py_DECREF(dict);
+ Py_XDECREF(type);
+ Py_XDECREF(bandwidth);
+ Py_XDECREF(cur);
+ Py_XDECREF(end);
+ return NULL;
}
static PyObject *
--
1.8.1.4
11 years, 1 month
[libvirt] [PATCH] python: virConnect: fix destructor
by Sandro Bonazzola
Fixed virConnect destructor checking for attribute
existance before trying to use it.
Avoids:
Exception AttributeError: AttributeError("virConnect instance has no
attribute 'domainEventCallbacks'",) in <bound method virConnect.__del__
of <libvirt.virConnect instance at 0x4280f38>> ignored
However, something still doesn't work:
Exception TypeError: TypeError("'NoneType' object is not callable",)
in <bound method virConnect.__del__ of <libvirt.virConnect object at 0x37576d0>> ignored
Signed-off-by: Sandro Bonazzola <sbonazzo(a)redhat.com>
---
python/libvirt-override-virConnect.py | 32 +++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/python/libvirt-override-virConnect.py b/python/libvirt-override-virConnect.py
index 5495b70..28d6d41 100644
--- a/python/libvirt-override-virConnect.py
+++ b/python/libvirt-override-virConnect.py
@@ -1,11 +1,12 @@
def __del__(self):
- try:
- for cb,opaque in self.domainEventCallbacks.items():
- del self.domainEventCallbacks[cb]
- del self.domainEventCallbacks
- libvirtmod.virConnectDomainEventDeregister(self._o, self)
- except AttributeError:
- pass
+ if hasattr(self, 'domainEventCallbacks'):
+ try:
+ for cb,opaque in self.domainEventCallbacks.items():
+ del self.domainEventCallbacks[cb]
+ del self.domainEventCallbacks
+ libvirtmod.virConnectDomainEventDeregister(self._o, self)
+ except AttributeError:
+ pass
if self._o != None:
libvirtmod.virConnectClose(self._o)
@@ -14,14 +15,15 @@
def domainEventDeregister(self, cb):
"""Removes a Domain Event Callback. De-registering for a
domain callback will disable delivery of this event type """
- try:
- del self.domainEventCallbacks[cb]
- if len(self.domainEventCallbacks) == 0:
- del self.domainEventCallbacks
- ret = libvirtmod.virConnectDomainEventDeregister(self._o, self)
- if ret == -1: raise libvirtError ('virConnectDomainEventDeregister() failed', conn=self)
- except AttributeError:
- pass
+ if hasattr(self, 'domainEventCallbacks'):
+ try:
+ del self.domainEventCallbacks[cb]
+ if len(self.domainEventCallbacks) == 0:
+ del self.domainEventCallbacks
+ ret = libvirtmod.virConnectDomainEventDeregister(self._o, self)
+ if ret == -1: raise libvirtError ('virConnectDomainEventDeregister() failed', conn=self)
+ except AttributeError:
+ pass
def domainEventRegister(self, cb, opaque):
"""Adds a Domain Event Callback. Registering for a domain
--
1.8.1.4
11 years, 2 months
[libvirt] [PATCH 0/3] qemu: Fix how files are being opened
by Martin Kletzander
There were some places in the code, where files were being opened with
uid:gid of the daemon instead of the qemu process related to the file.
First patch exposes the parseIds() function in order for it to be used
somewhere else in the code than in the DAC security driver. The next
patch fixes how the files are opened and the last one fixes occurences
of open() that should use different uid:gid for opening files.
There maybe should be a check for whether the file being opened is an
image and whether the label used to open the file should be imagelabel
or not. But, the QEMU process opening the file is running as the
label (not imagelabel) and accessing the files as such.
Martin Kletzander (3):
Expose ownership ID parsing
Make qemuOpenFile aware of per-VM DAC seclabel.
Use qemuOpenFile in qemu_driver.c
src/libvirt_private.syms | 1 +
src/qemu/qemu_driver.c | 87 +++++++++++++++++++++++++++++++--------------
src/security/security_dac.c | 51 ++------------------------
src/util/virutil.c | 56 +++++++++++++++++++++++++++++
src/util/virutil.h | 2 ++
5 files changed, 122 insertions(+), 75 deletions(-)
--
1.8.2.1
11 years, 2 months