[libvirt] [PATCH] lxc: export container=lxc-libvirt for systemd
by Eric Blake
Systemd detects containers based on whether they have
an environment variable starting with 'container=lxc';
using a longer name fits the expectations, while also
allowing detection of who created the container.
Requested by Lennart Poettering, in response to
https://bugs.freedesktop.org/show_bug.cgi?id=45175
* src/lxc/lxc_container.c (lxcContainerBuildInitCmd): Add another
env-var.
---
src/lxc/lxc_container.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index c1ec9c4..70f6908 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2011 Red Hat, Inc.
+ * Copyright (C) 2008-2012 Red Hat, Inc.
* Copyright (C) 2008 IBM Corp.
*
* lxc_container.c: file description
@@ -124,6 +124,7 @@ static virCommandPtr lxcContainerBuildInitCmd(virDomainDefPtr vmDef)
virCommandAddEnvString(cmd, "PATH=/bin:/sbin");
virCommandAddEnvString(cmd, "TERM=linux");
+ virCommandAddEnvString(cmd, "container=lxc-libvirt");
virCommandAddEnvPair(cmd, "LIBVIRT_LXC_UUID", uuidstr);
virCommandAddEnvPair(cmd, "LIBVIRT_LXC_NAME", vmDef->name);
if (vmDef->os.cmdline)
--
1.7.7.5
12 years, 10 months
[libvirt] [PATCH] schema: Relax schema for domain name
by Peter Krempa
The domain schema enforced restrictions on the domain name string that
the code doesn't. This patch relaxes the check, leaving the restrictions
on the driver or hypervisor.
---
And maybe we should consider adding some restrictions on the qemu driver, as the daemon
is competely fine with creating a domain with the name "../../../../../../../test" that
has its configuration stored in "/test.xml" then.
docs/schemas/domaincommon.rng | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 2041dfb..1922cd6 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3003,9 +3003,7 @@
</data>
</define>
<define name="domainName">
- <data type="string">
- <param name="pattern">[A-Za-z0-9_\.\+\-&:/]+</param>
- </data>
+ <data type="string" />
</define>
<define name="diskSerial">
<data type="string">
--
1.7.3.4
12 years, 10 months
[libvirt] [PATCH] Add support for forcing a private network namespace for LXC guests
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
If no <interface> elements are included in an LXC guest XML
description, then the LXC guest will just see the host's
network interfaces. It is desirable to be able to hide the
host interfaces, without having to define any guest interfaces.
This patch introduces a new feature flag <privnet/> to allow
forcing of a private network namespace for LXC. In the future
I also anticipate that we will add <privuser/> to force a
private user ID namespace.
* src/conf/domain_conf.c, src/conf/domain_conf.h: Add support
for <privnet/> feature. Auto-set <privnet> if any <interface>
devices are defined
* src/lxc/lxc_container.c: Honour request for private network
namespace
---
docs/formatdomain.html.in | 7 +++++++
docs/schemas/domaincommon.rng | 5 +++++
src/conf/domain_conf.c | 3 ++-
src/conf/domain_conf.h | 1 +
src/lxc/lxc_container.c | 11 +++++++----
5 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 1d0211d..b7ad638 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -843,6 +843,7 @@
<acpi/>
<apic/>
<hap/>
+ <privnet/>
</features>
...</pre>
@@ -870,6 +871,12 @@
<dd>Enable Viridian hypervisor extensions for paravirtualizing
guest operating systems
</dd>
+ <dt><code>privnet</code></dt>
+ <dd>Always create a private network namespace. This is
+ automatically set if any interface devices are defined.
+ This feature is only relevant for container based
+ virtualization drivers eg LXC.
+ </dd>
</dl>
<h3><a name="elementsTime">Time keeping</a></h3>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 2f655a9..9f12a6d 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2530,6 +2530,11 @@
<empty/>
</element>
</optional>
+ <optional>
+ <element name="privnet">
+ <empty/>
+ </element>
+ </optional>
</interleave>
</element>
</optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e872396..66d7f39 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -103,7 +103,8 @@ VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST,
"apic",
"pae",
"hap",
- "viridian")
+ "viridian",
+ "privnet")
VIR_ENUM_IMPL(virDomainLifecycle, VIR_DOMAIN_LIFECYCLE_LAST,
"destroy",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3b522a9..2131ff9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1221,6 +1221,7 @@ enum virDomainFeature {
VIR_DOMAIN_FEATURE_PAE,
VIR_DOMAIN_FEATURE_HAP,
VIR_DOMAIN_FEATURE_VIRIDIAN,
+ VIR_DOMAIN_FEATURE_PRIVNET,
VIR_DOMAIN_FEATURE_LAST
};
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index dcd65ef..0820a0e 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -254,7 +254,8 @@ int lxcContainerWaitForContinue(int control)
*
* Returns 0 on success or nonzero in case of error
*/
-static int lxcContainerRenameAndEnableInterfaces(unsigned int nveths,
+static int lxcContainerRenameAndEnableInterfaces(bool privNet,
+ unsigned int nveths,
char **veths)
{
int rc = 0;
@@ -282,7 +283,7 @@ static int lxcContainerRenameAndEnableInterfaces(unsigned int nveths,
}
/* enable lo device only if there were other net devices */
- if (veths)
+ if (veths || privNet)
rc = virNetDevSetOnline("lo", true);
error_out:
@@ -1277,7 +1278,8 @@ static int lxcContainerChild( void *data )
VIR_DEBUG("Received container continue message");
/* rename and enable interfaces */
- if (lxcContainerRenameAndEnableInterfaces(argv->nveths,
+ if (lxcContainerRenameAndEnableInterfaces(vmDef->features & (1 << VIR_DOMAIN_FEATURE_PRIVNET),
+ argv->nveths,
argv->veths) < 0) {
goto cleanup;
}
@@ -1386,7 +1388,8 @@ int lxcContainerStart(virDomainDefPtr def,
cflags |= CLONE_NEWUSER;
}
- if (def->nets != NULL) {
+ if (def->nets != NULL ||
+ (def->features & (1 << VIR_DOMAIN_FEATURE_PRIVNET))) {
VIR_DEBUG("Enable network namespaces");
cflags |= CLONE_NEWNET;
}
--
1.7.7.5
12 years, 10 months
[libvirt] [PATCH] Add missing docs for <viridian/> feature flag
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
---
docs/formatdomain.html.in | 4 ++++
docs/schemas/domaincommon.rng | 5 +++++
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index dfb010d..1d0211d 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -866,6 +866,10 @@
<dd>Enable use of Hardware Assisted Paging if available in
the hardware.
</dd>
+ <dt><code>viridian</code></dt>
+ <dd>Enable Viridian hypervisor extensions for paravirtualizing
+ guest operating systems
+ </dd>
</dl>
<h3><a name="elementsTime">Time keeping</a></h3>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 4fa968d..2f655a9 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2525,6 +2525,11 @@
<empty/>
</element>
</optional>
+ <optional>
+ <element name="viridian">
+ <empty/>
+ </element>
+ </optional>
</interleave>
</element>
</optional>
--
1.7.7.5
12 years, 10 months
[libvirt] [PATCH] qemu: Emit bootindex even for direct boot
by Jiri Denemark
Direct boot (using kernel, initrd, and command line) is used by
virt-install/virt-manager for network install. While any bootindex has
no direct effect since -kernel is always first, we need it as a hint for
SeaBIOS to present disks in the same order as they will be presented
during normal boot.
---
src/qemu/qemu_command.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index aaccf62..9b69ad0 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4334,8 +4334,7 @@ qemuBuildCommandLine(virConnectPtr conn,
if (qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) {
int bootCD = 0, bootFloppy = 0, bootDisk = 0;
- if ((qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) || emitBootindex) &&
- !def->os.kernel) {
+ if ((qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_BOOT) || emitBootindex)) {
/* bootDevs will get translated into either bootindex=N or boot=on
* depending on what qemu supports */
for (i = 0 ; i < def->os.nBootDevs ; i++) {
--
1.7.8.4
12 years, 10 months
[libvirt] [PATCH v2] Add two NUMA tuning python bindings APIs
by Guannan Ren
*virDomainSetNumaParameters
*virDomainGetNumaParameters
---
python/libvirt-override-api.xml | 13 +++
python/libvirt-override.c | 186 +++++++++++++++++++++++++++++++++++++++
2 files changed, 199 insertions(+), 0 deletions(-)
diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
index 704fee9..e09290c 100644
--- a/python/libvirt-override-api.xml
+++ b/python/libvirt-override-api.xml
@@ -248,6 +248,19 @@
<arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
<arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
</function>
+ <function name='virDomainSetNumaParameters' file='python'>
+ <info>Change the NUMA tunables</info>
+ <return type='int' info='-1 in case of error, 0 in case of success.'/>
+ <arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
+ <arg name='params' type='virTypedParameterPtr' info='pointer to numa tunable objects'/>
+ <arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
+ </function>
+ <function name='virDomainGetNumaParameters' file='python'>
+ <info>Get the NUMA parameters</info>
+ <return type='virTypedParameterPtr' info='the numa tunables value or None in case of error'/>
+ <arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
+ <arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
+ </function>
<function name='virConnectListStoragePools' file='python'>
<info>list the storage pools, stores the pointers to the names in @names</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index d2aad0f..27ad1d8 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -1000,6 +1000,190 @@ libvirt_virDomainGetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED,
}
static PyObject *
+libvirt_virDomainSetNumaParameters(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args) {
+ virDomainPtr domain;
+ PyObject *pyobj_domain, *info;
+ int i_retval;
+ int nparams = 0, i;
+ unsigned int flags;
+ virTypedParameterPtr params;
+
+ if (!PyArg_ParseTuple(args,
+ (char *)"OOi:virDomainSetNumaParameters",
+ &pyobj_domain, &info, &flags))
+ return(NULL);
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetNumaParameters(domain, NULL, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0)
+ return VIR_PY_INT_FAIL;
+
+ if ((params = malloc(sizeof(*params)*nparams)) == NULL)
+ return VIR_PY_INT_FAIL;
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetNumaParameters(domain, params, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0) {
+ free(params);
+ return VIR_PY_INT_FAIL;
+ }
+
+ /* convert to a Python tuple of long objects */
+ for (i = 0; i < nparams; i++) {
+ PyObject *key, *val;
+ key = libvirt_constcharPtrWrap(params[i].field);
+ val = PyDict_GetItem(info, key);
+ Py_DECREF(key);
+
+ if (val == NULL)
+ continue;
+
+ switch (params[i].type) {
+ case VIR_TYPED_PARAM_INT:
+ params[i].value.i = (int)PyInt_AS_LONG(val);
+ break;
+
+ case VIR_TYPED_PARAM_UINT:
+ params[i].value.ui = (unsigned int)PyInt_AS_LONG(val);
+ break;
+
+ case VIR_TYPED_PARAM_LLONG:
+ params[i].value.l = (long long)PyLong_AsLongLong(val);
+ break;
+
+ case VIR_TYPED_PARAM_ULLONG:
+ params[i].value.ul = (unsigned long long)PyLong_AsLongLong(val);
+ break;
+
+ case VIR_TYPED_PARAM_DOUBLE:
+ params[i].value.d = (double)PyFloat_AsDouble(val);
+ break;
+
+ case VIR_TYPED_PARAM_BOOLEAN:
+ {
+ /* Hack - Python's definition of Py_True breaks strict
+ * aliasing rules, so can't directly compare
+ */
+ PyObject *hacktrue = PyBool_FromLong(1);
+ params[i].value.b = hacktrue == val ? 1: 0;
+ Py_DECREF(hacktrue);
+ }
+ break;
+
+ case VIR_TYPED_PARAM_STRING:
+ params[i].value.s = PyString_AsString(val);
+ break;
+
+ default:
+ free(params);
+ return VIR_PY_INT_FAIL;
+ }
+ }
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainSetNumaParameters(domain, params, nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+ if (i_retval < 0) {
+ free(params);
+ return VIR_PY_INT_FAIL;
+ }
+
+ free(params);
+ return VIR_PY_INT_SUCCESS;
+}
+
+static PyObject *
+libvirt_virDomainGetNumaParameters(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args) {
+ virDomainPtr domain;
+ PyObject *pyobj_domain, *info;
+ int i_retval;
+ int nparams = 0, i;
+ unsigned int flags;
+ virTypedParameterPtr params;
+
+ if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainGetNumaParameters",
+ &pyobj_domain, &flags))
+ return(NULL);
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetNumaParameters(domain, NULL, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0)
+ return VIR_PY_NONE;
+
+ if ((params = malloc(sizeof(*params)*nparams)) == NULL)
+ return VIR_PY_NONE;
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetNumaParameters(domain, params, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0) {
+ free(params);
+ return VIR_PY_NONE;
+ }
+
+ /* convert to a Python tuple of long objects */
+ if ((info = PyDict_New()) == NULL) {
+ free(params);
+ return VIR_PY_NONE;
+ }
+
+ for (i = 0 ; i < nparams ; i++) {
+ PyObject *key, *val;
+
+ switch (params[i].type) {
+ case VIR_TYPED_PARAM_INT:
+ val = PyInt_FromLong((long)params[i].value.i);
+ break;
+
+ case VIR_TYPED_PARAM_UINT:
+ val = PyInt_FromLong((long)params[i].value.ui);
+ break;
+
+ case VIR_TYPED_PARAM_LLONG:
+ val = PyLong_FromLongLong((long long)params[i].value.l);
+ break;
+
+ case VIR_TYPED_PARAM_ULLONG:
+ val = PyLong_FromLongLong((long long)params[i].value.ul);
+ break;
+
+ case VIR_TYPED_PARAM_DOUBLE:
+ val = PyFloat_FromDouble((double)params[i].value.d);
+ break;
+
+ case VIR_TYPED_PARAM_BOOLEAN:
+ val = PyBool_FromLong((long)params[i].value.b);
+ break;
+
+ case VIR_TYPED_PARAM_STRING:
+ val = libvirt_constcharPtrWrap(params[i].value.s);
+ break;
+
+ default:
+ free(params);
+ Py_DECREF(info);
+ return VIR_PY_NONE;
+ }
+
+ key = libvirt_constcharPtrWrap(params[i].field);
+ PyDict_SetItem(info, key, val);
+ }
+ free(params);
+ return(info);
+}
+
+static PyObject *
libvirt_virDomainGetVcpus(PyObject *self ATTRIBUTE_UNUSED,
PyObject *args) {
virDomainPtr domain;
@@ -5162,6 +5346,8 @@ static PyMethodDef libvirtMethods[] = {
{(char *) "virDomainGetBlkioParameters", libvirt_virDomainGetBlkioParameters, METH_VARARGS, NULL},
{(char *) "virDomainSetMemoryParameters", libvirt_virDomainSetMemoryParameters, METH_VARARGS, NULL},
{(char *) "virDomainGetMemoryParameters", libvirt_virDomainGetMemoryParameters, METH_VARARGS, NULL},
+ {(char *) "virDomainGetNumaParameters", libvirt_virDomainGetNumaParameters, METH_VARARGS, NULL},
+ {(char *) "virDomainSetNumaParameters", libvirt_virDomainSetNumaParameters, METH_VARARGS, NULL},
{(char *) "virDomainGetVcpus", libvirt_virDomainGetVcpus, METH_VARARGS, NULL},
{(char *) "virDomainPinVcpu", libvirt_virDomainPinVcpu, METH_VARARGS, NULL},
{(char *) "virDomainPinVcpuFlags", libvirt_virDomainPinVcpuFlags, METH_VARARGS, NULL},
--
1.7.7.5
12 years, 10 months
[libvirt] [PATCH][RFC] adding a title to the domain description informations
by Daniel Veillard
The idea is that currently we have only the domain name usable as
a description for the domain. It is not really a good human readable
identifier, as the kind of string allowed is limited (no space for
example). The idea would then be to extend the existing <description>
field in the domain XML to keep 40 or less character string to describe
a domain and provide that information later for example in an extended
virsh list command or for other interfaces.
While the idea is simple, see attached patch for this, it becomes more
complex when one tries to make accessors to set/get that title for a
domain, since it's mutable and possibly could be coming from the
hypervisor itself (is there anything like this in VMWare or VirtualBox?)
it should to be implemented down at the driver level. Is that worth the
effort ? If we go that route should we do this for other objects
(network, storage, etc ...) too in the end ?
here is a basic patch for just the XML side to give an idea, but
adding APIs is far more work.
Opinions ?
Daniel
Provide a title attribute on domain descriptions
Allow to provide a title attribute to domain descriptions
useful when presenting the domain in an user interface.
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index de9b480..ad5ffb0 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -58,7 +58,13 @@
<dd>The content of the <code>description</code> element provides a
human readable description of the virtual machine. This data is not
used by libvirt in any way, it can contain any information the user
- wants. <span class="since">Since 0.7.2</span></dd>
+ wants. <span class="since">Since 0.7.2</span>. It is also possible
+ to provide an human readable title for the virtual machine, by
+ providing it as a <code>title<code> attribute on the
+ <code>description</code> element, this can be useful to provide an
+ human description when listing virtual machines (<span class="since"
+ >Since 0.9.10</span>)</dd>
+
</dl>
<h3><a name="elementsOS">Operating system booting</a></h3>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 2041dfb..78ba67c 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -10,6 +10,11 @@
-->
<define name="description">
<element name="description">
+ <optional>
+ <attribute name="title">
+ <ref name="title-value"/>
+ </attribute>
+ </optional>
<text/>
</element>
</define>
@@ -3115,4 +3120,9 @@
</element>
<empty/>
</define>
+ <define name="title-value">
+ <data type="string">
+ <param name="pattern">.{0,40}</param>
+ </data>
+ </define>
</grammar>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f97014e..0e1ff44 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1478,6 +1478,7 @@ void virDomainDefFree(virDomainDefPtr def)
VIR_FREE(def->cpumask);
VIR_FREE(def->emulator);
VIR_FREE(def->description);
+ VIR_FREE(def->title);
virBlkioDeviceWeightArrayClear(def->blkio.devices,
def->blkio.ndevices);
@@ -7092,6 +7093,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
/* Extract documentation if present */
def->description = virXPathString("string(./description[1])", ctxt);
+ def->title = virXPathString("string(./description[1]/@title)", ctxt);
/* analysis of security label, done early even though we format it
* late, so devices can refer to this for defaults */
@@ -11417,8 +11419,16 @@ virDomainDefFormatInternal(virDomainDefPtr def,
virUUIDFormat(uuid, uuidstr);
virBufferAsprintf(buf, " <uuid>%s</uuid>\n", uuidstr);
- virBufferEscapeString(buf, " <description>%s</description>\n",
- def->description);
+ if (def->title || def->description) {
+ virBufferAddLit(buf, " <description");
+ if (def->title)
+ virBufferEscapeString(buf, " title='%s'", def->title);
+ if (def->description)
+ virBufferEscapeString(buf, ">%s</description>\n",
+ def->description);
+ else
+ virBufferAddLit(buf, "/>");
+ }
virBufferAsprintf(buf, " <memory>%lu</memory>\n", def->mem.max_balloon);
virBufferAsprintf(buf, " <currentMemory>%lu</currentMemory>\n",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index b121f9c..45d70e6 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1421,6 +1421,7 @@ struct _virDomainDef {
unsigned char uuid[VIR_UUID_BUFLEN];
char *name;
char *description;
+ char *title;
struct {
unsigned int weight;
--
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, 10 months
[libvirt] [PATCH] docs: fix a few small typos in formatdomain.html.in
by Laine Stump
---
Pushed under the trivial rule.
docs/formatdomain.html.in | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index dca9a81..dfb010d 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2275,8 +2275,8 @@
<pre>
...
<devices>
- <mac address='52:54:00:6d:90:01'>
<interface type='mcast'>
+ <mac address='52:54:00:6d:90:01'>
<source address='230.0.0.1' port='5558'/>
</interface>
</devices>
@@ -2297,13 +2297,13 @@
...
<devices>
<interface type='server'>
- <mac address='52:54:00:22:c9:42'>
+ <mac address='52:54:00:22:c9:42'>
<source address='192.168.0.1' port='5558'/>
</interface>
...
<interface type='client'>
- <mac address='52:54:00:8b:c9:51'>
- <source address='192.168.0.1' port='5558'/>
+ <mac address='52:54:00:8b:c9:51'>
+ <source address='192.168.0.1' port='5558'/>
</interface>
</devices>
...</pre>
@@ -2470,7 +2470,7 @@ qemu-kvm -net nic,model=? /dev/null
...</pre>
<p>
- For hypervisors which support this, you can set exact NIC which should
+ For hypervisors which support this, you can set a specific NIC to
be used for network boot. The <code>order</code> attribute determines
the order in which devices will be tried during boot sequence. The
per-device <code>boot</code> elements cannot be used together with
--
1.7.7.5
12 years, 10 months
[libvirt] Allow custom metadata in domain configuration XML
by Zeeshan Ali (Khattak)
From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
Applications can now insert custom nodes and hierarchies into domain
cofiguration XML. Although currently not enforced, application are
required to use their own namespaces on every custom node they insert.
---
docs/formatdomain.html.in | 18 +++++++++
docs/schemas/domaincommon.rng | 26 +++++++++++++
src/conf/domain_conf.c | 24 ++++++++++++
src/conf/domain_conf.h | 3 ++
tests/domainsnapshotxml2xmlout/metadata.xml | 38 ++++++++++++++++++++
tests/domainsnapshotxml2xmltest.c | 1 +
tests/qemuxml2argvdata/qemuxml2argv-metadata.args | 4 ++
tests/qemuxml2argvdata/qemuxml2argv-metadata.xml | 29 +++++++++++++++
.../qemuxml2xmloutdata/qemuxml2xmlout-metadata.xml | 29 +++++++++++++++
tests/qemuxml2xmltest.c | 2 +
10 files changed, 174 insertions(+), 0 deletions(-)
create mode 100644 tests/domainsnapshotxml2xmlout/metadata.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-metadata.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-metadata.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index de9b480..fa7dc7c 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3548,6 +3548,24 @@ qemu-kvm -net nic,model=? /dev/null
sub-element <code>label</code> are supported.
</p>
+ <h3><a name="customMetadata">Custom metadata</a></h3>
+
+<pre>
+ ...
+ <metadata>
+ <app1:foo xmlns:app1="http://app1.org/app1/">..</app1:foo>
+ <app2:bar xmlns:app2="http://app1.org/app2/">..</app2:bar>
+ </metadata>
+ ...</pre>
+
+ <dl>
+ <dt><code>metadata</code></dt>
+ <dd><code>metadata</code> node could be used by applications to
+ store custom metadata in the form of XML nodes/trees. Applications
+ must use custom namespaces on their XML nodes/trees.
+ <span class="since">Since 0.9.9</span></dd>
+ </dl>
+
<h2><a name="examples">Example configs</a></h2>
<p>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 2041dfb..b42d758 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -43,6 +43,9 @@
<ref name="seclabel"/>
</optional>
<optional>
+ <ref name="metadata"/>
+ </optional>
+ <optional>
<ref name='qemucmdline'/>
</optional>
</interleave>
@@ -2942,6 +2945,29 @@
</element>
</define>
+ <define name="metadata">
+ <element name="metadata">
+ <zeroOrMore>
+ <ref name="customElement"/>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name="customElement">
+ <element>
+ <anyName/>
+ <zeroOrMore>
+ <choice>
+ <attribute>
+ <anyName/>
+ </attribute>
+ <text/>
+ <ref name="customElement"/>
+ </choice>
+ </zeroOrMore>
+ </element>
+ </define>
+
<!--
Type library
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8eed85b..fb78d93 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1500,6 +1500,9 @@ void virDomainDefFree(virDomainDefPtr def)
if (def->namespaceData && def->ns.free)
(def->ns.free)(def->namespaceData);
+ if (def->metadata)
+ xmlFreeNode(def->metadata);
+
VIR_FREE(def);
}
@@ -8072,6 +8075,11 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
def->os.smbios_mode = VIR_DOMAIN_SMBIOS_NONE; /* not present */
}
+ /* Extract custom metadata */
+ if ((node = virXPathNode("./metadata[1]", ctxt)) != NULL) {
+ def->metadata = xmlCopyNode (node, 1);
+ }
+
/* we have to make a copy of all of the callback pointers here since
* we won't have the virCaps structure available during free
*/
@@ -11833,6 +11841,22 @@ virDomainDefFormatInternal(virDomainDefPtr def,
goto cleanup;
}
+ /* Custom metadata comes at the end */
+ if (def->metadata) {
+ xmlBufferPtr xmlbuf;
+
+ xmlbuf = xmlBufferCreate();
+ if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata, 4, 1) < 0) {
+ xmlBufferFree(xmlbuf);
+ goto cleanup;
+ }
+ virBufferAdjustIndent(buf, 2);
+ virBufferAdd(buf, (char *) xmlBufferContent(xmlbuf), xmlBufferLength(xmlbuf));
+ virBufferAdjustIndent(buf, -2);
+ xmlBufferFree(xmlbuf);
+ virBufferAddLit(buf, "\n");
+ }
+
virBufferAddLit(buf, "</domain>\n");
if (virBufferError(buf))
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a49795c..3b522a9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1525,6 +1525,9 @@ struct _virDomainDef {
void *namespaceData;
virDomainXMLNamespace ns;
+
+ /* Application-specific custom metadata */
+ xmlNodePtr metadata;
};
enum virDomainTaintFlags {
diff --git a/tests/domainsnapshotxml2xmlout/metadata.xml b/tests/domainsnapshotxml2xmlout/metadata.xml
new file mode 100644
index 0000000..45180c9
--- /dev/null
+++ b/tests/domainsnapshotxml2xmlout/metadata.xml
@@ -0,0 +1,38 @@
+<domainsnapshot>
+ <name>my snap name</name>
+ <description>!@#$%^</description>
+ <state>running</state>
+ <parent>
+ <name>earlier_snap</name>
+ </parent>
+ <creationTime>1272917631</creationTime>
+ <domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu cpuset='1-4,8-20,525'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+ <metadata>
+ <app1:foo xmlns:app1="http://foo.org/">fooish</app1:foo>
+ <app2:bar xmlns:app2="http://bar.com/" maman="baz">barish</app2:bar>
+ </metadata>
+ </domain>
+</domainsnapshot>
diff --git a/tests/domainsnapshotxml2xmltest.c b/tests/domainsnapshotxml2xmltest.c
index 90ff9bb..5c2e670 100644
--- a/tests/domainsnapshotxml2xmltest.c
+++ b/tests/domainsnapshotxml2xmltest.c
@@ -109,6 +109,7 @@ mymain(void)
DO_TEST("noparent_nodescription_noactive", NULL, 0);
DO_TEST("noparent_nodescription", NULL, 1);
DO_TEST("noparent", "9d37b878-a7cc-9f9a-b78f-49b3abad25a8", 0);
+ DO_TEST("metadata", "c7a5fdbd-edaf-9455-926a-d65c16db1809", 0);
virCapabilitiesFree(driver.caps);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-metadata.args b/tests/qemuxml2argvdata/qemuxml2argv-metadata.args
new file mode 100644
index 0000000..651793d
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-metadata.args
@@ -0,0 +1,4 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
+pc -m 214 -smp 1 -name QEMUGuest1 -nographic -monitor unix:/tmp/test-monitor,\
+server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial \
+none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-metadata.xml b/tests/qemuxml2argvdata/qemuxml2argv-metadata.xml
new file mode 100644
index 0000000..a6888ee
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-metadata.xml
@@ -0,0 +1,29 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu cpuset='1-4,8-20,525'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+ <metadata>
+ <app1:foo xmlns:app1="http://foo.org/">fooish</app1:foo>
+ <app2:bar xmlns:app2="http://bar.com/" maman="baz">barish</app2:bar>
+ </metadata>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata.xml
new file mode 100644
index 0000000..a6888ee
--- /dev/null
+++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-metadata.xml
@@ -0,0 +1,29 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu cpuset='1-4,8-20,525'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+ <metadata>
+ <app1:foo xmlns:app1="http://foo.org/">fooish</app1:foo>
+ <app2:bar xmlns:app2="http://bar.com/" maman="baz">barish</app2:bar>
+ </metadata>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 293c2a7..df317fd 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -210,6 +210,8 @@ mymain(void)
DO_TEST_DIFFERENT("graphics-listen-network2");
DO_TEST_DIFFERENT("graphics-spice-timeout");
+ DO_TEST_DIFFERENT("metadata");
+
virCapabilitiesFree(driver.caps);
return (ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
--
1.7.7.5
12 years, 10 months