[libvirt] [RFC] virCommandProcessIO(): make poll() usage more robust
by Laszlo Ersek
POLLIN and POLLHUP are not mutually exclusive. Currently the following
seems possible: the child writes 3K to its stdout or stderr pipe, and
immediately closes it. We get POLLIN|POLLHUP (I'm not sure that's possible
on Linux, but SUSv4 seems to allow it). We read 1K and throw away the
rest.
When poll() returns and we're about to check the /revents/ member in a
given array element, let's map all the revents bits to two (independent)
ideas: "let's attempt to read()", and "let's attempt to write()". This
should cover all errors, EOFs, and normal conditions; the read()/write()
call should report any pending error.
Under this approach, both POLLHUP and POLLERR are mapped to "needs read()"
if we're otherwise prepared for POLLIN. POLLERR also maps to "needs
write()" if we're otherwise prepared for POLLOUT. The rest of the mappings
(POLLPRI etc.) would be easy, but probably useless for pipes.
Additionally, SUSv4 doesn't appear to forbid POLLIN|POLLERR (or
POLLOUT|POLLERR) set simultaneously. One could argue that the read() or
write() call would return without blocking in these cases (with an error),
so POLLIN / POLLOUT would be justified beside POLLERR.
The code now penalizes POLLIN|POLLERR differently from plain POLLERR. The
former (ie. read() returning -1) is terminal and we jump to cleanup, while
plain POLLERR masks only the affected file descriptor for the future.
Let's unify those.
Build tested only.
Please keep me CC'd, I'm not subscribed. Thanks.
Signed-off-by: Laszlo Ersek <lersek(a)redhat.com>
---
src/util/command.c | 17 ++---------------
1 files changed, 2 insertions(+), 15 deletions(-)
diff --git a/src/util/command.c b/src/util/command.c
index f05493e..dc3cfc5 100644
--- a/src/util/command.c
+++ b/src/util/command.c
@@ -1710,7 +1710,7 @@ virCommandProcessIO(virCommandPtr cmd)
}
for (i = 0; i < nfds ; i++) {
- if (fds[i].revents & POLLIN &&
+ if (fds[i].revents & (POLLIN | POLLHUP | POLLERR) &&
(fds[i].fd == errfd || fds[i].fd == outfd)) {
char data[1024];
char **buf;
@@ -1751,7 +1751,7 @@ virCommandProcessIO(virCommandPtr cmd)
}
}
- if (fds[i].revents & POLLOUT &&
+ if (fds[i].revents & (POLLOUT | POLLERR) &&
fds[i].fd == infd) {
int done;
@@ -1777,19 +1777,6 @@ virCommandProcessIO(virCommandPtr cmd)
}
}
}
-
- if (fds[i].revents & (POLLHUP | POLLERR)) {
- if (fds[i].fd == errfd) {
- VIR_DEBUG("hangup on stderr");
- errfd = -1;
- } else if (fds[i].fd == outfd) {
- VIR_DEBUG("hangup on stdout");
- outfd = -1;
- } else {
- VIR_DEBUG("hangup on stdin");
- infd = -1;
- }
- }
}
}
--
1.7.1
12 years, 10 months
[libvirt] [PATCH 0/7] Introduce sVirt to LXC driver
by Daniel P. Berrange
This patch series adds support for sVirt to the LXC driver. In this
series, all LXC guests continue to run unconfined by default. The
app has to explicitly request sVirt confinement for the guest. This
is to ensure backwards compatibility with existing deployments. Since
we won't auto-relabel filesystem trees, it is not possible to turn it
on by default, as we previously did with QEMU
12 years, 10 months
[libvirt] [PATCH 0/3] Use guest agent to quiesce disks
by Michal Privoznik
Since we have qemu guest agent support in libvirt,
we can start wiring up some things that GA already
knows how to do. One of them is file system freeze
and thaw. Domain snapshots can profit from this
functionality.
Michal Privoznik (3):
qemu_agent: Create file system freeze and thaw functions
snapshots: Introduce VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE flag
virsh: Expose new VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE flag
include/libvirt/libvirt.h.in | 4 ++
src/libvirt.c | 6 ++
src/qemu/qemu_agent.c | 68 ++++++++++++++++++++++++
src/qemu/qemu_agent.h | 3 +
src/qemu/qemu_driver.c | 118 ++++++++++++++++++++++++++++++++++++-----
tools/virsh.c | 6 ++
tools/virsh.pod | 14 ++++-
7 files changed, 202 insertions(+), 17 deletions(-)
--
1.7.3.4
12 years, 10 months
[libvirt] [PATCH 0/3] qemu: support disabling/enabling kvmclock with <timer> elements
by Paolo Bonzini
QEMU supports a bunch of CPUID features that are tied to the kvm CPUID
nodes rather than the processor's. They are "kvmclock", "kvm_nopiodelay",
"kvm_mmu", "kvm_asyncpf". These are not known to libvirt and their
CPUID leaf might move if (for example) the Hyper-V extensions are enabled.
Hence their handling would anyway require some special-casing.
However, among these the most useful is kvmclock; an additional
"property" of this feature is that a <timer> element is a better model
than a CPUID feature.
This is what this series does. Patch 1 tweaks the -cpu parsing code so
that it detects the "default" CPU names and (instead of creating a <cpu>
element) sets the guest arch to either i686 or x86_64; this is useful and
helped writing testcases. The next two patches add the new feature.
Finally, patch 4 tweaks the default CPU model to be more precise when
KVM is enabled.
Paolo Bonzini (4):
qemu: get arch name from <cpu> element
conf: add kvmclock timer
qemu: parse and create -cpu ...,-kvmclock
qemu: default to kvm32/kvm64 when KVM is enabled
docs/formatdomain.html.in | 4 +-
docs/schemas/domaincommon.rng | 3 +-
src/conf/domain_conf.c | 3 +-
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 138 ++++++++++++++++----
tests/qemuargv2xmltest.c | 4 +
tests/qemuxml2argvdata/qemu-lib.sh | 1 +
.../qemuxml2argv-cpu-host-kvmclock.args | 4 +
.../qemuxml2argv-cpu-host-kvmclock.xml | 23 ++++
.../qemuxml2argv-cpu-kvmclock.args | 4 +
.../qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.xml | 24 ++++
tests/qemuxml2argvdata/qemuxml2argv-kvmclock.args | 4 +
tests/qemuxml2argvdata/qemuxml2argv-kvmclock.xml | 21 +++
tests/qemuxml2argvtest.c | 3 +
tests/qemuxml2xmltest.c | 3 +
15 files changed, 209 insertions(+), 31 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-kvmclock.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-host-kvmclock.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-cpu-kvmclock.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-kvmclock.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-kvmclock.xml
--
1.7.7.1
12 years, 10 months
[libvirt] [PATCH] src/datatypes.h: fix typo
by Alon Levy
Signed-off-by: Alon Levy <alevy(a)redhat.com>
---
src/datatypes.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/datatypes.h b/src/datatypes.h
index 91b1bfd..47058ed 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -31,7 +31,7 @@
* VIR_CONNECT_MAGIC:
*
* magic value used to protect the API when pointers to connection structures
- * are passed down by the uers.
+ * are passed down by the users.
*/
# define VIR_CONNECT_MAGIC 0x4F23DEAD
# define VIR_IS_CONNECT(obj) ((obj) && (obj)->magic==VIR_CONNECT_MAGIC)
--
1.7.8.4
12 years, 10 months
[libvirt] [PATCH 0/4] Add support for QEMU guest agent control
by Michal Privoznik
====
These patches are taken from here:
https://www.redhat.com/archives/libvir-list/2011-October/msg00135.html
I've just rebased and polished them.
====
The QEMU guest agent "/usr/bin/qemu-ga" has some handy functions
for controlling the guest, not least, shutdown/reboot and filesystem
freeze/thaw.
In Fedora 15/16 the semantics of the ACPI power button have been
changed to suspend-to-RAM which breaks our current shutdown
implementation.
By adding support for the agent we gain a more predictable way
to shutdown / reboot guests.
NB: the code currently has the same "flaw" as the monitor, in
so much as we wait forever for a guest agent reply. We need to
add a timeout ability to the agent code
Daniel P. Berrange (4):
QEMU guest agent support
Add new virDomainShutdownFlags API
Wire up QEMU agent to reboot/shutdown APIs
Allow choice of shutdown method via virsh
include/libvirt/libvirt.h.in | 15 +
po/POTFILES.in | 1 +
src/Makefile.am | 1 +
src/driver.h | 5 +
src/esx/esx_driver.c | 11 +-
src/libvirt.c | 65 +++-
src/libvirt_public.syms | 4 +
src/libxl/libxl_driver.c | 12 +-
src/openvz/openvz_driver.c | 1 +
src/qemu/qemu_agent.c | 1151 ++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_agent.h | 69 +++
src/qemu/qemu_domain.c | 97 ++++
src/qemu/qemu_domain.h | 22 +
src/qemu/qemu_driver.c | 107 ++++-
src/qemu/qemu_monitor_json.c | 2 +-
src/qemu/qemu_process.c | 188 +++++++
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 8 +-
src/remote_protocol-structs | 5 +
src/test/test_driver.c | 11 +-
src/uml/uml_driver.c | 11 +-
src/vbox/vbox_tmpl.c | 11 +-
src/vmware/vmware_driver.c | 1 +
src/xen/xen_driver.c | 14 +-
src/xenapi/xenapi_driver.c | 12 +-
tools/virsh.c | 47 ++-
tools/virsh.pod | 24 +-
27 files changed, 1854 insertions(+), 42 deletions(-)
create mode 100644 src/qemu/qemu_agent.c
create mode 100644 src/qemu/qemu_agent.h
--
1.7.3.4
12 years, 10 months
[libvirt] libvirt and mingw64 x64, bad idea?
by Marc-André Lureau
Hi,
I tried to update the fedora mingw package to follow the mingw64
packaging guideline and allow build for x86 and x64. But I got into
build warning and errors for x86_64. (using Fedora Cross project repo:
http://build1.openftd.org/fedora-cross/fedora-cross.repo,
x86_64-w64-mingw32-gcc (GCC) 4.6.2 20110908 and later)
./configure --host=x86_64-w64-mingw32 --build=x86_64-unknown-linux-gnu
--target=x86_64-w64-mingw32
--prefix=/usr/x86_64-w64-mingw32/sys-root/mingw
--exec-prefix=/usr/x86_64-w64-mingw32/sys-root/mingw
--bindir=/usr/x86_64-w64-mingw32/sys-root/mingw/bin
--sbindir=/usr/x86_64-w64-mingw32/sys-root/mingw/sbin
--sysconfdir=/usr/x86_64-w64-mingw32/sys-root/mingw/etc
--datadir=/usr/x86_64-w64-mingw32/sys-root/mingw/share
--includedir=/usr/x86_64-w64-mingw32/sys-root/mingw/include
--libdir=/usr/x86_64-w64-mingw32/sys-root/mingw/lib
--libexecdir=/usr/x86_64-w64-mingw32/sys-root/mingw/libexec
--localstatedir=/usr/x86_64-w64-mingw32/sys-root/mingw/var
--sharedstatedir=/usr/x86_64-w64-mingw32/sys-root/mingw/com
--mandir=/usr/x86_64-w64-mingw32/sys-root/mingw/share/man
--infodir=/usr/x86_64-w64-mingw32/sys-root/mingw/share/info
--without-xen --without-qemu --without-openvz --without-lxc
--without-vbox --without-xenapi --without-sasl --without-avahi
--without-polkit --without-python --without-libvirtd --without-uml
--without-phyp --without-hyperv --without-vmware --without-netcf
--without-audit --without-dtrace --enable-static
The somewhat worrying error is:
util/command.c:54:1: error: static assertion failed: "verify
(sizeof(pid_t) <= sizeof(int))"
/* We have quite a bit of changes to make if this doesn't hold. */
verify(sizeof(pid_t) <= sizeof(int));
There are a few other warnings, see attached files.
Is this going to be something difficult and worth to fix?
regards
--
Marc-André Lureau
12 years, 10 months
[libvirt] [libvirt-glib] API to get/set custom metadata from/to domain config
by Zeeshan Ali (Khattak)
From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
---
libvirt-gconfig/libvirt-gconfig-domain.c | 115 +++++++++++++++++++++++++++++
libvirt-gconfig/libvirt-gconfig-domain.h | 8 ++
libvirt-gconfig/libvirt-gconfig-helpers.c | 4 +-
libvirt-gconfig/libvirt-gconfig.sym | 2 +
4 files changed, 128 insertions(+), 1 deletions(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c
index 61af625..d1faabd 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain.c
@@ -449,3 +449,118 @@ GList *gvir_config_domain_get_devices(GVirConfigDomain *domain)
return data.devices;
}
+
+static void set_namespace_on_tree(xmlNodePtr node, xmlNsPtr namespace)
+{
+ xmlNodePtr child;
+
+ xmlSetNs(node, namespace);
+
+ for (child = node->children; child != NULL; child = child->next)
+ set_namespace_on_tree(child, namespace);
+}
+
+static xmlNodePtr gvir_config_domain_get_metadata_node
+ (GVirConfigDomain *domain, gboolean create)
+{
+ xmlNodePtr domain_node, metadata_node;
+
+ domain_node = gvir_config_object_get_xml_node(GVIR_CONFIG_OBJECT(domain));
+ metadata_node = gvir_config_xml_get_element(domain_node, "metadata", NULL);
+ if (metadata_node == NULL && create)
+ metadata_node = xmlNewChild(domain_node, NULL, (xmlChar *)"metadata", NULL);
+
+ return metadata_node;
+}
+
+static xmlNodePtr gvir_config_domain_get_custom_xml_node
+ (GVirConfigDomain *domain, const gchar *ns_uri)
+{
+ xmlNodePtr metadata_node, node;
+
+ g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
+
+ metadata_node = gvir_config_domain_get_metadata_node(domain, FALSE);
+ if (metadata_node == NULL)
+ return NULL;
+
+ for (node = metadata_node->children; node != NULL; node = node->next) {
+ if (node->ns != NULL &&
+ (g_strcmp0 ((gchar *)node->ns->href, ns_uri) == 0))
+ break;
+ }
+
+ return node;
+}
+
+gboolean gvir_config_domain_set_custom_xml(GVirConfigDomain *domain,
+ const gchar *xml,
+ const gchar *ns,
+ const gchar *ns_uri,
+ GError **error)
+{
+ xmlNodePtr metadata_node, node, old_node;
+ xmlDocPtr doc;
+ xmlNsPtr namespace;
+
+ g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), FALSE);
+ g_return_val_if_fail(xml != NULL, FALSE);
+ g_return_val_if_fail(ns != NULL, FALSE);
+ g_return_val_if_fail(ns_uri != NULL, FALSE);
+ g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+
+ metadata_node = gvir_config_domain_get_metadata_node(domain, TRUE);
+
+ node = gvir_config_xml_parse(xml, NULL, error);
+ if (error != NULL && *error != NULL)
+ return FALSE;
+
+ namespace = xmlNewNs(node, (xmlChar *)ns_uri, (xmlChar *)ns);
+ set_namespace_on_tree(node, namespace);
+ doc = node->doc;
+
+ old_node = gvir_config_domain_get_custom_xml_node(domain, ns_uri);
+ if (old_node != NULL)
+ xmlReplaceNode(old_node, node);
+ else {
+ xmlUnlinkNode(node);
+ xmlAddChild(metadata_node, node);
+ }
+
+ xmlFreeDoc(doc);
+
+ return TRUE;
+}
+
+gchar *gvir_config_domain_get_custom_xml(GVirConfigDomain *domain,
+ const gchar *ns_uri,
+ GError **error)
+{
+ xmlNodePtr metadata_node, node;
+ xmlBufferPtr xmlbuf;
+ gchar *xml = NULL;
+
+ g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
+
+ metadata_node = gvir_config_domain_get_metadata_node(domain, FALSE);
+ if (metadata_node == NULL)
+ return NULL;
+
+ node = gvir_config_domain_get_custom_xml_node(domain, ns_uri);
+ if (node == NULL)
+ return NULL;
+
+ xmlbuf = xmlBufferCreate();
+ if (xmlNodeDump(xmlbuf, metadata_node->doc, metadata_node, 0, 0) < 0)
+ gvir_config_set_error (error,
+ GVIR_CONFIG_OBJECT_ERROR,
+ 0,
+ "Failed to convert custom node '%s' to string",
+ node->name);
+ else
+ xml = g_strndup((gchar *)xmlBufferContent(xmlbuf), xmlBufferLength(xmlbuf));
+
+ xmlBufferFree(xmlbuf);
+
+ return xml;
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain.h b/libvirt-gconfig/libvirt-gconfig-domain.h
index 6cdaec9..96ded07 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.h
+++ b/libvirt-gconfig/libvirt-gconfig-domain.h
@@ -126,6 +126,14 @@ GList *gvir_config_domain_get_devices(GVirConfigDomain *domain);
void gvir_config_domain_set_lifecycle(GVirConfigDomain *domain,
GVirConfigDomainLifecycleEvent event,
GVirConfigDomainLifecycleAction action);
+gboolean gvir_config_domain_set_custom_xml(GVirConfigDomain *domain,
+ const gchar *xml,
+ const gchar *ns,
+ const gchar *ns_uri,
+ GError **error);
+gchar *gvir_config_domain_get_custom_xml(GVirConfigDomain *domain,
+ const gchar *ns_uri,
+ GError **error);
G_END_DECLS
diff --git a/libvirt-gconfig/libvirt-gconfig-helpers.c b/libvirt-gconfig/libvirt-gconfig-helpers.c
index c406a49..140a4a0 100644
--- a/libvirt-gconfig/libvirt-gconfig-helpers.c
+++ b/libvirt-gconfig/libvirt-gconfig-helpers.c
@@ -148,7 +148,9 @@ gvir_config_xml_parse(const char *xml, const char *root_node, GError **err)
"Unable to parse configuration");
return NULL;
}
- if ((!doc->children) || (strcmp((char *)doc->children->name, root_node) != 0)) {
+ if ((!doc->children) ||
+ (root_node != NULL &&
+ (strcmp((char *)doc->children->name, root_node) != 0))) {
g_set_error(err,
GVIR_CONFIG_OBJECT_ERROR,
0,
diff --git a/libvirt-gconfig/libvirt-gconfig.sym b/libvirt-gconfig/libvirt-gconfig.sym
index 88aef57..ab2c7bf 100644
--- a/libvirt-gconfig/libvirt-gconfig.sym
+++ b/libvirt-gconfig/libvirt-gconfig.sym
@@ -14,6 +14,8 @@ LIBVIRT_GCONFIG_0.0.4 {
gvir_config_domain_new;
gvir_config_domain_new_from_xml;
gvir_config_domain_set_clock;
+ gvir_config_domain_set_custom_xml;
+ gvir_config_domain_get_custom_xml;
gvir_config_domain_get_description;
gvir_config_domain_set_description;
gvir_config_domain_get_devices;
--
1.7.7.5
12 years, 10 months
[libvirt] [libvirt-glib] 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
[libvirt] [PATCH RFC 00/12] Fine grained access control proof of concept
by Daniel P. Berrange
This series of patch is the minimal required to get a working proof
of concept implementation of fine grained access control in libvirt.
This demonstrates
- Obtaining a client identity from a socket
- Ensuring RPC calls are executed with the correct identity sset
- A policykit access driver that checks based on access vector alone
- A SELinux access driver that checks based on access vector + object
- A set of hooks in the QEMU driver to protect virDomainObjPtr access
Things that are not done
- APIs for changing the real/effective identity post-connect
- A simple RBAC access driver for doing (Access vector, object)
checks
- SELinux policy for the SELinux driver
- Access control hooks on all other QEMU driver methods
- Access control hooks in LXC, UML, other libvirtd side drivers
- Access control hooks in storage, network, interface, etc drivers
- Document WTF todo to propagate SELinux contexts across TCP
sockets using IPSec. Any hints welcome...
- Lots more I can't think of right now
I should note that the policykit driver is mostly useless because it
is unable to let you do checks on anything other than permission name
and UNIX process ID at this time. In theory it is supposed to be
extendable to allow other types of identity information besides
the process ID, and to include some kind of object identiers in
the permission check, but no one seems to be attacking this.
So I expect the simple RBAC driver to be the most used one in the
common case usage of libvirt
12 years, 10 months