[libvirt] [PATCH v2 0/5] Introduce API for dumping domain IP addresses
by Michal Privoznik
This feature has been requested for a very long time. However,
we had to wait for guest agent to obtain reliable results as
user might create totally different structure of interfaces than
seen from outside (e.g. bonding, virtual interfaces, etc.).
That's the main reason why sniffing for domain traffic can
return bogus results. Fortunately, qemu guest agent implement
requested part for a while so nothing holds us back anymore.
To make matters worse, guest OS can assign whatever name to
an interface and changing MAC inside guest isn't propagated
to the host which in the end see original one.
Therefore, finding correlation between interface within guest
and the host side end is left as exercise for mgmt applications.
This API is called virDomainGetInterfacesAddresses (okay, maybe
too many plurals) and returns a XML document containing all
interesting data.
diff to v1:
-switch from struct to XML doc
Michal Privoznik (5):
Introduce virDomainGetInterfacesAddresses API
virsh: Expose virDomainGetInterfacesAddresses
qemu_agent: Implement 'guest-network-get-interfaces' command handling
qemu: Implement virDomainInterfacesAddresses
python: create example for dumping domain IP addresses
docs/schemas/interfaces.rng | 57 +++++++++++++++++
examples/python/Makefile.am | 2 +-
examples/python/README | 1 +
examples/python/domipaddrs.py | 62 +++++++++++++++++++
include/libvirt/libvirt.h.in | 2 +
src/driver.h | 4 +
src/libvirt.c | 49 +++++++++++++++
src/libvirt_public.syms | 1 +
src/qemu/qemu_agent.c | 135 +++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_agent.h | 2 +
src/qemu/qemu_driver.c | 68 +++++++++++++++++++++
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 12 +++-
src/remote_protocol-structs | 8 +++
tools/virsh.c | 41 ++++++++++++
tools/virsh.pod | 9 +++
16 files changed, 452 insertions(+), 2 deletions(-)
create mode 100644 docs/schemas/interfaces.rng
create mode 100644 examples/python/domipaddrs.py
--
1.7.8.5
12 years, 5 months
[libvirt] [Patch v2 0/3] Add QEMU network helper support
by rmarwah@linux.vnet.ibm.com
From: Richa Marwaha <rmarwah(a)linux.vnet.ibm.com>
QEMU has a new feature which allows QEMU to execute under an unprivileged user ID and still be able to
add a tap device to a Linux network bridge. Below is the link to the QEMU patches for the bridge helper
feature:
http://lists.gnu.org/archive/html/qemu-devel/2012-01/msg03562.html
The existing libvirt tap network device support for adding a tap device to a bridge (-netdev tap) works
only when connected to a libvirtd instance running as the privileged system account 'root'.
When connected to a libvirtd instance running as an unprivileged user (ie. using the session URI) creation of
the tap device fails as follows:
error: Failed to start domain F14_64 error: Unable to create tap device vnet%d: Operation not permitted
With this support, creating a tap device in the above scenario will be possible. Additionally, hot attaching
a tap device to a bridge while running when connected to a libvirtd instance running as an unprivileged user
will be possible.
Richa Marwaha (3):
Add -netdev bridge capabilities
Add -netdev bridge support
apparmor: QEMU bridge helper policy updates
examples/apparmor/libvirt-qemu | 21 +++++++++++++-
src/qemu/qemu_capabilities.c | 13 ++++++--
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 61 ++++++++++++++++++++++++++++-----------
src/qemu/qemu_command.h | 2 +
src/qemu/qemu_hotplug.c | 31 ++++++++++++++------
6 files changed, 97 insertions(+), 32 deletions(-)
12 years, 5 months
[libvirt] [PATCH] qemu: fix use after free
by Eric Blake
Detected by Coverity.
* src/qemu/qemu_hotplug.c (qemuDomainAttachHostDevice): Avoid
double free of usb on failure.
---
src/qemu/qemu_hotplug.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index ba841e9..ceffe22 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1170,6 +1170,7 @@ int qemuDomainAttachHostDevice(struct qemud_driver *driver,
if (usbDeviceListAdd(list, usb) < 0) {
usbFreeDevice(usb);
+ usb = NULL:
goto cleanup;
}
--
1.7.11.2
12 years, 5 months
[libvirt] [QEMU PATCH 0/3] versioned CPU models / per-machine-type aliases
by Eduardo Habkost
Hi,
This is the first try at a simple system to make the CPU model definitions
versioned (to allow them to get bug fixes while allowing migration from older
versions and keeping command-line compatibility), and per- machine-type aliases
for compatibility.
The lack of CPU model versioning is blocking multiple bug fixes that are
necessary on CPU model definitions, but can't be included today because they
would break migration.
Later, after this gets in (or at least gets some feedback), I plan to send a
proposal for a machine-friendly CPU feature / CPU model probing interface that
libvirt could use.
Eduardo Habkost (3):
vl.c: extract qemu_machine_init() function
per-machine-type CPU model alias system
x86: pc: versioned CPU model names & compatibility aliases
hw/boards.h | 13 +++++++++
hw/pc_piix.c | 56 ++++++++++++++++++++++++++++++++++++
sysconfigs/target/cpus-x86_64.conf | 18 ++++++------
vl.c | 28 +++++++++++++++++-
4 files changed, 105 insertions(+), 10 deletions(-)
--
1.7.10.4
12 years, 5 months
[libvirt] [PATCH][TCK] Add listen type for graphic
by Kyla Zhang
For default domain build there is no graphic listen type so it will
report error. This patch will fix it with adding default type with
"address"
---
lib/Sys/Virt/TCK/DomainBuilder.pm | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/lib/Sys/Virt/TCK/DomainBuilder.pm b/lib/Sys/Virt/TCK/DomainBuilder.pm
index dfd988e..dbfb65f 100644
--- a/lib/Sys/Virt/TCK/DomainBuilder.pm
+++ b/lib/Sys/Virt/TCK/DomainBuilder.pm
@@ -460,7 +460,8 @@ sub as_xml {
$w->emptyTag("autoport",
autoport => $graphic->{autoport});
$w->emptyTag("listen",
- listen => $graphic->{listen});
+ listen => $graphic->{listen},
+ $graphic->{listen_type} ? (type => $graphic->{listen_type}) : type => "address");
$w->emptyTag("keymap",
keymap => $graphic->{keymap});
$w->endTag("graphics");
--
1.7.1
12 years, 5 months
[libvirt] Question about pci-passthrough
by Shradha Shah
Hello All,
I had a question about pci-passthrough using hostdev mode in Libvirt.
When I assign hostdev->parent.type = VIR_DOMAIN_DEVICE_NET, the hostdev is passed into the guest and acts as a network device.
When I assign hostdev->parent.type = VIR_DOMAIN_DEVICE_NONE, the hostdev is passed into the guest and acts as a PCI Host device.
Please can someone point me to the part of code in libvirt where this decision is made based on hostdev->parent.type?
--
Many Thanks,
Regards,
Shradha Shah
12 years, 5 months
[libvirt] [PATCH v2 1/3] conf: Format numatune XML correctly while placement is none
by Osier Yang
setNumaParameters tunes the numa setting using cgroup, it's another
entry except libnuma/numad for numa tuning. And it doesn't set the
placement, and further more, the formating codes doesn't take this
into consideration.
How to reproduce:
conn = libvirt.open(None)
dom = conn.lookupByName('linux')
param = {'numa_nodeset': '0', 'numa_mode': 1}
dom.setNumaParameters(param, 2)
% virsh start linux
error: Failed to start domain rhel6.3rc
error: (domain_definition):8: error parsing attribute name
<memory mode='preferred' </numatune>
-------------------------------^
---
src/conf/domain_conf.c | 17 ++++++++++-------
1 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 81c6308..c44d89d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -12795,23 +12795,26 @@ virDomainDefFormatInternal(virDomainDefPtr def,
const char *placement;
mode = virDomainNumatuneMemModeTypeToString(def->numatune.memory.mode);
- virBufferAsprintf(buf, " <memory mode='%s' ", mode);
+ virBufferAsprintf(buf, " <memory mode='%s'", mode);
- if (def->numatune.memory.placement_mode ==
- VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_STATIC) {
+ if (def->numatune.memory.nodemask) {
nodemask = virDomainCpuSetFormat(def->numatune.memory.nodemask,
- VIR_DOMAIN_CPUMASK_LEN);
+ VIR_DOMAIN_CPUMASK_LEN);
if (nodemask == NULL) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("failed to format nodeset for "
"NUMA memory tuning"));
goto cleanup;
}
- virBufferAsprintf(buf, "nodeset='%s'/>\n", nodemask);
+ virBufferAsprintf(buf, " nodeset='%s'/>\n", nodemask);
VIR_FREE(nodemask);
- } else if (def->numatune.memory.placement_mode) {
+ } else if (def->numatune.memory.placement_mode ==
+ VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO) {
placement = virDomainNumatuneMemPlacementModeTypeToString(def->numatune.memory.placement_mode);
- virBufferAsprintf(buf, "placement='%s'/>\n", placement);
+ virBufferAsprintf(buf, " placement='%s'/>\n", placement);
+ } else {
+ /* Should not hit here. */
+ virBufferAddLit(buf, "/>\n");
}
virBufferAddLit(buf, " </numatune>\n");
}
--
1.7.7.3
12 years, 5 months
[libvirt] [PATCH] build: distribute virsh related source files
by Guannan Ren
In virsh.c, it includes multiple virsh source files, we need
to have them distributed.
---
tools/Makefile.am | 13 +++++++++++--
1 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 723db8e..7c048b2 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -25,8 +25,17 @@ EXTRA_DIST = \
virt-sanlock-cleanup.in \
virt-sanlock-cleanup.8 \
virsh.pod \
- libvirt-guests.sysconf \
- virsh-edit.c
+ libvirt-guests.sysconf \
+ virsh-edit.c \
+ virsh-domain.c \
+ virsh-domain-monitor.c \
+ virsh-host.c virsh-interface.c \
+ virsh-network.c virsh-nodedev.c \
+ virsh-nwfilter.c virsh-pool.c \
+ virsh-secret.c virsh-snapshot.c \
+ virsh-volume.c
+
+
DISTCLEANFILES =
--
1.7.7.6
12 years, 5 months
[libvirt] [PATCH] build: fix build without HAVE_CAPNG
by Eric Blake
Otherwise, a build may fail with:
lxc/lxc_conatiner.c: In function 'lxcContainerDropCapabilities':
lxc/lxc_container.c:1662:46: error: unused parameter 'keepReboot' [-Werror=unused-parameter]
* src/lxc/lxc_container.c (lxcContainerDropCapabilities): Mark
parameter unused.
---
Pushing under the build-breaker rule.
src/lxc/lxc_container.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 6043b00..f3a4622 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -1659,7 +1659,7 @@ static int lxcContainerSetupMounts(virDomainDefPtr vmDef,
* It removes some capabilities that could be dangerous to
* host system, since they are not currently "containerized"
*/
-static int lxcContainerDropCapabilities(bool keepReboot)
+static int lxcContainerDropCapabilities(bool keepReboot ATTRIBUTE_UNUSED)
{
#if HAVE_CAPNG
int ret;
--
1.7.11.2
12 years, 5 months
[libvirt] [PATCH] Bind connection close callback APIs to python binding
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Add code in the python binding to cope with the new APIs
virConnectRegisterCloseCallback and
virConnectDeregisterCloseCallback. Also demonstrate their
use in the python domain events demo
---
examples/domain-events/events-python/event-test.py | 14 ++-
python/generator.py | 5 +-
python/libvirt-override-virConnect.py | 24 +++++
python/libvirt-override.c | 107 ++++++++++++++++++++
4 files changed, 147 insertions(+), 3 deletions(-)
diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py
index 736c225..8193d18 100644
--- a/examples/domain-events/events-python/event-test.py
+++ b/examples/domain-events/events-python/event-test.py
@@ -490,6 +490,16 @@ def myDomainEventPMSuspendCallback(conn, dom, reason, opaque):
dom.name(), dom.ID())
def myDomainEventBalloonChangeCallback(conn, dom, utcoffset, actual):
print "myDomainEventBalloonChangeCallback: Domain %s(%s) %d" % (dom.name(), dom.ID(), actual)
+
+run = True
+
+def myConnectionCloseCallback(conn, reason, opaque):
+ reasonStrings = (
+ "Error", "End-of-file", "Keepalive", "Client",
+ )
+ print "myConnectionCloseCallback: %s: %s" % (conn.getURI(), reasonStrings[reason])
+ run = False
+
def usage(out=sys.stderr):
print >>out, "usage: "+os.path.basename(sys.argv[0])+" [-hdl] [uri]"
print >>out, " uri will default to qemu:///system"
@@ -539,6 +549,8 @@ def main():
if (old_exitfunc): old_exitfunc()
sys.exitfunc = exit
+ vc.registerCloseCallback(myConnectionCloseCallback, None)
+
#Add 2 callbacks to prove this works with more than just one
vc.domainEventRegister(myDomainEventCallback1,None)
vc.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE, myDomainEventCallback2, None)
@@ -559,7 +571,7 @@ def main():
# of demo we'll just go to sleep. The other option is to
# run the event loop in your main thread if your app is
# totally event based.
- while vc.isAlive() == 1:
+ while run:
time.sleep(1)
diff --git a/python/generator.py b/python/generator.py
index 6559ece..6ccbf56 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -425,8 +425,6 @@ skip_impl = (
'virDomainGetInterfaceParameters',
'virDomainGetCPUStats',
'virDomainGetDiskErrors',
- 'virConnectUnregisterCloseCallback',
- 'virConnectRegisterCloseCallback',
)
qemu_skip_impl = (
@@ -464,6 +462,9 @@ skip_function = (
'virStreamRecv', # overridden in libvirt-override-virStream.py
'virStreamSend', # overridden in libvirt-override-virStream.py
+ 'virConnectDeregisterCloseCallback', # overriden in virConnect.py
+ 'virConnectRegisterCloseCallback', # overriden in virConnect.py
+
# 'Ref' functions have no use for bindings users.
"virConnectRef",
"virDomainRef",
diff --git a/python/libvirt-override-virConnect.py b/python/libvirt-override-virConnect.py
index 50177ab..de8167e 100644
--- a/python/libvirt-override-virConnect.py
+++ b/python/libvirt-override-virConnect.py
@@ -206,3 +206,27 @@
retlist.append(virDomain(self, _obj=domptr))
return retlist
+
+ def _dispatchCloseCallback(self, reason, cbData):
+ """Dispatches events to python user close callback"""
+ cb = cbData["cb"]
+ opaque = cbData["opaque"]
+
+ cb(self, reason, opaque)
+ return 0
+
+
+ def deregisterCloseCallback(self):
+ """Removes a close event callback"""
+ ret = libvirtmod.virConnectDeregisterCloseCallback(self._o)
+ if ret == -1: raise libvirtError ('virConnectDeregisterCloseCallback() failed', conn=self)
+
+ def registerCloseCallback(self, cb, opaque):
+ """Adds a close event callback, providing a notification
+ when a connection fails / closes"""
+ cbData = { "cb": cb, "conn": self, "opaque": opaque }
+ ret = libvirtmod.virConnectRegisterCloseCallback(self._o, cbData)
+ if ret == -1:
+ raise libvirtError ('virConnectRegisterCloseCallback() failed', conn=self)
+ return ret
+
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 8b41dff..b7269fc 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -5521,6 +5521,111 @@ libvirt_virConnectDomainEventDeregisterAny(ATTRIBUTE_UNUSED PyObject * self,
return py_retval;
}
+
+static void
+libvirt_virConnectCloseCallbackDispatch(virConnectPtr conn ATTRIBUTE_UNUSED,
+ int reason,
+ void *opaque)
+{
+ PyObject *pyobj_cbData = (PyObject*)opaque;
+ PyObject *pyobj_ret;
+ PyObject *pyobj_conn;
+ PyObject *dictKey;
+
+ LIBVIRT_ENSURE_THREAD_STATE;
+
+ Py_INCREF(pyobj_cbData);
+
+ dictKey = libvirt_constcharPtrWrap("conn");
+ pyobj_conn = PyDict_GetItem(pyobj_cbData, dictKey);
+ Py_DECREF(dictKey);
+
+ /* Call the Callback Dispatcher */
+ pyobj_ret = PyObject_CallMethod(pyobj_conn,
+ (char*)"_dispatchCloseCallback",
+ (char*)"iO",
+ reason,
+ pyobj_cbData);
+
+ Py_DECREF(pyobj_cbData);
+
+ if(!pyobj_ret) {
+ DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret);
+ PyErr_Print();
+ } else {
+ Py_DECREF(pyobj_ret);
+ }
+
+ LIBVIRT_RELEASE_THREAD_STATE;
+}
+
+static PyObject *
+libvirt_virConnectRegisterCloseCallback(ATTRIBUTE_UNUSED PyObject * self,
+ PyObject * args)
+{
+ PyObject *py_retval; /* return value */
+ PyObject *pyobj_conn; /* virConnectPtr */
+ PyObject *pyobj_cbData; /* hash of callback data */
+ virConnectPtr conn;
+ int ret = 0;
+
+ if (!PyArg_ParseTuple
+ (args, (char *) "OO:virConnectRegisterCloseCallback",
+ &pyobj_conn, &pyobj_cbData)) {
+ DEBUG("%s failed parsing tuple\n", __FUNCTION__);
+ return VIR_PY_INT_FAIL;
+ }
+
+ DEBUG("libvirt_virConnectRegisterCloseCallback(%p %p) called\n",
+ pyobj_conn, pyobj_cbData);
+ conn = PyvirConnect_Get(pyobj_conn);
+
+ Py_INCREF(pyobj_cbData);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ ret = virConnectRegisterCloseCallback(conn,
+ libvirt_virConnectCloseCallbackDispatch,
+ pyobj_cbData,
+ libvirt_virConnectDomainEventFreeFunc);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (ret < 0) {
+ Py_DECREF(pyobj_cbData);
+ }
+
+ py_retval = libvirt_intWrap(ret);
+ return py_retval;
+}
+
+static PyObject *
+libvirt_virConnectDeregisterCloseCallback(ATTRIBUTE_UNUSED PyObject * self,
+ PyObject * args)
+{
+ PyObject *py_retval;
+ PyObject *pyobj_conn;
+ virConnectPtr conn;
+ int ret = 0;
+
+ if (!PyArg_ParseTuple
+ (args, (char *) "O:virConnectDomainEventDeregister",
+ &pyobj_conn))
+ return NULL;
+
+ DEBUG("libvirt_virConnectDomainEventDeregister(%p) called\n",
+ pyobj_conn);
+
+ conn = PyvirConnect_Get(pyobj_conn);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+
+ ret = virConnectDeregisterCloseCallback(conn,
+ libvirt_virConnectCloseCallbackDispatch);
+
+ LIBVIRT_END_ALLOW_THREADS;
+ py_retval = libvirt_intWrap(ret);
+ return py_retval;
+}
+
static void
libvirt_virStreamEventFreeFunc(void *opaque)
{
@@ -5822,10 +5927,12 @@ static PyMethodDef libvirtMethods[] = {
{(char *) "virConnectListDomainsID", libvirt_virConnectListDomainsID, METH_VARARGS, NULL},
{(char *) "virConnectListDefinedDomains", libvirt_virConnectListDefinedDomains, METH_VARARGS, NULL},
{(char *) "virConnectListAllDomains", libvirt_virConnectListAllDomains, METH_VARARGS, NULL},
+ {(char *) "virConnectDeregisterCloseCallback", libvirt_virConnectDeregisterCloseCallback, METH_VARARGS, NULL},
{(char *) "virConnectDomainEventRegister", libvirt_virConnectDomainEventRegister, METH_VARARGS, NULL},
{(char *) "virConnectDomainEventDeregister", libvirt_virConnectDomainEventDeregister, METH_VARARGS, NULL},
{(char *) "virConnectDomainEventRegisterAny", libvirt_virConnectDomainEventRegisterAny, METH_VARARGS, NULL},
{(char *) "virConnectDomainEventDeregisterAny", libvirt_virConnectDomainEventDeregisterAny, METH_VARARGS, NULL},
+ {(char *) "virConnectRegisterCloseCallback", libvirt_virConnectRegisterCloseCallback, METH_VARARGS, NULL},
{(char *) "virStreamEventAddCallback", libvirt_virStreamEventAddCallback, METH_VARARGS, NULL},
{(char *) "virStreamRecv", libvirt_virStreamRecv, METH_VARARGS, NULL},
{(char *) "virStreamSend", libvirt_virStreamSend, METH_VARARGS, NULL},
--
1.7.10.4
12 years, 5 months