Re: [libvirt] fail to convert qemu xml to args with libvirt-1.0.4: An error occurred, but the cause is unknown
by Yin Olivia-R63875
Hi Daniel,
Just Ping.
Did you ever successfully convert QEMU xml file to argv on other platforms?
Best Regards,
Olivia
> -----Original Message-----
> From: Yin Olivia-R63875
> Sent: Tuesday, April 09, 2013 1:22 PM
> To: 'libvir-list(a)redhat.com'
> Cc: 'libvirt-users(a)redhat.com'
> Subject: fail to convert qemu xml to args with libvirt-1.0.4: An error
> occurred, but the cause is unknown
>
> Hi,
>
> I used to convert qemu XML to args with libvirt-1.0.3.
> But it failed to convert with libvirt-1.0.4.
>
> # virsh domxml-to-native qemu-argv test.xml >test.sh
> error: An error occurred, but the cause is unknown
>
>
> Comparing the debug file as below:
> 1) lbvirt-1.0.3
> <cut>
> 2013-04-09 03:23:47.296+0000: 2669: debug :
> virEventPollInterruptLocked:716 : Interrupting
> 2013-04-09 03:23:47.296+0000: 2669: debug : virNetClientIO:1807 : All done
> with our call head=(nil) call=0x100871c0 rv=0
> 2013-04-09 03:23:47.297+0000: 2670: debug : virEventPollRunOnce:640 : Poll
> got 1 event(s)
> 2013-04-09 03:23:47.297+0000: 2670: debug :
> virEventPollDispatchTimeouts:425 : Dispatch 0
> 2013-04-09 03:23:47.297+0000: 2669: debug : virNetMessageFree:73 :
> msg=0x10087500 nfds=0 cb=(nil)
> 2013-04-09 03:23:47.297+0000: 2670: debug :
> virEventPollDispatchHandles:470 : Dispatch 1
> 2013-04-09 03:23:47.297+0000: 2670: debug :
> virEventPollDispatchHandles:484 : i=0 w=1
> 2013-04-09 03:23:47.297+0000: 2669: debug : virConnectClose:1483 :
> conn=0x100878b8 <cut>
>
> 2) libvirt-1.0.4
> <cut>
> 2013-04-09 03:07:58.012+0000: 2834: debug :
> virEventPollInterruptLocked:716 : Interrupting
> 2013-04-09 03:07:58.012+0000: 2834: debug : virNetClientIO:1810 : All done
> with our call head=(nil) call=0x10089db8 rv=0
> 2013-04-09 03:07:58.012+0000: 2835: debug : virEventPollRunOnce:640 : Poll
> got 1 event(s)
> 2013-04-09 03:07:58.012+0000: 2835: debug :
> virEventPollDispatchTimeouts:425 : Dispatch 0
> 2013-04-09 03:07:58.012+0000: 2834: error :
> virNetClientProgramDispatchError:175 : An error occurred, but the cause is
> unknown
> 2013-04-09 03:07:58.012+0000: 2835: debug :
> virEventPollDispatchHandles:470 : Dispatch 1
> 2013-04-09 03:07:58.012+0000: 2834: debug : virNetMessageFree:73 :
> msg=0x1008a0f8 nfds=0 cb=(nil)
> 2013-04-09 03:07:58.012+0000: 2835: debug :
> virEventPollDispatchHandles:484 : i=0 w=1
> 2013-04-09 03:07:58.012+0000: 2835: debug :
> virEventPollDispatchHandles:498 : EVENT_POLL_DISPATCH_HANDLE: watch=1
> events=1
> 2013-04-09 03:07:58.012+0000: 2835: debug :
> virEventPollCleanupTimeouts:516 : Cleanup 0
> 2013-04-09 03:07:58.013+0000: 2835: debug :
> virEventPollCleanupTimeouts:552 : Found 0 out of 0 timeout slots used,
> releasing 0
> 2013-04-09 03:07:58.013+0000: 2835: debug : virEventPollCleanupHandles:564 :
> Cleanup 2
> 2013-04-09 03:07:58.013+0000: 2834: debug : virConnectClose:1483 :
> conn=0x1008a4b0 <cut>
>
>
> How can I debug this cause unknown error?
>
> Best Regards,
> Olivia
11 years, 7 months
[libvirt] [PATCH] conf: fix a memory leak when parsing nat port XML nodes
by Guannan Ren
==5306== 8 bytes in 1 blocks are definitely lost in loss record 24 of 277
==5306== at 0x4C28B2F: calloc (vg_replace_malloc.c:593)
==5306== by 0x5293CAF: virAllocN (viralloc.c:152)
==5306== by 0x52DFEAE: virXPathNodeSet (virxml.c:611)
==5306== by 0x5313DD9: virNetworkDefParseXML (network_conf.c:1408)
==5306== by 0x53170F6: virNetworkObjUpdateParseFile (network_conf.c:2031)
==5306== by 0x131DA63C: networkStartup (bridge_driver.c:279)
==5306== by 0x53481DF: virStateInitialize (libvirt.c:822)
==5306== by 0x40DF44: daemonRunStateInit (libvirtd.c:877)
==5306== by 0x52D2FF5: virThreadHelper (virthreadpthread.c:161)
==5306== by 0x5D00C52: start_thread (in /usr/lib64/libpthread-2.17.so)
==5306== by 0x6410ECC: clone (in /usr/lib64/libc-2.17.so)
---
src/conf/network_conf.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index c5535e6..968cf11 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -1440,6 +1440,7 @@ cleanup:
VIR_FREE(addrStart);
VIR_FREE(addrEnd);
VIR_FREE(natAddrNodes);
+ VIR_FREE(natPortNodes);
ctxt->node = save;
return ret;
}
--
1.7.11.2
11 years, 7 months
[libvirt] [libvirt-designer v2] Add Vala API
by Zeeshan Ali (Khattak)
From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
This is mostly (modified) copy&paste from libvirt-glib.
---
v2: Removed redundant libvirt-gobject dependency.
Makefile.am | 2 +-
configure.ac | 37 +++++++++++++++++++++++++++++++++++++
vapi/Makefile.am | 25 +++++++++++++++++++++++++
vapi/libvirt-designer-1.0.deps | 2 ++
4 files changed, 65 insertions(+), 1 deletion(-)
create mode 100644 vapi/Makefile.am
create mode 100644 vapi/libvirt-designer-1.0.deps
diff --git a/Makefile.am b/Makefile.am
index f5bcc47..53d36ea 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,5 @@
-SUBDIRS = libvirt-designer examples docs
+SUBDIRS = libvirt-designer vapi examples docs
ACLOCAL_AMFLAGS = -I m4
diff --git a/configure.ac b/configure.ac
index a9c5c34..c999826 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,10 +71,46 @@ if test "x$enable_examples" != "xno" ; then
fi
AM_CONDITIONAL(WITH_EXAMPLES, [test "x$enable_examples" = "xyes"])
+AC_ARG_ENABLE([vala],
+ AS_HELP_STRING([--enable-vala], [enable Vala binding generation]),
+ [], [enable_vala=check])
+if test "x$enable_introspection" = "xyes" ; then
+ if test "x$enable_vala" != "xno" ; then
+ AC_PATH_PROG(VAPIGEN, vapigen, no)
+ if test "x$VAPIGEN" == "xno"; then
+ if test "x$enable_vala" == "xcheck" ; then
+ enable_vala=no
+ else
+ AC_MSG_ERROR([Cannot find the "vapigen" binary in your PATH])
+ fi
+ fi
+ AC_SUBST(VAPIGEN)
+ fi
+ if test "x$enable_vala" != "xno" ; then
+ AC_MSG_CHECKING([$VAPIGEN support for --metadatadir])
+ $VAPIGEN --help | grep metadatadir 1>/dev/null 2>&1
+ if test $? != 0 ; then
+ if test "x$enable_vala" == "xcheck" ; then
+ enable_vala=no
+ AC_MSG_RESULT([no])
+ else
+ AC_MSG_ERROR(["vapigen" binary in your PATH is too old (< 0.13)])
+ fi
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+ if test "x$enable_vala" = "xcheck" ; then
+ enable_vala=yes
+ fi
+fi
+AM_CONDITIONAL([WITH_VALA], [test "x$enable_vala" = "xyes"])
+
AC_OUTPUT(Makefile
libvirt-designer/Makefile
libvirt-designer.spec
libvirt-designer-1.0.pc
+ vapi/Makefile
docs/Makefile
examples/Makefile)
@@ -83,6 +119,7 @@ AC_MSG_NOTICE([Configuration summary])
AC_MSG_NOTICE([=====================])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([])
+AC_MSG_NOTICE([ Vala API: $enable_vala])
AC_MSG_NOTICE([ examples: $enable_examples])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([])
diff --git a/vapi/Makefile.am b/vapi/Makefile.am
new file mode 100644
index 0000000..0c5d117
--- /dev/null
+++ b/vapi/Makefile.am
@@ -0,0 +1,25 @@
+NULL =
+
+if WITH_VALA
+vapidir = $(datadir)/vala/vapi
+vapi_DATA = \
+ libvirt-designer-1.0.deps \
+ libvirt-designer-1.0.vapi \
+ $(NULL)
+
+libvirt-designer-1.0.vapi: $(top_builddir)/libvirt-designer/LibvirtDesigner-1.0.gir
+ $(AM_V_GEN)$(VAPIGEN) \
+ --vapidir=$(builddir) \
+ --pkg gio-2.0 \
+ --pkg libosinfo-1.0 \
+ --pkg libvirt-gconfig-1.0 \
+ --library libvirt-designer-1.0 \
+ --metadatadir=$(srcdir) \
+ $<
+endif
+
+CLEANFILES = \
+ libvirt-designer-1.0.vapi \
+ $(NULL)
+
+EXTRA_DIST = libvirt-designer-1.0.deps
diff --git a/vapi/libvirt-designer-1.0.deps b/vapi/libvirt-designer-1.0.deps
new file mode 100644
index 0000000..ba30bfd
--- /dev/null
+++ b/vapi/libvirt-designer-1.0.deps
@@ -0,0 +1,2 @@
+libosinfo-1.0
+libvirt-gconfig-1.0
--
1.8.1.4
11 years, 7 months
[libvirt] [libvirt-designer] Add Vala API
by Zeeshan Ali (Khattak)
From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
This is mostly (modified) copy&paste from libvirt-glib.
---
Makefile.am | 2 +-
configure.ac | 37 +++++++++++++++++++++++++++++++++++++
vapi/Makefile.am | 26 ++++++++++++++++++++++++++
vapi/libvirt-designer-1.0.deps | 3 +++
4 files changed, 67 insertions(+), 1 deletion(-)
create mode 100644 vapi/Makefile.am
create mode 100644 vapi/libvirt-designer-1.0.deps
diff --git a/Makefile.am b/Makefile.am
index f5bcc47..53d36ea 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,5 @@
-SUBDIRS = libvirt-designer examples docs
+SUBDIRS = libvirt-designer vapi examples docs
ACLOCAL_AMFLAGS = -I m4
diff --git a/configure.ac b/configure.ac
index a9c5c34..c999826 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,10 +71,46 @@ if test "x$enable_examples" != "xno" ; then
fi
AM_CONDITIONAL(WITH_EXAMPLES, [test "x$enable_examples" = "xyes"])
+AC_ARG_ENABLE([vala],
+ AS_HELP_STRING([--enable-vala], [enable Vala binding generation]),
+ [], [enable_vala=check])
+if test "x$enable_introspection" = "xyes" ; then
+ if test "x$enable_vala" != "xno" ; then
+ AC_PATH_PROG(VAPIGEN, vapigen, no)
+ if test "x$VAPIGEN" == "xno"; then
+ if test "x$enable_vala" == "xcheck" ; then
+ enable_vala=no
+ else
+ AC_MSG_ERROR([Cannot find the "vapigen" binary in your PATH])
+ fi
+ fi
+ AC_SUBST(VAPIGEN)
+ fi
+ if test "x$enable_vala" != "xno" ; then
+ AC_MSG_CHECKING([$VAPIGEN support for --metadatadir])
+ $VAPIGEN --help | grep metadatadir 1>/dev/null 2>&1
+ if test $? != 0 ; then
+ if test "x$enable_vala" == "xcheck" ; then
+ enable_vala=no
+ AC_MSG_RESULT([no])
+ else
+ AC_MSG_ERROR(["vapigen" binary in your PATH is too old (< 0.13)])
+ fi
+ else
+ AC_MSG_RESULT([no])
+ fi
+ fi
+ if test "x$enable_vala" = "xcheck" ; then
+ enable_vala=yes
+ fi
+fi
+AM_CONDITIONAL([WITH_VALA], [test "x$enable_vala" = "xyes"])
+
AC_OUTPUT(Makefile
libvirt-designer/Makefile
libvirt-designer.spec
libvirt-designer-1.0.pc
+ vapi/Makefile
docs/Makefile
examples/Makefile)
@@ -83,6 +119,7 @@ AC_MSG_NOTICE([Configuration summary])
AC_MSG_NOTICE([=====================])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([])
+AC_MSG_NOTICE([ Vala API: $enable_vala])
AC_MSG_NOTICE([ examples: $enable_examples])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([])
diff --git a/vapi/Makefile.am b/vapi/Makefile.am
new file mode 100644
index 0000000..0aecb7e
--- /dev/null
+++ b/vapi/Makefile.am
@@ -0,0 +1,26 @@
+NULL =
+
+if WITH_VALA
+vapidir = $(datadir)/vala/vapi
+vapi_DATA = \
+ libvirt-designer-1.0.deps \
+ libvirt-designer-1.0.vapi \
+ $(NULL)
+
+libvirt-designer-1.0.vapi: $(top_builddir)/libvirt-designer/LibvirtDesigner-1.0.gir
+ $(AM_V_GEN)$(VAPIGEN) \
+ --vapidir=$(builddir) \
+ --pkg gio-2.0 \
+ --pkg libosinfo-1.0 \
+ --pkg libvirt-gobject-1.0 \
+ --pkg libvirt-gconfig-1.0 \
+ --library libvirt-designer-1.0 \
+ --metadatadir=$(srcdir) \
+ $<
+endif
+
+CLEANFILES = \
+ libvirt-designer-1.0.vapi \
+ $(NULL)
+
+EXTRA_DIST = libvirt-designer-1.0.deps
diff --git a/vapi/libvirt-designer-1.0.deps b/vapi/libvirt-designer-1.0.deps
new file mode 100644
index 0000000..757e44e
--- /dev/null
+++ b/vapi/libvirt-designer-1.0.deps
@@ -0,0 +1,3 @@
+libosinfo-1.0
+libvirt-gobject-1.0
+libvirt-gconfig-1.0
--
1.8.1.4
11 years, 7 months
[libvirt] [PATCH] v2:Support for adding a static route to a bridge
by Gene Czarcinski
This patch adds support for adding a static route for
a network. The "via" specifies the gateway's IP
address. Both IPv4 and IPv6 static routes are
supported although it is expected that this
functionality will have more use with IPv6.
Extensive tests are done to validate that the input
definitions are correct. For example, for a static
route ip definition, the address must be for a network
and not a host. Additional checks are added to ensure
that the specified gateway has a network defined on
this bridge.
Whan a static route is added to a bridge, there is a slight
possibility that the gateway address will be incorrect. If
this is handled as an error, that bridge becomes unusable and
can only be recovered by rebooting. If the error is
ignored, then that network can be destroyed and the network
definition file edited to correct the problem. Unfortunately,
the error message only appears in syslog. However, with
the checks performed when the network definition file is parsed,
it is unlikely that this condition will ever occur.
The command used is of the following form:
ip route add <address>/<prefix> via <gateway> dev <virbr-bridge> \
proto static metric 1
.
Signed-off-by: Gene Czarcinski <gene(a)czarc.net>
---
docs/formatnetwork.html.in | 32 +++-
docs/schemas/network.rng | 3 +
src/conf/network_conf.c | 168 ++++++++++++++++++++-
src/conf/network_conf.h | 2 +
src/libvirt_private.syms | 1 +
src/network/bridge_driver.c | 42 ++++++
src/util/virnetdev.c | 47 ++++++
src/util/virnetdev.h | 5 +
.../networkxml2xmlin/dhcp6host-routed-network.xml | 4 +
.../networkxml2xmlout/dhcp6host-routed-network.xml | 4 +
10 files changed, 304 insertions(+), 4 deletions(-)
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index 4dd0415..f0cadf0 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -537,7 +537,9 @@
associated with the virtual network, and optionally enable DHCP
services. These elements are only valid for isolated networks
(no <code>forward</code> element specified), and for those with
- a forward mode of 'route' or 'nat'.
+ a forward mode of 'route' or 'nat'. Another optional addressing
+ element <code>via</code> can be used to establish a static
+ route for IPv4 or IPv6 networks.
</p>
<pre>
@@ -560,6 +562,7 @@
</dhcp>
</ip>
<ip family="ipv6" address="2001:db8:ca2:2::1" prefix="64" />
+ <ip family="ipv6" address="2001:db9:ca1:1::" prefix="64" via="2001:db8:ca2:2::2" />
</network></pre>
<dl>
@@ -633,7 +636,10 @@
IPv6, multiple addresses on a single network, <code>family</code>, and
<code>prefix</code> are support <span class="since">Since 0.8.7</span>.
Similar to IPv4, one IPv6 address per network can also have
- a <code>dhcp</code> definition. <span class="since">Since 1.0.1</span>
+ a <code>dhcp</code> definition. <span class="since">Since 1.0.1</span> The <code>via</code>
+ can be used to establish a static route for IPv4 or IPv6 networks. It is an error
+ to specify <code>via</code> and <code>dhcp</code> for the same IP address.
+ <span class="since">Since 1.0.4</span>
<dl>
<dt><code>tftp</code></dt>
@@ -809,6 +815,28 @@
</ip>
</network></pre>
+ <p>
+ Below is yet another IPv6 variation. This variation has only IPv6
+ defined with DHCPv6 on the primary IPv6 network. A second IPv6
+ network has a static link to a host on the first (virtual) IPv6
+ network. <span class="since">Since 1.0.4</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>
+ <ip family="ipv6" address="2001:db8:ca2:8::" prefix="64" via="2001:db8:ca2::4" >
+ </ip>
+ </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 6c3fae2..c1cca23 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -262,6 +262,9 @@
<attribute name="family"><ref name="addr-family"/></attribute>
</optional>
<optional>
+ <attribute name="via"><ref name="ipAddr"/></attribute>
+ </optional>
+ <optional>
<element name="tftp">
<attribute name="root"><text/></attribute>
</element>
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index c022fe4..ea98d85 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -1149,8 +1149,10 @@ virNetworkIPDefParseXML(const char *networkName,
xmlNodePtr cur, save;
char *address = NULL, *netmask = NULL;
- unsigned long prefix;
+ char *gateway = NULL;
+ unsigned long prefix = 0;
int result = -1;
+ virSocketAddr testAddr;
save = ctxt->node;
ctxt->node = node;
@@ -1162,6 +1164,7 @@ virNetworkIPDefParseXML(const char *networkName,
def->prefix = 0;
else
def->prefix = prefix;
+ gateway = virXPathString("string(./@via)", ctxt);
netmask = virXPathString("string(./@netmask)", ctxt);
@@ -1175,7 +1178,17 @@ virNetworkIPDefParseXML(const char *networkName,
}
- /* validate family vs. address */
+ if (gateway) {
+ if (virSocketAddrParse(&def->gateway, gateway, AF_UNSPEC) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Bad gateway address '%s' in definition of network '%s'"),
+ gateway, networkName);
+ goto cleanup;
+ }
+
+ }
+
+ /* validate family vs. address (and gateway address too) */
if (def->family == NULL) {
if (!(VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET) ||
VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_UNSPEC))) {
@@ -1184,6 +1197,20 @@ virNetworkIPDefParseXML(const char *networkName,
address, networkName);
goto cleanup;
}
+ if (gateway &&
+ (!(VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET) ||
+ VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_UNSPEC)))) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("no family specified for non-IPv4 gateway address '%s' in network '%s'"),
+ address, networkName);
+ goto cleanup;
+ }
+ if (def->prefix > 0 && def->prefix > 32) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid prefix=%u specified for IPv4 address '%s' in network '%s'"),
+ def->prefix, address, networkName);
+ goto cleanup;
+ }
} else if (STREQ(def->family, "ipv4")) {
if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -1191,6 +1218,18 @@ virNetworkIPDefParseXML(const char *networkName,
address, networkName);
goto cleanup;
}
+ if (gateway && (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET))) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("family 'ipv4' specified for non-IPv4 gateway address '%s' in network '%s'"),
+ address, networkName);
+ goto cleanup;
+ }
+ if (def->prefix > 0 && def->prefix > 32) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid prefix=%u specified for IPv4 address '%s' in network '%s'"),
+ def->prefix, address, networkName);
+ goto cleanup;
+ }
} else if (STREQ(def->family, "ipv6")) {
if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET6)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -1198,6 +1237,24 @@ virNetworkIPDefParseXML(const char *networkName,
address, networkName);
goto cleanup;
}
+ if (def->prefix == 0 || def->prefix > 64) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("invalid prefix=%u specified for IPv6 address '%s' in network '%s'"),
+ def->prefix, address, networkName);
+ goto cleanup;
+ }
+ if (netmask) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("specifying netmask invalid for IPv6 address '%s' in network '%s'"),
+ address, networkName);
+ goto cleanup;
+ }
+ if (gateway && (!VIR_SOCKET_ADDR_IS_FAMILY(&def->gateway, AF_INET6))) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("family 'ipv6' specified for non-IPv6 gateway address '%s' in network '%s'"),
+ gateway, networkName);
+ goto cleanup;
+ }
} else {
virReportError(VIR_ERR_XML_ERROR,
_("Unrecognized family '%s' in definition of network '%s'"),
@@ -1241,16 +1298,55 @@ virNetworkIPDefParseXML(const char *networkName,
}
}
+ /* if static route gateway specified, make sure the address is a network address */
+ if (gateway) {
+ if (def->prefix > 0) {
+ if (virSocketAddrMaskByPrefix(&def->address, def->prefix, &testAddr) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("error converting address '%s' with prefix=%u to network-address in network '%s'"),
+ address, def->prefix, networkName);
+ goto cleanup;
+ }
+ }
+ 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 network '%s'"),
+ address, netmask, networkName);
+ goto cleanup;
+ }
+ }
+ if (!virSocketAddrEqual(&def->address, &testAddr)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("address '%s' in network '%s' is not a network-address"),
+ address, networkName);
+ goto cleanup;
+ }
+ }
+
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE &&
xmlStrEqual(cur->name, BAD_CAST "dhcp")) {
+ if (gateway) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("<dhcp> element unsupported when static route (via) previously defined in network '%s'"),
+ networkName);
+ goto cleanup;
+ }
if (virNetworkDHCPDefParseXML(networkName, cur, def) < 0)
goto cleanup;
} else if (cur->type == XML_ELEMENT_NODE &&
xmlStrEqual(cur->name, BAD_CAST "tftp")) {
char *root;
+ if (gateway) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("<tftp> element unsupported when static route (via) previously defined in network '%s'"),
+ networkName);
+ goto cleanup;
+ }
+
if (!VIR_SOCKET_ADDR_IS_FAMILY(&def->address, AF_INET)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unsupported <tftp> element in an IPv6 element in network '%s'"),
@@ -1274,6 +1370,7 @@ cleanup:
}
VIR_FREE(address);
VIR_FREE(netmask);
+ VIR_FREE(gateway);
ctxt->node = save;
return result;
@@ -1828,6 +1925,58 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
goto error;
def->nips++;
}
+ /* now validate the correctness of any static route gateways specified
+ *
+ * note: the parameters within each definition are varified/assumed valid;
+ * the question being asked and answered here is if the specified gateway
+ * address has a network definition on this bridge
+ */
+ for (ii = 0; ii < nIps; ii++) {
+ int jj;
+ virSocketAddr testAddr, testGw;
+ bool addrMatch;
+ virNetworkIpDefPtr gwdef = &def->ips[ii];
+ if (VIR_SOCKET_ADDR_VALID(&gwdef->gateway)) {
+ addrMatch = false;
+ for (jj = 0; jj < nIps; jj++) {
+ virNetworkIpDefPtr def2 = &def->ips[jj];
+ if (VIR_SOCKET_ADDR_VALID(&def2->gateway))
+ continue;
+ if ((VIR_SOCKET_ADDR_IS_FAMILY(&gwdef->gateway, AF_INET6)) &&
+ (!VIR_SOCKET_ADDR_IS_FAMILY(&def2->address, AF_INET6)))
+ continue;
+ if ((VIR_SOCKET_ADDR_IS_FAMILY(&def2->address, AF_INET6)) &&
+ (!VIR_SOCKET_ADDR_IS_FAMILY(&gwdef->gateway, AF_INET6)))
+ continue;
+ if ((VIR_SOCKET_ADDR_IS_FAMILY(&gwdef->gateway, AF_INET) ||
+ VIR_SOCKET_ADDR_IS_FAMILY(&gwdef->gateway, AF_UNSPEC)) &&
+ VIR_SOCKET_ADDR_IS_FAMILY(&def2->address, AF_INET6))
+ continue;
+ if (def2->prefix > 0) {
+ virSocketAddrMaskByPrefix(&def2->address, def2->prefix, &testAddr);
+ virSocketAddrMaskByPrefix(&gwdef->gateway, def2->prefix, &testGw);
+ }
+ if (VIR_SOCKET_ADDR_VALID(&def2->netmask)) {
+ virSocketAddrMask(&def2->address, &def2->netmask, &testAddr);
+ virSocketAddrMask(&gwdef->gateway, &def2->netmask, &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,
+ _("invalid static route gateway specified: '%s'"),
+ gw);
+ VIR_FREE(gw);
+ goto error;
+ }
+ }
+ }
}
VIR_FREE(ipNodes);
@@ -2108,6 +2257,7 @@ virNetworkIpDefFormat(virBufferPtr buf,
const virNetworkIpDefPtr def)
{
int result = -1;
+ bool routeFlg = false;
virBufferAddLit(buf, "<ip");
@@ -2131,15 +2281,29 @@ virNetworkIpDefFormat(virBufferPtr buf,
if (def->prefix > 0) {
virBufferAsprintf(buf," prefix='%u'", def->prefix);
}
+ if (VIR_SOCKET_ADDR_VALID(&def->gateway)) {
+ char *addr = virSocketAddrFormat(&def->gateway);
+ if (!addr)
+ goto error;
+ routeFlg = true;
+ virBufferAsprintf(buf, " via='%s'", addr);
+ VIR_FREE(addr);
+ }
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2);
if (def->tftproot) {
+ if (routeFlg) /* this should not occur */
+ goto error; /* but in case it does, better to error out */
virBufferEscapeString(buf, "<tftp root='%s' />\n",
def->tftproot);
}
if ((def->nranges || def->nhosts)) {
int ii;
+
+ if (routeFlg) /* this should not occur */
+ goto error; /* but in case it does, better to error out */
+
virBufferAddLit(buf, "<dhcp>\n");
virBufferAdjustIndent(buf, 2);
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 6ce9a00..91aff5f 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -115,6 +115,8 @@ struct _virNetworkIpDef {
char *family; /* ipv4 or ipv6 - default is ipv4 */
virSocketAddr address; /* Bridge IP address */
+ virSocketAddr gateway; /* gateway IP address for ip-route */
+
/* One or the other of the following two will be used for a given
* IP address, but never both. The parser guarantees this.
* Use virNetworkIpDefPrefix/virNetworkIpDefNetmask rather
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ed46479..988b97a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1470,6 +1470,7 @@ virNetDevReplaceMacAddress;
virNetDevReplaceNetConfig;
virNetDevRestoreMacAddress;
virNetDevRestoreNetConfig;
+virNetDevSetGateway;
virNetDevSetIPv4Address;
virNetDevSetMAC;
virNetDevSetMTU;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 31c8585..07058f3 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2360,6 +2360,7 @@ out:
return ret;
}
+/* add an IP address to a bridge */
static int
networkAddAddrToBridge(virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
@@ -2380,6 +2381,28 @@ networkAddAddrToBridge(virNetworkObjPtr network,
return 0;
}
+/* add an IP route to a bridge */
+static int
+networkAddRouteToBridge(virNetworkObjPtr network,
+ virNetworkIpDefPtr ipdef)
+{
+ int prefix = virNetworkIpDefPrefix(ipdef);
+
+ if (prefix < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("bridge '%s' has an invalid netmask or IP address"),
+ network->def->bridge);
+ return -1;
+ }
+
+ if (virNetDevSetGateway(network->def->bridge,
+ &ipdef->address,
+ prefix,
+ &ipdef->gateway) < 0)
+ return -1;
+ return 0;
+}
+
static int
networkStartNetworkVirtual(struct network_driver *driver,
virNetworkObjPtr network)
@@ -2446,9 +2469,12 @@ networkStartNetworkVirtual(struct network_driver *driver,
if (networkAddIptablesRules(driver, network) < 0)
goto err1;
+ /* first, do all of the addresses */
for (ii = 0;
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
ii++) {
+ if (VIR_SOCKET_ADDR_VALID(&ipdef->gateway))
+ continue; /* this is a static route specification */
if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET))
v4present = true;
if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6))
@@ -2464,6 +2490,22 @@ networkStartNetworkVirtual(struct network_driver *driver,
if (virNetDevSetOnline(network->def->bridge, 1) < 0)
goto err2;
+ /* then do all of the static routes */
+ for (ii = 0;
+ (ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
+ 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(&ipdef->gateway)) {
+ if (networkAddRouteToBridge(network, ipdef) < 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 296871c..c90b3d2 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -729,6 +729,7 @@ int virNetDevGetVLanID(const char *ifname ATTRIBUTE_UNUSED,
* Add an IP address to an interface. This function *does not* remove
* any previously added IP addresses - that must be done separately with
* brDelInetAddress.
+ * TODO: what is "brDelInetAddress"?
*
* Returns 0 in case of success or -1 in case of error.
*/
@@ -769,6 +770,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 virNetDevSetGateway(const char *ifname,
+ virSocketAddr *addr,
+ unsigned int prefix,
+ virSocketAddr *gateway)
+{
+ 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", NULL);
+ virCommandAddArgFormat(cmd, "%s", gatewaystr);
+ virCommandAddArgList(cmd, "dev", ifname, NULL);
+ virCommandAddArgList(cmd, "proto", "static", "metric", NULL);
+ virCommandAddArgFormat(cmd, "%u", 1);
+
+ 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 06d0650..8b94ea8 100644
--- a/src/util/virnetdev.h
+++ b/src/util/virnetdev.h
@@ -42,6 +42,11 @@ int virNetDevSetIPv4Address(const char *ifname,
virSocketAddr *addr,
unsigned int prefix)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
+int virNetDevSetGateway(const char *ifname,
+ virSocketAddr *addr,
+ unsigned int prefix,
+ virSocketAddr *gateway)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) 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..dcad62d 100644
--- a/tests/networkxml2xmlin/dhcp6host-routed-network.xml
+++ b/tests/networkxml2xmlin/dhcp6host-routed-network.xml
@@ -19,4 +19,8 @@
<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>
+ <ip address="192.168.222.0" netmask="255.255.255.0" via="192.168.122.10">
+ </ip>
+ <ip family="ipv6" address="2001:db8:ac10:fc00::" prefix="64" via="2001:db8:ac10:fd01::1:24">
+ </ip>
</network>
diff --git a/tests/networkxml2xmlout/dhcp6host-routed-network.xml b/tests/networkxml2xmlout/dhcp6host-routed-network.xml
index 7305043..880c2dd 100644
--- a/tests/networkxml2xmlout/dhcp6host-routed-network.xml
+++ b/tests/networkxml2xmlout/dhcp6host-routed-network.xml
@@ -21,4 +21,8 @@
<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>
+ <ip address='192.168.222.0' netmask='255.255.255.0' via='192.168.122.10'>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fc00::' prefix='64' via='2001:db8:ac10:fd01::1:24'>
+ </ip>
</network>
--
1.8.1.4
11 years, 7 months
[libvirt] [PATCH v2] qemu: Set correct migrate host in client_migrate_info
by Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=920441
Currently, we are discarding listen attribute from qemu cookie even though
we strive to gather it. This result in not so cool bug: if user have
different networks, one for management/migration, and one for VNC/SPICE we
pass incorrect host to the qemu in client_migrate_info. What we actually
pass is remote hostname, while we should be passing remote listen address.
It doesn't matter as long as these two are the same, but they don't need
necessary to be like that.
---
src/conf/domain_conf.c | 4 +++-
src/qemu/qemu_migration.c | 6 +++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e00a532..2afa982 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -16557,8 +16557,10 @@ virDomainGraphicsListenGetAddress(virDomainGraphicsDefPtr def, size_t ii)
virDomainGraphicsListenDefPtr listenInfo
= virDomainGraphicsGetListen(def, ii, false);
+ /* even a network can have a listen address */
if (!listenInfo ||
- (listenInfo->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS))
+ !(listenInfo->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS ||
+ listenInfo->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK))
return NULL;
return listenInfo->address;
}
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 41ad768..434b19a 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1720,6 +1720,7 @@ qemuDomainMigrateGraphicsRelocate(virQEMUDriverPtr driver,
{
qemuDomainObjPrivatePtr priv = vm->privateData;
int ret;
+ char *listenAddress = cookie->graphics->listen;
if (!cookie)
return 0;
@@ -1733,12 +1734,15 @@ qemuDomainMigrateGraphicsRelocate(virQEMUDriverPtr driver,
if (cookie->graphics->type != VIR_DOMAIN_GRAPHICS_TYPE_SPICE)
return 0;
+ if (STREQ(listenAddress, "0.0.0.0"))
+ listenAddress = cookie->remoteHostname;
+
ret = qemuDomainObjEnterMonitorAsync(driver, vm,
QEMU_ASYNC_JOB_MIGRATION_OUT);
if (ret == 0) {
ret = qemuMonitorGraphicsRelocate(priv->mon,
cookie->graphics->type,
- cookie->remoteHostname,
+ listenAddress,
cookie->graphics->port,
cookie->graphics->tlsPort,
cookie->graphics->tlsSubject);
--
1.8.1.5
11 years, 7 months
[libvirt] [PATCH] qemu: Set correct migrate host in client_migrate_info
by Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=920441
Currently, we are discarding listen attribute from qemu cookie even though
we strive to gather it. This result in not so cool bug: if user have
different networks, one for management/migration, and one for VNC/SPICE we
pass incorrect host to the qemu in client_migrate_info. What we actually
pass is remote hostname, while we should be passing remote listen address.
It doesn't matter as long as these two are the same, but they don't need
necessary to be like that.
---
src/conf/domain_conf.c | 4 +++-
src/qemu/qemu_migration.c | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e00a532..2afa982 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -16557,8 +16557,10 @@ virDomainGraphicsListenGetAddress(virDomainGraphicsDefPtr def, size_t ii)
virDomainGraphicsListenDefPtr listenInfo
= virDomainGraphicsGetListen(def, ii, false);
+ /* even a network can have a listen address */
if (!listenInfo ||
- (listenInfo->type != VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS))
+ !(listenInfo->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_ADDRESS ||
+ listenInfo->type == VIR_DOMAIN_GRAPHICS_LISTEN_TYPE_NETWORK))
return NULL;
return listenInfo->address;
}
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 41ad768..089b75a 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1738,7 +1738,7 @@ qemuDomainMigrateGraphicsRelocate(virQEMUDriverPtr driver,
if (ret == 0) {
ret = qemuMonitorGraphicsRelocate(priv->mon,
cookie->graphics->type,
- cookie->remoteHostname,
+ cookie->graphics->listen,
cookie->graphics->port,
cookie->graphics->tlsPort,
cookie->graphics->tlsSubject);
--
1.8.1.5
11 years, 7 months
Re: [libvirt] [Qemu-devel] GSoC 2013, "Introduce API to query IP addresses for given domain" Libvirt project
by Stefan Hajnoczi
On Wed, Apr 10, 2013 at 04:46:45AM +0200, Tabibel Sami wrote:
> I am doing master degree of Cryptology and information security
> I have good C and Python skills, and i am interested to work on
> "Introduce API to query IP addresses for given domain" Libvirt
> project.
>
> I am looking for any comment about the difficulty and the content of
> the project, and also about my chances to be accepted if i apply for.
Adding libvirt mailing list and CCing mprivozn who is the mentor for
this project.
Stefan
11 years, 7 months