[libvirt] [PATCH] XenXs: Update documentation
by Philipp Hahn
Fix several references to now renamed functions and parameters when the
functions were moved from src/xen/ to src/xenxs/.
Signed-off-by: Philipp Hahn <hahn(a)univention.de>
---
src/xenxs/xen_sxpr.c | 222 +++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 185 insertions(+), 37 deletions(-)
diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c
index 04ba5aa..ac15853 100644
--- a/src/xenxs/xen_sxpr.c
+++ b/src/xenxs/xen_sxpr.c
@@ -37,7 +37,7 @@
#include "xenxs_private.h"
#include "xen_sxpr.h"
-/* Get a domain id from a sexpr string */
+/* Get a domain id from a S-expression string */
int xenGetDomIdFromSxprString(const char *sexpr, int xendConfigVersion)
{
struct sexpr *root = string2sexpr(sexpr);
@@ -50,7 +50,7 @@ int xenGetDomIdFromSxprString(const char *sexpr, int xendConfigVersion)
return id;
}
-/* Get a domain id from a sexpr */
+/* Get a domain id from a S-expression */
int xenGetDomIdFromSxpr(const struct sexpr *root, int xendConfigVersion)
{
int id = -1;
@@ -66,16 +66,15 @@ int xenGetDomIdFromSxpr(const struct sexpr *root, int xendConfigVersion)
/*****************************************************************
******
- ****** Parsing of SEXPR into virDomainDef objects
+ ****** Parsing of S-Expression into virDomainDef objects
******
*****************************************************************/
/**
- * xenParseSxprOS
+ * xenParseSxprOS:
* @node: the root of the parsed S-Expression
* @def: the domain config
- * @hvm: true or 1 if no contains HVM S-Expression
- * @bootloader: true or 1 if a bootloader is defined
+ * @hvm: true or 1 if node contains HVM S-Expression
*
* Parse the xend sexp for description of os and append it to buf.
*
@@ -166,6 +165,16 @@ no_memory:
return -1;
}
+
+/**
+ * xenParseSxprChar:
+ * @value: A string describing a character device.
+ * @tty: the console pty path
+ *
+ * Parse the xend S-expression for description of a character device.
+ *
+ * Returns a character device object or NULL in case of failure.
+ */
virDomainChrDefPtr
xenParseSxprChar(const char *value,
const char *tty)
@@ -316,13 +325,15 @@ error:
return NULL;
}
+
/**
- * xend_parse_sexp_desc_disks
- * @conn: connection
- * @root: root sexpr
+ * xenParseSxprDisks:
+ * @def: the domain config
+ * @root: root S-expression
+ * @hvm: true or 1 if node contains HVM S-Expression
* @xendConfigVersion: version of xend
*
- * This parses out block devices from the domain sexpr
+ * This parses out block devices from the domain S-expression
*
* Returns 0 if successful or -1 if failed.
*/
@@ -518,6 +529,15 @@ error:
}
+/**
+ * xenParseSxprNets:
+ * @def: the domain config
+ * @root: root S-expression
+ *
+ * This parses out network devices from the domain S-expression
+ *
+ * Returns 0 if successful or -1 if failed.
+ */
static int
xenParseSxprNets(virDomainDefPtr def,
const struct sexpr *root)
@@ -614,6 +634,15 @@ cleanup:
}
+/**
+ * xenParseSxprSound:
+ * @def: the domain config
+ * @str: comma separated list of sound models
+ *
+ * This parses out sound devices from the domain S-expression
+ *
+ * Returns 0 if successful or -1 if failed.
+ */
int
xenParseSxprSound(virDomainDefPtr def,
const char *str)
@@ -692,6 +721,15 @@ error:
}
+/**
+ * xenParseSxprUSB:
+ * @def: the domain config
+ * @root: root S-expression
+ *
+ * This parses out USB devices from the domain S-expression
+ *
+ * Returns 0 if successful or -1 if failed.
+ */
static int
xenParseSxprUSB(virDomainDefPtr def,
const struct sexpr *root)
@@ -733,6 +771,19 @@ no_memory:
return -1;
}
+
+/*
+ * xenParseSxprGraphicsOld:
+ * @def: the domain config
+ * @root: root S-expression
+ * @hvm: true or 1 if root contains HVM S-Expression
+ * @xendConfigVersion: version of xend
+ * @vncport: VNC port number
+ *
+ * This parses out VNC devices from the domain S-expression
+ *
+ * Returns 0 if successful or -1 if failed.
+ */
static int
xenParseSxprGraphicsOld(virDomainDefPtr def,
const struct sexpr *root,
@@ -821,6 +872,16 @@ error:
}
+/*
+ * xenParseSxprGraphicsNew:
+ * @def: the domain config
+ * @root: root S-expression
+ * @vncport: VNC port number
+ *
+ * This parses out VNC devices from the domain S-expression
+ *
+ * Returns 0 if successful or -1 if failed.
+ */
static int
xenParseSxprGraphicsNew(virDomainDefPtr def,
const struct sexpr *root, int vncport)
@@ -918,11 +979,13 @@ error:
return -1;
}
+
/**
- * xenParseSxprPCI
+ * xenParseSxprPCI:
+ * @def: the domain config
* @root: root sexpr
*
- * This parses out block devices from the domain sexpr
+ * This parses out PCI devices from the domain sexpr
*
* Returns 0 if successful or -1 if failed.
*/
@@ -1044,16 +1107,17 @@ error:
/**
* xenParseSxpr:
- * @conn: the connection associated with the XML
* @root: the root of the parsed S-Expression
* @xendConfigVersion: version of xend
* @cpus: set of cpus the domain may be pinned to
+ * @tty: the console pty path
+ * @vncport: VNC port number
*
- * Parse the xend sexp description and turn it into the XML format similar
- * to the one unsed for creation.
+ * Parse the xend S-expression description and turn it into a virDomainDefPtr
+ * representing these settings as closeley as is practical.
*
- * Returns the 0 terminated XML string or NULL in case of error.
- * the caller must free() the returned value.
+ * Returns the domain config or NULL in case of error.
+ * The caller must free() the returned value.
*/
virDomainDefPtr
xenParseSxpr(const struct sexpr *root,
@@ -1424,6 +1488,20 @@ error:
return NULL;
}
+
+/**
+ * xenParseSxprString:
+ * @sexpr: the root of the parsed S-Expression
+ * @xendConfigVersion: version of xend
+ * @tty: the console pty path
+ * @vncport: VNC port number
+ *
+ * Parse the xend S-expression description and turn it into a virDomainDefPtr
+ * representing these settings as closeley as is practical.
+ *
+ * Returns the domain config or NULL in case of error.
+ * The caller must free() the returned value.
+ */
virDomainDefPtr
xenParseSxprString(const char *sexpr,
int xendConfigVersion, char *tty, int vncport)
@@ -1449,15 +1527,12 @@ xenParseSxprString(const char *sexpr,
/**
- * virtDomainParseXMLGraphicsDescVFB:
- * @conn: pointer to the hypervisor connection
- * @node: node containing graphics description
- * @buf: a buffer for the result S-Expr
+ * xenFormatSxprGraphicsNew:
+ * @def: the domain config
+ * @buf: a buffer for the result S-expression
*
- * Parse the graphics part of the XML description and add it to the S-Expr
- * in buf. This is a temporary interface as the S-Expr interface will be
- * replaced by XML-RPC in the future. However the XML format should stay
- * valid over time.
+ * Convert the graphics part of the domain description into a S-expression
+ * in buf. (HVM > 3.0.4 or PV > 3.0.3)
*
* Returns 0 in case of success, -1 in case of error
*/
@@ -1508,6 +1583,17 @@ xenFormatSxprGraphicsNew(virDomainGraphicsDefPtr def,
}
+/**
+ * xenFormatSxprGraphicsOld:
+ * @def: the domain config
+ * @buf: a buffer for the result S-expression
+ * @xendConfigVersion: version of xend
+ *
+ * Convert the graphics part of the domain description into a S-expression
+ * in buf. (HVM <= 3.0.4 or PV <= 3.0.3)
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
static int
xenFormatSxprGraphicsOld(virDomainGraphicsDefPtr def,
virBufferPtr buf,
@@ -1553,6 +1639,17 @@ xenFormatSxprGraphicsOld(virDomainGraphicsDefPtr def,
return 0;
}
+
+/**
+ * xenFormatSxprChr:
+ * @def: the domain config
+ * @buf: a buffer for the result S-expression
+ *
+ * Convert the character deivce part of the domain config into a S-expression
+ * in buf.
+ *
+ * Returns 0 in case of success, -1 in case of error
+ */
int
xenFormatSxprChr(virDomainChrDefPtr def,
virBufferPtr buf)
@@ -1631,15 +1728,14 @@ xenFormatSxprChr(virDomainChrDefPtr def,
/**
- * virDomainParseXMLDiskDesc:
- * @node: node containing disk description
- * @buf: a buffer for the result S-Expr
+ * xenFormatSxprDisk:
+ * @node: node containing the disk description
+ * @buf: a buffer for the result S-expression
+ * @hvm: true or 1 if domain is HVM
* @xendConfigVersion: xend configuration file format
+ * @isAttach: create expression for device attach (1).
*
- * Parse the one disk in the XML description and add it to the S-Expr in buf
- * This is a temporary interface as the S-Expr interface
- * will be replaced by XML-RPC in the future. However the XML format should
- * stay valid over time.
+ * Convert the disk device part of the domain config into a S-expresssion in buf.
*
* Returns 0 in case of success, -1 in case of error.
*/
@@ -1757,12 +1853,15 @@ xenFormatSxprDisk(virDomainDiskDefPtr def,
}
/**
- * xenFormatSxprNet
- * @node: node containing the interface description
- * @buf: a buffer for the result S-Expr
+ * xenFormatSxprNet:
+ * @conn: connection
+ * @def: the domain config
+ * @buf: a buffer for the result S-expression
+ * @hvm: true or 1 if domain is HVM
* @xendConfigVersion: xend configuration file format
+ * @isAttach: create expression for device attach (1).
*
- * Parse the one interface the XML description and add it to the S-Expr in buf
+ * Convert the interface description of the domain config into a S-expression in buf.
* This is a temporary interface as the S-Expr interface
* will be replaced by XML-RPC in the future. However the XML format should
* stay valid over time.
@@ -1893,6 +1992,15 @@ xenFormatSxprNet(virConnectPtr conn,
}
+/**
+ * xenFormatSxprPCI:
+ * @def: the device config
+ * @buf: a buffer for the result S-expression
+ *
+ * Convert a single PCI device part of the domain config into a S-expresssion in buf.
+ *
+ * Returns 0 in case of success, -1 in case of error.
+ */
static void
xenFormatSxprPCI(virDomainHostdevDefPtr def,
virBufferPtr buf)
@@ -1904,6 +2012,17 @@ xenFormatSxprPCI(virDomainHostdevDefPtr def,
def->source.subsys.u.pci.function);
}
+
+/**
+ * xenFormatSxprOnePCI:
+ * @def: the device config
+ * @buf: a buffer for the result S-expression
+ * @detach: create expression for device detach (1).
+ *
+ * Convert a single PCI device part of the domain config into a S-expresssion in buf.
+ *
+ * Returns 0 in case of success, -1 in case of error.
+ */
int
xenFormatSxprOnePCI(virDomainHostdevDefPtr def,
virBufferPtr buf,
@@ -1926,6 +2045,16 @@ xenFormatSxprOnePCI(virDomainHostdevDefPtr def,
return 0;
}
+
+/**
+ * xenFormatSxprAllPCI:
+ * @def: the domain config
+ * @buf: a buffer for the result S-expression
+ *
+ * Convert all PCI device parts of the domain config into a S-expresssion in buf.
+ *
+ * Returns 0 in case of success, -1 in case of error.
+ */
static int
xenFormatSxprAllPCI(virDomainDefPtr def,
virBufferPtr buf)
@@ -1973,6 +2102,16 @@ xenFormatSxprAllPCI(virDomainDefPtr def,
return 0;
}
+
+/**
+ * xenFormatSxprSound:
+ * @def: the domain config
+ * @buf: a buffer for the result S-expression
+ *
+ * Convert all sound device parts of the domain config into S-expression in buf.
+ *
+ * Returns 0 if successful or -1 if failed.
+ */
int
xenFormatSxprSound(virDomainDefPtr def,
virBufferPtr buf)
@@ -2001,6 +2140,15 @@ xenFormatSxprSound(virDomainDefPtr def,
}
+/**
+ * xenFormatSxprInput:
+ * @input: the input config
+ * @buf: a buffer for the result S-expression
+ *
+ * Convert all input device parts of the domain config into S-expression in buf.
+ *
+ * Returns 0 if successful or -1 if failed.
+ */
static int
xenFormatSxprInput(virDomainInputDefPtr input,
virBufferPtr buf)
@@ -2033,7 +2181,7 @@ verify(MAX_VIRT_CPUS <= sizeof(1UL) * CHAR_BIT);
* @def: domain config definition
* @xendConfigVersion: xend configuration file format
*
- * Generate an SEXPR representing the domain configuration.
+ * Generate an S-expression representing the domain configuration.
*
* Returns the 0 terminated S-Expr string or NULL in case of error.
* the caller must free() the returned value.
--
1.7.1
12 years, 9 months
[libvirt] [PATCH] tests: virnettlscontexttest needs gnutls-2.6.0
by Philipp Hahn
virnettlscontexttest uses gnutls_x509_crt_set_subject_alt_name() and
GNUTLS_FSAN_APPEND, which - according to
<http://www.gnu.org/software/gnutls/manual/gnutls.html> - are only
available since 2.6.0.
Since libvirt still works fine with gnutls-1.0.25 from RHEL5, only
enable the test when the version of GNUTLS is at least 2.6.0.
Signed-off-by: Philipp Hahn <hahn(a)univention.de>
---
tests/virnettlscontexttest.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/tests/virnettlscontexttest.c b/tests/virnettlscontexttest.c
index 51f75b4..6dd42d4 100644
--- a/tests/virnettlscontexttest.c
+++ b/tests/virnettlscontexttest.c
@@ -36,7 +36,7 @@
#include "virsocketaddr.h"
#include "gnutls_1_0_compat.h"
-#if !defined WIN32 && HAVE_LIBTASN1_H && !defined GNUTLS_1_0_COMPAT
+#if !defined WIN32 && HAVE_LIBTASN1_H && !defined GNUTLS_1_0_COMPAT && LIBGNUTLS_VERSION_NUMBER > 0x020600
# include <libtasn1.h>
# include "rpc/virnettlscontext.h"
--
1.7.1
12 years, 9 months
[libvirt] [[libvirt-glib PATCHv3] 1/3] Add proper error reporting to gvir_storage_vol_get_path
by Christophe Fergeau
gvir_storage_vol_get_name currently call g_error when an error occurs.
Since g_error trigger a coredump, calling it in a library is harmful.
Replace this with proper GError error reporting.
---
libvirt-gobject/libvirt-gobject-storage-vol.c | 7 +++++--
libvirt-gobject/libvirt-gobject-storage-vol.h | 2 +-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.c b/libvirt-gobject/libvirt-gobject-storage-vol.c
index 5b18877..5e83e1b 100644
--- a/libvirt-gobject/libvirt-gobject-storage-vol.c
+++ b/libvirt-gobject/libvirt-gobject-storage-vol.c
@@ -184,13 +184,16 @@ const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol)
return name;
}
-const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol)
+const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol, GError **error)
{
GVirStorageVolPrivate *priv = vol->priv;
const char *path;
if (!(path = virStorageVolGetPath(priv->handle))) {
- g_error("Failed to get storage_vol path on %p", priv->handle);
+ gvir_set_error(error, GVIR_STORAGE_VOL_ERROR, 0,
+ "Failed to get storage_vol path on %p",
+ priv->handle);
+ return NULL;
}
return path;
diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.h b/libvirt-gobject/libvirt-gobject-storage-vol.h
index db63865..25f683a 100644
--- a/libvirt-gobject/libvirt-gobject-storage-vol.h
+++ b/libvirt-gobject/libvirt-gobject-storage-vol.h
@@ -78,7 +78,7 @@ GType gvir_storage_vol_info_get_type(void);
GType gvir_storage_vol_handle_get_type(void);
const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol);
-const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol);
+const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol, GError **error);
gboolean gvir_storage_vol_delete(GVirStorageVol *vol,
guint flags,
--
1.7.7.6
12 years, 9 months
[libvirt] RFC: setting mac address on network devices being assigned to a guest via PCI passthrough (<hostdev>)
by Laine Stump
To refresh everyone's memory, the origin of the problem I'm trying to
solve here is that the VFs of an SRIOV-capable ethernet card are given
new random MAC addresses each time the card is initialized. If those VFs
are then passed-through to a guest using the existing <hostdev> config,
the guest will see a new MAC address each time the host is restarted,
and will thus believe that a new ethernet card has been installed. This
can result in anything from a dialog claiming that the guest has
connected to a new network (MS products) to a new network device name
showing up (Linux - "hmm, eth0 was unplugged, but here's this new
device. Let's call it "eth1"!)
Several months ago I sent out some mail proposing a scheme for
automatically allocating network devices from a pool to be assigned to
guests via PCI passthrough:
https://www.redhat.com/archives/libvir-list/2011-August/msg00937.html
My idea was to have a new <network> forward mode combined with guest
<interface> definitions that would end up auto-generating a transient
<hostdev> entry in the guest's config (and setting the VF's mac address
in the process). Dan Berrange pointed out in that thread that we really
do need to have a persistent <hostdev> entry for these devices in the
domain xml, if for no other reason than to guarantee that the same
guest-side PCI address is always used (thus preventing surprises in the
guest, such as re-activation demands from Microsoft OSes). (There were
other reasons, but that one was the real "hard stop" for me.)
I've come back to this problem, and have decided that, while having the
actual host device auto-allocated at runtime would be nice, first
implementing a less ambitious solution that uses a hand-picked device
would not preclude adding the more complicated/useful functionality
later. So, here's a new simpler proposal.
Step 1
------
In the end, the solution will be that the VF's auto-generated random MAC
address should be replaced with a fixed MAC address supplied by libvirt
prior to assigning the VF to the guest. As a first step to satisfy this
basic requirement, I'm figuring to just extend the <hostdev> xml in this
way:
|<hostdev mode='subsystem' type='pci' managed='yes'>
|<source>
|<address bus='0x06' slot='0x02' function='0x0'/>
|</source>
|<mac address='11:22:33:44:55:66"/>
|</hostdev>
When libvirt sees <mac address...> in the hostdev at device attach time,
it would first verify that the device is a network device (if not, it
would log an error and fail the operation). If it is a network device,
the pci address would be converted into a network device name, and that
device would have its MAC address set to the configured value, and then
the attach would proceed.
My main questions here are:
1) Is this the right place for the new element? Or should it go into
<source>?
2) Should we bother trying to save the original MAC address to restore
when the device is released? (I guess that might be important if, for
example, the guest config was changed to use a different device but same
MAC address - you could end up with two devices having the same MAC
address).
3) I've seen requests from 2 places to do host-side virtual port
association (i.e. vepa / 802.1Qb[gh]). Would it be feasible to do that
association with the device after setting MAC address and before
assigning it to the guest? (and likewise for the inverse) Or would the
act of PCI assignment screw that up somehow? (one of the messages in the
earlier thread says something about the device initialization by the
guest un-doing necessary setup) (if it would work, a <virtualport> could
just be added along with <mac address>).
Beyond those 3 questons, this all seems rather uncontroversial, so I'll
start coding something up right away (and modify as necessary after
discussion).
Step 2
------
Once the basic functionality is in place, a further step would be one
just to simplify the admins job - we could do this by replacing this config:
| <source>
| <address bus='x' slot='y' function='z'/>
| </source>
with:
| <source>
| <address netdev='eth22'/>
| </source>
(or possibly it could be a separate element within <source>, e.g.
"<network dev='eth22'/>") As long as the domain isn't running, the
config would remain like this. The first time the device was attached,
the name in netdev would be resolved to a pci address (or failed if the
given netdev wasn't a PCI device); and the config auto-filled as follows:
| <source>
| <address bus='x' slot='y' function='z' netdev='eth22'/>
| </source>
On subsequent attaches (i.e. when both netdev and a pci address are
present) the netdev would again be resolved and compared to the pci
address to make sure they still agree; if not, the operation would fail.
This would satisfy management applications' desire to see the pci
address info of all devices assigned to guests, while retaining the
original config info (and also lead quite nicely into step 3...).
Step 3
------
To further simplify configuration, it would be very nice if the choice
of network device could be done automatically. Since libvirt's networks
already have the concept of a pool of devices (and also of portgroups
which can be used to set <virtualport> parameters), it kind of makes to
sense to use that. In this case, a network would be defined something
like this:
| <network>
| <name>passthrough-net</name>
| <forward dev='eth20' mode='hostdev'> <!-- or "hardware" or "device" -->
| <interface dev='eth20'/>
| <interface dev='eth21'/>
| <interface dev='eth22'/>
| ..
| </forward>
| </network>
(it could also contain a virtualport definition and/or portgroups
containing virtualport definitions. Obviously, we would have to prohibit
<bandwidth> elements (and several other things) in the definitions>)
Then, in lieu of a pci address or network device name (as "netdev"), the
<hostdev>'s <source> would have a reference to the network:
|<hostdev mode='subsystem' type='pci' managed='yes'>
|<source>
|<address network='passthrough-net'/>
|</source>
|<mac address='11:22:33:44:55:66"/>
|</hostdev>
(or, again, maybe use the separate <network> element: "<network
name='passthrough-net'/>) At attach time, the pool of devices in
passthrough-net would be searched for a free device, and if found, that
device would have its MAC address changed and be assigned to the guest.
In this case, the live XML would be updated with the pci address
information, but when the guest was destroyed, the device would be
handed back to the pool, and the pci address info once again removed
from the config.
Step 2 & 3 probably won't be implemented right away, but I thought I
should toss the ideas out there in case they lead to something else that
would require a change in step 1.
12 years, 9 months
[libvirt] [[libvirt-glib PATCHv2]] API to get/set custom metadata from/to domain config
by Christophe Fergeau
Based on a patch from Zeeshan Ali (Khattak) <zeeshanak(a)gnome.org>
---
libvirt-gconfig/libvirt-gconfig-domain.c | 60 +++++++++++++++++++++
libvirt-gconfig/libvirt-gconfig-domain.h | 7 +++
libvirt-gconfig/libvirt-gconfig-helpers-private.h | 1 +
libvirt-gconfig/libvirt-gconfig-helpers.c | 23 ++++++++-
libvirt-gconfig/libvirt-gconfig-object-private.h | 3 +
libvirt-gconfig/libvirt-gconfig-object.c | 20 +++++++
libvirt-gconfig/libvirt-gconfig.sym | 2 +
7 files changed, 115 insertions(+), 1 deletions(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c
index 61af625..606f5a4 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain.c
@@ -449,3 +449,63 @@ GList *gvir_config_domain_get_devices(GVirConfigDomain *domain)
return data.devices;
}
+
+gboolean gvir_config_domain_set_custom_xml(GVirConfigDomain *domain,
+ const gchar *xml,
+ const gchar *ns,
+ const gchar *ns_uri,
+ GError **error)
+{
+ GVirConfigObject *metadata;
+ GVirConfigObject *custom_xml;
+
+ g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), FALSE);
+ g_return_val_if_fail(xml != NULL, FALSE);
+ g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
+
+ metadata = gvir_config_object_add_child(GVIR_CONFIG_OBJECT(domain), "metadata");
+
+ custom_xml = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_OBJECT, NULL, NULL, xml, error);
+ if (error != NULL && *error != NULL)
+ return FALSE;
+
+ gvir_config_object_set_namespace(custom_xml, ns, ns_uri);
+
+ gvir_config_object_attach_replace(metadata, custom_xml);
+
+ return TRUE;
+}
+
+struct LookupNamespacedNodeData {
+ const char *ns_uri;
+ xmlNodePtr node;
+};
+
+static gboolean lookup_namespaced_node(xmlNodePtr node, gpointer opaque)
+{
+ struct LookupNamespacedNodeData* data = opaque;
+
+ if (node->ns == NULL)
+ return TRUE;
+
+ if (g_strcmp0((char *)node->ns->href, data->ns_uri) == 0) {
+ data->node = node;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gchar *gvir_config_domain_get_custom_xml(GVirConfigDomain *domain,
+ const gchar *ns_uri)
+{
+ struct LookupNamespacedNodeData data = { NULL, NULL };
+
+ g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN(domain), NULL);
+ g_return_val_if_fail(ns_uri != NULL, NULL);
+
+ data.ns_uri = ns_uri;
+ gvir_config_object_foreach_child(GVIR_CONFIG_OBJECT(domain), "metadata",
+ lookup_namespaced_node, &data);
+ return gvir_config_xml_node_to_string(data.node);
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain.h b/libvirt-gconfig/libvirt-gconfig-domain.h
index 6cdaec9..769d2f0 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.h
+++ b/libvirt-gconfig/libvirt-gconfig-domain.h
@@ -126,6 +126,13 @@ 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);
G_END_DECLS
diff --git a/libvirt-gconfig/libvirt-gconfig-helpers-private.h b/libvirt-gconfig/libvirt-gconfig-helpers-private.h
index 96ec02e..514aeb0 100644
--- a/libvirt-gconfig/libvirt-gconfig-helpers-private.h
+++ b/libvirt-gconfig/libvirt-gconfig-helpers-private.h
@@ -56,6 +56,7 @@ char *gvir_config_xml_get_child_element_content_glib (xmlNode *node,
const char *child_name);
xmlChar *gvir_config_xml_get_attribute_content(xmlNodePtr node,
const char *attr_name);
+char *gvir_config_xml_node_to_string(xmlNodePtr node);
char *gvir_config_xml_get_attribute_content_glib(xmlNodePtr node,
const char *attr_name);
const char *gvir_config_genum_get_nick (GType enum_type, gint value);
diff --git a/libvirt-gconfig/libvirt-gconfig-helpers.c b/libvirt-gconfig/libvirt-gconfig-helpers.c
index fecf3eb..a324d0e 100644
--- a/libvirt-gconfig/libvirt-gconfig-helpers.c
+++ b/libvirt-gconfig/libvirt-gconfig-helpers.c
@@ -148,7 +148,8 @@ 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) ||
+ (g_strcmp0((char *)doc->children->name, root_node) != 0)) {
g_set_error(err,
GVIR_CONFIG_OBJECT_ERROR,
0,
@@ -307,3 +308,23 @@ gvir_config_genum_get_value (GType enum_type, const char *nick,
g_return_val_if_reached(default_value);
}
+
+G_GNUC_INTERNAL char *
+gvir_config_xml_node_to_string(xmlNodePtr node)
+{
+ xmlBufferPtr xmlbuf;
+ char *xml;
+
+ if (node == NULL)
+ return NULL;
+
+ xmlbuf = xmlBufferCreate();
+ if (xmlNodeDump(xmlbuf, node->doc, node, 0, 0) < 0)
+ return NULL;
+ else
+ xml = g_strndup((gchar *)xmlBufferContent(xmlbuf), xmlBufferLength(xmlbuf));
+
+ xmlBufferFree(xmlbuf);
+
+ return xml;
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-object-private.h b/libvirt-gconfig/libvirt-gconfig-object-private.h
index 781e1a3..7e000f5 100644
--- a/libvirt-gconfig/libvirt-gconfig-object-private.h
+++ b/libvirt-gconfig/libvirt-gconfig-object-private.h
@@ -90,6 +90,9 @@ void gvir_config_object_foreach_child(GVirConfigObject *object,
const char *parent_name,
GVirConfigXmlNodeIterator iter_func,
gpointer opaque);
+gboolean gvir_config_object_set_namespace(GVirConfigObject *object,
+ const char *ns,
+ const char *ns_uri);
G_END_DECLS
diff --git a/libvirt-gconfig/libvirt-gconfig-object.c b/libvirt-gconfig/libvirt-gconfig-object.c
index 2e28208..f664b12 100644
--- a/libvirt-gconfig/libvirt-gconfig-object.c
+++ b/libvirt-gconfig/libvirt-gconfig-object.c
@@ -846,3 +846,23 @@ gvir_config_object_remove_attribute(GVirConfigObject *object,
status = xmlUnsetProp(object->priv->node, (xmlChar *)attr_name);
} while (status == 0);
}
+
+G_GNUC_INTERNAL gboolean
+gvir_config_object_set_namespace(GVirConfigObject *object, const char *ns,
+ const char *ns_uri)
+{
+ xmlNsPtr namespace;
+
+ g_return_val_if_fail(GVIR_CONFIG_IS_OBJECT(object), FALSE);
+ g_return_val_if_fail(ns != NULL, FALSE);
+ g_return_val_if_fail(ns_uri != NULL, FALSE);
+
+ namespace = xmlNewNs(object->priv->node,
+ (xmlChar *)ns_uri, (xmlChar *)ns);
+ if (namespace == NULL)
+ return FALSE;
+
+ xmlSetNs(object->priv->node, namespace);
+
+ return TRUE;
+}
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.6
12 years, 9 months
[libvirt] [[libvirt-glib PATCHv2] 1/4] Add proper error reporting to GVirStorageVol getters
by Christophe Fergeau
gvir_storage_vol_get_name and gvir_storage_vol_get_path currently
call g_error when an error occurs. Since g_error trigger a coredump,
calling it in a library is harmful. Replace this with proper GError
error reporting.
---
libvirt-gobject/libvirt-gobject-storage-pool.c | 10 +++++++---
libvirt-gobject/libvirt-gobject-storage-vol.c | 14 ++++++++++----
libvirt-gobject/libvirt-gobject-storage-vol.h | 4 ++--
3 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/libvirt-gobject/libvirt-gobject-storage-pool.c b/libvirt-gobject/libvirt-gobject-storage-pool.c
index bf25641..a88699e 100644
--- a/libvirt-gobject/libvirt-gobject-storage-pool.c
+++ b/libvirt-gobject/libvirt-gobject-storage-pool.c
@@ -528,6 +528,7 @@ GVirStorageVol *gvir_storage_pool_create_volume
const gchar *xml;
virStorageVolPtr handle;
GVirStoragePoolPrivate *priv = pool->priv;
+ const char *name;
xml = gvir_config_object_to_xml(GVIR_CONFIG_OBJECT(conf));
@@ -545,11 +546,14 @@ GVirStorageVol *gvir_storage_pool_create_volume
volume = GVIR_STORAGE_VOL(g_object_new(GVIR_TYPE_STORAGE_VOL,
"handle", handle,
NULL));
+ name = gvir_storage_vol_get_name(volume, err);
+ if (name == NULL) {
+ g_object_unref(G_OBJECT(volume));
+ return NULL;
+ }
g_mutex_lock(priv->lock);
- g_hash_table_insert(priv->volumes,
- g_strdup(gvir_storage_vol_get_name(volume)),
- volume);
+ g_hash_table_insert(priv->volumes, g_strdup(name), volume);
g_mutex_unlock(priv->lock);
return g_object_ref(volume);
diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.c b/libvirt-gobject/libvirt-gobject-storage-vol.c
index 5b18877..c427e42 100644
--- a/libvirt-gobject/libvirt-gobject-storage-vol.c
+++ b/libvirt-gobject/libvirt-gobject-storage-vol.c
@@ -172,25 +172,31 @@ gvir_storage_vol_info_free(GVirStorageVolInfo *info)
G_DEFINE_BOXED_TYPE(GVirStorageVolInfo, gvir_storage_vol_info,
gvir_storage_vol_info_copy, gvir_storage_vol_info_free)
-const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol)
+const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol, GError **error)
{
GVirStorageVolPrivate *priv = vol->priv;
const char *name;
if (!(name = virStorageVolGetName(priv->handle))) {
- g_error("Failed to get storage_vol name on %p", priv->handle);
+ gvir_set_error(error, GVIR_STORAGE_VOL_ERROR, 0,
+ "Failed to get storage_vol name on %p",
+ priv->handle);
+ return NULL;
}
return name;
}
-const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol)
+const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol, GError **error)
{
GVirStorageVolPrivate *priv = vol->priv;
const char *path;
if (!(path = virStorageVolGetPath(priv->handle))) {
- g_error("Failed to get storage_vol path on %p", priv->handle);
+ gvir_set_error(error, GVIR_STORAGE_VOL_ERROR, 0,
+ "Failed to get storage_vol path on %p",
+ priv->handle);
+ return NULL;
}
return path;
diff --git a/libvirt-gobject/libvirt-gobject-storage-vol.h b/libvirt-gobject/libvirt-gobject-storage-vol.h
index db63865..fd2be80 100644
--- a/libvirt-gobject/libvirt-gobject-storage-vol.h
+++ b/libvirt-gobject/libvirt-gobject-storage-vol.h
@@ -77,8 +77,8 @@ GType gvir_storage_vol_get_type(void);
GType gvir_storage_vol_info_get_type(void);
GType gvir_storage_vol_handle_get_type(void);
-const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol);
-const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol);
+const gchar *gvir_storage_vol_get_name(GVirStorageVol *vol, GError **error);
+const gchar *gvir_storage_vol_get_path(GVirStorageVol *vol, GError **error);
gboolean gvir_storage_vol_delete(GVirStorageVol *vol,
guint flags,
--
1.7.7.6
12 years, 9 months
[libvirt] Build issue with libvirt 0.9.8
by Christophe Fergeau
Hi,
When building libvirt 0.9.8 with jhbuild, I have now reproduced twice some
issue during the build. Namely, after successfully building and installing
libvirt 0.9.8, when I try to run virsh, I get:
virsh: /home/teuf/jhbuild-boxes/opt/lib64/libvirt.so.0: version
`LIBVIRT_PRIVATE_0.9.7' not found (required by
/home/teuf/jhbuild-boxes/opt/lib64/libvirt-qemu.so.0)
This happens when I start from a clean prefix (no libvirt in it), then I
install 0.9.7, and then I try to install 0.9.8 on top of it. If I rebuild
libvirt-0.9.8 once more this goes away, so this is not a blocking problem
for me.
I have checked that libvirt-qemu.so.0 is the 0.9.8 version, I have looked
in the build logs and in Makefile.am and everything looks correct to me, so
I was wondering if anyone had any explanation for this behaviour. Once
again, it's easy to workaround so it's not a big issue, but I'm mentioning
it in case there would something obvious I missed.
I put the build logs at
http://people.gnome.org/~teuf/libvirt-0.9.7
and
http://people.gnome.org/~teuf/libvirt-0.9.8
Christophe
12 years, 9 months
[libvirt] g_error considered harmful
by Christophe Fergeau
Hi,
g_error calls abort() when it's called, thus it should only be used for
bad assertion failures. We currently are using it in some places in
libvirt-gobject as if it was g_warning. This patch series gets rid of most
occurrences of g_error by either replacing it with g_warning or by adding a
GError ** argument to the function calling g_error.
Christophe
12 years, 9 months
[libvirt] [PATCH] resize: slightly alter signature
by Eric Blake
Our existing virDomainBlockResize takes an unsigned long long
argument; if that command is later taught a DELTA and SHRINK flag,
we cannot change its type without breaking API (but at least such
a change would be ABI compatible). Meanwhile, the only time a
negative size makes sense is if both DELTA and SHRINK are used
together, but if we keep the argument unsigned, applications can
pass the positive delta amount by which they would like to shrink
the system, and have the flags imply the negative value. So,
since this API has not yet been released, and in the interest of
consistency with existing API, we swap virStorageVolResize to
always pass an unsigned value.
* include/libvirt/libvirt.h.in (virStorageVolResize): Use unsigned
argument.
* src/libvirt.c (virStorageVolResize): Likewise.
* src/driver.h (virDrvStorageVolUpload): Adjust clients.
* src/remote/remote_protocol.x (remote_storage_vol_resize_args):
Likewise.
* src/remote_protocol-structs: Regenerate.
Suggested by Daniel P. Berrange.
---
include/libvirt/libvirt.h.in | 2 +-
src/driver.h | 2 +-
src/libvirt.c | 17 +++++++++--------
src/remote/remote_protocol.x | 2 +-
src/remote_protocol-structs | 2 +-
5 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 0a7b324..d9b9b95 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -2415,7 +2415,7 @@ typedef enum {
} virStorageVolResizeFlags;
int virStorageVolResize (virStorageVolPtr vol,
- long long capacity,
+ unsigned long long capacity,
unsigned int flags);
diff --git a/src/driver.h b/src/driver.h
index ba7dbc4..2e2042e 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -1277,7 +1277,7 @@ typedef int
unsigned int flags);
typedef int
(*virDrvStorageVolResize) (virStorageVolPtr vol,
- long long capacity,
+ unsigned long long capacity,
unsigned int flags);
typedef int
diff --git a/src/libvirt.c b/src/libvirt.c
index e702a34..c609202 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -13014,16 +13014,20 @@ error:
* Normally, this operation should only be used to enlarge capacity;
* but if @flags contains VIR_STORAGE_RESIZE_SHRINK, it is possible to
* attempt a reduction in capacity even though it might cause data loss.
+ * If VIR_STORAGE_RESIZE_DELTA is also present, then @capacity is
+ * subtracted from the current size; without it, @capacity represents
+ * the absolute new size regardless of whether it is larger or smaller
+ * than the current size.
*
* Returns 0 on success, or -1 on error.
*/
int
virStorageVolResize(virStorageVolPtr vol,
- long long capacity,
+ unsigned long long capacity,
unsigned int flags)
{
virConnectPtr conn;
- VIR_DEBUG("vol=%p capacity=%lld flags=%x", vol, capacity, flags);
+ VIR_DEBUG("vol=%p capacity=%llu flags=%x", vol, capacity, flags);
virResetLastError();
@@ -13040,12 +13044,9 @@ virStorageVolResize(virStorageVolPtr vol,
goto error;
}
- /* Negative capacity is valid only with both delta and shrink;
- * zero capacity is valid with either delta or shrink. */
- if ((capacity < 0 && !(flags & VIR_STORAGE_VOL_RESIZE_DELTA) &&
- !(flags & VIR_STORAGE_VOL_RESIZE_SHRINK)) ||
- (capacity == 0 && !((flags & VIR_STORAGE_VOL_RESIZE_DELTA) ||
- (flags & VIR_STORAGE_VOL_RESIZE_SHRINK)))) {
+ /* Zero capacity is only valid with either delta or shrink. */
+ if (capacity == 0 && !((flags & VIR_STORAGE_VOL_RESIZE_DELTA) ||
+ (flags & VIR_STORAGE_VOL_RESIZE_SHRINK))) {
virLibStorageVolError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error;
}
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index b58925a..b2c8426 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -1709,7 +1709,7 @@ struct remote_storage_vol_get_path_ret {
struct remote_storage_vol_resize_args {
remote_nonnull_storage_vol vol;
- hyper capacity;
+ unsigned hyper capacity;
unsigned int flags;
};
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 5eac9bf..e9137a9 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -1282,7 +1282,7 @@ struct remote_storage_vol_get_path_ret {
};
struct remote_storage_vol_resize_args {
remote_nonnull_storage_vol vol;
- int64_t capacity;
+ uint64_t capacity;
u_int flags;
};
struct remote_node_num_of_devices_args {
--
1.7.7.6
12 years, 9 months
[libvirt] [PATCHv2 0/4] API for modification of domain metadata
by Peter Krempa
This is a corrected version of the domain metadata modification API.
I dropped the limit on length of the domain title and added skipping
of newlines added at the end of file by some editors, which made
--edit unusable with --title for the new desc command.
Peter Krempa (4):
xml: Add element <title> to allow short description of domains
API: Add api to set and get domain metadata
virsh: Add support for modifying domain description and titles
qemu: Add support for virDomainGetMetadata and virDomainSetMetadata
docs/formatdomain.html.in | 6 +
docs/schemas/domaincommon.rng | 13 +-
include/libvirt/libvirt.h.in | 24 ++
include/libvirt/virterror.h | 1 +
src/conf/domain_conf.c | 11 +
src/conf/domain_conf.h | 1 +
src/driver.h | 16 ++
src/libvirt.c | 181 +++++++++++++
src/libvirt_public.syms | 2 +
src/qemu/qemu_driver.c | 174 ++++++++++++
src/remote/remote_driver.c | 2 +
src/remote/remote_protocol.x | 24 ++-
src/util/virterror.c | 6 +
.../qemu-simple-description-title.xml | 27 ++
tests/qemuxml2argvdata/qemuxml2argv-minimal.xml | 5 +
tools/virsh.c | 283 ++++++++++++++++++--
tools/virsh.pod | 34 +++-
17 files changed, 787 insertions(+), 23 deletions(-)
create mode 100644 tests/domainschemadata/qemu-simple-description-title.xml
--
1.7.3.4
12 years, 9 months