[libvirt] [PATCH] parallels: fix libvirt crash if parallelsNetworkOpen fails
by Maxim Nestratov
If, by any reason, parallelsNetworkOpen fails it dereferences
newly allocated privconn->networks via virObjectUnref, which in
turn deallocates its memory.
Subsequent call of parallelsNetworkClose calls virObjectUnref
that leads to double memory free. To prevent this we should zero
privconn->networks to make all subsequent virObjectUnref be safe.
Signed-off-by: Maxim Nestratov <mnestratov(a)parallels.com>
---
src/parallels/parallels_network.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/parallels/parallels_network.c b/src/parallels/parallels_network.c
index 8cc0582..8caad4a 100644
--- a/src/parallels/parallels_network.c
+++ b/src/parallels/parallels_network.c
@@ -348,6 +348,7 @@ parallelsNetworkOpen(virConnectPtr conn,
return VIR_DRV_OPEN_SUCCESS;
error:
virObjectUnref(privconn->networks);
+ privconn->networks = NULL;
return VIR_DRV_OPEN_DECLINED;
}
--
1.7.1
9 years, 8 months
[libvirt] [PATCH v11] Expose virDomainInterfacesAddresses to python binding
by Daniel P. Berrange
From: Nehal J Wani <nehaljw.kkd1(a)gmail.com>
examples/Makefile.am:
* Add new file domipaddrs.py
examples/README:
* Add documentation for the python example
libvirt-override-api.xml:
* Add new symbol for virDomainInterfacesAddresses
libvirt-override.c:
* Hand written python api
Example:
$ python examples/domipaddrs.py qemu:///system f18
Interface MAC address Protocol Address
vnet0 52:54:00:20:70:3d ipv4 192.168.105.240/16
In v11:
- Cope with hwaddr being NULL by filling in PY_NONE
---
MANIFEST.in | 1 +
examples/README | 1 +
examples/domipaddrs.py | 57 ++++++++++++++++++++++++
generator.py | 2 +
libvirt-override-api.xml | 9 +++-
libvirt-override.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++
sanitytest.py | 3 ++
7 files changed, 182 insertions(+), 1 deletion(-)
create mode 100755 examples/domipaddrs.py
diff --git a/MANIFEST.in b/MANIFEST.in
index d7bc545..dd05221 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -4,6 +4,7 @@ include COPYING
include COPYING.LESSER
include ChangeLog
include examples/consolecallback.py
+include examples/domipaddrs.py
include examples/dominfo.py
include examples/domrestore.py
include examples/domsave.py
diff --git a/examples/README b/examples/README
index 5b5d405..1d4b425 100644
--- a/examples/README
+++ b/examples/README
@@ -11,6 +11,7 @@ domrestore.py - restore domU's from their saved files in a directory
esxlist.py - list active domains of an VMware ESX host and print some info.
also demonstrates how to use the libvirt.openAuth() method
dhcpleases.py - list dhcp leases for a given virtual network
+domipaddrs.py - list IP addresses for guest domains
The XML files in this directory are examples of the XML format that libvirt
expects, and will have to be adapted for your setup. They are only needed
diff --git a/examples/domipaddrs.py b/examples/domipaddrs.py
new file mode 100755
index 0000000..d6d5cac
--- /dev/null
+++ b/examples/domipaddrs.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# domipaddrs - print domain interfaces along with their MAC and IP addresses
+
+import libvirt
+import sys
+
+def usage():
+ print "Usage: %s [URI] DOMAIN" % sys.argv[0]
+ print " Print domain interfaces along with their MAC and IP addresses"
+
+uri = None
+name = None
+args = len(sys.argv)
+
+if args == 2:
+ name = sys.argv[1]
+elif args == 3:
+ uri = sys.argv[1]
+ name = sys.argv[2]
+else:
+ usage()
+ sys.exit(2)
+
+conn = libvirt.open(uri)
+if conn == None:
+ print "Unable to open connection to libvirt"
+ sys.exit(1)
+
+try:
+ dom = conn.lookupByName(name)
+except libvirt.libvirtError:
+ print "Domain %s not found" % name
+ sys.exit(0)
+
+ifaces = dom.interfaceAddresses(libvirt.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE);
+if (ifaces == None):
+ print "Failed to get domain interfaces"
+ sys.exit(0)
+
+print " {0:10} {1:20} {2:12} {3}".format("Interface", "MAC address", "Protocol", "Address")
+
+def toIPAddrType(addrType):
+ if addrType == libvirt.VIR_IP_ADDR_TYPE_IPV4:
+ return "ipv4"
+ elif addrType == libvirt.VIR_IP_ADDR_TYPE_IPV6:
+ return "ipv6"
+
+for (name, val) in ifaces.iteritems():
+ if val['addrs']:
+ for addr in val['addrs']:
+ print " {0:10} {1:19}".format(name, val['hwaddr']),
+ print " {0:12} {1}/{2} ".format(toIPAddrType(addr['type']), addr['addr'], addr['prefix']),
+ print
+ else:
+ print " {0:10} {1:19}".format(name, val['hwaddr']),
+ print " {0:12} {1}".format("N/A", "N/A"),
+ print
diff --git a/generator.py b/generator.py
index df7a74d..8c1c48e 100755
--- a/generator.py
+++ b/generator.py
@@ -483,6 +483,7 @@ skip_impl = (
'virDomainBlockCopy',
'virNodeAllocPages',
'virDomainGetFSInfo',
+ 'virDomainInterfaceAddresses',
)
lxc_skip_impl = (
@@ -595,6 +596,7 @@ skip_function = (
'virDomainStatsRecordListFree', # only useful in C, python uses dict
'virDomainFSInfoFree', # only useful in C, python code uses list
'virDomainIOThreadsInfoFree', # only useful in C, python code uses list
+ 'virDomainInterfaceFree', # only useful in C, python code uses list
)
lxc_skip_function = (
diff --git a/libvirt-override-api.xml b/libvirt-override-api.xml
index 4660c9f..b197639 100644
--- a/libvirt-override-api.xml
+++ b/libvirt-override-api.xml
@@ -678,5 +678,12 @@
<arg name='flags' type='unsigned int' info='unused, pass 0'/>
<return type='char *' info="list of mounted filesystems information"/>
</function>
- </symbols>
+ <function name='virDomainInterfaceAddresses' file='python'>
+ <info>returns a dictionary of domain interfaces along with their MAC and IP addresses</info>
+ <arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
+ <arg name='source' type='unsigned int' info='the data source'/>
+ <arg name='flags' type='unsigned int' info='extra flags; not used yet, so callers should always pass 0'/>
+ <return type='char *' info="dictionary of domain interfaces along with their MAC and IP addresses"/>
+ </function>
+</symbols>
</api>
diff --git a/libvirt-override.c b/libvirt-override.c
index 1241305..548be24 100644
--- a/libvirt-override.c
+++ b/libvirt-override.c
@@ -5120,6 +5120,113 @@ cleanup:
return py_retval;
}
+
+static PyObject *
+libvirt_virDomainInterfaceAddresses(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args)
+{
+ PyObject *py_retval = VIR_PY_NONE;
+ virDomainPtr domain;
+ PyObject *pyobj_domain;
+ unsigned int source;
+ unsigned int flags;
+ virDomainInterfacePtr *ifaces = NULL;
+ int ifaces_count = 0;
+ size_t i, j;
+ int ret;
+ bool full_free = true;
+
+ if (!PyArg_ParseTuple(args, (char *) "Oii:virDomainInterfacePtr",
+ &pyobj_domain, &source, &flags))
+ return NULL;
+
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ ifaces_count = virDomainInterfaceAddresses(domain, &ifaces, source, flags);
+ ret = ifaces_count;
+ LIBVIRT_END_ALLOW_THREADS;
+ if (ret < 0)
+ goto cleanup;
+
+ if (!(py_retval = PyDict_New()))
+ goto no_memory;
+
+ for (i = 0; i < ifaces_count; i++) {
+ virDomainInterfacePtr iface = ifaces[i];
+ PyObject *py_addrs = NULL;
+ PyObject *py_iface = NULL;
+
+ if (!(py_iface = PyDict_New()))
+ goto no_memory;
+
+ if (iface->naddrs) {
+ if (!(py_addrs = PyList_New(iface->naddrs))) {
+ Py_DECREF(py_iface);
+ goto no_memory;
+ }
+ } else {
+ py_addrs = VIR_PY_NONE;
+ }
+
+ for (j = 0; j < iface->naddrs; j++) {
+ virDomainIPAddressPtr addr = &(iface->addrs[j]);
+ PyObject *py_addr = PyDict_New();
+ int type = addr->type;
+
+ if (!addr) {
+ Py_DECREF(py_iface);
+ Py_DECREF(py_addrs);
+ goto no_memory;
+ }
+
+ PyDict_SetItem(py_addr, libvirt_constcharPtrWrap("addr"),
+ libvirt_constcharPtrWrap(addr->addr));
+ PyDict_SetItem(py_addr, libvirt_constcharPtrWrap("prefix"),
+ libvirt_intWrap(addr->prefix));
+ PyDict_SetItem(py_addr, libvirt_constcharPtrWrap("type"),
+ libvirt_intWrap(type));
+
+ PyList_SetItem(py_addrs, j, py_addr);
+ }
+
+ PyDict_SetItem(py_iface, libvirt_constcharPtrWrap("addrs"),
+ py_addrs);
+ if (iface->hwaddr) {
+ PyDict_SetItem(py_iface, libvirt_constcharPtrWrap("hwaddr"),
+ libvirt_constcharPtrWrap(iface->hwaddr));
+ } else {
+ PyDict_SetItem(py_iface, libvirt_constcharPtrWrap("hwaddr"),
+ VIR_PY_NONE);
+ }
+
+ PyDict_SetItem(py_retval, libvirt_charPtrWrap(iface->name),
+ py_iface);
+ }
+
+ full_free = false;
+
+cleanup:
+ if (ifaces && ifaces_count > 0) {
+ for (i = 0; full_free && i < ifaces_count; i++) {
+ /*
+ * We don't want to free values we've just shared with python variables unless
+ * there was an error and hence we are returning PY_NONE or equivalent
+ */
+ virDomainInterfaceFree(ifaces[i]);
+ }
+ }
+ VIR_FREE(ifaces);
+
+ return py_retval;
+
+no_memory:
+ Py_XDECREF(py_retval);
+ py_retval = PyErr_NoMemory();
+ goto cleanup;
+}
+
+
/*******************************************
* Helper functions to avoid importing modules
* for every callback
@@ -8750,6 +8857,9 @@ static PyMethodDef libvirtMethods[] = {
#if LIBVIR_CHECK_VERSION(1, 2, 11)
{(char *) "virDomainGetFSInfo", libvirt_virDomainGetFSInfo, METH_VARARGS, NULL},
#endif /* LIBVIR_CHECK_VERSION(1, 2, 11) */
+#if LIBVIR_CHECK_VERSION(1, 2, 14)
+ {(char *) "virDomainInterfaceAddresses", libvirt_virDomainInterfaceAddresses, METH_VARARGS, NULL},
+#endif /* LIBVIR_CHECK_VERSION(1, 2, 14) */
{NULL, NULL, 0, NULL}
};
diff --git a/sanitytest.py b/sanitytest.py
index 0e6e0e5..2b609a9 100644
--- a/sanitytest.py
+++ b/sanitytest.py
@@ -145,6 +145,9 @@ for cname in wantfunctions:
if name[0:26] == "virDomainIOThreadsInfoFree":
continue
+ if name[0:33] == "virDomainInterfaceFree":
+ continue
+
if name[0:21] == "virDomainListGetStats":
name = "virConnectDomainListGetStats"
--
2.1.0
9 years, 8 months
[libvirt] LXC container with user namespace and root fs on loop device - how it's supposed to work?
by Dmitry Guryanov
Hello,
It's not possible to start LXC container inside user namespace with root
filesystem on loop device, because it tries to mount root FS from
container's user namespace (lxcContainerSetupPivotRoot) and gets EPERM:
2015-03-19 12:48:18.545+0000: 1: debug : lxcContainerChild:2278 :
Tearing down container
Failed to mount device /dev/loop0 to
/var/run/libvirt/lxc/instance-0000000b.root: Operation not permitted
So I wonder, if someone tried to run LXC container with such
configuration with success.
Here is my config:
<domain type='lxc'>
<name>instance-0000000b</name>
<uuid>d918c415-0a00-4c12-896e-19e4711111d3</uuid>
<memory unit='KiB'>524288</memory>
<currentMemory unit='KiB'>524288</currentMemory>
<cputune>
<shares>1024</shares>
</cputune>
<os>
<type arch='x86_64'>exe</type>
<init>/sbin/init</init>
<cmdline>console=tty0 console=ttyS0</cmdline>
</os>
<idmap>
<uid start='0' target='10000' count='1000'/>
<gid start='0' target='10000' count='1000'/>
</idmap>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/libexec/libvirt_lxc</emulator>
<filesystem type='file' accessmode='passthrough'>
<driver type='loop' format='raw'/>
<source file='/root/2.img'/>
<target dir='/'/>
</filesystem>
<console type='pty'>
<target type='lxc' port='0'/>
</console>
</devices>
</domain>
--
Dmitry Guryanov
9 years, 8 months
[libvirt] [PATCH v2 0/6] parallels: implement managed save
by Dmitry Guryanov
This patch series is intended to implement all needed code, so
that suspend/resume in openstack nova will work.
It implements .domainHasManagedSaveImage, .domainManagedSave
and .domainManagedSaveRemove functions. Also it adds
workaround to parallelsDomainDefineXMLFlags to skip
applying configuration, if VM is in managed save state and
config hasn't been changed, because it's not possible
to change VM config in suspended state in PCS.
Changes in v2:
* rebased
Dmitry Guryanov (6):
parallels: fix headers in parallels_sdk.h
parallels: split prlsdkDomainChangeState function
parallels: implement virDomainManagedSave
parallels: report, that cdroms are readonly
parallels: add controllers in prlsdkLoadDomain
parallels: fix virDomainDefineXML for domain in saved state
src/parallels/parallels_driver.c | 101 +++++++++++++++++++++++++++++++++++++--
src/parallels/parallels_sdk.c | 65 ++++++++++++++++++-------
src/parallels/parallels_sdk.h | 17 +++++--
3 files changed, 157 insertions(+), 26 deletions(-)
--
2.1.0
9 years, 8 months
[libvirt] USB hostdev de/reattaching
by Martin Polednik
Hello,
according to libvirt documentation, when using hostdev with USB device
"...the user is responsible to call virNodeDeviceDettach (or virsh nodedev-detach)
before starting the guest...". In libvirt-1.2.13-1.el7.x86_64, this leads to
virsh nodedev-detach usb_usb1
error: Failed to detach device usb_usb1
error: invalid argument: device usb_usb1 is not a PCI device
The failure is most probably caused in qemuNodeDeviceDeta where qemuNodeDeviceGetPCIInfo
is called. Is it a bug, or usb hostdev can be done without detaching/reattaching?
Thanks,
mpolednik
9 years, 8 months
Re: [libvirt] [SOLVED] Domain XML isn't dumping full backing chain
by Deepak Shetty
On Wed, Mar 18, 2015 at 5:33 PM, Shanzhi Yu <shyu(a)redhat.com> wrote:
>
>
> ------------------------------
>
> *From: *"Deepak Shetty" <dpkshetty(a)gmail.com>
> *To: *libvir-list(a)redhat.com
> *Sent: *Wednesday, March 18, 2015 7:19:05 PM
> *Subject: *[libvirt] Domain XML isn't dumping full backing chain
>
>
> Hi,
> I am using libvirt version 1.2.9.2 on F21 and i am unable to get the
> complete backing chain info in the virsh dumpxml output. Details below :
>
> *My backing chain per qemu-img :*
>
> [stack@devstack-f21 test]$ qemu-img info --backing-chain snap4.qcow2
> image: snap4.qcow2
> file format: qcow2
> virtual size: 1.0G (1073741824 bytes)
> disk size: 196K
> cluster_size: 65536
> backing file: ./snap3.qcow2
> Format specific information:
> compat: 1.1
> lazy refcounts: false
>
> image: ./snap3.qcow2
> file format: qcow2
> virtual size: 1.0G (1073741824 bytes)
> disk size: 196K
> cluster_size: 65536
> backing file: ./snap2.qcow2 (actual path: ././snap2.qcow2)
> Format specific information:
> compat: 1.1
> lazy refcounts: false
>
> image: ././snap2.qcow2
> file format: qcow2
> virtual size: 1.0G (1073741824 bytes)
> disk size: 196K
> cluster_size: 65536
> backing file: ./snap1.qcow2 (actual path: ./././snap1.qcow2)
> Format specific information:
> compat: 1.1
> lazy refcounts: false
>
> image: ./././snap1.qcow2
> file format: qcow2
> virtual size: 1.0G (1073741824 bytes)
> disk size: 196K
> cluster_size: 65536
> backing file: ./base.qcow2 (actual path: ././././base.qcow2)
> Format specific information:
> compat: 1.1
> lazy refcounts: false
>
> image: ././././base.qcow2
> file format: qcow2
> virtual size: 1.0G (1073741824 bytes)
> disk size: 196K
> cluster_size: 65536
> Format specific information:
> compat: 1.1
> lazy refcounts: false
>
> If you want prepare the backing chain yourself, you should add "-o
> backing_fmt=$farmat" options,
> like "qemu-img create -f qcow2 base.s1 -b base.qcow2 -o backing_fmt=qcow2"
>
Thanks, it works after I did the above
thanx,
deepak
9 years, 8 months
[libvirt] [PATCH] qemu: fix sometimes error overwrite when we fail to start/migrate/restore
by Luyao Huang
https://bugzilla.redhat.com/show_bug.cgi?id=1196934
When start/migrate/restore a vm failed, libvirt will try to catch the log in
/var/log/libvirt/qemu/vm.log and output them before. However we add a check in
qemuDomainObjExitMonitor after commit dc2fd51f, this will overwrite
the error set in priv->mon which has set by qemuMonitorIO (a qemu monitor
I/O event callback function).
Add a check in qemuDomainObjExitMonitor, if there is an error have been
set by other function, we won't overwrite it.
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
src/qemu/qemu_domain.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 2eacef2..41d1263 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1609,8 +1609,9 @@ int qemuDomainObjExitMonitor(virQEMUDriverPtr driver,
{
qemuDomainObjExitMonitorInternal(driver, obj);
if (!virDomainObjIsActive(obj)) {
- virReportError(VIR_ERR_OPERATION_FAILED, "%s",
- _("domain is no longer running"));
+ if (!virGetLastError())
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("domain is no longer running"));
return -1;
}
return 0;
--
1.8.3.1
9 years, 8 months
[libvirt] [PATCH v2 0/2] network_conf: check if bridge exists on host for user created bridges
by Shivaprasad G Bhat
The patch fixes the below problem.
==============================
If the bridge name is not mentioned in the <network> xml, the bridge name is
auto generated from virNetworkAllocateBridge(). If the default template named
bridge is created manually by a user, the bridge start will fail with
"File exists".
bash-4.3$ sudo brctl addbr virbr1
bash-4.3$ brctl show
bridge name bridge id STP enabled interfaces
br0 8000.000000000000 no
virbr0 8000.525400a91d03 yes virbr0-nic
virbr1 8000.000000000000 no
bash-4.3$ sudo virsh net-list --all
Name State Autostart Persistent
----------------------------------------------------------
default active no yes
bash-4.3$ cat /tmp/isolated # Notice that the <bridge> intentionally not given.
<network>
<name>isolated</name>
<forward/>
<ip address="192.168.123.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.123.2" end="192.168.123.254"/>
</dhcp>
</ip>
</network>
bash-4.3$ sudo virsh net-create /tmp/isolated
error: Failed to create network from isolated
error: Unable to create bridge virbr1: File exists
===============================
---
Shivaprasad G Bhat (2):
cleanup conf/device_conf.h reference from util/virnetdev.h
network_conf: check if bridge exists on host for user created bridges
src/Makefile.am | 3 +--
src/conf/device_conf.h | 21 +--------------------
src/conf/network_conf.c | 11 +++++++++--
src/util/virnetdev.h | 21 ++++++++++++++++++++-
4 files changed, 31 insertions(+), 25 deletions(-)
--
Signature
9 years, 8 months
[libvirt] [PATCH v2] doc: Fix doc for backingStore
by Deepak Shetty
I spent quite some time figuring that backingStore info
isn't included in the dom xml, unless guest is up and
running. Hopefully putting that in the doc should help.
This patch adds that info to the doc.
Signed-off-by: Deepak C Shetty <deepakcs(a)redhat.com>
---
docs/formatdomain.html.in | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index ab51982..a41c2c6 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2113,7 +2113,12 @@
and only used for output to describe the detected backing chains.
<span class="since">Since 1.2.4</span>. An empty
<code>backingStore</code> element means the sibling source is
- self-contained and is not based on any backing store. The following
+ self-contained and is not based on any backing store. Note that
+ <code>backingStore</code> info is included in the output only when
+ the guest is up and running, otherwise it's not included. For
accurate
+ <code>backingStore</code> info, when using external snapshot with
the
+ destination of a existing file, the snapshot must be created with
+ backing file format specified in the metadata. The following
attributes and sub-elements are supported in
<code>backingStore</code>:
<dl>
--
1.9.3
9 years, 8 months
[libvirt] [PATCH] libxl: Don't overwrite errors from xenconfig
by Jim Fehlig
When converting domXML from native, the libxl driver was overwriting
useful errors from the xenconfig parsing code with a useless, generic
error. E.g. "internal error: parsing xm config failed" vs
"internal error: config value usbdevice was malformed". Remove the
redundant (and useless) error reporting in the libxl driver.
Signed-off-by: Jim Fehlig <jfehlig(a)suse.com>
---
src/libxl/libxl_driver.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index e555ca4..1c1af79 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -2222,22 +2222,16 @@ libxlConnectDomainXMLFromNative(virConnectPtr conn,
goto cleanup;
if (!(def = xenParseXL(conf,
cfg->caps,
- cfg->verInfo->xen_version_major))) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("parsing xl config failed"));
+ cfg->verInfo->xen_version_major)))
goto cleanup;
- }
} else if (STREQ(nativeFormat, LIBXL_CONFIG_FORMAT_XM)) {
if (!(conf = virConfReadMem(nativeConfig, strlen(nativeConfig), 0)))
goto cleanup;
if (!(def = xenParseXM(conf,
cfg->verInfo->xen_version_major,
- cfg->caps))) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("parsing xm config failed"));
+ cfg->caps)))
goto cleanup;
- }
} else if (STREQ(nativeFormat, LIBXL_CONFIG_FORMAT_SEXPR)) {
/* only support latest xend config format */
if (!(def = xenParseSxprString(nativeConfig,
--
1.8.4.5
9 years, 8 months