[libvirt] beta libvirt-java port uploaded
by Daniel Schwager
Hi,
we are using libvirt in our softwaredemo.de plattform (launching in 2 or 3 weeks)..
Because I saw some thread relating to the java-port, I uploaded our modified version (SNAPSHOT of my eclipse-workspace,
based on the Tóth István libvir-java port - e.g. http://www.mail-archive.com/libvir-list@redhat.com/msg03131.html) to
http://www.softwaredemo.de/index.php?id=154
for free access.
At the moment, it's does not support all the XML-elements, because if haven't enough time to update it out XSD-file - but I works
with the current libvirt 0.4.4-1 (-: - and work for us ....
The uploaded java-project depends on some other (internal) staff of our company (devtools, ivy-repository), so it will
not compile out-of-the-box for you - sorry for this at the moment.
The TGZ includes all
Dependant libs in lib/compiler
Dependant infos in output/ivy-report
Output artifacts in output/artifact (jar-files for using to access libvirt ...)
If there are people wanting to work-on/update/extend these sources, I will think about
adapting our individual-company-dependant project-build-framework to run everywhere
(replace our ivy-repos with public maven-repos, insert the missing ant-scripts, ...)
Maybe it could be also a good input for other people's to restart the libvirt-java project for their own
(look into the project and uses some fragemets/ideas - staf, testing, buildprocess, ..)
Thx to libvirt-community
Danny
(from softwaredemo.de ;-)
If you have question, please ask (-:
16 years, 5 months
[libvirt] PATCH: Fix memory leak in OOM cleanup for capabilities
by Daniel P. Berrange
The combo of the OOM testing and valgrind identified a place where we fail
to correctly free memory when cleaning up from an OOM failure in the NUMA
code for capabilities. This patch addresses that problem
Daniel
diff -r 0f3ebb9e7958 src/capabilities.c
--- a/src/capabilities.c Thu Jul 03 11:42:29 2008 +0100
+++ b/src/capabilities.c Thu Jul 03 14:24:20 2008 +0100
@@ -224,17 +224,19 @@
if (VIR_ALLOC(cell) < 0)
return -1;
- caps->host.numaCell[caps->host.nnumaCell] = cell;
- if (VIR_ALLOC_N(caps->host.numaCell[caps->host.nnumaCell]->cpus,
- ncpus) < 0)
+ if (VIR_ALLOC_N(cell->cpus, ncpus) < 0) {
+ VIR_FREE(cell);
return -1;
- memcpy(caps->host.numaCell[caps->host.nnumaCell]->cpus,
+ }
+ memcpy(cell->cpus,
cpus,
ncpus * sizeof(*cpus));
- caps->host.numaCell[caps->host.nnumaCell]->ncpus = ncpus;
- caps->host.numaCell[caps->host.nnumaCell]->num = num;
+ cell->ncpus = ncpus;
+ cell->num = num;
+
+ caps->host.numaCell[caps->host.nnumaCell] = cell;
caps->host.nnumaCell++;
return 0;
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
16 years, 5 months
[libvirt] PATCH: Parallelize OOM testing
by Daniel P. Berrange
The OOM testing takes a long time to run. Add in valgrind, and it takes a
very very very long time to run. My dev box has 8 cpus though and it'd be
nice to use all 8 rather than just 1 to cut the time by a factor of 8. So
this patch tweaks the control harness for the OOM testrig so that it can
fork off multiple worker processes. Each worker is assigned a number from
1 -> n, and will be responsible for test all allocations failures divisible
by their number.
By default it still runs single process, but if you set VIR_TEST_MP=1 then
we use sysconf() to get the actual number of online CPUs and fork off one
worker per CPU.
eg, so to run the OOM testing with valgrind, parallelized
$ VIR_TEST_MP=1 VIR_TEST_OOM=1 make valgrind
Or to run a test directly
$ VIR_TEST_MP=1 VIR_TEST_OOM=1 valgrind --leak-check=full ./xmconfigtest
Daniel
diff -r 3548706d639f tests/testutils.c
--- a/tests/testutils.c Thu Jul 03 14:24:20 2008 +0100
+++ b/tests/testutils.c Thu Jul 03 14:24:40 2008 +0100
@@ -330,7 +330,9 @@
int n;
char *oomStr = NULL, *debugStr;
int oomCount;
-
+ int mp = 0;
+ pid_t *workers;
+ int worker = 0;
if ((debugStr = getenv("VIR_TEST_DEBUG")) != NULL) {
if (virStrToLong_ui(debugStr, NULL, 10, &testDebug) < 0)
testDebug = 0;
@@ -344,6 +346,13 @@
oomCount = 0;
if (oomCount)
testOOM = 1;
+ }
+
+ if (getenv("VIR_TEST_MP") != NULL) {
+ mp = sysconf(_SC_NPROCESSORS_ONLN);
+ fprintf(stderr, "Using %d worker processes\n", mp);
+ if (VIR_ALLOC_N(workers, mp) < 0)
+ return EXIT_FAILURE;
}
if (testOOM)
@@ -371,11 +380,27 @@
else
fprintf(stderr, "%d) OOM of %d allocs ", testCounter, approxAlloc);
+ if (mp) {
+ int i;
+ for (i = 0 ; i < mp ; i++) {
+ workers[i] = fork();
+ if (workers[i] == 0) {
+ worker = i + 1;
+ break;
+ }
+ }
+ }
+
/* Run once for each alloc, failing a different one
and validating that the test case failed */
- for (n = 0; n < approxAlloc ; n++) {
+ for (n = 0; n < approxAlloc && (!mp || worker) ; n++) {
+ if ((n % mp) != (worker - 1))
+ continue;
if (!testDebug) {
- fprintf(stderr, ".");
+ if (mp)
+ fprintf(stderr, "%d", worker);
+ else
+ fprintf(stderr, ".");
fflush(stderr);
}
virAllocTestOOM(n+1, oomCount);
@@ -383,6 +408,20 @@
if (((func)(argc, argv)) != EXIT_FAILURE) {
ret = EXIT_FAILURE;
break;
+ }
+ }
+
+ if (mp) {
+ if (worker) {
+ _exit(ret);
+ } else {
+ int i, status;
+ for (i = 0 ; i < mp ; i++) {
+ waitpid(workers[i], &status, 0);
+ if (WEXITSTATUS(status) != EXIT_SUCCESS)
+ ret = EXIT_FAILURE;
+ }
+ VIR_FREE(workers);
}
}
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
16 years, 5 months
[libvirt] <script path='...'/> ignored for interface types 'bridge' and 'network'
by Emele, Joshua M
Hello,
I'm new to libvirt, but I've looked around the internet for answers to
my question with little success. I'd like to have a configuration script
do host network integration when starting a virtual machine using virsh.
The documentation
(http://libvirt.org/formatdomain.html#elementsNICSBridge) suggests that
the interface configuration can include a script tag that describes the
path to the configuration script. My domain configuration
(/etc/libvirt/qemu/test1.xml) includes:
<interface type='bridge'>
<source bridge='br0'/>
<script path='/etc/libvirt/qemu/test1-networking'/>
</interface>
Unfortunately this value is never used. I'm using:
[root@thoroughbred qemu]# rpm -qi libvirt
Name : libvirt Relocations: (not
relocatable)
Version : 0.4.3 Vendor: Fedora
Project
Release : 1.fc8 Build Date: Fri 13 Jun
2008 03:15:16 AM PDT
Looking at the source, the script value is used when 'ethernet' is
specified (libvirt-0.4.3/src/qemu_conf.c:2690):
case QEMUD_NET_ETHERNET:
{
char arg[PATH_MAX];
if (snprintf(arg, PATH_MAX-1,
"tap,ifname=%s,script=%s,vlan=%d",
net->dst.ethernet.ifname,
net->dst.ethernet.script,
vlan) >= (PATH_MAX-1))
goto error;
ADD_ARG_LIT(arg);
}
However, the script value is not used when 'bridge' or 'network' is
specified (libvirt-0.4.3/src/qemu_conf.c:2313):
snprintf(tapfdstr, sizeof(tapfdstr),
"tap,fd=%d,script=,vlan=%d,ifname=%s",
tapfd, vlan, ifname);
Is there a way to force libvirt to use the specified script with
interface type 'network' or 'bridge'? If not, are there plans in the
future to do so?
Cheers,
Joshua Emele
16 years, 5 months
[libvirt] [PATCH] Return VIR_ERR_NO_SUPPORT in qemu SetMemory()/SetVcpus() if domain is active.
by Kaitlin Rupert
qemu doesn't support setting the memory or vcpus of an active guest. In
this case, use the VIR_ERR_NO_SUPPORT return code to indicate that the
action failed because its not supported.
Index: src/qemu_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_driver.c,v
retrieving revision 1.85
diff -u -p -r1.85 qemu_driver.c
--- src/qemu_driver.c 10 Jun 2008 10:43:28 -0000 1.85
+++ src/qemu_driver.c 11 Jun 2008 20:35:09 -0000
@@ -2148,7 +2148,7 @@ static int qemudDomainSetMemory(virDomai
}
if (qemudIsActiveVM(vm)) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT,
"%s", _("cannot set memory of an active
domain"));
return -1;
}
@@ -2404,7 +2404,7 @@ static int qemudDomainSetVcpus(virDomain
}
if (qemudIsActiveVM(vm)) {
- qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR,
"%s",
+ qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, "%s",
_("cannot change vcpu count of an active
domain"));
return -1;
}
--
Kaitlin Rupert
IBM Linux Technology Center
kaitlin(a)linux.vnet.ibm.com
16 years, 5 months
[Libvir] Re: libvirt on mingw
by Richard W.M. Jones
Brecht Sanders wrote:
> Hi,
> I saw on the following link:
> http://www.mail-archive.com/libvir-list@redhat.com/msg04103.html
> that you are also trying to compile libvirt on win32.
> I'm also attempting to do this, and I guess I got stuck at the same
> point your post was about.
> Have you in the mean time found an XDR implementation that compiles on
> MinGW and that implements xdr_u_quad_t?
> If you did, can you please tell me where to find it?
You'll find the answer to this question and more if you look through the
libvir-list archives for the current month:
https://www.redhat.com/archives/libvir-list/2008-January/thread.html
Rich.
--
Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/
Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
Street, Windsor, Berkshire, SL4 1TE, United Kingdom. Registered in
England and Wales under Company Registration No. 03798903
16 years, 5 months
[libvirt] RFC: virt-console
by John Levon
See implementation here:
http://cr.opensolaris.org/~johnlev/virt-console/
(inside libvirt.hg/patches/libvirt/virt-console)
This splits virsh console into a separate binary to allow it to be
setuid-root on Solaris (where we check permissions then drop privilege).
It also fixes a number of RFEs
This is against 0.4.0, so it's not ready for merging yet (I hope to get
it forward ported at some point).
regards
john
16 years, 5 months
[libvirt] PATCH: Generic internal API for network XML parser/formatter
by Daniel P. Berrange
We currently have two drivers which handle the networking XML containing
duplicated parsers and formatters for the XML, and very similar structs.
This patch introduces a new general purpose internal API for parsing and
formatting network XML, and representing it as a series of structs.
This code is derived from the current equivalent code in the QEMU driver
for networks.
The naming conventions I'm adopting in this patch follow those in the
storage driver:
- virNetworkPtr - the public opaque object in libvirt.h
- virNetworkObjPtr - the primary internal object for network state
- virNetworkDefPtr - the configuration data for a network
A virNetworkObjPtr contains a reference to one or two virNetworkDefPtr
objects - the current live config, and potentially a secondary inactive
config which will become live at the next restart.
The structs are defined in network_conf.h, along with a bunch of APIs for
dealing with them. These APIs are the same as similarly named ones from
the current qemu driver, but I'll go over them again for a reminder:
virNetworkObjPtr virNetworkFindByUUID(const virNetworkObjPtr nets,
const unsigned char *uuid);
virNetworkObjPtr virNetworkFindByName(const virNetworkObjPtr nets,
const char *name);
Allow lookup of a virNetworkObjPtr object based on its name or UUID, as
typically obtained from the public virNetworkPtr object.
The 'nets' parameter to both of thse is a linked list of networks which
are currently known to the driver using this API.
void virNetworkDefFree(virNetworkDefPtr def);
void virNetworkObjFree(virNetworkObjPtr net);
Convenience APIs to totally free the memory associated with these
objects.
virNetworkObjPtr virNetworkAssignDef(virConnectPtr conn,
virNetworkObjPtr *nets,
const virNetworkDefPtr def);
Given a virNetworkDefPtr object, it'll search for a pre-existing
virNetworkObjPtr object with matching config. If one is found, its
config will be updated, otherwise a new object will be allocated.
void virNetworkRemoveInactive(virNetworkObjPtr *nets,
const virNetworkObjPtr net);
Convenience for removing and free'ing a virNetworkObjPtr object in
the current list of active networks.
virNetworkDefPtr virNetworkDefParse(virConnectPtr conn,
const char *xmlStr,
const char *displayName);
Given an XML document describing a network, parses the doc and generates
a virNetworkDefPtr to represent it in memory.
char *virNetworkDefFormat(virConnectPtr conn,
const virNetworkDefPtr def);
Given a virNetworkDefPtr object, generate a XML document describing the
network.
As a mentioned earlier, the impl of these APIs is just copied from the QEMU
driver, but instead of using pre-declared char[PATH_MAX] fields, we allocate
memory for strings as required.
Regards,
Daniel
diff -r a6e5acdd23df src/Makefile.am
--- a/src/Makefile.am Tue Jun 24 15:07:21 2008 +0100
+++ b/src/Makefile.am Tue Jun 24 15:07:23 2008 +0100
@@ -52,6 +52,7 @@
driver.h \
proxy_internal.c proxy_internal.h \
conf.c conf.h \
+ network_conf.c network_conf.h \
xm_internal.c xm_internal.h \
remote_internal.c remote_internal.h \
bridge.c bridge.h \
diff -r a6e5acdd23df src/network_conf.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network_conf.c Tue Jun 24 15:07:23 2008 +0100
@@ -0,0 +1,467 @@
+/*
+ * network_conf.h: network XML handling
+ *
+ * Copyright (C) 2006-2008 Red Hat, Inc.
+ * Copyright (C) 2006-2008 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+
+
+#include <config.h>
+
+#include <arpa/inet.h>
+
+#include "internal.h"
+
+#include "network_conf.h"
+#include "memory.h"
+#include "xml.h"
+#include "uuid.h"
+#include "util.h"
+#include "buf.h"
+
+VIR_ENUM_DECL(virNetworkForward)
+
+VIR_ENUM_IMPL(virNetworkForward,
+ VIR_NETWORK_FORWARD_LAST,
+ "none", "nat", "route" )
+
+static void virNetworkReportError(virConnectPtr conn,
+ int code, const char *fmt, ...)
+{
+ va_list args;
+ char errorMessage[1024];
+ const char *virerr;
+
+ if (fmt) {
+ va_start(args, fmt);
+ vsnprintf(errorMessage, sizeof(errorMessage)-1, fmt, args);
+ va_end(args);
+ } else {
+ errorMessage[0] = '\0';
+ }
+
+ virerr = __virErrorMsg(code, (errorMessage[0] ? errorMessage : NULL));
+ __virRaiseError(conn, NULL, NULL, VIR_FROM_QEMU, code, VIR_ERR_ERROR,
+ virerr, errorMessage, NULL, -1, -1, virerr, errorMessage);
+}
+
+
+virNetworkObjPtr virNetworkFindByUUID(const virNetworkObjPtr nets,
+ const unsigned char *uuid)
+{
+ virNetworkObjPtr net = nets;
+ while (net) {
+ if (!memcmp(net->def->uuid, uuid, VIR_UUID_BUFLEN))
+ return net;
+ net = net->next;
+ }
+
+ return NULL;
+}
+
+virNetworkObjPtr virNetworkFindByName(const virNetworkObjPtr nets,
+ const char *name)
+{
+ virNetworkObjPtr net = nets;
+ while (net) {
+ if (STREQ(net->def->name, name))
+ return net;
+ net = net->next;
+ }
+
+ return NULL;
+}
+
+
+void virNetworkDefFree(virNetworkDefPtr def)
+{
+ int i;
+
+ if (!def)
+ return;
+
+ VIR_FREE(def->name);
+ VIR_FREE(def->bridge);
+ VIR_FREE(def->forwardDev);
+ VIR_FREE(def->ipAddress);
+ VIR_FREE(def->network);
+ VIR_FREE(def->netmask);
+
+ for (i = 0 ; i < def->nranges && def->ranges ; i++) {
+ VIR_FREE(def->ranges[i].start);
+ VIR_FREE(def->ranges[i].end);
+ }
+ VIR_FREE(def->ranges);
+
+ VIR_FREE(def);
+}
+
+void virNetworkObjFree(virNetworkObjPtr net)
+{
+ if (!net)
+ return;
+
+ virNetworkDefFree(net->def);
+ virNetworkDefFree(net->newDef);
+
+ VIR_FREE(net->configFile);
+ VIR_FREE(net->autostartLink);
+
+ VIR_FREE(net);
+}
+
+virNetworkObjPtr virNetworkAssignDef(virConnectPtr conn,
+ virNetworkObjPtr *nets,
+ const virNetworkDefPtr def)
+{
+ virNetworkObjPtr network;
+
+ if ((network = virNetworkFindByName(*nets, def->name))) {
+ if (!virNetworkIsActive(network)) {
+ virNetworkDefFree(network->def);
+ network->def = def;
+ } else {
+ if (network->newDef)
+ virNetworkDefFree(network->newDef);
+ network->newDef = def;
+ }
+
+ return network;
+ }
+
+ if (VIR_ALLOC(network) < 0) {
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ return NULL;
+ }
+
+ network->def = def;
+ network->next = *nets;
+
+ *nets = network;
+
+ return network;
+
+}
+
+void virNetworkRemoveInactive(virNetworkObjPtr *nets,
+ const virNetworkObjPtr net)
+{
+ virNetworkObjPtr prev = NULL;
+ virNetworkObjPtr curr = *nets;
+
+ while (curr &&
+ curr != net) {
+ prev = curr;
+ curr = curr->next;
+ }
+
+ if (curr) {
+ if (prev)
+ prev->next = curr->next;
+ else
+ *nets = curr->next;
+ }
+
+ virNetworkObjFree(net);
+}
+
+
+static int
+virNetworkDHCPRangeDefParseXML(virConnectPtr conn,
+ virNetworkDefPtr def,
+ xmlNodePtr node) {
+
+ xmlNodePtr cur;
+
+ cur = node->children;
+ while (cur != NULL) {
+ xmlChar *start, *end;
+
+ if (cur->type != XML_ELEMENT_NODE ||
+ !xmlStrEqual(cur->name, BAD_CAST "range")) {
+ cur = cur->next;
+ continue;
+ }
+
+ if (!(start = xmlGetProp(cur, BAD_CAST "start"))) {
+ cur = cur->next;
+ continue;
+ }
+ if (!(end = xmlGetProp(cur, BAD_CAST "end"))) {
+ cur = cur->next;
+ xmlFree(start);
+ continue;
+ }
+
+ if (VIR_REALLOC_N(def->ranges, def->nranges + 1) < 0) {
+ xmlFree(start);
+ xmlFree(end);
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ return -1;
+ }
+ def->ranges[def->nranges].start = (char *)start;
+ def->ranges[def->nranges].end = (char *)end;
+ def->nranges++;
+
+ cur = cur->next;
+ }
+
+ return 0;
+}
+
+static virNetworkDefPtr
+virNetworkDefParseXML(virConnectPtr conn,
+ xmlDocPtr xml)
+{
+ xmlNodePtr root = NULL;
+ xmlXPathContextPtr ctxt = NULL;
+ virNetworkDefPtr def;
+ char *tmp;
+
+ if (VIR_ALLOC(def) < 0) {
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ return NULL;
+ }
+
+ /* Prepare parser / xpath context */
+ root = xmlDocGetRootElement(xml);
+ if ((root == NULL) || (!xmlStrEqual(root->name, BAD_CAST "network"))) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("incorrect root element"));
+ goto error;
+ }
+
+ ctxt = xmlXPathNewContext(xml);
+ if (ctxt == NULL) {
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY,
+ "%s", _("failed to allocate space for xmlXPathContext string"));
+ goto error;
+ }
+
+
+ /* Extract network name */
+ def->name = virXPathString("string(/network/name[1])", ctxt);
+ if (!def->name) {
+ virNetworkReportError(conn, VIR_ERR_NO_NAME, NULL);
+ goto error;
+ }
+
+ /* Extract network uuid */
+ tmp = virXPathString("string(/network/uuid[1])", ctxt);
+ if (!tmp) {
+ int err;
+ if ((err = virUUIDGenerate(def->uuid))) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("Failed to generate UUID: %s"), strerror(err));
+ goto error;
+ }
+ } else {
+ if (virUUIDParse(tmp, def->uuid) < 0) {
+ VIR_FREE(tmp);
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("malformed uuid element"));
+ goto error;
+ }
+ VIR_FREE(tmp);
+ }
+
+ /* Parse bridge information */
+ def->bridge = virXPathString("string(/network/bridge[1]/@name)", ctxt);
+ tmp = virXPathString("string(/network/bridge[1]/@stp)", ctxt);
+ if (tmp && STREQ(tmp, "off"))
+ def->stp = 0;
+ else
+ def->stp = 1;
+ VIR_FREE(tmp);
+
+ if (virXPathLong("string(/network/bridge[1]/@delay)", ctxt, &def->delay) < 0)
+ def->delay = 0;
+
+ def->ipAddress = virXPathString("string(/network/ip[1]/@address)", ctxt);
+ def->netmask = virXPathString("string(/network/ip[1]/@netmask)", ctxt);
+ if (def->ipAddress &&
+ def->netmask) {
+ /* XXX someday we want IPv6 too, so inet_aton won't work there */
+ struct in_addr inaddress, innetmask;
+ char *netaddr;
+ int netlen;
+ xmlNodePtr dhcp;
+
+ if (!inet_aton(def->ipAddress, &inaddress)) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse IP address '%s'"),
+ def->ipAddress);
+ goto error;
+ }
+ if (!inet_aton(def->netmask, &innetmask)) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse netmask '%s'"),
+ def->netmask);
+ goto error;
+ }
+
+ inaddress.s_addr &= innetmask.s_addr;
+ netaddr = inet_ntoa(inaddress);
+
+ netlen = strlen(netaddr) + 1 + strlen(def->netmask) + 1;
+ if (VIR_ALLOC_N(def->network, netlen) < 0) {
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ goto error;
+ }
+ strcpy(def->network, netaddr);
+ strcat(def->network, "/");
+ strcat(def->network, def->netmask);
+
+
+ if ((dhcp = virXPathNode("/network/ip[1]/dhcp[1]", ctxt)) &&
+ virNetworkDHCPRangeDefParseXML(conn, def, dhcp) < 0)
+ goto error;
+ }
+
+
+ /* IPv4 forwarding setup */
+ if (virXPathBoolean("count(/network/forward) > 0", ctxt)) {
+ if (!def->ipAddress ||
+ !def->netmask) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Forwarding requested, but no IPv4 address/netmask provided"));
+ goto error;
+ }
+
+ tmp = virXPathString("string(/network/forward[1]/@mode)", ctxt);
+ if (tmp) {
+ if ((def->forwardType = virNetworkForwardTypeFromString(tmp)) < 0) {
+ virNetworkReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("unknown forwarding type '%s'"), tmp);
+ VIR_FREE(tmp);
+ }
+ VIR_FREE(tmp);
+ } else {
+ def->forwardType = VIR_NETWORK_FORWARD_NAT;
+ }
+
+
+ def->forwardDev = virXPathString("string(/network/forward[1]/@dev)", ctxt);
+ } else {
+ def->forwardType = VIR_NETWORK_FORWARD_NONE;
+ }
+
+ xmlXPathFreeContext(ctxt);
+
+ return def;
+
+ error:
+ xmlXPathFreeContext(ctxt);
+ virNetworkDefFree(def);
+ return NULL;
+}
+
+virNetworkDefPtr virNetworkDefParse(virConnectPtr conn,
+ const char *xmlStr,
+ const char *displayName)
+{
+ xmlDocPtr xml;
+ virNetworkDefPtr def;
+
+ if (!(xml = xmlReadDoc(BAD_CAST xmlStr, displayName ? displayName : "network.xml", NULL,
+ XML_PARSE_NOENT | XML_PARSE_NONET |
+ XML_PARSE_NOERROR | XML_PARSE_NOWARNING))) {
+ virNetworkReportError(conn, VIR_ERR_XML_ERROR, NULL);
+ return NULL;
+ }
+
+ def = virNetworkDefParseXML(conn, xml);
+
+ xmlFreeDoc(xml);
+
+ return def;
+}
+
+char *virNetworkDefFormat(virConnectPtr conn,
+ const virNetworkDefPtr def)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ unsigned char *uuid;
+ char *tmp;
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+ virBufferAddLit(&buf, "<network>\n");
+ virBufferVSprintf(&buf, " <name>%s</name>\n", def->name);
+
+ uuid = def->uuid;
+ virUUIDFormat(uuid, uuidstr);
+ virBufferVSprintf(&buf, " <uuid>%s</uuid>\n", uuidstr);
+
+ if (def->forwardType != VIR_NETWORK_FORWARD_NONE) {
+ const char *mode = virNetworkForwardTypeToString(def->forwardType);
+ if (mode) {
+ if (def->forwardDev) {
+ virBufferVSprintf(&buf, " <forward dev='%s' mode='%s'/>\n",
+ def->forwardDev, mode);
+ } else {
+ virBufferVSprintf(&buf, " <forward mode='%s'/>\n", mode);
+ }
+ }
+ }
+
+ virBufferAddLit(&buf, " <bridge");
+ if (def->bridge)
+ virBufferVSprintf(&buf, " name='%s'", def->bridge);
+ virBufferVSprintf(&buf, " stp='%s' forwardDelay='%ld' />\n",
+ def->stp ? "on" : "off",
+ def->delay);
+
+ if (def->ipAddress || def->netmask) {
+ virBufferAddLit(&buf, " <ip");
+
+ if (def->ipAddress)
+ virBufferVSprintf(&buf, " address='%s'", def->ipAddress);
+
+ if (def->netmask)
+ virBufferVSprintf(&buf, " netmask='%s'", def->netmask);
+
+ virBufferAddLit(&buf, ">\n");
+
+ if (def->nranges) {
+ int i;
+ virBufferAddLit(&buf, " <dhcp>\n");
+ for (i = 0 ; i < def->nranges ; i++)
+ virBufferVSprintf(&buf, " <range start='%s' end='%s' />\n",
+ def->ranges[i].start, def->ranges[i].end);
+ virBufferAddLit(&buf, " </dhcp>\n");
+ }
+
+ virBufferAddLit(&buf, " </ip>\n");
+ }
+
+ virBufferAddLit(&buf, "</network>\n");
+
+ if (virBufferError(&buf))
+ goto no_memory;
+
+ return virBufferContentAndReset(&buf);
+
+ no_memory:
+ virNetworkReportError(conn, VIR_ERR_NO_MEMORY, NULL);
+ tmp = virBufferContentAndReset(&buf);
+ VIR_FREE(tmp);
+ return NULL;
+}
+
diff -r a6e5acdd23df src/network_conf.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/network_conf.h Tue Jun 24 15:07:23 2008 +0100
@@ -0,0 +1,114 @@
+/*
+ * network_conf.h: network XML handling
+ *
+ * Copyright (C) 2006-2008 Red Hat, Inc.
+ * Copyright (C) 2006-2008 Daniel P. Berrange
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Author: Daniel P. Berrange <berrange(a)redhat.com>
+ */
+
+#ifndef __NETWORK_CONF_H__
+#define __NETWORK_CONF_H__
+
+#include "internal.h"
+
+/* 2 possible types of forwarding */
+enum virNetworkForwardType {
+ VIR_NETWORK_FORWARD_NONE = 0,
+ VIR_NETWORK_FORWARD_NAT,
+ VIR_NETWORK_FORWARD_ROUTE,
+
+ VIR_NETWORK_FORWARD_LAST,
+};
+
+typedef struct _virNetworkDHCPRangeDef virNetworkDHCPRangeDef;
+typedef virNetworkDHCPRangeDef *virNetworkDHCPRangeDefPtr;
+struct _virNetworkDHCPRangeDef {
+ char *start;
+ char *end;
+};
+
+typedef struct _virNetworkDef virNetworkDef;
+typedef virNetworkDef *virNetworkDefPtr;
+struct _virNetworkDef {
+ unsigned char uuid[VIR_UUID_BUFLEN];
+ char *name;
+
+ char *bridge; /* Name of bridge device */
+ int stp : 1; /* Spanning tree protocol */
+ long delay; /* Bridge forward delay (ms) */
+
+ int forwardType; /* One of virNetworkForwardType constants */
+ char *forwardDev; /* Destination device for forwarding */
+
+ char *ipAddress; /* Bridge IP address */
+ char *netmask;
+ char *network;
+
+ int nranges; /* Zero or more dhcp ranges */
+ virNetworkDHCPRangeDefPtr ranges;
+};
+
+typedef struct _virNetworkObj virNetworkObj;
+typedef virNetworkObj *virNetworkObjPtr;
+struct _virNetworkObj {
+ int dnsmasqPid;
+ unsigned int active : 1;
+ unsigned int autostart : 1;
+ unsigned int persistent : 1;
+
+ char *configFile; /* Persistent config file path */
+ char *autostartLink; /* Symlink path for autostart */
+
+ virNetworkDefPtr def; /* The current definition */
+ virNetworkDefPtr newDef; /* New definition to activate at shutdown */
+
+ virNetworkObjPtr next;
+};
+
+static inline int
+virNetworkIsActive(const virNetworkObjPtr net)
+{
+ return net->active;
+}
+
+
+virNetworkObjPtr virNetworkFindByUUID(const virNetworkObjPtr nets,
+ const unsigned char *uuid);
+virNetworkObjPtr virNetworkFindByName(const virNetworkObjPtr nets,
+ const char *name);
+
+
+void virNetworkDefFree(virNetworkDefPtr def);
+void virNetworkObjFree(virNetworkObjPtr net);
+
+virNetworkObjPtr virNetworkAssignDef(virConnectPtr conn,
+ virNetworkObjPtr *nets,
+ const virNetworkDefPtr def);
+void virNetworkRemoveInactive(virNetworkObjPtr *nets,
+ const virNetworkObjPtr net);
+
+virNetworkDefPtr virNetworkDefParse(virConnectPtr conn,
+ const char *xmlStr,
+ const char *displayName);
+
+char *virNetworkDefFormat(virConnectPtr conn,
+ const virNetworkDefPtr def);
+
+
+#endif /* __NETWORK_CONF_H__ */
+
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
16 years, 5 months