Re: [libvirt] [libvirt-java] [PATCH 00/12] event support
by Stefan Majer
Hi,
back in January 2013 Claudio Bley submit a series of patches [1] to enable
event support to libvirt-java.
There was no response on his work and they didn't get merged.
Probably because there was not enough need out there.
But i would like to see this merged and had some conversion with Claudio
the last 2 weeks, i tested his work and can confirm it works. I have some
small additional, mostly cosmetic patches on top, but i would like to get
feedback from the list if there is a chance to get them merged.
So any comments and suggestions welcome !
Greetings
--
Stefan Majer
[1] http://www.redhat.com/archives/libvir-list/2013-January/msg01236.html
11 years, 6 months
[libvirt] [libvirt PATCH] storage: Skip not active lv volumes
by Osier Yang
If the volume is of a clustered volume group, and not active, the
related pool APIs fails on open /dev/vg/lv. If the volume is suspended,
it hangs on open(2) the volume.
Though the best solution is to expose the volume status in volume
XML, and even better to provide API to active/deactive the volume,
but it's not the work I want to touch currently. Volume status in
other status is just fine to skip.
About the 5th field of lv_attr (from man lvs[8])
<quote>
5 State: (a)ctive, (s)uspended, (I)nvalid snapshot, invalid
(S)uspended snapshot, snapshot (m)erge failed,suspended
snapshot (M)erge failed, mapped (d)evice present without
tables, mapped device present with (i)nactive table
</quote>
---
src/storage/storage_backend_logical.c | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c
index 316043f..c5f09cb 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -78,6 +78,11 @@ virStorageBackendLogicalMakeVol(virStoragePoolObjPtr pool,
regmatch_t *vars = NULL;
char *p = NULL;
int i, err, nextents, nvars, ret = -1;
+ const char *attrs = groups[9];
+
+ /* Skip not active volume */
+ if (attrs[4] != 'a')
+ return 0;
/* See if we're only looking for a specific volume */
if (data != NULL) {
@@ -280,14 +285,17 @@ virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool,
virStorageVolDefPtr vol)
{
/*
- * # lvs --separator , --noheadings --units b --unbuffered --nosuffix --options "lv_name,origin,uuid,devices,seg_size,vg_extent_size,size" VGNAME
- * RootLV,,06UgP5-2rhb-w3Bo-3mdR-WeoL-pytO-SAa2ky,/dev/hda2(0),5234491392,33554432,5234491392
- * SwapLV,,oHviCK-8Ik0-paqS-V20c-nkhY-Bm1e-zgzU0M,/dev/hda2(156),1040187392,33554432,1040187392
- * Test2,,3pg3he-mQsA-5Sui-h0i6-HNmc-Cz7W-QSndcR,/dev/hda2(219),1073741824,33554432,1073741824
- * Test3,,UB5hFw-kmlm-LSoX-EI1t-ioVd-h7GL-M0W8Ht,/dev/hda2(251),2181038080,33554432,2181038080
- * Test3,Test2,UB5hFw-kmlm-LSoX-EI1t-ioVd-h7GL-M0W8Ht,/dev/hda2(187),1040187392,33554432,1040187392
+ * # lvs --separator , --noheadings --units b --unbuffered --nosuffix --options \
+ * "lv_name,origin,uuid,devices,seg_size,vg_extent_size,size,lv_attr" VGNAME
+ *
+ * RootLV,,06UgP5-2rhb-w3Bo-3mdR-WeoL-pytO-SAa2ky,/dev/hda2(0),5234491392,33554432,5234491392,-wi-ao
+ * SwapLV,,oHviCK-8Ik0-paqS-V20c-nkhY-Bm1e-zgzU0M,/dev/hda2(156),1040187392,33554432,1040187392,-wi-ao
+ * Test2,,3pg3he-mQsA-5Sui-h0i6-HNmc-Cz7W-QSndcR,/dev/hda2(219),1073741824,33554432,1073741824,owi-a-
+ * Test3,,UB5hFw-kmlm-LSoX-EI1t-ioVd-h7GL-M0W8Ht,/dev/hda2(251),2181038080,33554432,2181038080,-wi-a-
+ * Test3,Test2,UB5hFw-kmlm-LSoX-EI1t-ioVd-h7GL-M0W8Ht,/dev/hda2(187),1040187392,33554432,1040187392,swi-a-
*
- * Pull out name, origin, & uuid, device, device extent start #, segment size, extent size.
+ * Pull out name, origin, & uuid, device, device extent start #,
+ * segment size, extent size, size, attrs
*
* NB can be multiple rows per volume if they have many extents
*
@@ -299,10 +307,10 @@ virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool,
* striped, so "," is not a suitable separator either (rhbz 727474).
*/
const char *regexes[] = {
- "^\\s*(\\S+)#(\\S*)#(\\S+)#(\\S+)#(\\S+)#([0-9]+)#(\\S+)#([0-9]+)#([0-9]+)#?\\s*$"
+ "^\\s*(\\S+)#(\\S*)#(\\S+)#(\\S+)#(\\S+)#([0-9]+)#(\\S+)#([0-9]+)#([0-9]+)#(\\S+)#?\\s*$"
};
int vars[] = {
- 9
+ 10
};
int ret = -1;
virCommandPtr cmd;
@@ -313,7 +321,8 @@ virStorageBackendLogicalFindLVs(virStoragePoolObjPtr pool,
"--units", "b",
"--unbuffered",
"--nosuffix",
- "--options", "lv_name,origin,uuid,devices,segtype,stripes,seg_size,vg_extent_size,size",
+ "--options",
+ "lv_name,origin,uuid,devices,segtype,stripes,seg_size,vg_extent_size,size,lv_attr",
pool->def->source.name,
NULL);
if (virStorageBackendRunProgRegex(pool,
--
1.8.1.4
11 years, 6 months
Re: [libvirt] [libvirt-users] libvirt-snmp on Ubuntu
by george john
Thank you.
I was able to compile/install libvirt-snmp on Ubuntu by mainly following the instructions on:
http://lost-and-found-narihiro.blogspot.com/2013/01/how-to-install-libvir...
When I check the data returned by snmpwalk, I find that values for the UUID of the Virtual Guest, libvirtGuestUUID(1.3.6.1.4.1.12345.1.1.1.1) are not getting populated. This is a key piece of information. Does anyone know why this is not being populated?
Also I noticed that the value returned by libvirtGuestMemoryCurrent (current memory usage by VirtualGuest) is not the correct value. The value returned by this is same as libvirtGuestMemoryLimit (The maximum amount of memory (in MiB) that can be used by the virtual guest.).
Thanks.
--- On Thu, 5/2/13, Eric Blake <eblake(a)redhat.com> wrote:
> From: Eric Blake <eblake(a)redhat.com>
> Subject: Re: [libvirt-users] libvirt-snmp on Ubuntu
> To: "george john" <simplyjoe13(a)yahoo.com>
> Cc: "Michal Privoznik" <mprivozn(a)redhat.com>, libvirt-users(a)redhat.com
> Date: Thursday, May 2, 2013, 9:00 AM
> On 05/02/2013 09:45 AM, george john
> wrote:
> > Thank you Michal. I verified the binary rpmbuild exists
> at /usr/bin/rpmbuild and ran autobuild but it failed
> with these errors:
> >
>
> >
> > ../autogen.sh --prefix=$AUTOBUILD_INSTALL_ROOT \
> > --with-mibdir=$MIBDIR
> > Can't exec "libtoolize": No such file or directory at
> /usr/bin/autoreconf line 196.
> > Use of uninitialized value in pattern match (m//) at
> /usr/bin/autoreconf line 196.
>
> Do you have libtool properly installed?
>
> > checking return type of signal handlers... void
> > ../configure: line 4433: syntax error near unexpected
> token `LIBVIRT,'
> > ../configure: line 4433: `PKG_CHECK_MODULES(LIBVIRT,
> libvirt >= $LIBVIRT_REQUIRED)'
> > root@nv-kvm02:/tmp/libvirt-snmp-0.0.3#
>
> Are you sure you have pkg-config properly installed?
>
> --
> Eric Blake eblake redhat com
> +1-919-301-3266
> Libvirt virtualization library http://libvirt.org
>
>
11 years, 6 months
[libvirt] [PATCH-v5.1] Support for static routes on a virtual bridge
by Gene Czarcinski
network: static route support for <network>
This update includes Laine Stump's comments/suggestions. Once
again he has improved my over-engineered solutions. My original
patch and his patch have been squashed/merged with this being the
result. That plus a little simplified code added to
bridge_driver.c to handle the zero address situations.
This code does not restrict any combination of
address/netmask/prefix for a static route specification. The
metric attribute has been added so that existing route specifications
can be overridden.
Documentation has been updated to reflect a v1.0.6 target.
This patch adds the <route> subelement of <network> to define a static
route. the address and prefix (or netmask) attribute identify the
destination network, and the gateway attribute specifies the next hop
address (which must be directly reachable from the containing
<network>) which is to receive the packets destined for
"address/(prefix|netmask)".
Tests are done to validate that the input definitions are
correct. For example, for a static route ip definition,
the address must be a network address and not a host address.
Additional checks are added to ensure that the specified gateway
is directly reachable via a network defined on this bridge.
The command used is of the following form:
ip route add <address>/<prefix> via <gateway> dev <virbr-bridge> \
proto static metric 1
For family='ipv4' address='0.0.0.0' netmask='0.0.0.0' or prefix='0' is
supported.
For family='ipv6' address='::' prefix=0' is supported.
Anytime an attempt is made to define a static route which duplicates
an existing static route (for example, address=::, prefix=0, metric=1),
the following error message will be sent to syslog:
RTNETLINK answers: File exists
This can be overridden by increasing the value of metric. Caution should
be used when doing this ... especially for a default route.
Note: The use of the command-line interface should be replaced by
direct use of libnl so that error conditions can be handled better. But,
that is being left as an exersize for another day.
.
Signed-off-by: Gene Czarcinski <gene(a)czarc.net>
---
docs/formatnetwork.html.in | 77 +++++
docs/schemas/network.rng | 22 ++
src/conf/network_conf.c | 340 ++++++++++++++++++++-
src/conf/network_conf.h | 22 ++
src/libvirt_private.syms | 1 +
src/network/bridge_driver.c | 64 ++++
src/util/virnetdev.c | 46 +++
src/util/virnetdev.h | 7 +
.../networkxml2xmlin/dhcp6host-routed-network.xml | 2 +
.../networkxml2xmlout/dhcp6host-routed-network.xml | 2 +
10 files changed, 582 insertions(+), 1 deletion(-)
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index d72bd0a..4c7e74f 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -546,6 +546,56 @@
starting.
</p>
+ <h5><a name="elementsStaticroute">Static Routes</a></h5>
+ <p>
+ Static route definitions are used to provide routing
+ information to the virtualization host for networks which are not
+ defined as a network on one of the virtual bridges so that such
+ networks can be reachable from the virtualization
+ host <span class="since">Since 1.0.6</span>.
+ </p>
+
+ <p>
+ As shown in <a href="formatnetwork.html#examplesNoGateway">this example</a>,
+ it is possible to define a virtual bridge interface with no
+ IPv4 or IPv6 networks. Such interfaces are useful in supporting
+ networks which have no visibility or direct connectivity with the
+ virtualization host, but can be used to support
+ virtual networks which only have guest connectivity. A guest
+ with connectivity to the guest-only network and another network
+ that is directly reachable from the host can act as a gateway between the
+ networks. A static route added to the "visible" network definition
+ provides the routing information so that IP packets can be sent
+ from the virtualization host to guests on the hidden network.
+ </p>
+
+ <p>
+ Here is a fragment of a definition which shows the static
+ route specification as well as the IPv4 and IPv6 definitions
+ for network addresses which are referred to in the
+ <code>gateway</code> gateway address specifications. Note
+ that the third static route specification includes the
+ <code>metric</code> attribute specification with a value of 2.
+ This indicates that this particular definition is overriding another
+ route definition with the same address and prefix but with a lower
+ value for the metric.
+ </p>
+
+ <pre>
+ ...
+ <ip address="192.168.122.1" netmask="255.255.255.0">
+ <dhcp>
+ <range start="192.168.122.128" end="192.168.122.254" />
+ </dhcp>
+ </ip>
+ <route address="192.168.222.0" prefix="24" gateway="192.168.122.2" />
+ <ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" />
+ <route family="ipv6" address="2001:db8:ca2:3::" prefix="64" gateway="2001:db8:ca2:2::2"/>
+ <route family="ipv6" address="2001:db9:4:1::" prefix="64" gateway="2001:db8:ca2:2::3" metric='2'>
+ </route>
+ ...
+ </pre>
+
<h3><a name="elementsAddress">Addressing</a></h3>
<p>
@@ -577,6 +627,7 @@
</dhcp>
</ip>
<ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" />
+ <route family="ipv6" address="2001:db9:ca1:1::" prefix="64" gateway="2001:db8:ca2:2::2" />
</network></pre>
<dl>
@@ -826,6 +877,32 @@
</ip>
</network></pre>
+ <p>
+ Below is yet another IPv6 variation. This variation has only IPv6
+ defined with DHCPv6 on the primary IPv6 network. A static link
+ if defined for a second IPv6 network which will not be visable on
+ the bridge interface but will have a static route defined for this
+ network via the specified gateway. Note that the gateway address
+ must be directly reachable via (on the same subnet as) one of the
+ <ip> addresses defined for this <network>.
+ <span class="since">Since 1.0.5</span>
+ </p>
+
+ <pre>
+ <network>
+ <name>net7</name>
+ <bridge name="virbr7" />
+ <forward mode="route"/>
+ <ip family="ipv6" address="2001:db8:ca2:7::1" prefix="64" >
+ <dhcp>
+ <range start="2001:db8:ca2:7::100" end="2001:db8:ca2::1ff" />
+ <host id="0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63" name="lucas" ip="2001:db8:ca2:2:3::4" />
+ </dhcp>
+ </ip>
+ <route family="ipv6" address="2001:db8:ca2:8::" prefix="64" gateway="2001:db8:ca2:7::4" >
+ </route>
+ </network></pre>
+
<h3><a name="examplesPrivate">Isolated network config</a></h3>
<p>
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 493edae..ded8580 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -316,6 +316,28 @@
</optional>
</element>
</zeroOrMore>
+ <!-- <route> element -->
+ <zeroOrMore>
+ <!-- The (static) route element specifies a network address and gateway
+ address to access that network. Both the network address and
+ the gateway address must be specified. -->
+ <element name="route">
+ <optional>
+ <attribute name="family"><ref name="addr-family"/></attribute>
+ </optional>
+ <attribute name="address"><ref name="ipAddr"/></attribute>
+ <optional>
+ <choice>
+ <attribute name="netmask"><ref name="ipv4Addr"/></attribute>
+ <attribute name="prefix"><ref name="ipPrefix"/></attribute>
+ </choice>
+ </optional>
+ <attribute name="gateway"><ref name="ipAddr"/></attribute>
+ <optional>
+ <attribute name="metric"><ref name="unsignedInt"/></attribute>
+ </optional>
+ </element>
+ </zeroOrMore>
</interleave>
</element>
</define>
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 8abfa53..12ac879 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -143,6 +143,12 @@ virNetworkIpDefClear(virNetworkIpDefPtr def)
}
static void
+virNetworkRouteDefClear(virNetworkRouteDefPtr def)
+{
+ VIR_FREE(def->family);
+}
+
+static void
virNetworkDNSTxtDefClear(virNetworkDNSTxtDefPtr def)
{
VIR_FREE(def->name);
@@ -221,6 +227,11 @@ virNetworkDefFree(virNetworkDefPtr def)
}
VIR_FREE(def->ips);
+ for (ii = 0 ; ii < def->nroutes && def->routes ; ii++) {
+ virNetworkRouteDefClear(&def->routes[ii]);
+ }
+ VIR_FREE(def->routes);
+
for (ii = 0; ii < def->nPortGroups && def->portGroups; ii++) {
virPortGroupDefClear(&def->portGroups[ii]);
}
@@ -1270,6 +1281,219 @@ cleanup:
}
static int
+virNetworkRouteDefParseXML(const char *networkName,
+ xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ virNetworkRouteDefPtr def)
+{
+ /*
+ * virNetworkRouteDef object is already allocated as part
+ * of an array. On failure clear: it out, but don't free it.
+ */
+
+ xmlNodePtr save;
+ char *address = NULL, *netmask = NULL;
+ char *gateway = NULL;
+ unsigned long prefix = 0, metric = 0;
+ int result = -1;
+ int prefixRc, metricRc;
+ virSocketAddr testAddr;
+
+ save = ctxt->node;
+ ctxt->node = node;
+
+ /* grab raw data from XML */
+ def->family = virXPathString("string(./@family)", ctxt);
+ address = virXPathString("string(./@address)", ctxt);
+ netmask = virXPathString("string(./@netmask)", ctxt);
+ gateway = virXPathString("string(./@gateway)", ctxt);
+ prefixRc = virXPathULong("string(./@prefix)", ctxt, &prefix);
+ if (prefixRc == -2) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid prefix specified "
+ "in route definition of network '%s'"),
+ networkName);
+ goto cleanup;
+ }
+ def->has_prefix = (prefixRc == 0);
+ def->prefix = prefix;
+ metricRc = virXPathULong("string(./@metric)", ctxt, &metric);
+ if (metricRc == -2) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid metric specified "
+ "in route definition of network '%s'"),
+ networkName);
+ goto cleanup;
+ }
+ def->has_metric = (metricRc == 0);
+ def->metric = metric;
+
+ /* Note: both network and gateway addresses must be specified */
+
+ if (!address) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Missing required address attribute "
+ "in route definition of network '%s'"),
+ networkName);
+ goto cleanup;
+ }
+
+ if (!gateway) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Missing required gateway attribute "
+ "in route definition of network '%s'"),
+ networkName);
+ goto cleanup;
+ }
+
+ if (virSocketAddrParse(&def->address, address, AF_UNSPEC) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Bad network address '%s' "
+ "in route definition of network '%s'"),
+ address, networkName);
+ goto cleanup;
+ }
+
+ if (virSocketAddrParse(&def->gateway, gateway, AF_UNSPEC) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Bad gateway address '%s' "
+ "in route definition of network '%s'"),
+ gateway, networkName);
+ goto cleanup;
+ }
+
+ /* validate network address, etc. for each family */
+ if ((def->family == NULL) || (STREQ(def->family, "ipv4"))) {
+ if (!(VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) ||
+ VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_UNSPEC))) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("%s family specified for non-IPv4 address '%s' "
+ "in route definition of network '%s'"),
+ def->family == NULL? "no" : "ipv4",
+ address, networkName);
+ goto cleanup;
+ }
+ if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("%s family specified for non-IPv4 gateway '%s' "
+ "in route definition of network '%s'"),
+ def->family == NULL? "no" : "ipv4",
+ address, networkName);
+ goto cleanup;
+ }
+ if (netmask) {
+ if (virSocketAddrParse(&def->netmask, netmask, AF_UNSPEC) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Bad netmask address '%s' "
+ "in route definition of network '%s'"),
+ netmask, networkName);
+ goto cleanup;
+ }
+ if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->netmask, AF_INET)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("network '%s' has invalid netmask '%s' "
+ "for address '%s' (both must be IPv4)"),
+ networkName, netmask, address);
+ goto cleanup;
+ }
+ if (def->has_prefix) {
+ /* can't have both netmask and prefix at the same time */
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("route definition '%s' cannot have both "
+ "a prefix and a netmask"),
+ networkName);
+ goto cleanup;
+ }
+ }
+ if (def->prefix > 32) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Invalid IPv4 prefix %u for '%s' specified "
+ "in route definition of network '%s'"),
+ def->prefix,
+ def->family == NULL? "no" : "ipv4", networkName);
+ goto cleanup;
+ }
+ } else if (STREQ(def->family, "ipv6")) {
+ if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("ipv6 family specified for non-IPv6 address '%s' "
+ "in route definition of network '%s'"),
+ address, networkName);
+ goto cleanup;
+ }
+ if (netmask) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("specifying netmask invalid for IPv6 address '%s' "
+ "in route definition of network '%s'"),
+ address, networkName);
+ goto cleanup;
+ }
+ if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET6)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("ipv6 specified for non-IPv6 gateway address '%s' "
+ "in route definition of network '%s'"),
+ gateway, networkName);
+ goto cleanup;
+ }
+ if (def->prefix > 128) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Invalid IPv6 prefix %u for '%s' specified "
+ "in route definition of network '%s'"),
+ def->prefix, def->family, networkName);
+ goto cleanup;
+ }
+ } else {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Unrecognized family '%s' "
+ "in route definition of network'%s'"),
+ def->family, networkName);
+ goto cleanup;
+ }
+
+ /* make sure the address is a network address */
+ if (netmask) {
+ if (virSocketAddrMask(&def->address, &def->netmask, &testAddr) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("error converting address '%s' with netmask '%s' "
+ "to network-address "
+ "in route definition of network '%s'"),
+ address, netmask, networkName);
+ goto cleanup;
+ }
+ } else {
+ if (virSocketAddrMaskByPrefix(&def->address,
+ def->prefix, &testAddr) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("error converting address '%s' with prefix %u "
+ "to network-address "
+ "in route definition of network '%s'"),
+ address, def->prefix, networkName);
+ goto cleanup;
+ }
+ }
+ if (!virSocketAddrEqual(&def->address, &testAddr)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("address '%s' in route definition of network '%s' "
+ "is not a network address"),
+ address, networkName);
+ goto cleanup;
+ }
+
+ result = 0;
+
+cleanup:
+ if (result < 0) {
+ virNetworkRouteDefClear(def);
+ }
+ VIR_FREE(address);
+ VIR_FREE(netmask);
+ VIR_FREE(gateway);
+
+ ctxt->node = save;
+ return result;
+}
+
+static int
virNetworkPortGroupParseXML(virPortGroupDefPtr def,
xmlNodePtr node,
xmlXPathContextPtr ctxt)
@@ -1684,8 +1908,9 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
char *tmp;
char *stp = NULL;
xmlNodePtr *ipNodes = NULL;
+ xmlNodePtr *routeNodes = NULL;
xmlNodePtr *portGroupNodes = NULL;
- int nIps, nPortGroups;
+ int nIps, nPortGroups, nRoutes;
xmlNodePtr dnsNode = NULL;
xmlNodePtr virtPortNode = NULL;
xmlNodePtr forwardNode = NULL;
@@ -1839,6 +2064,68 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
}
VIR_FREE(ipNodes);
+ nRoutes = virXPathNodeSet("./route", ctxt, &routeNodes);
+ if (nRoutes < 0)
+ goto error;
+
+ if (nRoutes > 0) {
+ int ii;
+
+ /* allocate array to hold all the route definitions */
+ if (VIR_ALLOC_N(def->routes, nRoutes) < 0) {
+ virReportOOMError();
+ goto error;
+ }
+ /* parse each definition */
+ for (ii = 0; ii < nRoutes; ii++) {
+ int ret = virNetworkRouteDefParseXML(def->name, routeNodes[ii],
+ ctxt, &def->routes[ii]);
+ if (ret < 0)
+ goto error;
+ def->nroutes++;
+ }
+
+ /* now validate the correctness of any static route gateways specified
+ *
+ * note: the parameters within each definition are verified/assumed valid;
+ * the question being asked and answered here is if the specified gateway
+ * is directly reachable from this bridge.
+ */
+ nRoutes = def->nroutes;
+ nIps = def->nips;
+ for (ii = 0; ii < nRoutes; ii++) {
+ int jj;
+ virSocketAddr testAddr, testGw;
+ bool addrMatch;
+ virNetworkRouteDefPtr gwdef = &def->routes[ii];
+ addrMatch = false;
+ for (jj = 0; jj < nIps; jj++) {
+ virNetworkIpDefPtr def2 = &def->ips[jj];
+ if (VIR_SOCKET_ADDR_FAMILY(&gwdef->gateway)
+ != VIR_SOCKET_ADDR_FAMILY(&def2->address)) {
+ continue;
+ }
+ int prefix = virNetworkIpDefPrefix(def2);
+ virSocketAddrMaskByPrefix(&def2->address, prefix, &testAddr);
+ virSocketAddrMaskByPrefix(&gwdef->gateway, prefix, &testGw);
+ if (VIR_SOCKET_ADDR_VALID(&testAddr) &&
+ VIR_SOCKET_ADDR_VALID(&testGw) &&
+ virSocketAddrEqual(&testAddr, &testGw)) {
+ addrMatch = true;
+ break;
+ }
+ }
+ if (!addrMatch) {
+ char *gw = virSocketAddrFormat(&gwdef->gateway);
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unreachable static route gateway '%s' specified for network '%s'"),
+ gw, def->name);
+ VIR_FREE(gw);
+ goto error;
+ }
+ }
+ }
+
forwardNode = virXPathNode("./forward", ctxt);
if (forwardNode &&
virNetworkForwardDefParseXML(def->name, forwardNode, ctxt, &def->forward) < 0) {
@@ -1911,6 +2198,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
return def;
error:
+ VIR_FREE(routeNodes);
VIR_FREE(stp);
virNetworkDefFree(def);
VIR_FREE(ipNodes);
@@ -2136,6 +2424,51 @@ error:
}
static int
+virNetworkRouteDefFormat(virBufferPtr buf,
+ const virNetworkRouteDefPtr def)
+{
+ int result = -1;
+
+ virBufferAddLit(buf, "<route");
+
+ if (def->family) {
+ virBufferAsprintf(buf, " family='%s'", def->family);
+ }
+ if (VIR_SOCKET_ADDR_VALID(&def->address)) {
+ char *addr = virSocketAddrFormat(&def->address);
+ if (!addr)
+ goto error;
+ virBufferAsprintf(buf, " address='%s'", addr);
+ VIR_FREE(addr);
+ }
+ if (VIR_SOCKET_ADDR_VALID(&def->netmask)) {
+ char *addr = virSocketAddrFormat(&def->netmask);
+ if (!addr)
+ goto error;
+ virBufferAsprintf(buf, " netmask='%s'", addr);
+ VIR_FREE(addr);
+ }
+ if (def->has_prefix) {
+ virBufferAsprintf(buf," prefix='%u'", def->prefix);
+ }
+ if (VIR_SOCKET_ADDR_VALID(&def->gateway)) {
+ char *addr = virSocketAddrFormat(&def->gateway);
+ if (!addr)
+ goto error;
+ virBufferAsprintf(buf, " gateway='%s'", addr);
+ VIR_FREE(addr);
+ }
+ if (def->has_metric && def->metric > 0) {
+ virBufferAsprintf(buf," metric='%u'", def->metric);
+ }
+ virBufferAddLit(buf, "/>\n");
+
+ result = 0;
+error:
+ return result;
+}
+
+static int
virPortGroupDefFormat(virBufferPtr buf,
const virPortGroupDefPtr def)
{
@@ -2347,6 +2680,11 @@ virNetworkDefFormatInternal(virBufferPtr buf,
goto error;
}
+ for (ii = 0; ii < def->nroutes; ii++) {
+ if (virNetworkRouteDefFormat(buf, &def->routes[ii]) < 0)
+ goto error;
+ }
+
if (virNetDevVPortProfileFormat(def->virtPortProfile, buf) < 0)
goto error;
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index e187f05..43f80d4 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -149,6 +149,25 @@ struct _virNetworkIpDef {
virSocketAddr bootserver;
};
+typedef struct _virNetworkRouteDef virNetworkRouteDef;
+typedef virNetworkRouteDef *virNetworkRouteDefPtr;
+struct _virNetworkRouteDef {
+ char *family; /* ipv4 or ipv6 - default is ipv4 */
+ virSocketAddr address; /* Routed Network IP address */
+
+ /* One or the other of the following two will be used for a given
+ * Network address, but never both. The parser guarantees this.
+ * The virSocketAddrGetIpPrefix() can be used to get a
+ * valid prefix.
+ */
+ virSocketAddr netmask; /* ipv4 - either netmask or prefix specified */
+ unsigned int prefix; /* ipv6 - only prefix allowed */
+ bool has_prefix; /* prefix= was specified */
+ unsigned int metric; /* value for metric (defaults to 1) */
+ bool has_metric; /* metric= was specified */
+ virSocketAddr gateway; /* gateway IP address for ip-route */
+ };
+
typedef struct _virNetworkForwardIfDef virNetworkForwardIfDef;
typedef virNetworkForwardIfDef *virNetworkForwardIfDefPtr;
struct _virNetworkForwardIfDef {
@@ -224,6 +243,9 @@ struct _virNetworkDef {
size_t nips;
virNetworkIpDefPtr ips; /* ptr to array of IP addresses on this network */
+ size_t nroutes;
+ virNetworkRouteDefPtr routes; /* ptr to array of static routes on this interface */
+
virNetworkDNSDef dns; /* dns related configuration */
virNetDevVPortProfilePtr virtPortProfile;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d4cb4a3..dfa4779 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1463,6 +1463,7 @@ virMacAddrSetRaw;
# util/virnetdev.h
+virNetDevAddRoute;
virNetDevClearIPv4Address;
virNetDevExists;
virNetDevGetIndex;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 9c5a8ae..4392e20 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2391,6 +2391,7 @@ out:
return ret;
}
+/* add an IP address to a bridge */
static int
networkAddAddrToBridge(virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
@@ -2411,6 +2412,55 @@ networkAddAddrToBridge(virNetworkObjPtr network,
return 0;
}
+/* add an IP (static) route to a bridge */
+static int
+networkAddRouteToBridge(virNetworkObjPtr network,
+ virNetworkRouteDefPtr routedef)
+{
+ int prefix = 0;
+ unsigned int metric;
+ virSocketAddrPtr addr = &routedef->address;
+ virSocketAddrPtr mask = &routedef->netmask;
+ virSocketAddr zero;
+
+ /* this creates an all-0 address of the appropriate family */
+ ignore_value(virSocketAddrParse(&zero,
+ (VIR_SOCKET_ADDR_IS_FAMILY(addr,AF_INET)
+ ? "0.0.0.0" : "::"),
+ VIR_SOCKET_ADDR_FAMILY(addr)));
+
+ if (virSocketAddrEqual(addr, &zero)) {
+ if (routedef->has_prefix && routedef->prefix == 0)
+ prefix = 0;
+ else if ((VIR_SOCKET_ADDR_IS_FAMILY(mask, AF_INET) &&
+ virSocketAddrEqual(mask, &zero)))
+ prefix = 0;
+ else
+ prefix = virSocketAddrGetIpPrefix(addr, mask, routedef->prefix);
+ } else {
+ prefix = virSocketAddrGetIpPrefix(addr, mask, routedef->prefix);
+ }
+
+ if (prefix < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("network '%s' has an invalid netmask "
+ "or IP address in route definition"),
+ network->def->name);
+ return -1;
+ }
+
+ if (routedef->has_metric && routedef->metric > 0)
+ metric = routedef->metric;
+ else
+ metric = 1;
+
+ if (virNetDevAddRoute(network->def->bridge, &routedef->address,
+ prefix, &routedef->gateway, metric) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
static int
networkStartNetworkVirtual(struct network_driver *driver,
virNetworkObjPtr network)
@@ -2419,6 +2469,7 @@ networkStartNetworkVirtual(struct network_driver *driver,
bool v4present = false, v6present = false;
virErrorPtr save_err = NULL;
virNetworkIpDefPtr ipdef;
+ virNetworkRouteDefPtr routedef;
char *macTapIfName = NULL;
int tapfd = -1;
@@ -2495,6 +2546,19 @@ networkStartNetworkVirtual(struct network_driver *driver,
if (virNetDevSetOnline(network->def->bridge, 1) < 0)
goto err2;
+ for (ii = 0; ii < network->def->nroutes; ii++) {
+ routedef = &network->def->routes[ii];
+ /* Add the IP route to the bridge */
+ /* ignore errors, error msg will be generated */
+ /* but libvirt will not know and net-destroy will work. */
+ if (VIR_SOCKET_ADDR_VALID(&routedef->gateway)) {
+ if (networkAddRouteToBridge(network, routedef) < 0) {
+ /* an error occurred adding the static route */
+ continue; /* for now, do nothing */
+ }
+ }
+ }
+
/* If forward.type != NONE, turn on global IP forwarding */
if (network->def->forward.type != VIR_NETWORK_FORWARD_NONE &&
networkEnableIpForwarding(v4present, v6present) < 0) {
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index d987b8e..01aaff1 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -783,6 +783,52 @@ cleanup:
}
/**
+ * virNetDevSetGateway:
+ * @ifname: the interface name
+ * @addr: the IP network address (IPv4 or IPv6)
+ * @prefix: number of 1 bits in the netmask
+ * @gateway: via address for route (same as @addr)
+ *
+ * Add a route for a network IP address to an interface. This function
+ * *does not* remove any previously added IP static routes.
+ *
+ * Returns 0 in case of success or -1 in case of error.
+ */
+
+int
+virNetDevAddRoute(const char *ifname,
+ virSocketAddrPtr addr,
+ unsigned int prefix,
+ virSocketAddrPtr gateway,
+ unsigned int metric)
+{
+ virCommandPtr cmd = NULL;
+ char *addrstr = NULL, *gatewaystr = NULL;
+ int ret = -1;
+
+ if (!(addrstr = virSocketAddrFormat(addr)))
+ goto cleanup;
+ if (!(gatewaystr = virSocketAddrFormat(gateway)))
+ goto cleanup;
+ cmd = virCommandNew(IP_PATH);
+ virCommandAddArgList(cmd, "route", "add", NULL);
+ virCommandAddArgFormat(cmd, "%s/%u", addrstr, prefix);
+ virCommandAddArgList(cmd, "via", gatewaystr, "dev", ifname,
+ "proto", "static", "metric", NULL);
+ virCommandAddArgFormat(cmd, "%u", metric);
+
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+
+ ret = 0;
+cleanup:
+ VIR_FREE(addrstr);
+ VIR_FREE(gatewaystr);
+ virCommandFree(cmd);
+ return ret;
+}
+
+/**
* virNetDevClearIPv4Address:
* @ifname: the interface name
* @addr: the IP address (IPv4 or IPv6)
diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h
index 551ea22..0b394ad 100644
--- a/src/util/virnetdev.h
+++ b/src/util/virnetdev.h
@@ -42,6 +42,13 @@ int virNetDevSetIPv4Address(const char *ifname,
virSocketAddr *addr,
unsigned int prefix)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
+int virNetDevAddRoute(const char *ifname,
+ virSocketAddrPtr addr,
+ unsigned int prefix,
+ virSocketAddrPtr gateway,
+ unsigned int metric)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4)
+ ATTRIBUTE_NONNULL(5) ATTRIBUTE_RETURN_CHECK;
int virNetDevClearIPv4Address(const char *ifname,
virSocketAddr *addr,
unsigned int prefix)
diff --git a/tests/networkxml2xmlin/dhcp6host-routed-network.xml b/tests/networkxml2xmlin/dhcp6host-routed-network.xml
index 2693d87..40f6dfe 100644
--- a/tests/networkxml2xmlin/dhcp6host-routed-network.xml
+++ b/tests/networkxml2xmlin/dhcp6host-routed-network.xml
@@ -19,4 +19,6 @@
<host id='0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66' name='badbob' ip='2001:db8:ac10:fd01::1:24' />
</dhcp>
</ip>
+ <route address="192.168.222.0" netmask="255.255.255.0" gateway="192.168.122.10"/>
+ <route family="ipv6" address="2001:db8:ac10:fc00::" prefix="64" gateway="2001:db8:ac10:fd01::1:24"/>
</network>
diff --git a/tests/networkxml2xmlout/dhcp6host-routed-network.xml b/tests/networkxml2xmlout/dhcp6host-routed-network.xml
index 1d3035b..fc8666b 100644
--- a/tests/networkxml2xmlout/dhcp6host-routed-network.xml
+++ b/tests/networkxml2xmlout/dhcp6host-routed-network.xml
@@ -21,4 +21,6 @@
<host id='0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66' name='badbob' ip='2001:db8:ac10:fd01::1:24' />
</dhcp>
</ip>
+ <route address='192.168.222.0' netmask='255.255.255.0' gateway='192.168.122.10'/>
+ <route family='ipv6' address='2001:db8:ac10:fc00::' prefix='64' gateway='2001:db8:ac10:fd01::1:24'/>
</network>
--
1.8.1.4
11 years, 6 months
[libvirt] [PATCH] qemu: allocate network connections sooner during domain startup
by Laine Stump
VFIO device assignment requires a cgroup ACL to be setup for access to
the /dev/vfio/nn "group" device for any devices that will be assigned
to a guest. In the case of a host device that is allocated from a
pool, it was being allocated during qemuBuildCommandLine(), which is
called by qemuProcessStart() *after* the all-encompassing
qemuSetupCgroup() is called, meaning that the standard Cgroup ACL
setup wasn't catching these devices allocated from pools.
One possible solution was to manually add a single ACL down inside
qemuBuildCommandLine() when networkAllocateActualDevice() is called,
but that has two problems: 1) the function that adds the cgroup ACL
requires a virDomainObjPtr, which isn't available in
qemuBuildCommandLine(), and 2) we really shouldn't be doing network
device setup inside qemuBuildCommandLine() anyway.
Instead, I've created a new function called
qemuNetworkPrepareDevices() which is called just before
qemuPrepareHostDevices() during qemuProcessStart() (explanation of
ordering in the comments), i.e. well before the call to
qemuSetupCgroup(). To minimize code churn in a patch that will be
backported to 1.0.5-maint, qemuNetworkPrepareDevices only does
networkAllocateActualDevice() and the bare amount of setup required
for type='hostdev network devices.
Note that some of the code that was previously needed in
qemuBuildCommandLine() is no longer required when
networkAllocateActualDevice() is called earlier:
* qemuAssignDeviceHostdevAlias() is already done further down in
qemuProcessStart().
* qemuPrepareHostdevPCIDevices() is called by
qemuPrepareHostDevices() which is called after
qemuNetworkPrepareDevices() in qemuProcessStart().
This new function should be moved into a separate qemu_network.c (or
similarly named) file along with qemuPhysIfaceConnect(),
qemuNetworkIfaceConnect(), and qemuOpenVhostNet(), and expanded to call
those functions as well, then the nnets loop in qemuBuildCommandLine() should
be reduced to only build the commandline string. However, this will
require storing away an array of tapfd and vhostfd that are needed
for the commandline, so I would rather do that in a separate patch and
leave this patch at the minimum to fix the bug.
---
src/qemu/qemu_command.c | 104 ++++++++++++++++++++++++++----------------------
src/qemu/qemu_command.h | 4 +-
src/qemu/qemu_process.c | 8 ++++
3 files changed, 67 insertions(+), 49 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 144620c..5ce97e8 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -457,6 +457,58 @@ qemuOpenVhostNet(virDomainDefPtr def,
return 0;
}
+int
+qemuNetworkPrepareDevices(virDomainDefPtr def)
+{
+ int ret = -1;
+ int ii;
+
+ for (ii = 0; ii < def->nnets; ii++) {
+ virDomainNetDefPtr net = def->nets[ii];
+ int actualType;
+
+ /* If appropriate, grab a physical device from the configured
+ * network's pool of devices, or resolve bridge device name
+ * to the one defined in the network definition.
+ */
+ if (networkAllocateActualDevice(net) < 0)
+ goto cleanup;
+
+ actualType = virDomainNetGetActualType(net);
+ if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV &&
+ net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+ /* Each type='hostdev' network device must also have a
+ * corresponding entry in the hostdevs array. For netdevs
+ * that are hardcoded as type='hostdev', this is already
+ * done by the parser, but for those allocated from a
+ * network / determined at runtime, we need to do it
+ * separately.
+ */
+ virDomainHostdevDefPtr hostdev = virDomainNetGetActualHostdev(net);
+
+ if (virDomainHostdevFind(def, hostdev, NULL) >= 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("PCI device %04x:%02x:%02x.%x "
+ "allocated from network %s is already "
+ "in use by domain %s"),
+ hostdev->source.subsys.u.pci.addr.domain,
+ hostdev->source.subsys.u.pci.addr.bus,
+ hostdev->source.subsys.u.pci.addr.slot,
+ hostdev->source.subsys.u.pci.addr.function,
+ net->data.network.name,
+ def->name);
+ goto cleanup;
+ }
+ if (virDomainHostdevInsert(def, hostdev) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+ }
+ ret = 0;
+cleanup:
+ return ret;
+}
static int qemuDomainDeviceAliasIndex(virDomainDeviceInfoPtr info,
const char *prefix)
@@ -7106,12 +7158,15 @@ qemuBuildCommandLine(virConnectPtr conn,
char vhostfd_name[50] = "";
int vlan;
int bootindex = bootNet;
- int actualType;
+ int actualType = virDomainNetGetActualType(net);
bootNet = 0;
if (!bootindex)
bootindex = net->info.bootIndex;
+ if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV)
+ continue;
+
/* VLANs are not used with -netdev, so don't record them */
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE))
@@ -7119,53 +7174,6 @@ qemuBuildCommandLine(virConnectPtr conn,
else
vlan = i;
- /* If appropriate, grab a physical device from the configured
- * network's pool of devices, or resolve bridge device name
- * to the one defined in the network definition.
- */
- if (networkAllocateActualDevice(net) < 0)
- goto error;
-
- actualType = virDomainNetGetActualType(net);
- if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
- if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
- virDomainHostdevDefPtr hostdev = virDomainNetGetActualHostdev(net);
- virDomainHostdevDefPtr found;
- /* For a network with <forward mode='hostdev'>, there is a need to
- * add the newly minted hostdev to the hostdevs array.
- */
- if (qemuAssignDeviceHostdevAlias(def, hostdev,
- (def->nhostdevs-1)) < 0) {
- goto error;
- }
-
- if (virDomainHostdevFind(def, hostdev, &found) < 0) {
- if (virDomainHostdevInsert(def, hostdev) < 0) {
- virReportOOMError();
- goto error;
- }
- if (qemuPrepareHostdevPCIDevices(driver, def->name, def->uuid,
- &hostdev, 1) < 0) {
- goto error;
- }
- }
- else {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("PCI device %04x:%02x:%02x.%x "
- "allocated from network %s is already "
- "in use by domain %s"),
- hostdev->source.subsys.u.pci.addr.domain,
- hostdev->source.subsys.u.pci.addr.bus,
- hostdev->source.subsys.u.pci.addr.slot,
- hostdev->source.subsys.u.pci.addr.function,
- net->data.network.name,
- def->name);
- goto error;
- }
- }
- continue;
- }
-
if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
int tapfd = qemuNetworkIfaceConnect(def, conn, driver, net,
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index a706942..e690dee 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -1,7 +1,7 @@
/*
* qemu_command.h: QEMU command generation
*
- * Copyright (C) 2006-2012 Red Hat, Inc.
+ * Copyright (C) 2006-2013 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -161,6 +161,8 @@ int qemuOpenVhostNet(virDomainDefPtr def,
virQEMUCapsPtr qemuCaps,
int *vhostfd);
+int qemuNetworkPrepareDevices(virDomainDefPtr def);
+
/*
* NB: def->name can be NULL upon return and the caller
* *must* decide how to fill in a name in this case
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 3dd178c..d7b0aee 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3422,6 +3422,14 @@ int qemuProcessStart(virConnectPtr conn,
goto cleanup;
}
+ /* network devices must be "prepared" before hostdevs, because
+ * setting up a network device might create a new hostdev that
+ * will need to be setup.
+ */
+ VIR_DEBUG("Preparing network devices");
+ if (qemuNetworkPrepareDevices(vm->def) < 0)
+ goto cleanup;
+
/* Must be run before security labelling */
VIR_DEBUG("Preparing host devices");
if (qemuPrepareHostDevices(driver, vm->def, !migrateFrom) < 0)
--
1.7.11.7
11 years, 6 months
[libvirt] Bug in DOMINFO command when balloon driver is used on a vm with more then 8 GB of MaxMemory ?
by fc lists
Hi ,
I have been banging my head on this for the last 8 hours ... and i really
need to know if is really a bug or i am doing something wrong.
Description of the problem:
When the virsh setmem command is used to inflate the balloon on a VM to
which 8GB of MaxMemory or more are allocated then the information reported
with virsh dominfo , virsh dumpxml after the balloon change has been
performed are wrong.
The actual balloon is inflated correctly though and that is verifiable both
in the vm itself and through the "virsh dommemstat" commands.
I *think* that is because the dommestat command will perform a proper query
to find out the amount of ram currently used (and i can see that in the
logs when issuing a dommestat command)
2013-03-22 21:22:41.820+0000: 23181: debug : virJSONValueToString:1133 :
result={"execute":"query-balloon","id":"libvirt-9"}
2013-03-22 21:22:41.820+0000: 23181: debug :
qemuMonitorJSONCommandWithFd:265 : Send command
'{"execute":"query-balloon","id":"libvirt-9"}' for write with FD -1
2013-03-22 21:22:41.820+0000: 23181: debug : qemuMonitorSend:903 :
QEMU_MONITOR_SEND_MSG: mon=0x7f3d643eb5a0
msg={"execute":"query-balloon","id":"libvirt-9"}
2013-03-22 21:22:41.820+0000: 23179: debug : qemuMonitorIOWrite:461 :
QEMU_MONITOR_IO_WRITE: mon=0x7f3d643eb5a0
buf={"execute":"query-balloon","id":"libvirt-9"}
but no entries are shown in the log for qemu-monitor when virsh dominfo is
run, how does dominfo gather those informations?
I am going to raise a ticket on RED HAT bugzilla for this but was hoping to
get some feedback here first to avoid raising a ticket for something that
maybe i just misunderstood.
Platform is Centos 6.4 (problem was present in 6.3 as well starting
with libvirt-0.9.10-21.el6.3.7 )
The patch that actually is causing the problem is patch number 398 in the
src rpm for libvirt-0.9.10-21.el6.3.7 :
libvirt-Wire-up-handling-for-QMP-s-BALLOON_EVENT.patch (
https://bugzilla.redhat.com/show_bug.cgi?id=884713)
And i verified it by removing the patch and recompiling the rpm , that
indeed worked perfectly after that.
The problem exists in every version up to the latest (that is what i am
running now) but now the patch is part of the libvirt source code in itself
and not a patch in the rpm anymore.
Software used:
# yum list installed | egrep -i "qemu|libvirt"
gpxe-roms-qemu.noarch 0.9.7-6.9.el6 @base
libvirt.x86_64 0.10.2-18.el6_4.2 @updates
libvirt-client.x86_64 0.10.2-18.el6_4.2 @updates
libvirt-python.x86_64 0.10.2-18.el6_4.2 @updates
qemu-img.x86_64 2:0.12.1.2-2.355.0.1.el6.centos.2 @updates
qemu-kvm.x86_64 2:0.12.1.2-2.355.0.1.el6.centos.2 @updates
qemu-kvm-tools.x86_64 2:0.12.1.2-2.355.0.1.el6.centos.2 @updates
Full example ( long and include debug logs ) :
1) Start VM with 12GB of MAX and CURRENT (12582912)
(tail -f libvirtd.log | grep -i balloon)
2013-03-22 21:06:34.438+0000: 23180: debug : qemuMonitorSetBalloon:1690 :
mon=0x7f3d6c1789e0 newmem=12582912
2013-03-22 21:06:34.438+0000: 23180: debug : virJSONValueToString:1133 :
result={"execute":"balloon","arguments":{"value":12884901888},"id":"libvirt-6"}
2013-03-22 21:06:34.438+0000: 23180: debug :
qemuMonitorJSONCommandWithFd:265 : Send command
'{"execute":"balloon","arguments":{"value":12884901888},"id":"libvirt-6"}'
for write with FD -1
2013-03-22 21:06:34.438+0000: 23180: debug : qemuMonitorSend:903 :
QEMU_MONITOR_SEND_MSG: mon=0x7f3d6c1789e0
msg={"execute":"balloon","arguments":{"value":12884901888},"id":"libvirt-6"}
2013-03-22 21:06:34.439+0000: 23179: debug : qemuMonitorIOWrite:461 :
QEMU_MONITOR_IO_WRITE: mon=0x7f3d6c1789e0
buf={"execute":"balloon","arguments":{"value":12884901888},"id":"libvirt-6"}
# dominfo 2
Id: 2
Name: centos_jt
UUID: bc25a6c4-ba34-a593-47c7-6372999946d6
OS Type: hvm
State: running
CPU(s): 1
CPU time: 26.6s
Max memory: 12582912 KiB
Used memory: 12582912 KiB
Persistent: yes
Autostart: disable
Managed save: no
Security model: none
Security DOI: 0
2) set mem to 8GB
# setmem 2 --live --config --size 8388608
2013-03-22 21:13:45.522+0000: 23183: debug : qemuMonitorSetBalloon:1690 :
mon=0x7f3d6c1789e0 newmem=8388608
2013-03-22 21:13:45.522+0000: 23183: debug : virJSONValueToString:1133 :
result={"execute":"balloon","arguments":{"value":8589934592},"id":"libvirt-9"}
2013-03-22 21:13:45.522+0000: 23183: debug :
qemuMonitorJSONCommandWithFd:265 : Send command
'{"execute":"balloon","arguments":{"value":8589934592},"id":"libvirt-9"}'
for write with FD -1
2013-03-22 21:13:45.522+0000: 23183: debug : qemuMonitorSend:903 :
QEMU_MONITOR_SEND_MSG: mon=0x7f3d6c1789e0
msg={"execute":"balloon","arguments":{"value":8589934592},"id":"libvirt-9"}
2013-03-22 21:13:45.523+0000: 23179: debug : qemuMonitorIOWrite:461 :
QEMU_MONITOR_IO_WRITE: mon=0x7f3d6c1789e0
buf={"execute":"balloon","arguments":{"value":8589934592},"id":"libvirt-9"}
2013-03-22 21:13:45.528+0000: 23179: debug : qemuMonitorIOProcess:353 :
QEMU_MONITOR_IO_PROCESS: mon=0x7f3d6c1789e0 buf={"timestamp": {"seconds":
1363986825, "microseconds": 528314}, "event": "BALLOON_CHANGE", "data":
{"actual": 12883853312}}
2013-03-22 21:13:45.528+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:152 : Line [{"timestamp": {"seconds":
1363986825, "microseconds": 528314}, "event": "BALLOON_CHANGE", "data":
{"actual": 12883853312}}]
2013-03-22 21:13:45.528+0000: 23179: debug : virJSONValueFromString:975 :
string={"timestamp": {"seconds": 1363986825, "microseconds": 528314},
"event": "BALLOON_CHANGE", "data": {"actual": 12883853312}}
2013-03-22 21:13:45.528+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:167 : QEMU_MONITOR_RECV_EVENT:
mon=0x7f3d6c1789e0 event={"timestamp": {"seconds": 1363986825,
"microseconds": 528314}, "event": "BALLOON_CHANGE", "data": {"actual":
12883853312}}
2013-03-22 21:13:45.528+0000: 23179: debug :
qemuMonitorJSONIOProcessEvent:138 : handle BALLOON_CHANGE handler=0x4b4de0
data=0x1685ce0
2013-03-22 21:13:45.528+0000: 23179: debug :
qemuMonitorEmitBalloonChange:1151 : mon=0x7f3d6c1789e0
2013-03-22 21:13:45.528+0000: 23179: debug :
qemuProcessHandleBalloonChange:1248 : Updating balloon from 12582912 to
12581888 kb
2013-03-22 21:13:46.528+0000: 23179: debug : qemuMonitorIOProcess:353 :
QEMU_MONITOR_IO_PROCESS: mon=0x7f3d6c1789e0 buf={"timestamp": {"seconds":
1363986826, "microseconds": 352941}, "event": "BALLOON_CHANGE", "data":
{"actual": 12884901888}}
2013-03-22 21:13:46.528+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:152 : Line [{"timestamp": {"seconds":
1363986826, "microseconds": 352941}, "event": "BALLOON_CHANGE", "data":
{"actual": 12884901888}}]
2013-03-22 21:13:46.528+0000: 23179: debug : virJSONValueFromString:975 :
string={"timestamp": {"seconds": 1363986826, "microseconds": 352941},
"event": "BALLOON_CHANGE", "data": {"actual": 12884901888}}
2013-03-22 21:13:46.528+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:167 : QEMU_MONITOR_RECV_EVENT:
mon=0x7f3d6c1789e0 event={"timestamp": {"seconds": 1363986826,
"microseconds": 352941}, "event": "BALLOON_CHANGE", "data": {"actual":
12884901888}}
2013-03-22 21:13:46.528+0000: 23179: debug :
qemuMonitorJSONIOProcessEvent:138 : handle BALLOON_CHANGE handler=0x4b4de0
data=0x1686770
2013-03-22 21:13:46.528+0000: 23179: debug :
qemuMonitorEmitBalloonChange:1151 : mon=0x7f3d6c1789e0
2013-03-22 21:13:46.528+0000: 23179: debug :
qemuProcessHandleBalloonChange:1248 : Updating balloon from 12581888 to
12582912 kb
virsh # dominfo 2
Id: 2
Name: centos_jt
UUID: bc25a6c4-ba34-a593-47c7-6372999946d6
OS Type: hvm
State: running
CPU(s): 1
CPU time: 41.6s
Max memory: 12582912 KiB
Used memory: 12582912 KiB
Persistent: yes
Autostart: disable
Managed save: no
Security model: none
Security DOI: 0
virsh # dommemstat 2
actual 8388608
rss 599916
The Balloon was actually inflated , and in the VM i can see 8GB of Ram
available with free
3) setmem to to 3000000
2013-03-22 21:18:19.182+0000: 23181: debug : qemuMonitorSetBalloon:1690 :
mon=0x7f3d6c1789e0 newmem=3000000
2013-03-22 21:18:19.182+0000: 23181: debug : virJSONValueToString:1133 :
result={"execute":"balloon","arguments":{"value":3072000000},"id":"libvirt-63"}
2013-03-22 21:18:19.182+0000: 23181: debug :
qemuMonitorJSONCommandWithFd:265 : Send command
'{"execute":"balloon","arguments":{"value":3072000000},"id":"libvirt-63"}'
for write with FD -1
2013-03-22 21:18:19.182+0000: 23181: debug : qemuMonitorSend:903 :
QEMU_MONITOR_SEND_MSG: mon=0x7f3d6c1789e0
msg={"execute":"balloon","arguments":{"value":3072000000},"id":"libvirt-63"}
2013-03-22 21:18:19.183+0000: 23179: debug : qemuMonitorIOWrite:461 :
QEMU_MONITOR_IO_WRITE: mon=0x7f3d6c1789e0
buf={"execute":"balloon","arguments":{"value":3072000000},"id":"libvirt-63"}
2013-03-22 21:18:19.184+0000: 23179: debug : qemuMonitorIOProcess:353 :
QEMU_MONITOR_IO_PROCESS: mon=0x7f3d6c1789e0 buf={"timestamp": {"seconds":
1363987099, "microseconds": 184245}, "event": "BALLOON_CHANGE", "data":
{"actual": 12883853312}}
2013-03-22 21:18:19.184+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:152 : Line [{"timestamp": {"seconds":
1363987099, "microseconds": 184245}, "event": "BALLOON_CHANGE", "data":
{"actual": 12883853312}}]
2013-03-22 21:18:19.184+0000: 23179: debug : virJSONValueFromString:975 :
string={"timestamp": {"seconds": 1363987099, "microseconds": 184245},
"event": "BALLOON_CHANGE", "data": {"actual": 12883853312}}
2013-03-22 21:18:19.184+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:167 : QEMU_MONITOR_RECV_EVENT:
mon=0x7f3d6c1789e0 event={"timestamp": {"seconds": 1363987099,
"microseconds": 184245}, "event": "BALLOON_CHANGE", "data": {"actual":
12883853312}}
2013-03-22 21:18:19.184+0000: 23179: debug :
qemuMonitorJSONIOProcessEvent:138 : handle BALLOON_CHANGE handler=0x4b4de0
data=0x1688320
2013-03-22 21:18:19.184+0000: 23179: debug :
qemuMonitorEmitBalloonChange:1151 : mon=0x7f3d6c1789e0
2013-03-22 21:18:19.191+0000: 23179: debug :
qemuProcessHandleBalloonChange:1248 : Updating balloon from 12582912 to
12581888 kb
2013-03-22 21:18:20.184+0000: 23179: debug : qemuMonitorIOProcess:353 :
QEMU_MONITOR_IO_PROCESS: mon=0x7f3d6c1789e0 buf={"timestamp": {"seconds":
1363987100, "microseconds": 184128}, "event": "BALLOON_CHANGE", "data":
{"actual": 11874074624}}
2013-03-22 21:18:20.184+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:152 : Line [{"timestamp": {"seconds":
1363987100, "microseconds": 184128}, "event": "BALLOON_CHANGE", "data":
{"actual": 11874074624}}]
2013-03-22 21:18:20.184+0000: 23179: debug : virJSONValueFromString:975 :
string={"timestamp": {"seconds": 1363987100, "microseconds": 184128},
"event": "BALLOON_CHANGE", "data": {"actual": 11874074624}}
2013-03-22 21:18:20.184+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:167 : QEMU_MONITOR_RECV_EVENT:
mon=0x7f3d6c1789e0 event={"timestamp": {"seconds": 1363987100,
"microseconds": 184128}, "event": "BALLOON_CHANGE", "data": {"actual":
11874074624}}
2013-03-22 21:18:20.184+0000: 23179: debug :
qemuMonitorJSONIOProcessEvent:138 : handle BALLOON_CHANGE handler=0x4b4de0
data=0x1685ce0
2013-03-22 21:18:20.184+0000: 23179: debug :
qemuMonitorEmitBalloonChange:1151 : mon=0x7f3d6c1789e0
2013-03-22 21:18:20.184+0000: 23179: debug :
qemuProcessHandleBalloonChange:1248 : Updating balloon from 12581888 to
11595776 kb
2013-03-22 21:18:21.184+0000: 23179: debug : qemuMonitorIOProcess:353 :
QEMU_MONITOR_IO_PROCESS: mon=0x7f3d6c1789e0 buf={"timestamp": {"seconds":
1363987100, "microseconds": 224930}, "event": "BALLOON_CHANGE", "data":
{"actual": 11661934592}}
2013-03-22 21:18:21.184+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:152 : Line [{"timestamp": {"seconds":
1363987100, "microseconds": 224930}, "event": "BALLOON_CHANGE", "data":
{"actual": 11661934592}}]
2013-03-22 21:18:21.184+0000: 23179: debug : virJSONValueFromString:975 :
string={"timestamp": {"seconds": 1363987100, "microseconds": 224930},
"event": "BALLOON_CHANGE", "data": {"actual": 11661934592}}
2013-03-22 21:18:21.184+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:167 : QEMU_MONITOR_RECV_EVENT:
mon=0x7f3d6c1789e0 event={"timestamp": {"seconds": 1363987100,
"microseconds": 224930}, "event": "BALLOON_CHANGE", "data": {"actual":
11661934592}}
2013-03-22 21:18:21.184+0000: 23179: debug :
qemuMonitorJSONIOProcessEvent:138 : handle BALLOON_CHANGE handler=0x4b4de0
data=0x1686770
2013-03-22 21:18:21.184+0000: 23179: debug :
qemuMonitorEmitBalloonChange:1151 : mon=0x7f3d6c1789e0
2013-03-22 21:18:21.184+0000: 23179: debug :
qemuProcessHandleBalloonChange:1248 : Updating balloon from 11595776 to
11388608
virsh # dominfo 2
Id: 2
Name: centos_jt
UUID: bc25a6c4-ba34-a593-47c7-6372999946d6
OS Type: hvm
State: running
CPU(s): 1
CPU time: 53.0s
Max memory: 12582912 KiB
Used memory: 11388608 KiB
Persistent: yes
Autostart: disable
Managed save: no
Security model: none
Security DOI: 0
virsh # dommemstat 2
actual 3000000
rss 599036
4) Restart vm with 4GB of Current and Max (4194304)
2013-03-22 21:20:58.894+0000: 23182: debug : qemuMonitorSetBalloon:1690 :
mon=0x7f3d643eb5a0 newmem=4194304
2013-03-22 21:20:58.894+0000: 23182: debug : virJSONValueToString:1133 :
result={"execute":"balloon","arguments":{"value":4294967296},"id":"libvirt-6"}
2013-03-22 21:20:58.894+0000: 23182: debug :
qemuMonitorJSONCommandWithFd:265 : Send command
'{"execute":"balloon","arguments":{"value":4294967296},"id":"libvirt-6"}'
for write with FD -1
2013-03-22 21:20:58.894+0000: 23182: debug : qemuMonitorSend:903 :
QEMU_MONITOR_SEND_MSG: mon=0x7f3d643eb5a0
msg={"execute":"balloon","arguments":{"value":4294967296},"id":"libvirt-6"}
2013-03-22 21:20:58.894+0000: 23179: debug : qemuMonitorIOWrite:461 :
QEMU_MONITOR_IO_WRITE: mon=0x7f3d643eb5a0
buf={"execute":"balloon","arguments":{"value":4294967296},"id":"libvirt-6"}
virsh # dominfo 3
Id: 3
Name: centos_jt
UUID: bc25a6c4-ba34-a593-47c7-6372999946d6
OS Type: hvm
State: running
CPU(s): 1
CPU time: 15.4s
Max memory: 4194304 KiB
Used memory: 4194304 KiB
Persistent: yes
Autostart: disable
Managed save: no
Security model: none
Security DOI: 0
virsh # dommemstat 3
actual 4194304
rss 431384
5) reduce ram to 1GB
virsh # setmem 3 --live --config --size 1048576
2013-03-22 21:26:08.783+0000: 23183: debug : qemuMonitorSetBalloon:1690 :
mon=0x7f3d643eb5a0 newmem=1048576
2013-03-22 21:26:08.783+0000: 23183: debug : virJSONValueToString:1133 :
result={"execute":"balloon","arguments":{"value":1073741824},"id":"libvirt-11"}
2013-03-22 21:26:08.783+0000: 23183: debug :
qemuMonitorJSONCommandWithFd:265 : Send command
'{"execute":"balloon","arguments":{"value":1073741824},"id":"libvirt-11"}'
for write with FD -1
2013-03-22 21:26:08.783+0000: 23183: debug : qemuMonitorSend:903 :
QEMU_MONITOR_SEND_MSG: mon=0x7f3d643eb5a0
msg={"execute":"balloon","arguments":{"value":1073741824},"id":"libvirt-11"}
2013-03-22 21:26:08.784+0000: 23179: debug : qemuMonitorIOWrite:461 :
QEMU_MONITOR_IO_WRITE: mon=0x7f3d643eb5a0
buf={"execute":"balloon","arguments":{"value":1073741824},"id":"libvirt-11"}
2013-03-22 21:26:08.789+0000: 23179: debug : qemuMonitorIOProcess:353 :
QEMU_MONITOR_IO_PROCESS: mon=0x7f3d643eb5a0 buf={"timestamp": {"seconds":
1363987568, "microseconds": 789570}, "event": "BALLOON_CHANGE", "data":
{"actual": 4293918720}}
2013-03-22 21:26:08.789+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:152 : Line [{"timestamp": {"seconds":
1363987568, "microseconds": 789570}, "event": "BALLOON_CHANGE", "data":
{"actual": 4293918720}}]
2013-03-22 21:26:08.789+0000: 23179: debug : virJSONValueFromString:975 :
string={"timestamp": {"seconds": 1363987568, "microseconds": 789570},
"event": "BALLOON_CHANGE", "data": {"actual": 4293918720}}
2013-03-22 21:26:08.789+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:167 : QEMU_MONITOR_RECV_EVENT:
mon=0x7f3d643eb5a0 event={"timestamp": {"seconds": 1363987568,
"microseconds": 789570}, "event": "BALLOON_CHANGE", "data": {"actual":
4293918720}}
2013-03-22 21:26:08.789+0000: 23179: debug :
qemuMonitorJSONIOProcessEvent:138 : handle BALLOON_CHANGE handler=0x4b4de0
data=0x1686360
2013-03-22 21:26:08.789+0000: 23179: debug :
qemuMonitorEmitBalloonChange:1151 : mon=0x7f3d643eb5a0
2013-03-22 21:26:08.789+0000: 23179: debug :
qemuProcessHandleBalloonChange:1248 : Updating balloon from 4194304 to
4193280 kb
2013-03-22 21:26:09.789+0000: 23179: debug : qemuMonitorIOProcess:353 :
QEMU_MONITOR_IO_PROCESS: mon=0x7f3d643eb5a0 buf={"timestamp": {"seconds":
1363987569, "microseconds": 408889}, "event": "BALLOON_CHANGE", "data":
{"actual": 1073741824}}
2013-03-22 21:26:09.789+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:152 : Line [{"timestamp": {"seconds":
1363987569, "microseconds": 408889}, "event": "BALLOON_CHANGE", "data":
{"actual": 1073741824}}]
2013-03-22 21:26:09.789+0000: 23179: debug : virJSONValueFromString:975 :
string={"timestamp": {"seconds": 1363987569, "microseconds": 408889},
"event": "BALLOON_CHANGE", "data": {"actual": 1073741824}}
2013-03-22 21:26:09.789+0000: 23179: debug :
qemuMonitorJSONIOProcessLine:167 : QEMU_MONITOR_RECV_EVENT:
mon=0x7f3d643eb5a0 event={"timestamp": {"seconds": 1363987569,
"microseconds": 408889}, "event": "BALLOON_CHANGE", "data": {"actual":
1073741824}}
2013-03-22 21:26:09.789+0000: 23179: debug :
qemuMonitorJSONIOProcessEvent:138 : handle BALLOON_CHANGE handler=0x4b4de0
data=0x16826e0
2013-03-22 21:26:09.789+0000: 23179: debug :
qemuMonitorEmitBalloonChange:1151 : mon=0x7f3d643eb5a0
2013-03-22 21:26:09.789+0000: 23179: debug :
qemuProcessHandleBalloonChange:1248 : Updating balloon from 4193280 to
1048576 kb
virsh # dominfo 3
Id: 3
Name: centos_jt
UUID: bc25a6c4-ba34-a593-47c7-6372999946d6
OS Type: hvm
State: running
CPU(s): 1
CPU time: 28.6s
Max memory: 4194304 KiB
Used memory: 1048576 KiB
Persistent: yes
Autostart: disable
Managed save: no
Security model: none
Security DOI: 0
virsh # dommemstat 3
actual 1048576
rss 411740
11 years, 6 months
[libvirt] [PATCH] Ensure stub todo.html.in file is HTML5
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
If no todo.cfg is present, make sure the stub is in HTML5
format and clearly states that the config was not available
Pushed as another website build breaker fix
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
docs/Makefile.am | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/Makefile.am b/docs/Makefile.am
index b4855d1..2d22743 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -149,7 +149,7 @@ todo.html.in: todo.pl
|| { rm $@ && exit 1; }; \
else \
echo "Stubbing $@"; \
- echo "<html><body><h1>Todo list</h1></body></html>" > $@ ; \
+ echo "<html xmlns=\"http://www.w3.org/1999/xhtml\"><body><h1>Todo list unavailable: no config file</h1></body></html>" > $@ ; \
fi
todo:
--
1.8.1.4
11 years, 6 months
[libvirt] ANNOUNCE: libvirt-sandbox "Nubian Desert" release 0.2.0
by Daniel P. Berrange
I pleased to announce the a new public release of libvirt-sandbox,
version 0.2.0, is now available for download
ftp://libvirt.org/libvirt/sandbox/
The packages are GPG signed with
Key fingerprint: DAF3 A6FD B26B 6291 2D0E 8E3F BE86 EBB4 1510 4FDF (4096R)
The libvirt-sandbox package provides an API layer on top of libvirt-gobject
which facilitates the cration of application sandboxes using virtualization
technology. An application sandbox is a virtual machine or container that
runs a single application binary, directly from the host OS filesystem.
In other words there is no separate guest operating system install to build
or manager.
At this point in time libvirt-sandbox can create sandboxes using either LXC
or KVM, and should in theory be extendable to any libvirt driver. This
release has focused entirely on improving the virt-sandbox-service tool
Changed in this release:
- Requires systemd >= 198
- Fix termination of interactive sandbox client to
avoid loosing final I/O
- Stop hardcoding default security label
- Misc docs typos / fixes
- Fix infinite loop handling security opts
- Mandate enablement of introspection
- Handle NULL broadcast address for NICs
- Don't assume /var/log/journal exists
- Improve rollback if creation of service sandbox fails
- Block host NICs from sandbox
- Sanity check requested network config
- Fix sandbox journal location to be a dir not a file
- Fix parsing of --security option
- Change virt-sandbox-service to use --security opts
instead of SELinux specific -l/-t/-d args
- Replace use of YUM with RPM to improve performance
- Send dhclient output to /dev/null
- Avoid getting stuck in waitpid if non-primary process
exits
- Allow choice of host virtual networks
- Support network config with virt-sandbox-service
- Do not create any NIC in service sandbox by default
- Cope with SELinux label lacking a category pair
- Delay dropping credentials until after ttys are opened
- Fix tty permissions in QEMU init helper to be 0700 instead
of 0777
- Add support for non-systemd service containers
- Add support for i18n of all output strings
- Remove hardcoding of lxc:/// in virt-sandbox-service
- Correctly handle EOF from raw console
- Improve I/O performance of virt-sandbox
- Allow custom uid/gid for generic service sandboxes
- Do not run debug shell in service sandboxes
- Add --package option to virt-sandbox-service for cases
where the unit file is not owned by an RPM
- Use drop in systemd service override, instead of
includes
- Support templated systemd service units
Thanks to everyone who contributed to this release
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
11 years, 6 months
[libvirt] [sandbox PATCH v2 1/2] Use drop-in configuration file instead of creating a custom file
by Michael Scherer
This permit to no longer track the source, to use a custom file
in /etc without conflict. This change require a newer version of
systemd ( > 198 )
---
bin/virt-sandbox-service | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/bin/virt-sandbox-service b/bin/virt-sandbox-service
index 2096be1..3cecff8 100755
--- a/bin/virt-sandbox-service
+++ b/bin/virt-sandbox-service
@@ -625,12 +625,16 @@ WantedBy=%(TARGET)s
self.add_bind_mount(source, d)
def create_container_unit(self, src, dest, unit):
- fd = open(dest + "/" + unit, "w")
- fd.write(""".include %s
+ dropin_dir = "%s/%s.d" % (dest, unit)
+ if not os.path.exists(dropin_dir):
+ os.mkdir(dropin_dir)
+
+ fd = open(dropin_dir + "/virt-sandbox.conf", "w")
+ fd.write("""; file placed here by virt-sandbox-service
[Service]
PrivateTmp=false
PrivateNetwork=false
-""" % src )
+""" )
fd.close()
def gen_content(self):
--
1.8.2.1
11 years, 6 months
[libvirt] [PATCH] get rid of virBufferAsprintf where possible
by Ján Tomko
Use virBufferAddLit or virBufferAddChar instead.
---
src/conf/domain_conf.c | 14 +++++++-------
src/conf/network_conf.c | 4 ++--
src/conf/storage_conf.c | 6 +++---
src/nwfilter/nwfilter_learnipaddr.c | 2 +-
src/phyp/phyp_driver.c | 28 +++++++++++++--------------
src/qemu/qemu_command.c | 38 ++++++++++++++++++-------------------
src/qemu/qemu_domain.c | 2 +-
src/qemu/qemu_migration.c | 4 ++--
src/security/virt-aa-helper.c | 2 +-
src/util/virlog.c | 2 +-
src/vmx/vmx.c | 2 +-
tools/virsh-domain.c | 12 ++++++------
12 files changed, 58 insertions(+), 58 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index fe97c02..59badf8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -13255,7 +13255,7 @@ static void
virSecurityDeviceLabelDefFormat(virBufferPtr buf,
virSecurityDeviceLabelDefPtr def)
{
- virBufferAsprintf(buf, "<seclabel");
+ virBufferAddLit(buf, "<seclabel");
if (def->model)
virBufferAsprintf(buf, " model='%s'", def->model);
@@ -13542,9 +13542,9 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferEscapeString(buf, " <auth username='%s'>\n",
def->auth.username);
if (def->protocol == VIR_DOMAIN_DISK_PROTOCOL_ISCSI) {
- virBufferAsprintf(buf, " <secret type='iscsi'");
+ virBufferAddLit(buf, " <secret type='iscsi'");
} else if (def->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD) {
- virBufferAsprintf(buf, " <secret type='ceph'");
+ virBufferAddLit(buf, " <secret type='ceph'");
}
if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_UUID) {
@@ -15010,13 +15010,13 @@ virDomainGraphicsDefFormat(virBufferPtr buf,
virBufferAddLit(buf, " port='0'");
if (def->data.rdp.autoport)
- virBufferAsprintf(buf, " autoport='yes'");
+ virBufferAddLit(buf, " autoport='yes'");
if (def->data.rdp.replaceUser)
- virBufferAsprintf(buf, " replaceUser='yes'");
+ virBufferAddLit(buf, " replaceUser='yes'");
if (def->data.rdp.multiUser)
- virBufferAsprintf(buf, " multiUser='yes'");
+ virBufferAddLit(buf, " multiUser='yes'");
if (listenAddr)
virBufferAsprintf(buf, " listen='%s'", listenAddr);
@@ -15536,7 +15536,7 @@ virDomainDefFormatInternal(virDomainDefPtr def,
if (def->cputune.emulatorpin) {
char *cpumask;
- virBufferAsprintf(buf, " <emulatorpin ");
+ virBufferAddLit(buf, " <emulatorpin ");
if (!(cpumask = virBitmapFormat(def->cputune.emulatorpin->cpumask))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 8abfa53..0c0e58e 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -2011,7 +2011,7 @@ virNetworkDNSDefFormat(virBufferPtr buf,
if (def->srvs[i].weight)
virBufferAsprintf(buf, " weight='%d'", def->srvs[i].weight);
- virBufferAsprintf(buf, "/>\n");
+ virBufferAddLit(buf, "/>\n");
}
}
@@ -2028,7 +2028,7 @@ virNetworkDNSDefFormat(virBufferPtr buf,
def->hosts[ii].names[j]);
virBufferAdjustIndent(buf, -2);
- virBufferAsprintf(buf, "</host>\n");
+ virBufferAddLit(buf, "</host>\n");
VIR_FREE(ip);
}
}
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 9f2012e..518cd1e 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -1092,7 +1092,7 @@ virStoragePoolSourceFormat(virBufferPtr buf,
virBufferAsprintf(buf," <auth username='%s' type='ceph'>\n",
src->auth.cephx.username);
- virBufferAsprintf(buf," %s", "<secret");
+ virBufferAddLit(buf," <secret");
if (src->auth.cephx.secret.uuidUsable) {
virUUIDFormat(src->auth.cephx.secret.uuid, uuid);
virBufferAsprintf(buf," uuid='%s'", uuid);
@@ -1101,9 +1101,9 @@ virStoragePoolSourceFormat(virBufferPtr buf,
if (src->auth.cephx.secret.usage != NULL) {
virBufferAsprintf(buf," usage='%s'", src->auth.cephx.secret.usage);
}
- virBufferAsprintf(buf,"%s", "/>\n");
+ virBufferAddLit(buf,"/>\n");
- virBufferAsprintf(buf," %s", "</auth>\n");
+ virBufferAddLit(buf," </auth>\n");
}
if (src->vendor != NULL) {
diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c
index 14fd32c..8eb7700 100644
--- a/src/nwfilter/nwfilter_learnipaddr.c
+++ b/src/nwfilter/nwfilter_learnipaddr.c
@@ -417,7 +417,7 @@ learnIPAddressThread(void *arg)
req->status = EINVAL;
goto done;
}
- virBufferAsprintf(&buf, "src port 67 and dst port 68");
+ virBufferAddLit(&buf, "src port 67 and dst port 68");
break;
default:
if (techdriver->applyBasicRules(req->ifname,
diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c
index 85eb650..4bc68d9 100644
--- a/src/phyp/phyp_driver.c
+++ b/src/phyp/phyp_driver.c
@@ -1684,12 +1684,12 @@ phypGetVIOSFreeSCSIAdapter(virConnectPtr conn)
virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
managed_system, vios_id);
- virBufferAsprintf(&buf, "lsmap -all -field svsa backing -fmt , ");
+ virBufferAddLit(&buf, "lsmap -all -field svsa backing -fmt , ");
if (system_type == HMC)
virBufferAddChar(&buf, '\'');
- virBufferAsprintf(&buf, "|sed '/,[^.*]/d; s/,//g; q'");
+ virBufferAddLit(&buf, "|sed '/,[^.*]/d; s/,//g; q'");
ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
if (exit_status < 0)
@@ -1882,7 +1882,7 @@ phypStorageVolGetKey(virConnectPtr conn, const char *name)
if (system_type == HMC)
virBufferAddChar(&buf, '\'');
- virBufferAsprintf(&buf, "|sed -e 's/^LV IDENTIFIER://' -e 's/ //g'");
+ virBufferAddLit(&buf, "|sed -e 's/^LV IDENTIFIER://' -e 's/ //g'");
ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
if (exit_status < 0)
@@ -1912,7 +1912,7 @@ phypGetStoragePoolDevice(virConnectPtr conn, char *name)
if (system_type == HMC)
virBufferAddChar(&buf, '\'');
- virBufferAsprintf(&buf, "|sed '1d; s/ //g'");
+ virBufferAddLit(&buf, "|sed '1d; s/ //g'");
ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
if (exit_status < 0)
@@ -1941,7 +1941,7 @@ phypGetStoragePoolSize(virConnectPtr conn, char *name)
if (system_type == HMC)
virBufferAddChar(&buf, '\'');
- virBufferAsprintf(&buf, "|sed '1d; s/ //g'");
+ virBufferAddLit(&buf, "|sed '1d; s/ //g'");
phypExecInt(session, &buf, conn, &sp_size);
return sp_size;
}
@@ -2123,7 +2123,7 @@ phypStorageVolGetPhysicalVolumeByStoragePool(virStorageVolPtr vol, char *sp)
if (system_type == HMC)
virBufferAddChar(&buf, '\'');
- virBufferAsprintf(&buf, "|sed 1d");
+ virBufferAddLit(&buf, "|sed 1d");
ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
if (exit_status < 0)
@@ -2155,7 +2155,7 @@ phypStorageVolLookupByPath(virConnectPtr conn, const char *volname)
if (system_type == HMC)
virBufferAddChar(&buf, '\'');
- virBufferAsprintf(&buf, "|sed -e 's/^VOLUME GROUP://g' -e 's/ //g'");
+ virBufferAddLit(&buf, "|sed -e 's/^VOLUME GROUP://g' -e 's/ //g'");
ret = phypExecBuffer(session, &buf, &exit_status, conn, true);
if (exit_status < 0 || ret == NULL)
@@ -2199,7 +2199,7 @@ phypGetStoragePoolUUID(virConnectPtr conn, unsigned char *uuid,
if (system_type == HMC)
virBufferAddChar(&buf, '\'');
- virBufferAsprintf(&buf, "|sed '1,2d'");
+ virBufferAddLit(&buf, "|sed '1,2d'");
ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
if (exit_status < 0 || ret == NULL)
@@ -2385,7 +2385,7 @@ phypStoragePoolListVolumes(virStoragePoolPtr pool, char **const volumes,
if (system_type == HMC)
virBufferAddChar(&buf, '\'');
- virBufferAsprintf(&buf, "|sed '1,2d'");
+ virBufferAddLit(&buf, "|sed '1,2d'");
ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
/* I need to parse the textual return in order to get the volumes */
@@ -2442,7 +2442,7 @@ phypStoragePoolNumOfVolumes(virStoragePoolPtr pool)
virBufferAsprintf(&buf, "lsvg -lv %s -field lvname", pool->name);
if (system_type == HMC)
virBufferAddChar(&buf, '\'');
- virBufferAsprintf(&buf, "|grep -c '^.*$'");
+ virBufferAddLit(&buf, "|grep -c '^.*$'");
if (phypExecInt(session, &buf, conn, &nvolumes) < 0)
return -1;
@@ -2551,12 +2551,12 @@ phypConnectNumOfStoragePools(virConnectPtr conn)
virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
managed_system, vios_id);
- virBufferAsprintf(&buf, "lsvg");
+ virBufferAddLit(&buf, "lsvg");
if (system_type == HMC)
virBufferAddChar(&buf, '\'');
- virBufferAsprintf(&buf, "|grep -c '^.*$'");
+ virBufferAddLit(&buf, "|grep -c '^.*$'");
phypExecInt(session, &buf, conn, &nsp);
return nsp;
}
@@ -2583,7 +2583,7 @@ phypConnectListStoragePools(virConnectPtr conn, char **const pools, int npools)
virBufferAsprintf(&buf, "viosvrcmd -m %s --id %d -c '",
managed_system, vios_id);
- virBufferAsprintf(&buf, "lsvg");
+ virBufferAddLit(&buf, "lsvg");
if (system_type == HMC)
virBufferAddChar(&buf, '\'');
@@ -3219,7 +3219,7 @@ phypConnectListDefinedDomains(virConnectPtr conn, char **const names, int nnames
virBufferAddLit(&buf, "lssyscfg -r lpar");
if (system_type == HMC)
virBufferAsprintf(&buf, " -m %s", managed_system);
- virBufferAsprintf(&buf, " -F name,state"
+ virBufferAddLit(&buf, " -F name,state"
"|sed -n '/Not Activated/ {\n s/,.*$//\n p\n}'");
ret = phypExecBuffer(session, &buf, &exit_status, conn, false);
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 144620c..7118b53 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -2174,7 +2174,7 @@ static void
qemuUsbId(virBufferPtr buf, int idx)
{
if (idx == 0)
- virBufferAsprintf(buf, "usb");
+ virBufferAddLit(buf, "usb");
else
virBufferAsprintf(buf, "usb%d", idx);
}
@@ -2219,9 +2219,9 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
}
} else {
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIBUS))
- virBufferAsprintf(buf, ",bus=pci.0");
+ virBufferAddLit(buf, ",bus=pci.0");
else
- virBufferAsprintf(buf, ",bus=pci");
+ virBufferAddLit(buf, ",bus=pci");
}
if (info->addr.pci.multi == VIR_DEVICE_ADDRESS_PCI_MULTI_ON)
virBufferAddLit(buf, ",multifunction=on");
@@ -2231,7 +2231,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
if (info->addr.pci.function != 0)
virBufferAsprintf(buf, ".0x%x", info->addr.pci.function);
} else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
- virBufferAsprintf(buf, ",bus=");
+ virBufferAddLit(buf, ",bus=");
qemuUsbId(buf, info->addr.usb.bus);
virBufferAsprintf(buf, ".0,port=%s", info->addr.usb.port);
} else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) {
@@ -3766,11 +3766,11 @@ qemuBuildUSBControllerDevStr(virDomainDefPtr domainDef,
virBufferAsprintf(buf, "%s", smodel);
if (def->info.mastertype == VIR_DOMAIN_CONTROLLER_MASTER_USB) {
- virBufferAsprintf(buf, ",masterbus=");
+ virBufferAddLit(buf, ",masterbus=");
qemuUsbId(buf, def->idx);
virBufferAsprintf(buf, ".0,firstport=%d", def->info.master.usb.startport);
} else {
- virBufferAsprintf(buf, ",id=");
+ virBufferAddLit(buf, ",id=");
qemuUsbId(buf, def->idx);
}
@@ -4515,33 +4515,33 @@ qemuBuildRedirdevDevStr(virDomainDefPtr def,
goto error;
}
- virBufferAsprintf(&buf, ",filter=");
+ virBufferAddLit(&buf, ",filter=");
for (i = 0; i < redirfilter->nusbdevs; i++) {
virDomainRedirFilterUsbDevDefPtr usbdev = redirfilter->usbdevs[i];
if (usbdev->usbClass >= 0)
virBufferAsprintf(&buf, "0x%02X:", usbdev->usbClass);
else
- virBufferAsprintf(&buf, "-1:");
+ virBufferAddLit(&buf, "-1:");
if (usbdev->vendor >= 0)
virBufferAsprintf(&buf, "0x%04X:", usbdev->vendor);
else
- virBufferAsprintf(&buf, "-1:");
+ virBufferAddLit(&buf, "-1:");
if (usbdev->product >= 0)
virBufferAsprintf(&buf, "0x%04X:", usbdev->product);
else
- virBufferAsprintf(&buf, "-1:");
+ virBufferAddLit(&buf, "-1:");
if (usbdev->version >= 0)
virBufferAsprintf(&buf, "0x%04X:", usbdev->version);
else
- virBufferAsprintf(&buf, "-1:");
+ virBufferAddLit(&buf, "-1:");
virBufferAsprintf(&buf, "%u", usbdev->allow);
if (i < redirfilter->nusbdevs -1)
- virBufferAsprintf(&buf, "|");
+ virBufferAddLit(&buf, "|");
}
}
@@ -5688,7 +5688,7 @@ qemuBuildMachineArgStr(virCommandPtr cmd,
* machine->init in QEMU, it needs to set usb=off
*/
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MACHINE_USB_OPT))
- virBufferAsprintf(&buf, ",usb=off");
+ virBufferAddLit(&buf, ",usb=off");
if (def->mem.dump_core) {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DUMP_GUEST_CORE)) {
@@ -6005,10 +6005,10 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg,
if (graphics->data.spice.mousemode) {
switch (graphics->data.spice.mousemode) {
case VIR_DOMAIN_GRAPHICS_SPICE_MOUSE_MODE_SERVER:
- virBufferAsprintf(&opt, ",agent-mouse=off");
+ virBufferAddLit(&opt, ",agent-mouse=off");
break;
case VIR_DOMAIN_GRAPHICS_SPICE_MOUSE_MODE_CLIENT:
- virBufferAsprintf(&opt, ",agent-mouse=on");
+ virBufferAddLit(&opt, ",agent-mouse=on");
break;
default:
break;
@@ -6027,10 +6027,10 @@ qemuBuildGraphicsSPICECommandLine(virQEMUDriverConfigPtr cfg,
switch (defaultMode) {
case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_SECURE:
- virBufferAsprintf(&opt, ",tls-channel=default");
+ virBufferAddLit(&opt, ",tls-channel=default");
break;
case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_INSECURE:
- virBufferAsprintf(&opt, ",plaintext-channel=default");
+ virBufferAddLit(&opt, ",plaintext-channel=default");
break;
case VIR_DOMAIN_GRAPHICS_SPICE_CHANNEL_MODE_ANY:
/* nothing */
@@ -6698,9 +6698,9 @@ qemuBuildCommandLine(virConnectPtr conn,
virBufferAddChar(&boot_buf, ',');
if (def->os.bootmenu == VIR_DOMAIN_BOOT_MENU_ENABLED)
- virBufferAsprintf(&boot_buf, "menu=on");
+ virBufferAddLit(&boot_buf, "menu=on");
else
- virBufferAsprintf(&boot_buf, "menu=off");
+ virBufferAddLit(&boot_buf, "menu=off");
} else {
/* We cannot emit an error when bootmenu is enabled but
* unsupported because of backward compatibility */
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 33088ea..97a8307 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -330,7 +330,7 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf, void *data)
priv->job.active = job;
if (priv->fakeReboot)
- virBufferAsprintf(buf, " <fakereboot/>\n");
+ virBufferAddLit(buf, " <fakereboot/>\n");
return 0;
}
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index d50099c..733c0c4 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -572,7 +572,7 @@ qemuMigrationCookieNetworkXMLFormat(virBufferPtr buf,
/* If optr->net[i].vporttype is not set, there is nothing to transfer */
if (optr->net[i].vporttype != VIR_NETDEV_VPORT_PROFILE_NONE) {
if (empty) {
- virBufferAsprintf(buf, " <network>\n");
+ virBufferAddLit(buf, " <network>\n");
empty = false;
}
virBufferAsprintf(buf, " <interface index='%d' vporttype='%s'",
@@ -604,7 +604,7 @@ qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver,
virUUIDFormat(mig->uuid, uuidstr);
virUUIDFormat(mig->localHostuuid, hostuuidstr);
- virBufferAsprintf(buf, "<qemu-migration>\n");
+ virBufferAddLit(buf, "<qemu-migration>\n");
virBufferEscapeString(buf, " <name>%s</name>\n", mig->name);
virBufferAsprintf(buf, " <uuid>%s</uuid>\n", uuidstr);
virBufferEscapeString(buf, " <hostname>%s</hostname>\n", mig->localHostname);
diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
index b526919..0831d2f 100644
--- a/src/security/virt-aa-helper.c
+++ b/src/security/virt-aa-helper.c
@@ -790,7 +790,7 @@ vah_add_file(virBufferPtr buf, const char *path, const char *perms)
virBufferAsprintf(buf, " \"%s\" %s,\n", tmp, perms);
if (readonly) {
- virBufferAsprintf(buf, " # don't audit writes to readonly files\n");
+ virBufferAddLit(buf, " # don't audit writes to readonly files\n");
virBufferAsprintf(buf, " deny \"%s\" w,\n", tmp);
}
diff --git a/src/util/virlog.c b/src/util/virlog.c
index eee9ddc..62ff838 100644
--- a/src/util/virlog.c
+++ b/src/util/virlog.c
@@ -1503,7 +1503,7 @@ virLogGetOutputs(void)
for (i = 0; i < virLogNbOutputs; i++) {
virLogDestination dest = virLogOutputs[i].dest;
if (i)
- virBufferAsprintf(&outputbuf, " ");
+ virBufferAddChar(&outputbuf, ' ');
switch (dest) {
case VIR_LOG_TO_SYSLOG:
case VIR_LOG_TO_FILE:
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index 9ec0269..2df8a83 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -3396,7 +3396,7 @@ virVMXFormatVNC(virDomainGraphicsDefPtr def, virBufferPtr buffer)
return -1;
}
- virBufferAsprintf(buffer, "RemoteDisplay.vnc.enabled = \"true\"\n");
+ virBufferAddLit(buffer, "RemoteDisplay.vnc.enabled = \"true\"\n");
if (def->data.vnc.autoport) {
VIR_WARN("VNC autoport is enabled, but the automatically assigned "
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 9ac9bd1..86786ee 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -526,7 +526,7 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
virBufferAddLit(&buf, ">\n");
if (driver || subdriver || cache) {
- virBufferAsprintf(&buf, " <driver");
+ virBufferAddLit(&buf, " <driver");
if (driver)
virBufferAsprintf(&buf, " name='%s'", driver);
@@ -550,7 +550,7 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
virBufferAsprintf(&buf, " <serial>%s</serial>\n", serial);
if (vshCommandOptBool(cmd, "shareable"))
- virBufferAsprintf(&buf, " <shareable/>\n");
+ virBufferAddLit(&buf, " <shareable/>\n");
if (straddr) {
if (str2DiskAddress(straddr, &diskAddr) != 0) {
@@ -814,14 +814,14 @@ cmdAttachInterface(vshControl *ctl, const vshCmd *cmd)
virBufferAsprintf(&buf, " <model type='%s'/>\n", model);
if (inboundStr || outboundStr) {
- virBufferAsprintf(&buf, " <bandwidth>\n");
+ virBufferAddLit(&buf, " <bandwidth>\n");
if (inboundStr && inbound.average > 0) {
virBufferAsprintf(&buf, " <inbound average='%llu'", inbound.average);
if (inbound.peak > 0)
virBufferAsprintf(&buf, " peak='%llu'", inbound.peak);
if (inbound.burst > 0)
virBufferAsprintf(&buf, " burst='%llu'", inbound.burst);
- virBufferAsprintf(&buf, "/>\n");
+ virBufferAddLit(&buf, "/>\n");
}
if (outboundStr && outbound.average > 0) {
virBufferAsprintf(&buf, " <outbound average='%llu'", outbound.average);
@@ -829,9 +829,9 @@ cmdAttachInterface(vshControl *ctl, const vshCmd *cmd)
virBufferAsprintf(&buf, " peak='%llu'", outbound.peak);
if (outbound.burst > 0)
virBufferAsprintf(&buf, " burst='%llu'", outbound.burst);
- virBufferAsprintf(&buf, "/>\n");
+ virBufferAddLit(&buf, "/>\n");
}
- virBufferAsprintf(&buf, " </bandwidth>\n");
+ virBufferAddLit(&buf, " </bandwidth>\n");
}
virBufferAddLit(&buf, "</interface>\n");
--
1.8.1.5
11 years, 6 months