[libvirt] [PATCH v2] Allow overriding default URI in config file
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Currently if the URI passed to virConnectOpen* is NULL, then we
- Look for LIBVIRT_DEFAULT_URI env var
- Probe for drivers
This changes it so that
- Look for LIBVIRT_DEFAULT_URI env var
- Look for 'uri_default' in $HOME/.libvirt/libvirt.conf
- Probe for drivers
---
docs/uri.html.in | 16 ++++++++-
src/libvirt.c | 107 +++++++++++++++++++++++++++++++++++++-----------------
src/libvirt.conf | 6 +++
tools/virsh.pod | 4 ++-
4 files changed, 98 insertions(+), 35 deletions(-)
diff --git a/docs/uri.html.in b/docs/uri.html.in
index 79f8786..2f76e8f 100644
--- a/docs/uri.html.in
+++ b/docs/uri.html.in
@@ -52,6 +52,19 @@ uri_aliases = [
set, no alias lookup will be attempted.
</p>
+ <h2><a name="URI_default">Default URI choice</a></h2>
+
+ <p>
+If the URI passed to <code>virConnectOpen*</code> is NULL, then libvirt will use the following
+logic to determine what URI to use.
+</p>
+
+ <ol>
+ <li>The environment variable <code>LIBVIRT_DEFAULT_URI</code></li>
+ <li>The client configuration file <code>uri_default</code> parameter</li>
+ <li>Probe each hypervisor in turn until one that works is found</li>
+ </ol>
+
<h2>
<a name="URI_virsh">Specifying URIs to virsh, virt-manager and virt-install</a>
</h2>
@@ -64,7 +77,8 @@ virsh <b>-c test:///default</b> list
<p>
If virsh finds the environment variable
<code>VIRSH_DEFAULT_CONNECT_URI</code> set, it will try this URI by
-default.
+default. Use of this environment variable is, however, deprecated
+now that libvirt supports <code>LIBVIRT_DEFAULT_URI</code> itself.
</p>
<p>
When using the interactive virsh shell, you can also use the
diff --git a/src/libvirt.c b/src/libvirt.c
index e916aa0..1c0cdf7 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -961,7 +961,7 @@ error:
}
static char *
-virConnectConfigFile(void)
+virConnectGetConfigFilePath(void)
{
char *path;
if (geteuid() == 0) {
@@ -989,6 +989,33 @@ error:
return NULL;
}
+static int
+virConnectGetConfigFile(virConfPtr *conf)
+{
+ char *filename = NULL;
+ int ret = -1;
+
+ *conf = NULL;
+
+ if (!(filename = virConnectGetConfigFilePath()))
+ goto cleanup;
+
+ if (!virFileExists(filename)) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ VIR_DEBUG("Loading config file '%s'", filename);
+ if (!(*conf = virConfReadFile(filename, 0)))
+ goto cleanup;
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(filename);
+ return ret;
+}
+
#define URI_ALIAS_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"
static int
@@ -1050,35 +1077,45 @@ virConnectOpenFindURIAliasMatch(virConfValuePtr value, const char *alias, char *
}
static int
-virConnectOpenResolveURIAlias(const char *alias, char **uri)
+virConnectOpenResolveURIAlias(virConfPtr conf,
+ const char *alias, char **uri)
{
- char *config = NULL;
int ret = -1;
- virConfPtr conf = NULL;
virConfValuePtr value = NULL;
*uri = NULL;
- if (!(config = virConnectConfigFile()))
- goto cleanup;
-
- if (!virFileExists(config)) {
- ret = 0;
- goto cleanup;
- }
-
- VIR_DEBUG("Loading config file '%s'", config);
- if (!(conf = virConfReadFile(config, 0)))
- goto cleanup;
-
if ((value = virConfGetValue(conf, "uri_aliases")))
ret = virConnectOpenFindURIAliasMatch(value, alias, uri);
else
ret = 0;
+ return ret;
+}
+
+
+static int
+virConnectGetDefaultURI(virConfPtr conf,
+ const char **name)
+{
+ int ret = -1;
+ virConfValuePtr value = NULL;
+ char *defname = getenv("LIBVIRT_DEFAULT_URI");
+ if (defname && *defname) {
+ VIR_DEBUG("Using LIBVIRT_DEFAULT_URI '%s'", defname);
+ *name = defname;
+ } else if ((value = virConfGetValue(conf, "uri_default"))) {
+ if (value->type != VIR_CONF_STRING) {
+ virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Expected a string for 'uri_default' config parameter"));
+ goto cleanup;
+ }
+ VIR_DEBUG("Using config file uri '%s'", value->str);
+ *name = value->str;
+ }
+
+ ret = 0;
cleanup:
- virConfFree(conf);
- VIR_FREE(config);
return ret;
}
@@ -1089,6 +1126,7 @@ do_open (const char *name,
{
int i, res;
virConnectPtr ret;
+ virConfPtr conf = NULL;
virResetLastError();
@@ -1096,20 +1134,20 @@ do_open (const char *name,
if (ret == NULL)
return NULL;
+ if (virConnectGetConfigFile(&conf) < 0)
+ goto failed;
+
+ if (name && name[0] == '\0')
+ name = NULL;
+
/*
* If no URI is passed, then check for an environment string if not
* available probe the compiled in drivers to find a default hypervisor
* if detectable.
*/
- if (!name || name[0] == '\0') {
- char *defname = getenv("LIBVIRT_DEFAULT_URI");
- if (defname && *defname) {
- VIR_DEBUG("Using LIBVIRT_DEFAULT_URI %s", defname);
- name = defname;
- } else {
- name = NULL;
- }
- }
+ if (!name &&
+ virConnectGetDefaultURI(conf, &name) < 0)
+ goto failed;
if (name) {
char *alias = NULL;
@@ -1124,7 +1162,7 @@ do_open (const char *name,
name = "xen:///";
if (!(flags & VIR_CONNECT_NO_ALIASES) &&
- virConnectOpenResolveURIAlias(name, &alias) < 0)
+ virConnectOpenResolveURIAlias(conf, name, &alias) < 0)
goto failed;
ret->uri = virURIParse (alias ? alias : name);
@@ -1308,9 +1346,12 @@ do_open (const char *name,
}
}
+ virConfFree(conf);
+
return ret;
failed:
+ virConfFree(conf);
virUnrefConnect(ret);
return NULL;
@@ -1325,11 +1366,11 @@ failed:
*
* Returns a pointer to the hypervisor connection or NULL in case of error
*
- * If @name is NULL then probing will be done to determine a suitable
- * default driver to activate. This involves trying each hypervisor
- * in turn until one successfully opens. If the LIBVIRT_DEFAULT_URI
- * environment variable is set, then it will be used in preference
- * to probing for a driver.
+ * If @name is NULL, if the LIBVIRT_DEFAULT_URI environment variable is set,
+ * then it will be used. Otherwise if the client configuration file
+ * has the "uri_default" parameter set, then it will be used. Finally
+ * probing will be done to determine a suitable default driver to activate.
+ * This involves trying each hypervisor in turn until one successfully opens.
*
* If connecting to an unprivileged hypervisor driver which requires
* the libvirtd daemon to be active, it will automatically be launched
diff --git a/src/libvirt.conf b/src/libvirt.conf
index c54903c..016cd24 100644
--- a/src/libvirt.conf
+++ b/src/libvirt.conf
@@ -10,3 +10,9 @@
# "hail=qemu+ssh://root@hail.cloud.example.com/system",
# "sleet=qemu+ssh://root@sleet.cloud.example.com/system",
#]
+
+#
+# This can be used to prevent probing of the hypervisor
+# driver when no URI is supplied by the application.
+
+#uri_default = "qemu:///system"
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 64b00ee..4cc91cc 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -2632,7 +2632,9 @@ The file to log virsh debug messages.
=item VIRSH_DEFAULT_CONNECT_URI
The hypervisor to connect to by default. Set this to a URI, in the same
-format as accepted by the B<connect> option.
+format as accepted by the B<connect> option. This environment variable
+is deprecated in favour of the global B<LIVIRT_DEFAULT_URI> variable
+which serves the same purpose.
=item VISUAL
--
1.7.7.6
12 years, 7 months
[libvirt] [PATCH] Allow overriding default URI in config file
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Currently if the URI passed to virConnectOpen* is NULL, then we
- Look for LIBVIRT_DEFAULT_URI env var
- Probe for drivers
This changes it so that
- Look for LIBVIRT_DEFAULT_URI env var
- Look for 'uri_default' in $HOME/.libvirt/libvirt.conf
- Probe for drivers
---
docs/uri.html.in | 13 +++++++
src/libvirt.c | 107 +++++++++++++++++++++++++++++++++++++-----------------
2 files changed, 87 insertions(+), 33 deletions(-)
diff --git a/docs/uri.html.in b/docs/uri.html.in
index 79f8786..48f6498 100644
--- a/docs/uri.html.in
+++ b/docs/uri.html.in
@@ -52,6 +52,19 @@ uri_aliases = [
set, no alias lookup will be attempted.
</p>
+ <h2><a name="URI_default">Default URI choice</a></h2>
+
+ <p>
+If the URI passed to <code>virConnectOpen*</code> is NULL, then libvirt will use the following
+logic to determine what URI to use.
+</p>
+
+ <ol>
+ <li>The environment variable <code>LIBVIRT_DEFAULT_URI</code></li>
+ <li>The client configuration file <code>uri_default</code> parameter</li>
+ <li>Probe each hypervisor in turn until one that works is found</li>
+ </ol>
+
<h2>
<a name="URI_virsh">Specifying URIs to virsh, virt-manager and virt-install</a>
</h2>
diff --git a/src/libvirt.c b/src/libvirt.c
index e916aa0..c5c2e84 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -961,7 +961,7 @@ error:
}
static char *
-virConnectConfigFile(void)
+virConnectGetConfigFilePath(void)
{
char *path;
if (geteuid() == 0) {
@@ -989,6 +989,32 @@ error:
return NULL;
}
+static int virConnectGetConfigFile(virConfPtr *conf)
+{
+ char *filename = NULL;
+ int ret = -1;
+
+ *conf = NULL;
+
+ if (!(filename = virConnectGetConfigFilePath()))
+ goto cleanup;
+
+ if (!virFileExists(filename)) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ VIR_DEBUG("Loading config file '%s'", filename);
+ if (!(*conf = virConfReadFile(filename, 0)))
+ goto cleanup;
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(filename);
+ return ret;
+}
+
#define URI_ALIAS_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"
static int
@@ -1050,35 +1076,46 @@ virConnectOpenFindURIAliasMatch(virConfValuePtr value, const char *alias, char *
}
static int
-virConnectOpenResolveURIAlias(const char *alias, char **uri)
+virConnectOpenResolveURIAlias(virConfPtr conf,
+ const char *alias, char **uri)
{
- char *config = NULL;
int ret = -1;
- virConfPtr conf = NULL;
virConfValuePtr value = NULL;
*uri = NULL;
- if (!(config = virConnectConfigFile()))
- goto cleanup;
-
- if (!virFileExists(config)) {
- ret = 0;
- goto cleanup;
- }
-
- VIR_DEBUG("Loading config file '%s'", config);
- if (!(conf = virConfReadFile(config, 0)))
- goto cleanup;
-
if ((value = virConfGetValue(conf, "uri_aliases")))
ret = virConnectOpenFindURIAliasMatch(value, alias, uri);
else
ret = 0;
+ return ret;
+}
+
+
+static int virConnectGetDefaultURI(virConfPtr conf,
+ const char **name)
+{
+ int ret = -1;
+ virConfValuePtr value = NULL;
+ char *defname = getenv("LIBVIRT_DEFAULT_URI");
+ if (defname && *defname) {
+ VIR_DEBUG("Using LIBVIRT_DEFAULT_URI %s", defname);
+ *name = defname;
+ }
+
+ if ((value = virConfGetValue(conf, "uri_default"))) {
+ if (value->type != VIR_CONF_STRING) {
+ virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Expected a string for 'uri_default' config parameter"));
+ goto cleanup;
+ }
+
+ *name = value->str;
+ }
+
+ ret = 0;
cleanup:
- virConfFree(conf);
- VIR_FREE(config);
return ret;
}
@@ -1089,6 +1126,7 @@ do_open (const char *name,
{
int i, res;
virConnectPtr ret;
+ virConfPtr conf = NULL;
virResetLastError();
@@ -1096,20 +1134,20 @@ do_open (const char *name,
if (ret == NULL)
return NULL;
+ if (virConnectGetConfigFile(&conf) < 0)
+ goto failed;
+
+ if (name && name[0] == '\0')
+ name = NULL;
+
/*
* If no URI is passed, then check for an environment string if not
* available probe the compiled in drivers to find a default hypervisor
* if detectable.
*/
- if (!name || name[0] == '\0') {
- char *defname = getenv("LIBVIRT_DEFAULT_URI");
- if (defname && *defname) {
- VIR_DEBUG("Using LIBVIRT_DEFAULT_URI %s", defname);
- name = defname;
- } else {
- name = NULL;
- }
- }
+ if (!name &&
+ virConnectGetDefaultURI(conf, &name) < 0)
+ goto failed;
if (name) {
char *alias = NULL;
@@ -1124,7 +1162,7 @@ do_open (const char *name,
name = "xen:///";
if (!(flags & VIR_CONNECT_NO_ALIASES) &&
- virConnectOpenResolveURIAlias(name, &alias) < 0)
+ virConnectOpenResolveURIAlias(conf, name, &alias) < 0)
goto failed;
ret->uri = virURIParse (alias ? alias : name);
@@ -1308,9 +1346,12 @@ do_open (const char *name,
}
}
+ virConfFree(conf);
+
return ret;
failed:
+ virConfFree(conf);
virUnrefConnect(ret);
return NULL;
@@ -1325,11 +1366,11 @@ failed:
*
* Returns a pointer to the hypervisor connection or NULL in case of error
*
- * If @name is NULL then probing will be done to determine a suitable
- * default driver to activate. This involves trying each hypervisor
- * in turn until one successfully opens. If the LIBVIRT_DEFAULT_URI
- * environment variable is set, then it will be used in preference
- * to probing for a driver.
+ * If @name is NULL, if the LIBVIRT_DEFAULT_URI environment variable is set,
+ * then it will be used. Otherwise if the client configuration file
+ * has the "uri_default" parameter set, then it will be used. Finally
+ * probing will be done to determine a suitable default driver to activate.
+ * This involves trying each hypervisor in turn until one successfully opens.
*
* If connecting to an unprivileged hypervisor driver which requires
* the libvirtd daemon to be active, it will automatically be launched
--
1.7.7.6
12 years, 7 months
[libvirt] [PATCH] Add container_uuid env variable to LXC guests
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Systemd has declared that all container virtualization technologies
should set 'container_uuid' to identify themselves.
http://cgit.freedesktop.org/systemd/systemd/commit/?id=09b967eaa51a39dabb...
---
src/lxc/lxc_container.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 2282eb0..d827b35 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -125,6 +125,7 @@ static virCommandPtr lxcContainerBuildInitCmd(virDomainDefPtr vmDef)
virCommandAddEnvString(cmd, "PATH=/bin:/sbin");
virCommandAddEnvString(cmd, "TERM=linux");
virCommandAddEnvString(cmd, "container=lxc-libvirt");
+ virCommandAddEnvPair(cmd, "container_uuid", uuidstr);
virCommandAddEnvPair(cmd, "LIBVIRT_LXC_UUID", uuidstr);
virCommandAddEnvPair(cmd, "LIBVIRT_LXC_NAME", vmDef->name);
if (vmDef->os.cmdline)
--
1.7.7.6
12 years, 7 months
[libvirt] [PATCH] python: add virDomainGetCPUStats python binding API
by Guannan Ren
dom.cPUStats(True, 0)
[{'cpu_time': 370942649768L, 'system_time': 11640000000L, 'user_time': 890000000L}]
dom.cPUStats(False, 0)
[{'cpu_time': 38378374721L}, {'cpu_time': 12475521087L}, {'cpu_time': 127388622598L}, {'cpu_time': 192720388324L}]
---
python/libvirt-override-api.xml | 10 +++
python/libvirt-override.c | 164 +++++++++++++++++++++++++++++++++++++++
2 files changed, 174 insertions(+), 0 deletions(-)
diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
index ab8f33a..c906cc3 100644
--- a/python/libvirt-override-api.xml
+++ b/python/libvirt-override-api.xml
@@ -149,6 +149,16 @@
<arg name='path' type='char *' info='the path for the block device'/>
<arg name='flags' type='int' info='flags (unused; pass 0)'/>
</function>
+ <function name='virDomainGetCPUStats' file='python'>
+ <info>Extracts CPU statistics for a running domain, On success it will return a list of data of dictionary type.
+ If boolean total is True, the first element of the list refers to CPU0 on the host, second element is CPU1, and so on.
+ The format of data struct is like [{cpu_time:xxx},{cpu_time:xxx}, ...]
+ If it is False, it returns total domain CPU statistics like [{cpu_time:xxx, user_time:xxx, system_time:xxx}]</info>
+ <return type='str *' info='returns a list of dictionary in case of success, None in case of error'/>
+ <arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
+ <arg name='total' type='bool' info='on true, return total domain CPU statistics, false return per-cpu info'/>
+ <arg name='flags' type='int' info='flags (unused; pass 0)'/>
+ </function>
<function name='virDomainInterfaceStats' file='python'>
<info>Extracts interface device statistics for a domain</info>
<return type='virDomainInterfaceStats' info='a tuple of statistics'/>
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 792cfa3..eb24c60 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -378,6 +378,169 @@ cleanup:
}
static PyObject *
+libvirt_virDomainGetCPUStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
+{
+ virDomainPtr domain;
+ PyObject *pyobj_domain, *totalbool;
+ PyObject *ret = NULL;
+ PyObject *cpu, *total;
+ PyObject *error;
+ int i, i_retval;
+ int ncpus = -1;
+ int sumparams, nparams = -1;
+ unsigned int flags;
+ virTypedParameterPtr params, cpuparams;
+
+ if (!PyArg_ParseTuple(args, (char *)"OOi:virDomainGetNumaParameters",
+ &pyobj_domain, &totalbool, &flags))
+ return NULL;
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ if (!PyBool_Check(totalbool)) {
+ PyErr_Format(PyExc_TypeError,
+ "The \"total\" attribute must be bool");
+ return NULL;
+ }
+
+ if ((ret = PyList_New(0)) == NULL)
+ return NULL;
+
+ if (totalbool == Py_False) {
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ ncpus = virDomainGetCPUStats(domain, NULL, 0, 0, 0, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (ncpus < 0) {
+ error = VIR_PY_NONE;
+ goto failed;
+ }
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ nparams = virDomainGetCPUStats(domain, NULL, 0, 0, 1, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (nparams < 0) {
+ error = VIR_PY_NONE;
+ goto failed;
+ }
+
+ if (!nparams) {
+ if ((cpu = PyDict_New()) == NULL) {
+ error = NULL;
+ goto failed;
+ }
+
+ if (PyList_Append(ret, cpu) < 0) {
+ Py_DECREF(cpu);
+ error = NULL;
+ goto failed;
+ }
+
+ Py_DECREF(cpu);
+ return ret;
+ }
+ sumparams = nparams * ncpus;
+
+ if (VIR_ALLOC_N(params, sumparams) < 0) {
+ error = PyErr_NoMemory();
+ goto failed;
+ }
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetCPUStats(domain, params, nparams, 0, ncpus, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0) {
+ error = VIR_PY_NONE;
+ goto cleanup;
+ }
+
+ for (i = 0; i < ncpus; i++) {
+ if (params[i * nparams].type == 0)
+ continue;
+
+ cpuparams = ¶ms[i * nparams];
+ if ((cpu = getPyVirTypedParameter(cpuparams, nparams)) == NULL) {
+ error = NULL;
+ goto cleanup;
+ }
+ if (PyList_Append(ret, cpu) < 0) {
+ Py_DECREF(cpu);
+ error = NULL;
+ goto cleanup;
+ }
+ Py_DECREF(cpu);
+ }
+
+ virTypedParameterArrayClear(params, sumparams);
+ VIR_FREE(params);
+ return ret;
+ } else {
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ nparams = virDomainGetCPUStats(domain, NULL, 0, -1, 1, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (nparams < 0) {
+ error = VIR_PY_NONE;
+ goto failed;
+ }
+
+ if (!nparams) {
+ if ((total = PyDict_New()) == NULL) {
+ error = NULL;
+ goto failed;
+ }
+ if (PyList_Append(ret, total) < 0) {
+ Py_DECREF(total);
+ error = NULL;
+ goto failed;
+ }
+
+ Py_DECREF(total);
+ return ret;
+ }
+ sumparams = nparams;
+
+ if (VIR_ALLOC_N(params, nparams) < 0) {
+ error = PyErr_NoMemory();
+ goto failed;
+ }
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetCPUStats(domain, params, nparams, -1, 1, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0) {
+ error = VIR_PY_NONE;
+ goto cleanup;
+ }
+
+ if ((total = getPyVirTypedParameter(params, nparams)) == NULL) {
+ error = NULL;
+ goto cleanup;
+ }
+ if (PyList_Append(ret, total) < 0) {
+ Py_DECREF(total);
+ error = NULL;
+ goto cleanup;
+ }
+ Py_DECREF(total);
+
+ virTypedParameterArrayClear(params, sumparams);
+ VIR_FREE(params);
+ return ret;
+ }
+
+cleanup:
+ virTypedParameterArrayClear(params, sumparams);
+ VIR_FREE(params);
+
+failed:
+ Py_DECREF(ret);
+ return error;
+}
+
+static PyObject *
libvirt_virDomainInterfaceStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
virDomainPtr domain;
PyObject *pyobj_domain;
@@ -5366,6 +5529,7 @@ static PyMethodDef libvirtMethods[] = {
{(char *) "virNetworkGetAutostart", libvirt_virNetworkGetAutostart, METH_VARARGS, NULL},
{(char *) "virDomainBlockStats", libvirt_virDomainBlockStats, METH_VARARGS, NULL},
{(char *) "virDomainBlockStatsFlags", libvirt_virDomainBlockStatsFlags, METH_VARARGS, NULL},
+ {(char *) "virDomainGetCPUStats", libvirt_virDomainGetCPUStats, METH_VARARGS, NULL},
{(char *) "virDomainInterfaceStats", libvirt_virDomainInterfaceStats, METH_VARARGS, NULL},
{(char *) "virDomainMemoryStats", libvirt_virDomainMemoryStats, METH_VARARGS, NULL},
{(char *) "virNodeGetCellsFreeMemory", libvirt_virNodeGetCellsFreeMemory, METH_VARARGS, NULL},
--
1.7.7.5
12 years, 7 months
[libvirt] [libvirt-glib 1/3] Fix GVIR_CONFIG_DOMAIN_CHANNEL_TARGET_GUESTFWD name
by Christophe Fergeau
It was called GVIR_CONFIG_DOMAIN_CONSOLE_TARGET_GUESTFWD, which in
turn confused glib-mkenums, leading to a wrong value being generated
in the XML when trying to use this enumeration.
---
libvirt-gconfig/libvirt-gconfig-domain-channel.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-channel.h b/libvirt-gconfig/libvirt-gconfig-domain-channel.h
index a8a3020..5141d11 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-channel.h
+++ b/libvirt-gconfig/libvirt-gconfig-domain-channel.h
@@ -57,7 +57,7 @@ struct _GVirConfigDomainChannelClass
};
typedef enum {
- GVIR_CONFIG_DOMAIN_CONSOLE_TARGET_GUESTFWD,
+ GVIR_CONFIG_DOMAIN_CHANNEL_TARGET_GUESTFWD,
GVIR_CONFIG_DOMAIN_CHANNEL_TARGET_VIRTIO,
} GVirConfigDomainChannelTargetType;
--
1.7.7.6
12 years, 7 months
[libvirt] [PATCH] qemu: Reverse condition in qemuDomainCheckDiskPresence
by Michal Privoznik
With current code, we pass true iff domain is cold booting. However,
if disk is inaccessible and startupPolicy for that disk is set to
'requisite' we have to fail iff cold booting.
---
src/qemu/qemu_domain.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index f8b7c96..625c595 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1703,7 +1703,7 @@ qemuDomainSetFakeReboot(struct qemud_driver *driver,
int
qemuDomainCheckDiskPresence(struct qemud_driver *driver,
virDomainObjPtr vm,
- bool start_with_state)
+ bool cold_boot)
{
int ret = -1;
int i;
@@ -1738,7 +1738,7 @@ qemuDomainCheckDiskPresence(struct qemud_driver *driver,
break;
case VIR_DOMAIN_STARTUP_POLICY_REQUISITE:
- if (!start_with_state) {
+ if (cold_boot) {
virReportSystemError(errno,
_("cannot access file '%s'"),
disk->src);
--
1.7.8.5
12 years, 7 months
[libvirt] Coverity automatic detection
by Alex Jia
This email is automatically generated.
The test result is based on the following git commit:
19c7980 qemu: fix segfault when detaching non-existent network device
Analysis summary report:
------------------------
Files analyzed : 254
Total LoC input to cov-analyze : 348334
Functions analyzed : 8419
Paths analyzed : 998857
Defect occurrences found : 88 Total
7 ATOMICITY
6 CHECKED_RETURN
13 DEADCODE
1 EVALUATION_ORDER
7 FORWARD_NULL
13 LOCK
3 NEGATIVE_RETURNS
1 NO_EFFECT
3 NULL_RETURNS
1 OVERRUN_STATIC
11 RESOURCE_LEAK
1 RETURN_LOCAL
12 REVERSE_INULL
1 SIZEOF_MISMATCH
6 UNINIT
2 UNUSED_VALUE
Exceeded path limit of 5000 paths in 0.49% of functions (normally up to 5% of functions encounter this limitation)
For details, please see attachment.
Regards,
Alex
12 years, 7 months
[libvirt] Schedule for the next release
by Daniel Veillard
I did let the one month cycle go a bit for a change, last release
was on the 13th and considering how short Feb is and the fact that
aligning with end of month makes things easier to remember and plan
for, I suggest to slip by two week and plan for the end of March.
More specifically I would suggest to enter freeze for 0.9.11 on the
24 i.e. in 10 days and shoot for a release on the 30th, using the
last week of March for testing and bug fixes. Then we will try to
keep aligned again with end of month release :-)
Hopefully this is okay, but please raise your voice if you
think this is a problem,
thanks !
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, 7 months
[libvirt] RFC: mirrored live block migration in libvirt 0.9.11
by Eric Blake
Here's what I'm planning on implementing for libvirt 0.9.11 to support
oVirt's desire to do live block migration, and built on top of qemu
1.1's new 'transaction' QMP monitor command. Comments are welcome
before I actually post patches.
Background
==========
Here is oVirt's description of mirrored live storage migration:
http://www.ovirt.org/wiki/Features/Design/StorageLiveMigration
The idea is that at all points in time, at least one storage domain has
a consistent view of all data in use by the guest. That way, if
something fails and has to be restarted, oVirt can tell libvirt to
create a new transient domain that points to the storage domain with
consistent data, and restart the migration process, rather than the
post-copy approach that would spread data across two storage domains at
once.
For more background, here is the qemu feature page for the 'transaction'
monitor command; that wiki page includes a section which summarizes the
impacts to libvirt as proposed in this email:
http://wiki.qemu.org/Features/SnapshotsMultipleDevices
One of the goals of this proposal is to add mirrored live block
migration without adding any new API, so that the feature can be
backported to any distro that ships with the API in libvirt 0.9.10.
My proposals for libvirt 0.9.11
===============================
Libvirt will probe qemu to see if it knows the 'transaction' monitor
command, and set a bit in qemuCaps accordingly.
virDomainSnapshotCreateXML will learn a new flag:
VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC. If this flag is present, then
libvirt guarantees that the snapshot operation will either succeed, or
that failure will be reported without changing domain XML or qemu
runtime state. If present, the creation API will fail if qemu lacks the
'transaction' command and more than one disk snapshot was requested in
the <domainsnapshot> XML. If this flag is not present, then libvirt
will use 'transaction' if available, but fall back to
'blockdev-snapshot-sync', so that it works with older qemu, but where
the caller then has to check virDomainGetXMLDesc on failure to see if a
partial snapshot occurred. This flag will be implied by any other part
of the API that requires the use of 'transaction'.
The VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT flag was added to
virDomainSnapshotCreateXML in 0.9.10, with semantics that it would stop
libvirt from complaining if a regular file already existed as the
snapshot destination, but without interacting with qemu, which would
blindly overwrite the contents of that file. Since this flag is
relatively new, and has not had much use, I propose to slightly alter
its documented semantics to now interact with the qemu 1.1 feature being
added as part of 'transaction'. If qemu supports 'transaction', then
presence of this flag implies that libvirt will explicitly request
'mode':'existing' for each snapshot, which tells qemu to open the
existing file without writing any new metadata, and that the caller is
responsible to ensure that the file has identical guest contents
(generally by creating a qcow2 file with the current file as backing
image and no additional contents). Additionally, libvirt will now
require the file to already exist (in 0.9.10, libvirt silently ignored
the fact if the flag was requested but the file did not exist).
Presence of the flag without qemu support for 'transaction' will now
fail (that is, VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT will now imply
VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC). Absence of the flag means that
libvirt will rely on qemu's default to 'mode':'absolute-paths', and will
require that the file does not exist as a regular file; this maps to
qemu 1.0 always writing a new qcow2 header with absolute backing file
name. If we want to later expose additional modes, like
'no-backing-file', it would be done via per-<disk> annotations in the
<domainsnapshot> XML rather than via new flags, but for this proposal, I
think oVirt is okay using the flag to set a single policy for all disks
mentioned in a given snapshot request.
virDomainSnapshotCreateXML's xml argument, <domainsnapshot>, will learn
an optional <mirror> sub-element to each <disk>. While the
'transaction' command supports multiple mirrors in one transaction, for
now, libvirt will enforce at most one mirror, which should be sufficient
for oVirt's needs. (Adding more support for the rest of the power of
'transaction' is probably best left for new libvirt API, but that's
outside the scope of this proposal). As an example,
<domainsnapshot>
<disks>
<disk name='/src/base.img' snapshot='external'>
<source file='/src/snap.img'/>
<mirror file='/dest/snap.img'/>
</disk>
</disks>
</domainsnapshot>
would create a new libvirt snapshot object with /src/snap.img as the
read-write new image, and /dest/snap.img as the new write-only mirror.
On success, this rewrites the domain's live XML to point to
/src/snap.img as its current file.
Finally, virDomainSnapshotDelete will learn a new flag,
VIR_DOMAIN_SNAPSHOT_DELETE_REOPEN_MIRROR, which says that the libvirt
snapshot object will be deleted, but only after first calling the qemu
'drive-reopen' monitor command for all disks that had a <mirror> in the
associated snapshot object. That is, for the above example, this would
reopen the disk from it's current read-write of /src/snap.img over to
the second storage domain's /dest/snap.img with it's accompanying
mirrored backing chain. On success, this rewrites the domain's live XML
to point to the just-opened mirror location. This flag will fail if the
libvirt snapshot being deleted is not the current image, or if the
snapshot being deleted does not have any mirrored disks.
Conclusion
==========
Back to the oVirt diagram, the transition from step 1 to 2 is done by
oVirt, the transition from step 2 to 3 is done by oVirt pre-creating
Snapshot 2 on storage domain 2 with a backing file of a relative
pathname to Snapshot 1, then creating a new libvirt snapshot with:
snap = virDomainSnapshotCreateXML(dom,
"<!-- XML with a <mirror> element for the migrated disk(s) -->...",
VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY |
VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT);
(VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC will be implied, since <mirror>
requires it, but can be provided for clarity; oVirt may also wish to use
VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE, although that is not strictly
necessary and would only work if a guest agent is present).
Then, the transition from step 3 to 4 is done by oVirt copying Snapshot
1 in the background, and the transition from step 4 to 5 is done by
oVirt calling:
virDomainSnapshotDelete(snap,
VIR_DOMAIN_SNAPSHOT_DELETE_REOPEN_MIRROR);
at which point the running qemu will be using the full image chain
located completely on storage 2, with libvirt having updated the domain
XML to reflect the new path name, and with the libvirt snapshot object
no longer present since the migration is complete.
If oVirt then desires to cut Snapshot 1 out of the backing chain, and
have Snapshot 2 backed directly by the Base volume, then oVirt would
then call:
virDomainSnapshotRebase(dom, "...disk", "Base", 0, 0)
to trigger a 'block_stream' monitor command that resets Snapshot 2 to
directly use Base as its backing file (effectively merging Snapshot 1
into Snapshot 2).
--
Eric Blake eblake(a)redhat.com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
12 years, 7 months
[libvirt] [PATCH] cpu: Add cpu definition for Intel Sandy Bridge cpu type
by Peter Krempa
This patch adds support for the new tsc-deadline feature flag
and a new model to the supported model list describing the
Intel Sandy Bridge platform.
---
Patches adding the SandyBridge cpu type in qemu are on review and not upstream yet. Please
don't prioritize this patch. I sent it for review as the chance that nothing will change is
greater than I'll have to post another version. Qemu upstream review:
http://lists.nongnu.org/archive/html/qemu-devel/2012-03/msg00914.html
(I'll push this only after qemu will add this functionality upstream)
Review help (c&p from the patches):
tsc-deadline flag:
static const char *ext_feature_name[] = {
"fma", "cx16", "xtpr", "pdcm",
NULL, NULL, "dca", "sse4.1|sse4_1",
"sse4.2|sse4_2", "x2apic", "movbe", "popcnt",
- NULL, "aes", "xsave", "osxsave",
+ "tsc-deadline", "aes", "xsave", "osxsave",
"avx", NULL, NULL, "hypervisor",
};
SandyBridge model:
[cpudef]
+ name = "SandyBridge"
+ level = "0xd"
+ vendor = "GenuineIntel"
+ family = "6"
+ model = "42"
+ stepping = "1"
+ feature_edx = " sse2 sse fxsr mmx clflush pse36 pat cmov mca pge mtrr sep apic cx8 mce pae msr tsc pse de fpu"
+ feature_ecx = "avx xsave aes tsc-deadline popcnt x2apic sse4.2 sse4.1 cx16 ssse3 pclmulqdq sse3"
+ extfeature_edx = "i64 rdtscp nx syscall "
+ extfeature_ecx = "lahf_lm"
+ xlevel = "0x8000000A"
+ model_id = "Intel Xeon E312xx (Sandy Bridge)"
(note that the sse3 flag is in libvirt known as pni and i64 is known as lm)
src/cpu/cpu_map.xml | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml
index 7ef230e..f79a727 100644
--- a/src/cpu/cpu_map.xml
+++ b/src/cpu/cpu_map.xml
@@ -160,6 +160,9 @@
<feature name='popcnt'> <!-- CPUID_EXT_POPCNT -->
<cpuid function='0x00000001' ecx='0x00800000'/>
</feature>
+ <feature name='tsc-deadline'>
+ <cpuid function='0x00000001' ecx='0x01000000'/>
+ </feature>
<feature name='aes'>
<cpuid function='0x00000001' ecx='0x02000000'/>
</feature>
@@ -595,6 +598,48 @@
<feature name='aes'/>
</model>
+ <model name='SandyBridge'>
+ <vendor name='Intel'/>
+ <feature name='aes'/>
+ <feature name='apic'/>
+ <feature name='avx'/>
+ <feature name='clflush'/>
+ <feature name='cmov'/>
+ <feature name='cx16'/>
+ <feature name='cx8'/>
+ <feature name='de'/>
+ <feature name='fpu'/>
+ <feature name='fxsr'/>
+ <feature name='lahf_lm'/>
+ <feature name='lm'/>
+ <feature name='mca'/>
+ <feature name='mce'/>
+ <feature name='mmx'/>
+ <feature name='msr'/>
+ <feature name='mtrr'/>
+ <feature name='nx'/>
+ <feature name='pae'/>
+ <feature name='pat'/>
+ <feature name='pclmuldq'/>
+ <feature name='pge'/>
+ <feature name='pni'/>
+ <feature name='popcnt'/>
+ <feature name='pse'/>
+ <feature name='pse36'/>
+ <feature name='rdtscp'/>
+ <feature name='sep'/>
+ <feature name='sse'/>
+ <feature name='sse2'/>
+ <feature name='sse4.1'/>
+ <feature name='sse4.2'/>
+ <feature name='ssse3'/>
+ <feature name='syscall'/>
+ <feature name='tsc'/>
+ <feature name='tsc-deadline'/>
+ <feature name='x2apic'/>
+ <feature name='xsave'/>
+ </model>
+
<model name='Opteron_G1'>
<vendor name='AMD'/>
<feature name='sse2'/>
--
1.7.3.4
12 years, 7 months