[libvirt] [PATCH] qemu: Fix parsing of x86 CPU models
by Jiri Denemark
QEMU changed the output of -cpu ? and CPU models can now be followed by
its description. Our parser just used both model name and its
description as a model name, which made any model with a description
unusable with libvirt.
---
src/qemu/qemu_capabilities.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index a5eb995..d16a7bc 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -379,7 +379,7 @@ typedef int
qemuCapsPtr caps);
/* Format:
- * <arch> <model>
+ * <arch> <model> <description>
* qemu-0.13 encloses some model names in []:
* <arch> [<model>]
*/
@@ -389,6 +389,7 @@ qemuCapsParseX86Models(const char *output,
{
const char *p = output;
const char *next;
+ const char *end;
int ret = -1;
do {
@@ -416,8 +417,12 @@ qemuCapsParseX86Models(const char *output,
goto cleanup;
}
- if (next)
- len = next - p - 1;
+ end = next ? next - 1 : NULL;
+ if ((t = strchr(p, ' ')) && (!next || t < next))
+ end = t;
+
+ if (end)
+ len = end - p;
else
len = strlen(p);
--
1.7.12
12 years, 1 month
[libvirt] [ANNOUNCE] libvirt-glib 0.1.3 release
by Daniel P. Berrange
I am pleased to announce that a new release of the libvirt-glib package,
version 0.1.3, is now available from
ftp://libvirt.org/libvirt/glib/
The packages are GPG signed with
Key fingerprint: DAF3 A6FD B26B 6291 2D0E 8E3F BE86 EBB4 1510 4FDF (4096R)
New in this release:
- Improve documentation for set_memory method in GVirConfigDomain
- Handle size units for memory attributes
- Add API for current memory
- Fix python example to specify virt type
- Use 1 GB of RAM in python example instead 1 TB !
- Add API to get hypervisor name and version
- Avoid NULL format string for g_set_error
- Fix XXX_new_with_xml constructors for config objects
- Add misc getters for VNC/SPICE config attributes
- Add handling of PMSUSPENDED state
- Add handling of WAKEUP events
- Require libvirt 0.10.2 minimum
- Add API for domain PM wakeup
libvirt-glib comprises three distinct libraries:
- libvirt-glib - Integrate with the GLib event loop and error handling
- libvirt-gconfig - Representation of libvirt XML documents as GObjects
- libvirt-gobject - Mapping of libvirt APIs into the GObject type system
NB: While libvirt aims to be API/ABI stable forever, with libvirt-glib
we are not yet guaranteeing that libvirt-glib libraries are API/ABI
permanently stable. As of the 0.0.8 release, we have tentatively frozen
the API/ABI with the intent of being longterm stable hereafter, but
there is still a small chance we might find flaws requiring an API/ABI
change. The likelihood of this is low, however, and we will strive to
avoid it.
Follow up comments about libvirt-glib should be directed to the regular
libvir-list(a)redhat.com development list.
Thanks to all the people involved in contributing to this release.
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
12 years, 1 month
[libvirt] Core dump caused by misusing openssl in multithread scenario!
by Benjamin Wang (gendwang)
Hi,
I am running libvirt with ESXi driver in multithread scenario to access ESXi by https. Sometimes a core dump will be generated as following:
#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 0x0000003f9b072fae in _int_malloc () from /lib64/libc.so.6
#4 0x0000003f9b074cde in malloc () from /lib64/libc.so.6
#5 0x0000003f9b07963b in strerror () from /lib64/libc.so.6
#6 0x0000003fa188032a in ERR_load_ERR_strings () from /lib64/libcrypto.so.6
#7 0x0000003fa187fde9 in ERR_load_crypto_strings () from /lib64/libcrypto.so.6
#8 0x0000003fa48309d9 in SSL_load_error_strings () from /lib64/libssl.so.6
#9 0x00002aaaba8e612e in Curl_ossl_init () from /opt/CSCOppm-unit/hypervisor/libcurl/lib/libcurl.so.4
#10 0x00002aaaba8ee6c1 in curl_global_init () from /opt/CSCOppm-unit/hypervisor/libcurl/lib/libcurl.so.4
#11 0x00002aaaba8ee6f8 in curl_easy_init () from /opt/CSCOppm-unit/hypervisor/libcurl/lib/libcurl.so.4
#12 0x00002aaaba0d932b in esxVI_SessionIsActive (ctx=0x2aaac093ca80, sessionID=0x2aaac06932a0 "`3i\300\252*", userName=0x2aaac0ae6e80 "root", output=0xffffffffffffffff) at esx/esx_vi_methods.generated.c:599
#13 0x00002aaaba0c7a60 in esxStorageVolumeLookupByKey (conn=0x7412, key=0x76c1 <Address 0x76c1 out of bounds>) at esx/esx_storage_driver.c:825
I checked that currently ESXi driver didn't initialize openssl. Because libcurl will not handle openssl for multi-thread. According to openssl API, libvirt should
register two methods to support mutli-threads. The detailed description is as following:
http://www.openssl.org/docs/crypto/threads.html
I have changed code as following:
1. virInitialize() in libvirt.c
Old Code:
int
virInitialize(void)
{
...
virLogSetFromEnv();
virNetTLSInit();
...
}
New Code:
int
virInitialize(void)
{
...
virLogSetFromEnv();
virNetTLSInit();
virOpenSSLInit();
...
}
2. In virnetServer.c
New Code:
pthread_mutex_t *lock_cs;
long *lock_count;
void virOpenSSLLockCallback(int mode, int type, const char *file ATTRIBUTE_UNUSED, int line ATTRIBUTE_UNUSED) {
if (mode & CRYPTO_LOCK)
{
pthread_mutex_lock(&(lock_cs[type]));
lock_count[type]++;
}
else
{
pthread_mutex_unlock(&(lock_cs[type]));
}
}
unsigned long virOpenSSLIdCallback(void)
{
unsigned long ret;
ret=(unsigned long)pthread_self();
return(ret);
}
void virOpenSSLInit(void)
{
int i;
lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
for (i=0; i<CRYPTO_num_locks(); i++)
{
lock_count[i]=0;
pthread_mutex_init(&(lock_cs[i]),NULL);
}
CRYPTO_set_id_callback(virOpenSSLIdCallback);
CRYPTO_set_locking_callback(virOpenSSLLockCallback);
}
To be honest, virOpenSSLInit/ virOpenSSLIdCallback/ virOpenSSLLockCallback should not be defined in this file. But It seems that Makefile generated by autoconfig can't
handle the new file recursively.
What about this solution? If you have any comments, please feel free to contact me.
BTW: If I add a new source/header file, is there a simple way to change Makefile?
B.R.
Benjamin Wang
12 years, 1 month
[libvirt] [PATCH 0/7] Add support for lock failure action
by Jiri Denemark
When sanlock is used as a locking driver and sanlock deamon loses access to its
lockspace, it automatically kills off the domains that had their locks stored
there. Apparently some management apps would like to change this behavior by
configuring what should happen when locks are lost.
Everything except the sanlock_helper code from patch 7/7 should be stable. The
helper code may need some additional work (perhaps even touching other parts of
libvirtd internals) because some lock failure action does not work as expected.
For example, when automatic disk locks are enabled, the "pause" action will
result in libvirtd calling back to sanlock and since it doesn't have access to
the lockspace, the call would just hang. However, since currently the only
requestor for this feature is VDSM and it doesn't use automatic disk locks, the
sanlock_helper could work for them without any modifications. And since current
sanlock_helper implementation is supposed to be changed when libvirtd gains
administrative interface (see patch 7/7 for more details) we may even just live
with its limitations for the time being.
Jiri Denemark (7):
conf: Generalize life cycle actions to event actions
conf: Add on_lockfailure event configuration
qemu: Use macro instead of "qemu" in the context of URI scheme
locking: Add const char * parameter to avoid ugly typecasts
locking: Pass hypervisor driver name when acquiring locks
locking: Add support for lock failure action
locking: Implement lock failure action in sanlock driver
docs/formatdomain.html.in | 37 +++++--
docs/internals/locking.html.in | 8 ++
docs/schemas/domaincommon.rng | 30 +++++-
libvirt.spec.in | 1 +
src/Makefile.am | 13 ++-
src/conf/domain_conf.c | 85 +++++++++------
src/conf/domain_conf.h | 18 +++-
src/libvirt_private.syms | 2 +
src/locking/domain_lock.c | 36 ++++---
src/locking/domain_lock.h | 4 +
src/locking/lock_driver.h | 8 +-
src/locking/lock_driver_nop.c | 1 +
src/locking/lock_driver_sanlock.c | 114 +++++++++++++++++---
src/locking/lock_manager.c | 10 +-
src/locking/lock_manager.h | 1 +
src/locking/sanlock_helper.c | 214 ++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_conf.h | 2 +
src/qemu/qemu_driver.c | 21 ++--
src/qemu/qemu_hotplug.c | 15 ++-
src/qemu/qemu_process.c | 4 +-
20 files changed, 537 insertions(+), 87 deletions(-)
create mode 100644 src/locking/sanlock_helper.c
--
1.7.12
12 years, 1 month
[libvirt] Support for qemu snapshot=on drives in libvirt
by Richard W.M. Jones
I notice that the qemu driver doesn't support snapshot drives
(-drive file=foo,snapshot=on). This is important for libguestfs.
Currently libguestfs hacks this using <qemu:arg>. That works fine for
static disks in the libvirt XML, but lack of direct support in libvirt
is a blocker for adding hotplugging to libguestfs.
In qemu, the snapshot=on feature does several things:
(a) It creates a temporary qcow2 disk in $TMPDIR.
(b) It sets the backing file of the temporary disk to the real disk.
(c) When running, writes to the disk go to the temporary overlay, and
not to the real disk.
(d) I believe it also lets you commit changes from the temporary disk
to the backing file using a monitor command ("commit"? "save"?).
However we don't need or use this feature.
(e) When qemu exits, the temporary qcow2 disk is deleted.
So note that when you use snapshot=on there is an implicit dependency
on the $TMPDIR environment variable. I don't know of a way to create
the snapshot in another directory (at least, not using snapshot=on
.. possibly one can do it by creating an explicit overlay disk in
libvirt).
A simple implementation therefore would be to add a <snapshot/>
element to <disk>. It would just add snapshot=on and ignore concerns
about $TMPDIR.
Or reuse the <readonly/> flag? Note that these disks are writable.
A more complex implementation would create an explicit overlay disk in
libvirt and clean it up afterwards. This would let us control where
the temporary disk is created. XML might look like this:
<snapshot [tmp=...] />
I'm also concerned about the time is takes to run the external
'qemu-img create' command, which is non-trivial in some versions
of qemu. In libguestfs, every millisecond counts.
$ time qemu-img create -f qcow2 test.qcow2 10M
Formatting 'test.qcow2', fmt=qcow2 size=10485760 encryption=off cluster_size=65536
real 0m0.610s
user 0m0.022s
sys 0m0.009s
Or, can this be done using existing libvirt features?
Any thoughts on this before I implement something ...
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming blog: http://rwmj.wordpress.com
Fedora now supports 80 OCaml packages (the OPEN alternative to F#)
http://cocan.org/getting_started_with_ocaml_on_red_hat_and_fedora
12 years, 1 month
[libvirt] [PATCH] python: keep consistent handling of Python integer conversion
by Guannan Ren
libvirt_ulonglongUnwrap requires the integer type of python obj.
But libvirt_longlongUnwrap still could handle python obj of
Pyfloat_type which causes the float value to be rounded up
to an integer.
For example
>>> dom.setSchedulerParameters({'vcpu_quota': 0.88})
0
libvirt_longlongUnwrap treats 0.88 as a valid value 0
However
>>> dom.setSchedulerParameters({'cpu_shares': 1000.22})
libvirt_ulonglongUnwrap will throw out an error
"TypeError: an integer is required"
The patch make this consistent.
---
python/typewrappers.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/python/typewrappers.c b/python/typewrappers.c
index 7580689..d633603 100644
--- a/python/typewrappers.c
+++ b/python/typewrappers.c
@@ -220,7 +220,7 @@ libvirt_ulongUnwrap(PyObject *obj, unsigned long *val)
int
libvirt_longlongUnwrap(PyObject *obj, long long *val)
{
- long long llong_val;
+ long long llong_val = -1;
if (!obj) {
PyErr_SetString(PyExc_TypeError, "unexpected type");
@@ -230,7 +230,11 @@ libvirt_longlongUnwrap(PyObject *obj, long long *val)
/* If obj is of PyInt_Type, PyLong_AsLongLong
* will call PyInt_AsLong() to handle it automatically.
*/
- llong_val = PyLong_AsLongLong(obj);
+ if (PyInt_Check(obj) || PyLong_Check(obj))
+ llong_val = PyLong_AsLongLong(obj);
+ else
+ PyErr_SetString(PyExc_TypeError, "an integer is required");
+
if ((llong_val == -1) && PyErr_Occurred())
return -1;
--
1.7.11.2
12 years, 1 month
[libvirt] [RFC] Private data pointer for virStoragePool and virStorageVol structs
by Matthias Bolte
Ata Bohra proposed a backend concept for the ESX storage driver to
simplify the addition of iSCSI support to the ESX storage driver.
The problem here is that most of the storage driver functions need to
determine the backend to be used from the pool name.
This overhead can be avoided by adding a private data pointer to the
virStoragePool and virStorageVol structs that the ESX storage driver
can use to store a pointer to the correct backend.
struct _virStoragePool {
virObject object;
virConnectPtr conn;
char *name;
unsigned char uuid[VIR_UUID_BUFLEN];
void *privateData;
virFreeCallback privateDataFreeFunc;
};
struct _virStorageVol {
virObject object;
virConnectPtr conn;
char *pool;
char *name;
char *key;
void *privateData;
virFreeCallback privateDataFreeFunc;
};
virGetStoragePool and virGetStorageVol would set privateData and
privateDataFreeFunc as given by the caller. virStoragePoolDispose and
virStorageVolDispose would call privateDataFreeFunc if set.
Comments?
--
Matthias Bolte
http://photron.blogspot.com
12 years, 1 month
[libvirt] [PATCH v3] esx: Support VLAN tags in virtual network port groups
by Matthias Bolte
---
v2: Use network level VLAN config if there is no portgroup specific VLAN
config given.
v3: Add ESX_VLAN_TRUNK define for magic number 4095
src/esx/esx_network_driver.c | 70 +++++++++++++++++++++++++++++++++++++++---
1 files changed, 65 insertions(+), 5 deletions(-)
diff --git a/src/esx/esx_network_driver.c b/src/esx/esx_network_driver.c
index 09d46d3..21eabbe 100644
--- a/src/esx/esx_network_driver.c
+++ b/src/esx/esx_network_driver.c
@@ -45,6 +45,9 @@
*/
verify(MD5_DIGEST_SIZE == VIR_UUID_BUFLEN);
+/* ESX utilizes the VLAN ID of 4095 to mean that this port is in trunk mode */
+#define ESX_VLAN_TRUNK 4095
+
static virDrvOpenStatus
@@ -489,7 +492,42 @@ esxNetworkDefineXML(virConnectPtr conn, const char *xml)
goto cleanup;
}
- hostPortGroupSpec->vlanId->value = 0;
+ if (def->portGroups[i].vlan.trunk) {
+ /* FIXME: Change this once tag-less trunk-mode is supported */
+ if (def->portGroups[i].vlan.nTags != 1 ||
+ *def->portGroups[i].vlan.tag != ESX_VLAN_TRUNK) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("VLAN tag has to be %d in trunk mode"),
+ ESX_VLAN_TRUNK);
+ goto cleanup;
+ }
+
+ hostPortGroupSpec->vlanId->value = ESX_VLAN_TRUNK;
+ } else if (def->portGroups[i].vlan.nTags == 1) {
+ hostPortGroupSpec->vlanId->value = *def->portGroups[i].vlan.tag;
+ } else if (def->portGroups[i].vlan.nTags > 1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Can apply one VLAN tag per port group only"));
+ goto cleanup;
+ } else if (def->vlan.trunk) {
+ /* FIXME: Change this once tag-less trunk-mode is supported */
+ if (def->vlan.nTags != 1 || *def->vlan.tag != ESX_VLAN_TRUNK) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("VLAN tag has to be %d in trunk mode"),
+ ESX_VLAN_TRUNK);
+ goto cleanup;
+ }
+
+ hostPortGroupSpec->vlanId->value = ESX_VLAN_TRUNK;
+ } else if (def->vlan.nTags == 1) {
+ hostPortGroupSpec->vlanId->value = *def->vlan.tag;
+ } else if (def->vlan.nTags > 1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Can apply one VLAN tag per port group only"));
+ goto cleanup;
+ } else {
+ hostPortGroupSpec->vlanId->value = 0;
+ }
if (def->portGroups[i].bandwidth != NULL) {
if (esxBandwidthToShapingPolicy
@@ -519,6 +557,8 @@ esxNetworkDefineXML(virConnectPtr conn, const char *xml)
network = virGetNetwork(conn, hostVirtualSwitch->name, md5);
cleanup:
+ /* FIXME: need to remove virtual switch if adding port groups failed */
+
virNetworkDefFree(def);
esxVI_HostVirtualSwitch_Free(&hostVirtualSwitch);
esxVI_HostPortGroup_Free(&hostPortGroupList);
@@ -695,6 +735,7 @@ esxNetworkGetXMLDesc(virNetworkPtr network_, unsigned int flags)
esxVI_String *hostPortGroupKey = NULL;
esxVI_String *networkName = NULL;
virNetworkDefPtr def;
+ virPortGroupDefPtr portGroup;
if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
@@ -824,9 +865,12 @@ esxNetworkGetXMLDesc(virNetworkPtr network_, unsigned int flags)
for (networkName = networkNameList; networkName != NULL;
networkName = networkName->_next) {
if (STREQ(networkName->value, hostPortGroup->spec->name)) {
- def->portGroups[def->nPortGroups].name = strdup(networkName->value);
+ portGroup = &def->portGroups[def->nPortGroups];
+ ++def->nPortGroups;
+
+ portGroup->name = strdup(networkName->value);
- if (def->portGroups[def->nPortGroups].name == NULL) {
+ if (portGroup->name == NULL) {
virReportOOMError();
goto cleanup;
}
@@ -834,13 +878,29 @@ esxNetworkGetXMLDesc(virNetworkPtr network_, unsigned int flags)
if (hostPortGroup->spec->policy != NULL) {
if (esxShapingPolicyToBandwidth
(hostPortGroup->spec->policy->shapingPolicy,
- &def->portGroups[def->nPortGroups].bandwidth) < 0) {
+ &portGroup->bandwidth) < 0) {
++def->nPortGroups;
goto cleanup;
}
}
- ++def->nPortGroups;
+ if (hostPortGroup->spec->vlanId->value > 0) {
+ if (hostPortGroup->spec->vlanId->value == ESX_VLAN_TRUNK) {
+ portGroup->vlan.trunk = true;
+ }
+
+ /* FIXME: Remove this once tag-less trunk-mode is supported */
+ portGroup->vlan.nTags = 1;
+
+ if (VIR_ALLOC_N(portGroup->vlan.tag, 1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ *portGroup->vlan.tag =
+ hostPortGroup->spec->vlanId->value;
+ }
+
break;
}
}
--
1.7.4.1
12 years, 1 month