[libvirt] [PATCH] storage: Report UUID/name consistently in driver errors
by Cole Robinson
Done with:
sed -i -e "s/no pool with matching uuid/no storage pool with matching uuid/g" src/storage/storage_driver.c
sed -i -e 's/"%s", _("no storage pool with matching uuid")/_("no storage pool with matching uuid %s"), obj->uuid/g' src/storage/storage_driver.c
sed -i -e 's/"%s", _("storage pool is not active")/_("storage pool '%s' is not active"), pool->def->name/g' src/storage/storage_driver.c
And a couple fixups before, during, and after, and a manual inspection
pass to make sure nothing was wonky.
---
src/storage/storage_driver.c | 122 ++++++++++++++++++++++++-------------------
1 file changed, 68 insertions(+), 54 deletions(-)
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 5ba3076..28829d3 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -269,7 +269,7 @@ storagePoolLookupByUUID(virConnectPtr conn,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), uuid);
goto cleanup;
}
@@ -294,7 +294,7 @@ storagePoolLookupByName(virConnectPtr conn,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- _("no pool with matching name '%s'"), name);
+ _("no storage pool with matching name '%s'"), name);
goto cleanup;
}
@@ -621,13 +621,14 @@ storagePoolUndefine(virStoragePoolPtr obj) {
pool = virStoragePoolObjFindByUUID(&driver->pools, obj->uuid);
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
if (virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("pool is still active"));
+ _("storage pool '%s' is still active"),
+ pool->def->name);
goto cleanup;
}
@@ -679,7 +680,7 @@ storagePoolStart(virStoragePoolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
@@ -688,7 +689,8 @@ storagePoolStart(virStoragePoolPtr obj,
if (virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("pool already active"));
+ _("storage pool '%s' is already active"),
+ pool->def->name);
goto cleanup;
}
if (backend->startPool &&
@@ -725,7 +727,7 @@ storagePoolBuild(virStoragePoolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
@@ -734,7 +736,8 @@ storagePoolBuild(virStoragePoolPtr obj,
if (virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is already active"));
+ _("storage pool '%s' is already active"),
+ pool->def->name);
goto cleanup;
}
@@ -762,7 +765,7 @@ storagePoolDestroy(virStoragePoolPtr obj) {
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
@@ -771,7 +774,7 @@ storagePoolDestroy(virStoragePoolPtr obj) {
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto cleanup;
}
@@ -822,7 +825,7 @@ storagePoolDelete(virStoragePoolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
@@ -831,7 +834,8 @@ storagePoolDelete(virStoragePoolPtr obj,
if (virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is still active"));
+ _("storage pool '%s' is still active"),
+ pool->def->name);
goto cleanup;
}
@@ -875,7 +879,7 @@ storagePoolRefresh(virStoragePoolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
@@ -884,7 +888,7 @@ storagePoolRefresh(virStoragePoolPtr obj,
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto cleanup;
}
@@ -931,7 +935,7 @@ storagePoolGetInfo(virStoragePoolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
@@ -971,7 +975,7 @@ storagePoolGetXMLDesc(virStoragePoolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
@@ -1001,7 +1005,7 @@ storagePoolGetAutostart(virStoragePoolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
@@ -1030,7 +1034,7 @@ storagePoolSetAutostart(virStoragePoolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
@@ -1090,13 +1094,13 @@ storagePoolNumVolumes(virStoragePoolPtr obj) {
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto cleanup;
}
ret = pool->volumes.count;
@@ -1123,13 +1127,13 @@ storagePoolListVolumes(virStoragePoolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto cleanup;
}
@@ -1172,14 +1176,15 @@ storagePoolListAllVolumes(virStoragePoolPtr pool,
storageDriverUnlock(driver);
if (!obj) {
- virReportError(VIR_ERR_NO_STORAGE_POOL, "%s",
- _("no storage pool with matching uuid"));
+ virReportError(VIR_ERR_NO_STORAGE_POOL,
+ _("no storage pool with matching uuid %s"),
+ pool->uuid);
goto cleanup;
}
if (!virStoragePoolObjIsActive(obj)) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("storage pool is not active"));
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("storage pool '%s' is not active"), obj->def->name);
goto cleanup;
}
@@ -1234,13 +1239,13 @@ storageVolumeLookupByName(virStoragePoolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto cleanup;
}
@@ -1288,7 +1293,7 @@ storageVolumeLookupByKey(virConnectPtr conn,
if (!ret)
virReportError(VIR_ERR_NO_STORAGE_VOL,
- "%s", _("no storage vol with matching key"));
+ _("no storage vol with matching key %s"), key);
return ret;
}
@@ -1339,7 +1344,7 @@ storageVolumeLookupByPath(virConnectPtr conn,
if (!ret)
virReportError(VIR_ERR_NO_STORAGE_VOL,
- "%s", _("no storage vol with matching path"));
+ _("no storage vol with matching path %s"), path);
VIR_FREE(cleanpath);
storageDriverUnlock(driver);
@@ -1367,13 +1372,13 @@ storageVolumeCreateXML(virStoragePoolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto cleanup;
}
@@ -1386,7 +1391,7 @@ storageVolumeCreateXML(virStoragePoolPtr obj,
if (virStorageVolDefFindByName(pool, voldef->name)) {
virReportError(VIR_ERR_NO_STORAGE_VOL,
- "%s", _("storage vol already exists"));
+ _("storage vol '%s' already exists"), voldef->name);
goto cleanup;
}
@@ -1496,7 +1501,7 @@ storageVolumeCreateXMLFrom(virStoragePoolPtr obj,
storageDriverUnlock(driver);
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching uuid %s"), obj->uuid);
goto cleanup;
}
@@ -1509,13 +1514,14 @@ storageVolumeCreateXMLFrom(virStoragePoolPtr obj,
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto cleanup;
}
if (origpool && !virStoragePoolObjIsActive(origpool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"),
+ origpool->def->name);
goto cleanup;
}
@@ -1655,13 +1661,14 @@ storageVolumeDownload(virStorageVolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching name '%s'"),
+ obj->pool);
goto out;
}
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto out;
}
@@ -1717,13 +1724,14 @@ storageVolumeUpload(virStorageVolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching name '%s'"),
+ obj->pool);
goto out;
}
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto out;
}
@@ -1779,14 +1787,15 @@ storageVolumeResize(virStorageVolPtr obj,
storageDriverUnlock(driver);
if (!pool) {
- virReportError(VIR_ERR_NO_STORAGE_POOL, "%s",
- _("no storage pool with matching uuid"));
+ virReportError(VIR_ERR_NO_STORAGE_POOL,
+ _("no storage pool with matching name '%s'"),
+ obj->pool);
goto out;
}
if (!virStoragePoolObjIsActive(pool)) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("storage pool is not active"));
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("storage pool '%s' is not active"), pool->def->name);
goto out;
}
@@ -2074,13 +2083,14 @@ storageVolumeWipePattern(virStorageVolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching name '%s'"),
+ obj->pool);
goto out;
}
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto out;
}
@@ -2138,13 +2148,14 @@ storageVolumeDelete(virStorageVolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching name '%s'"),
+ obj->pool);
goto cleanup;
}
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto cleanup;
}
@@ -2219,13 +2230,14 @@ storageVolumeGetInfo(virStorageVolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching name '%s'"),
+ obj->pool);
goto cleanup;
}
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto cleanup;
}
@@ -2275,13 +2287,14 @@ storageVolumeGetXMLDesc(virStorageVolPtr obj,
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching name '%s'"),
+ obj->pool);
goto cleanup;
}
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto cleanup;
}
@@ -2322,13 +2335,14 @@ storageVolumeGetPath(virStorageVolPtr obj) {
storageDriverUnlock(driver);
if (!pool) {
virReportError(VIR_ERR_NO_STORAGE_POOL,
- "%s", _("no storage pool with matching uuid"));
+ _("no storage pool with matching name '%s'"),
+ obj->pool);
goto cleanup;
}
if (!virStoragePoolObjIsActive(pool)) {
virReportError(VIR_ERR_OPERATION_INVALID,
- "%s", _("storage pool is not active"));
+ _("storage pool '%s' is not active"), pool->def->name);
goto cleanup;
}
--
1.7.11.4
12 years, 1 month
[libvirt] [PATCH 0/2] Cleanly save session VMs on logout/shutdown
by Alexander Larsson
Atm, when you exit the sessin (via logout or shutdown for instance) we
just leave the qemu:///session handling libvirtd process around, including
any running VMs. This is not particularly nice, as there is no way to
know that the VMs are running, and you risk data loss if you shutdown
while the VMs are running.
This new version is basically the same as the previous, except it
runs inside libvirtd, and it exits libvirtd too after saving the VMs.
Alexander Larsson (2):
virdbus: Add virDBusGetSessionBus helper
Shut down session libvirtd cleanly
daemon/libvirtd.c | 244 +++++++++++++++++++++++++++++++++++++++++++++++
src/libvirt_private.syms | 1 +
src/util/virdbus.c | 84 ++++++++++++----
src/util/virdbus.h | 1 +
4 files changed, 310 insertions(+), 20 deletions(-)
--
1.7.12.1
12 years, 1 month
[libvirt] [PATCH] Make virInitialize thread safe
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Currently there is a restriction that multi-threaded applications
must manually call virInitialize, before threads start using
libvirt, because it is not thread-safe. By switching it to use
a virOnceControl initializer we gain thread safety, and thus
applications no longer need to manually call it. They can rely
on virConnectOpen invoking it for them.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/libvirt.c | 139 ++++++++++++++++++++++++++++++----------------------------
1 file changed, 71 insertions(+), 68 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index 76e4401..b616f41 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -59,6 +59,7 @@
#include "command.h"
#include "virrandom.h"
#include "viruri.h"
+#include "threads.h"
#ifdef WITH_TEST
# include "test/test_driver.h"
@@ -119,7 +120,7 @@ static int virNWFilterDriverTabCount = 0;
static virStateDriverPtr virStateDriverTab[MAX_DRIVERS];
static int virStateDriverTabCount = 0;
#endif
-static int initialized = 0;
+
#if defined(POLKIT_AUTH)
static int virConnectAuthGainPolkit(const char *privilege) {
@@ -391,29 +392,16 @@ static struct gcry_thread_cbs virTLSThreadImpl = {
} \
} while (0)
-/**
- * virInitialize:
- *
- * Initialize the library. It's better to call this routine at startup
- * in multithreaded applications to avoid potential race when initializing
- * the library.
- *
- * Calling virInitialize is mandatory, unless your first API call is one of
- * virConnectOpen*.
- *
- * Returns 0 in case of success, -1 in case of error
- */
-int
-virInitialize(void)
-{
- if (initialized)
- return 0;
- initialized = 1;
+static bool virGlobalError = false;
+static virOnceControl virGlobalOnce = VIR_ONCE_CONTROL_INITIALIZER;
+static void
+virGlobalInit(void)
+{
if (virThreadInitialize() < 0 ||
virErrorInitialize() < 0)
- return -1;
+ goto error;
gcry_control(GCRYCTL_SET_THREAD_CBS, &virTLSThreadImpl);
gcry_check_version(NULL);
@@ -429,47 +417,87 @@ virInitialize(void)
VIR_DEBUG("register drivers");
#if HAVE_WINSOCK2_H
- if (winsock_init () == -1) return -1;
+ if (winsock_init () == -1)
+ goto error;
#endif
if (!bindtextdomain(PACKAGE, LOCALEDIR))
- return -1;
+ goto error;
/*
* Note that the order is important: the first ones have a higher
* priority when calling virConnectOpen.
*/
#ifdef WITH_TEST
- if (testRegister() == -1) return -1;
+ if (testRegister() == -1)
+ goto error;
#endif
#ifdef WITH_OPENVZ
- if (openvzRegister() == -1) return -1;
+ if (openvzRegister() == -1)
+ goto error;
#endif
#ifdef WITH_VMWARE
- if (vmwareRegister() == -1) return -1;
+ if (vmwareRegister() == -1)
+ goto error;
#endif
#ifdef WITH_PHYP
- if (phypRegister() == -1) return -1;
+ if (phypRegister() == -1)
+ goto error;
#endif
#ifdef WITH_VBOX
- if (vboxRegister() == -1) return -1;
+ if (vboxRegister() == -1)
+ goto error;
#endif
#ifdef WITH_ESX
- if (esxRegister() == -1) return -1;
+ if (esxRegister() == -1)
+ goto error;
#endif
#ifdef WITH_HYPERV
- if (hypervRegister() == -1) return -1;
+ if (hypervRegister() == -1)
+ goto error;
#endif
#ifdef WITH_XENAPI
- if (xenapiRegister() == -1) return -1;
+ if (xenapiRegister() == -1)
+ goto error;
#endif
#ifdef WITH_PARALLELS
- if (parallelsRegister() == -1) return -1;
+ if (parallelsRegister() == -1)
+ goto error;
#endif
#ifdef WITH_REMOTE
- if (remoteRegister () == -1) return -1;
+ if (remoteRegister () == -1)
+ goto error;
#endif
+ return;
+
+error:
+ virGlobalError = true;
+}
+
+/**
+ * virInitialize:
+ *
+ * Initialize the library.
+ *
+ * This method is invoked automatically by any of the virConnectOpen API
+ * calls. Since release 1.0.0, there is no need to call this method even
+ * in a multithreaded application, since initialization is performed in
+ * a thread safe manner.
+ *
+ * The only time it would be neccessary to call virInitialize is if the
+ * application did not invoke virConnectOpen as its first API call.
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
+int
+virInitialize(void)
+{
+ if (virOnce(&virGlobalOnce, virGlobalInit) < 0)
+ return -1;
+
+ if (virGlobalError)
+ return -1;
return 0;
}
@@ -553,9 +581,6 @@ DllMain (HINSTANCE instance ATTRIBUTE_UNUSED,
int
virRegisterNetworkDriver(virNetworkDriverPtr driver)
{
- if (virInitialize() < 0)
- return -1;
-
virCheckNonNullArgReturn(driver, -1);
if (virNetworkDriverTabCount >= MAX_DRIVERS) {
@@ -583,9 +608,6 @@ virRegisterNetworkDriver(virNetworkDriverPtr driver)
int
virRegisterInterfaceDriver(virInterfaceDriverPtr driver)
{
- if (virInitialize() < 0)
- return -1;
-
virCheckNonNullArgReturn(driver, -1);
if (virInterfaceDriverTabCount >= MAX_DRIVERS) {
@@ -613,9 +635,6 @@ virRegisterInterfaceDriver(virInterfaceDriverPtr driver)
int
virRegisterStorageDriver(virStorageDriverPtr driver)
{
- if (virInitialize() < 0)
- return -1;
-
virCheckNonNullArgReturn(driver, -1);
if (virStorageDriverTabCount >= MAX_DRIVERS) {
@@ -643,9 +662,6 @@ virRegisterStorageDriver(virStorageDriverPtr driver)
int
virRegisterDeviceMonitor(virDeviceMonitorPtr driver)
{
- if (virInitialize() < 0)
- return -1;
-
virCheckNonNullArgReturn(driver, -1);
if (virDeviceMonitorTabCount >= MAX_DRIVERS) {
@@ -673,9 +689,6 @@ virRegisterDeviceMonitor(virDeviceMonitorPtr driver)
int
virRegisterSecretDriver(virSecretDriverPtr driver)
{
- if (virInitialize() < 0)
- return -1;
-
virCheckNonNullArgReturn(driver, -1);
if (virSecretDriverTabCount >= MAX_DRIVERS) {
@@ -703,9 +716,6 @@ virRegisterSecretDriver(virSecretDriverPtr driver)
int
virRegisterNWFilterDriver(virNWFilterDriverPtr driver)
{
- if (virInitialize() < 0)
- return -1;
-
virCheckNonNullArgReturn(driver, -1);
if (virNWFilterDriverTabCount >= MAX_DRIVERS) {
@@ -736,9 +746,6 @@ virRegisterDriver(virDriverPtr driver)
{
VIR_DEBUG("driver=%p name=%s", driver, driver ? NULLSTR(driver->name) : "(null)");
- if (virInitialize() < 0)
- return -1;
-
virCheckNonNullArgReturn(driver, -1);
if (virDriverTabCount >= MAX_DRIVERS) {
@@ -767,9 +774,6 @@ virRegisterDriver(virDriverPtr driver)
int
virRegisterStateDriver(virStateDriverPtr driver)
{
- if (virInitialize() < 0)
- return -1;
-
virCheckNonNullArgReturn(driver, -1);
if (virStateDriverTabCount >= MAX_DRIVERS) {
@@ -895,9 +899,8 @@ virGetVersion(unsigned long *libVer, const char *type ATTRIBUTE_UNUSED,
{
VIR_DEBUG("libVir=%p, type=%s, typeVer=%p", libVer, type, typeVer);
- if (!initialized)
- if (virInitialize() < 0)
- goto error;
+ if (virInitialize() < 0)
+ goto error;
if (libVer == NULL)
goto error;
@@ -1332,9 +1335,9 @@ virConnectPtr
virConnectOpen (const char *name)
{
virConnectPtr ret = NULL;
- if (!initialized)
- if (virInitialize() < 0)
- goto error;
+
+ if (virInitialize() < 0)
+ goto error;
VIR_DEBUG("name=%s", name);
virResetLastError();
@@ -1367,9 +1370,9 @@ virConnectPtr
virConnectOpenReadOnly(const char *name)
{
virConnectPtr ret = NULL;
- if (!initialized)
- if (virInitialize() < 0)
- goto error;
+
+ if (virInitialize() < 0)
+ goto error;
VIR_DEBUG("name=%s", name);
virResetLastError();
@@ -1406,9 +1409,9 @@ virConnectOpenAuth(const char *name,
unsigned int flags)
{
virConnectPtr ret = NULL;
- if (!initialized)
- if (virInitialize() < 0)
- goto error;
+
+ if (virInitialize() < 0)
+ goto error;
VIR_DEBUG("name=%s, auth=%p, flags=%x", NULLSTR(name), auth, flags);
virResetLastError();
--
1.7.11.2
12 years, 1 month
[libvirt] Schedule for the next release: 1.0.0
by Daniel Veillard
After checking with Dan and other developpers, there is some agreement
that we should finally bump the major release number, and we would like
to do it beginning of November i.e. in sync for the next release. As
usual all API and ABIs will be kept, this is just a numbering issue !
To try to avoid if possible another "brown paper bag" release just
after 1.0.0, it seems logical to extend the testing period a bit, to a
week and a half. So be prepared to enter freeze for 1.0.0 around the
24th in a couple of weeks, and celebrate around Nov 2 !
Daniel
--
Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/
daniel(a)veillard.com | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library http://libvirt.org/
12 years, 1 month
[libvirt] [PATCH] libvirt: Change maximum CPU per node calculation.
by Viktor Mihajlovski
The macro VIR_NODEINFO_MAXCPUS computes the maximum number of supported
CPUs for a node as the product of sockets, cores and threads from the
virNodeInfo structure.
Since topology cannot be discovered for offline CPUs, any of the values
for sockets, cores or threads can be wrong (too small).
As a consequence the per-VCPU CPU masks are truncated incorrectly and
it's impossible to correlate the bits in the masks with actual CPUs on
the host.
Example:
Host has 3 logical CPUs, 1 socket, 3 cores, 1 thread.
Guest has 1 virtual CPU and is started while all 3 host CPUs are
online.
$ virsh vcpuinfo guest
VCPU: 0
CPU: 0
State: running
CPU time: 35.4s
CPU Affinity: yyy
$ echo 0 > /sys/devices/system/cpu/cpu1/online
$ virsh vcpuinfo guest
VCPU: 0
CPU: 0
State: running
CPU time: 35.5s
CPU Affinity: y-
The correct display for CPU affinity would have been y-y, as the guest
continues to use CPUs 0 and 2.
This is not a display problem only, because it is also not possible to
explicitly pin the virtual CPU to host CPUs 0 and 2, due to the
truncated CPU mask.
To prevent this, the following changes have been made:
1. In virNodeParseNode count all logical CPUs, offline or online
and pass them back in a new argument 'maxcpus'.
2. Extend the virNodeInfo struct with a new member 'maxcpus'
containing the number of all logical CPUs, online and offline.
3. Change the macro VIR_NODEINFO_MAXCPUS to return virNodeInfo.maxpus
Signed-off-by: Viktor Mihajlovski <mihajlov(a)linux.vnet.ibm.com>
---
include/libvirt/libvirt.h.in | 3 ++-
src/nodeinfo.c | 17 +++++++++++++----
src/remote/remote_protocol.x | 1 +
src/remote_protocol-structs | 1 +
4 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 81f12a4..16265b5 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -445,6 +445,7 @@ struct _virNodeInfo {
total number of CPU sockets otherwise */
unsigned int cores; /* number of cores per socket */
unsigned int threads;/* number of threads per core */
+ unsigned int maxcpus;/* number of maximum cpus - online and offline */
};
/**
@@ -1039,7 +1040,7 @@ int virDomainMigrateGetMaxSpeed(virDomainPtr domain,
*/
-#define VIR_NODEINFO_MAXCPUS(nodeinfo) ((nodeinfo).nodes*(nodeinfo).sockets*(nodeinfo).cores*(nodeinfo).threads)
+#define VIR_NODEINFO_MAXCPUS(nodeinfo) ((nodeinfo).maxcpus)
/**
* virNodeInfoPtr:
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index c0e60d8..2e9c111 100644
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -202,9 +202,11 @@ CPU_COUNT(cpu_set_t *set)
/* parses a node entry, returning number of processors in the node and
* filling arguments */
static int
-virNodeParseNode(const char *node, int *sockets, int *cores, int *threads)
+virNodeParseNode(const char *node, int *sockets, int *cores,
+ int *threads, int *cpus)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
+ ATTRIBUTE_NONNULL(5)
{
int ret = -1;
int processors = 0;
@@ -223,6 +225,7 @@ virNodeParseNode(const char *node, int *sockets, int *cores, int *threads)
*threads = 0;
*cores = 0;
*sockets = 0;
+ *cpus = 0;
if (!(cpudir = opendir(node))) {
virReportSystemError(errno, _("cannot opendir %s"), node);
@@ -275,6 +278,8 @@ virNodeParseNode(const char *node, int *sockets, int *cores, int *threads)
if (sscanf(cpudirent->d_name, "cpu%u", &cpu) != 1)
continue;
+ (*cpus)++;
+
if ((online = virNodeGetCpuValue(node, cpu, "online", true)) < 0)
goto cleanup;
@@ -348,7 +353,7 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo,
char line[1024];
DIR *nodedir = NULL;
struct dirent *nodedirent = NULL;
- int cpus, cores, socks, threads;
+ int cpus, cores, socks, threads, maxcpus;
unsigned int node;
int ret = -1;
char *sysfs_nodedir = NULL;
@@ -358,6 +363,7 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo,
nodeinfo->mhz = 0;
nodeinfo->cores = 0;
nodeinfo->nodes = 0;
+ nodeinfo->maxcpus = 0;
/* Start with parsing CPU clock speed from /proc/cpuinfo */
while (fgets(line, sizeof(line), cpuinfo) != NULL) {
@@ -470,12 +476,13 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo,
}
if ((cpus = virNodeParseNode(sysfs_cpudir, &socks,
- &cores, &threads)) < 0)
+ &cores, &threads, &maxcpus)) < 0)
goto cleanup;
VIR_FREE(sysfs_cpudir);
nodeinfo->cpus += cpus;
+ nodeinfo->maxcpus += maxcpus;
if (socks > nodeinfo->sockets)
nodeinfo->sockets = socks;
@@ -505,7 +512,8 @@ fallback:
goto cleanup;
}
- if ((cpus = virNodeParseNode(sysfs_cpudir, &socks, &cores, &threads)) < 0)
+ if ((cpus = virNodeParseNode(sysfs_cpudir, &socks, &cores,
+ &threads, &maxcpus)) < 0)
goto cleanup;
nodeinfo->nodes = 1;
@@ -513,6 +521,7 @@ fallback:
nodeinfo->sockets = socks;
nodeinfo->cores = cores;
nodeinfo->threads = threads;
+ nodeinfo->maxcpus = maxcpus;
done:
/* There should always be at least one cpu, socket, node, and thread. */
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index b0b530c..40883d0 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -465,6 +465,7 @@ struct remote_node_get_info_ret { /* insert@1 */
int sockets;
int cores;
int threads;
+ int maxcpus;
};
struct remote_get_capabilities_ret {
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 4d2627a..8fece92 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -144,6 +144,7 @@ struct remote_node_get_info_ret {
int sockets;
int cores;
int threads;
+ int maxcpus;
};
struct remote_get_capabilities_ret {
remote_nonnull_string capabilities;
--
1.7.0.4
12 years, 1 month
[libvirt] [PATCH] qemu: Create or remove cgroup when doing vcpu (un)hotpluging
by Osier Yang
Various APIs use cgroup to either set or get the statistics of
host or guest. Hotplug or unhotplug new vcpus without creating
or removing the cgroup for the vcpus could cause problems for
those APIs. E.g.
% virsh vcpucount dom
maximum config 10
maximum live 10
current config 1
current live 1
% virsh setvcpu dom 2
% virsh schedinfo dom --set vcpu_quota=1000
Scheduler : posix
error: Unable to find vcpu cgroup for rhel6.2(vcpu: 1): No such file or
directory
This patch fixes the problem by creating cgroups for each of the
onlined vcpus, and destroying cgroups for each of the offlined
vcpus.
---
src/qemu/qemu_driver.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 53 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 97ad23e..b8ceca1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3601,6 +3601,8 @@ static int qemudDomainHotplugVcpus(struct qemud_driver *driver,
int vcpus = oldvcpus;
pid_t *cpupids = NULL;
int ncpupids;
+ virCgroupPtr cgroup = NULL;
+ virCgroupPtr cgroup_vcpu = NULL;
qemuDomainObjEnterMonitor(driver, vm);
@@ -3654,6 +3656,53 @@ static int qemudDomainHotplugVcpus(struct qemud_driver *driver,
goto cleanup;
}
+ if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) == 0) {
+ int rv = -1;
+
+ if (nvcpus > oldvcpus) {
+ for (i = oldvcpus; i < nvcpus; i++) {
+ /* Create cgroup for the onlined vcpu */
+ rv = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 1);
+ if (rv < 0) {
+ virReportSystemError(-rv,
+ _("Unable to create vcpu cgroup for %s(vcpu:"
+ " %d)"),
+ vm->def->name, i);
+ goto cleanup;
+ }
+
+ /* Add vcpu thread to the cgroup */
+ rv = virCgroupAddTask(cgroup_vcpu, cpupids[i]);
+ if (rv < 0) {
+ virReportSystemError(-rv,
+ _("unable to add vcpu %d task %d to cgroup"),
+ i, cpupids[i]);
+ virCgroupRemove(cgroup_vcpu);
+ goto cleanup;
+ }
+
+ virCgroupFree(&cgroup_vcpu);
+ }
+ } else {
+ for (i = oldvcpus - 1; i >= nvcpus; i--) {
+ rv = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 0);
+ if (rv < 0) {
+ virReportSystemError(-rv,
+ _("Unable to access vcpu cgroup for %s(vcpu:"
+ " %d)"),
+ vm->def->name, i);
+ goto cleanup;
+ }
+
+ /* Remove cgroup for the offlined vcpu */
+ virCgroupRemove(cgroup_vcpu);
+ virCgroupFree(&cgroup_vcpu);
+ }
+ }
+
+ virCgroupFree(&cgroup);
+ }
+
priv->nvcpupids = ncpupids;
VIR_FREE(priv->vcpupids);
priv->vcpupids = cpupids;
@@ -3664,6 +3713,10 @@ cleanup:
vm->def->vcpus = vcpus;
VIR_FREE(cpupids);
virDomainAuditVcpu(vm, oldvcpus, nvcpus, "update", rc == 1);
+ if (cgroup)
+ virCgroupFree(&cgroup);
+ if (cgroup_vcpu)
+ virCgroupFree(&cgroup_vcpu);
return ret;
unsupported:
--
1.7.7.6
12 years, 1 month
[libvirt] [PATCH] win32: Pretend that close-on-exec works
by Matthias Bolte
Currently virNetSocketNew fails because virSetCloseExec fails as there
is no proper implementation for it on Windows at the moment. Workaround
this by pretending that setting close-on-exec on the fd works. This can
be done because libvirt currently lacks the ability to create child
processes on Windows anyway. So there is no point in failing to set a
flag that isn't useful at the moment anyway.
---
src/util/util.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/src/util/util.c b/src/util/util.c
index 43fdaf1..356a03a 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -275,7 +275,11 @@ int virSetInherit(int fd, bool inherit) {
int virSetInherit(int fd ATTRIBUTE_UNUSED, bool inherit ATTRIBUTE_UNUSED)
{
- return -1;
+ /* FIXME: Currently creating child processes is not supported on
+ * Win32, so there is no point in failing calls that are only relevant
+ * when creating child processes. So just pretend that we changed the
+ * inheritance property of the given fd as requested. */
+ return 0;
}
#endif /* WIN32 */
--
1.7.4.1
12 years, 1 month
[libvirt] [PATCH] esx: Fix dynamic dispatch for types with more than one level of inheritance
by Matthias Bolte
Traverse the whole inheritance hierarchy for dynamic dispatch as it is
already done for the dynamic cast.
Also make AnyType cast errors more verbose.
Reported by Ata Bohra.
---
src/esx/esx_vi_generator.py | 36 ++++++++++++++++++++++++------------
src/esx/esx_vi_types.c | 12 ++++++++----
2 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py
index c4bbb03..af4e7e8 100755
--- a/src/esx/esx_vi_generator.py
+++ b/src/esx/esx_vi_generator.py
@@ -484,6 +484,26 @@ class Object(Type):
return members
+ def generate_dispatch(self, suffix, is_first=True):
+ source = ""
+
+ if self.extended_by is not None:
+ if not is_first:
+ source += "\n"
+
+ source += " /* %s */\n" % self.name
+
+ for extended_by in self.extended_by:
+ source += " ESX_VI__TEMPLATE__DISPATCH__%s(%s)\n" \
+ % (suffix, extended_by)
+
+ for extended_by in self.extended_by:
+ source += objects_by_name[extended_by] \
+ .generate_dispatch(suffix, False)
+
+ return source
+
+
def generate_free_code(self, add_banner=False):
source = ""
@@ -835,9 +855,7 @@ class Object(Type):
source += "ESX_VI__TEMPLATE__DYNAMIC_DEEP_COPY(%s,\n" % self.name
source += "{\n"
- for extended_by in self.extended_by:
- source += " ESX_VI__TEMPLATE__DISPATCH__DEEP_COPY(%s)\n" \
- % extended_by
+ source += self.generate_dispatch('DEEP_COPY')
source += "},\n"
source += "{\n"
@@ -863,9 +881,7 @@ class Object(Type):
% self.name
source += "{\n"
- for extended_by in self.extended_by:
- source += " ESX_VI__TEMPLATE__DISPATCH__CAST_FROM_ANY_TYPE(%s)\n" \
- % extended_by
+ source += self.generate_dispatch('CAST_FROM_ANY_TYPE')
source += "})\n\n"
@@ -895,9 +911,7 @@ class Object(Type):
source += "ESX_VI__TEMPLATE__DYNAMIC_SERIALIZE(%s,\n" % self.name
source += "{\n"
- for extended_by in self.extended_by:
- source += " ESX_VI__TEMPLATE__DISPATCH__SERIALIZE(%s)\n" \
- % extended_by
+ source += self.generate_dispatch('SERIALIZE')
source += "},\n"
source += "{\n"
@@ -933,9 +947,7 @@ class Object(Type):
% self.name
source += "{\n"
- for extended_by in self.extended_by:
- source += " ESX_VI__TEMPLATE__DISPATCH__DESERIALIZE(%s)\n" \
- % extended_by
+ source += self.generate_dispatch('DESERIALIZE')
source += "},\n"
source += "{\n"
diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c
index d2c71c7..c5ddb51 100644
--- a/src/esx/esx_vi_types.c
+++ b/src/esx/esx_vi_types.c
@@ -212,8 +212,10 @@
{ \
if (anyType->type != esxVI_Type_##_type) { \
virReportError(VIR_ERR_INTERNAL_ERROR, \
- _("Call to %s for unexpected type '%s'"), \
- __FUNCTION__, anyType->other); \
+ _("Call to %s for unexpected type '%s', " \
+ "expected '%s'"), \
+ __FUNCTION__, anyType->other, \
+ esxVI_Type_ToString(esxVI_Type_##_type)); \
return -1; \
} \
}, /* nothing */)
@@ -225,8 +227,10 @@
{ \
if (anyType->type != esxVI_Type_##_type) { \
virReportError(VIR_ERR_INTERNAL_ERROR, \
- _("Call to %s for unexpected type '%s'"), \
- __FUNCTION__, anyType->other); \
+ _("Call to %s for unexpected type '%s', " \
+ "expected '%s'"), \
+ __FUNCTION__, anyType->other, \
+ esxVI_Type_ToString(esxVI_Type_##_type)); \
return -1; \
} \
}, Value)
--
1.7.4.1
12 years, 1 month
[libvirt] IPV6 and routing
by Gene Czarcinski
As I have mentioned in other messages, I am interested in having full
support for IPv6 in libvirt. To me this includes having dhcp6 for IPV6
address assignment and using RA (radvd) to establish the default route.
This is what I am using on my real LANs.
Before starting into adding dhcp6 support to libvirt, I wanted to see
just how it works with the current software. First of all, it appears
that, when nat or routed are specified for IPv4, the IPv6 is routed. If
it is an isolated/private network, then it can only work with other
guests on that network. The iptables and ip6tables settings
corresponded and were as expected. On the virtualization host, both
IPv4 and IPv6 forwarding are enabled.
While I can easily do stuff like ping6 and ssh -6 from virtual guests to
the virtualization host, I have been unable to do anything with external
hosts ... unless I add a static route for the virtual IPv6 network on
the target host back to the virtualization host. This is the only way I
have gotten anything to work. To complicate things, it seem that
"everything" wants the IPv6 network to have prefix=64 or things do not
work correctly.
The real systems use fd00:dead:beef:17::/64 for their network. The
virtual networks all use fd00:face:17:xx::/64 for their networks.
The network traffic on the virtualization host is forwarded to the
target host ... I can see the packets with wireshark on the target host.
On the target host I tried specifying a static route for network
fd00:face:17::/48 ... well, that really screwed things up, resulted in
some "redirects" from the virtualization host saying the that it was
sent a malformed packed ... it took a reboot to clean things up.
OK, so leave the fd00:face:17:6::/64 static route on the target host but
subnetwork this network on the virtualization host using networks like
fd00:face:17:6:8::/80 and fd00:face:6:9::/80. This works if I manually
configure IPv6 on the virtual guest. Since radvd is "upset" by a
non-prefix=64 network, I was not surprised when the guest's automatic
IPv6 address/network was not configured.
OK, what am I missing? What don't I understand?
If IPv6 is going to be useful in virtualization, then there must be some
"easy" way to have other systems understand that the virtualization host
is acting as a router for the virtual IPv6 networks it runs. While
being able to go between the virtualization hosts and the virtual guests
is very useful, I do not consider this sufficient.
I have googled and found some stuff as well as reading more RFCs than I
wanted to but I cannot find anything to address this issue.
IIRC, I did find something under a libvirt document that indicates
"routed" will be used for some kind of subnetworking.
Does libvirt need an IPv6 "NAT" to make this work?
Comments? Suggestions?
Gene
12 years, 1 month