Tue Feb 14 16:04:48 IST 2007 Mark McLoughlin <markmc@redhat.com>

* qemud/conf.c, qemud/internal.h: add dhcp config

        * qemud/qemud.c: start dnsmasq to provide dns/dhcp
        for virtual networks.
This commit is contained in:
Mark McLoughlin 2007-02-14 16:05:29 +00:00
parent c3373b92a0
commit ee777358b8
4 changed files with 320 additions and 11 deletions

114
ChangeLog
View File

@ -1,21 +1,115 @@
Tue Feb 14 15:03:22 EST 2007 Mark McLoughlin <markmc@redhat.com>
Tue Feb 14 16:04:48 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c, qemud/internal.h: add dhcp config
* qemud/qemud.c: start dnsmasq to provide dns/dhcp
for virtual networks.
Tue Feb 14 16:02:23 IST 2007 Mark McLoughlin <markmc@redhat.com>
* configure.in: add --disable-bridge-params, check
for libsysfs and various kernel headers
* bridge.[ch]: add code for managing bridges
* qemud/Makefile.am: add bridge.[ch] and link against
libsysfs if enabled.
* qemud/conf.c: add support for bridge config.
* qemud/internal.h: add various bridging bits
* qemud/qemud.c: implement qemudStartNetworkDaemon()
and qemudShutdownNetworkDaemon().
Tue Feb 14 15:55:02 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.[ch]: implement parsing and saving network
configs.
* qemud/driver.c: flesh out the stubs
* qemud/internal.h: add networks list etc. to
struct qemud_server
* qemud/qemud.c: add qemudStartNetworkDaemon() and
qemudShutdownNetworkDaemon() stubs.
Tue Feb 14 15:52:34 EST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/protocol.h: add the protocol for virtual networks
* qemud/dispatch.c: implement the protocol
* qemud/driver.[ch]: add stubs for the driver
* qemud/internal.h: add struct qemud_network
* src/qemu_internal.c: add a virtual networks driver
Tue Feb 14 15:43:28 IST 2007 Mark McLoughlin <markmc@redhat.com>
* src/virsh.c: add the net-* commands.
Tue Feb 14 15:37:17 IST 2007 Mark McLoughlin <markmc@redhat.com>
Note: potential ABI break here, but people should
only really be using virError structs returned from
libvirt itself.
* include/libvirt/virterror.h: add virNetwork
to virError
* src/internal.h, src/virterror.c: add network param
to __virRaiseError()
* src/conf.c, src/hash.c, src/libvirt.c, src/proxy_internal.c,
src/qemu_internal.c, src/sexpr.c, src/test.c, src/xen_internal.c,
src/xend_internal.c, src/xm_internal.c, src/xml.c, src/xmlrpc.c,
src/xs_internal.c: update.
Tue Feb 14 15:33:05 IST 2007 Mark McLoughlin <markmc@redhat.com>
* include/libvirt/libvirt.h.in: add the networks APIs
* include/libvirt/virterror.h: add some error codes
* src/driver.h: add network driver vtable
* src/hash.c: add networks hash
* src/internal.h: add virNetwork
* src/libvirt.c: hook up the APIs to the network
driver
* src/libvirt_sym.version: add the new APIs
* src/virterror.c: handle the new error codes
Tue Feb 14 15:07:26 IST 2007 Mark McLoughlin <markmc@redhat.com>
* src/conf.h: fix merge error - remove the argc argument
from qemudBuildCommandLine()
Tue Feb 14 15:03:22 IST 2007 Mark McLoughlin <markmc@redhat.com>
* src/virsh.c: Re-name some of the VSH_DOMBYFOO stuff
to VSH_BYFOO in order to re-use it for the network stuff.
Tue Feb 14 14:58:35 EST 2007 Mark McLoughlin <markmc@redhat.com>
Tue Feb 14 14:58:35 IST 2007 Mark McLoughlin <markmc@redhat.com>
* src/hash.c, src/internal.h: Re-name virConnect->domains_mux
to virConnect->hashes_mux since it will also be used to
protect the networks hash.
Tue Feb 14 14:57:52 EST 2007 Mark McLoughlin <markmc@redhat.com>
Tue Feb 14 14:57:52 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c: qemudSaveConfig() will always report a
more specific error, so we should avoid overwriting
this error.
Tue Feb 14 14:54:25 EST 2007 Mark McLoughlin <markmc@redhat.com>
Tue Feb 14 14:54:25 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/qemud.c: Re-factor out qemudExec() so that it can
be used to launch dnsmasq.
@ -23,7 +117,7 @@ Tue Feb 14 14:54:25 EST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c: don't return argc from qemudBuildCommandLine()
as exec() doesn't need it.
Tue Feb 14 14:52:12 EST 2007 Mark McLoughlin <markmc@redhat.com>
Tue Feb 14 14:52:12 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c: Re-factor bits of conf.c so that:
@ -33,25 +127,25 @@ Tue Feb 14 14:52:12 EST 2007 Mark McLoughlin <markmc@redhat.com>
- split qemudScanConfigDir() out so that qemudScanConfigs()
can scan multiple configDirs
Tue Feb 14 14:50:22 EST 2007 Mark McLoughlin <markmc@redhat.com>
Tue Feb 14 14:50:22 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c: handle an unspecified MAC address,
fix the argv freeing code in qemudBuildCommandLine()
and fix copy and paste error in qemudGenerateXML()
Tue Feb 14 14:42:38 EST 2007 Mark McLoughlin <markmc@redhat.com>
Tue Feb 14 14:42:38 IST 2007 Mark McLoughlin <markmc@redhat.com>
* src/internal.h: add virConnect->qemud_fd so that
xen and qemu don't share the handle member.
* src/hash.c, src/qemu_internal.c: update
Tue Feb 14 14:40:52 EST 2007 Mark McLoughlin <markmc@redhat.com>
Tue Feb 14 14:40:52 IST 2007 Mark McLoughlin <markmc@redhat.com>
* qemud/conf.c, qemud/dispatch.c, qemud/driver.c,
qemud/qemud.c: include autoconf's config.h
Tue Feb 14 14:39:18 EST 2007 Mark McLoughlin <markmc@redhat.com>
Tue Feb 14 14:39:18 IST 2007 Mark McLoughlin <markmc@redhat.com>
* conf.[ch]: rename from config.[ch] so we can use
autoconf's config.h
@ -60,7 +154,7 @@ Tue Feb 14 14:39:18 EST 2007 Mark McLoughlin <markmc@redhat.com>
* driver.c, qemud.c: upd.
Tue Feb 14 14:33:22 EST 2007 Mark McLoughlin <markmc@redhat.com>
Tue Feb 14 14:33:22 IST 2007 Mark McLoughlin <markmc@redhat.com>
* autogen.sh: run autoheader

View File

@ -1099,6 +1099,12 @@ struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
void qemudFreeNetwork(struct qemud_network *network) {
struct qemud_dhcp_range_def *range = network->def.ranges;
while (range) {
struct qemud_dhcp_range_def *next = range->next;
free(range);
range = next;
}
free(network);
}
@ -1177,11 +1183,61 @@ static int qemudParseBridgeXML(struct qemud_server *server ATTRIBUTE_UNUSED,
return 1;
}
static int qemudParseDhcpRangesXML(struct qemud_server *server,
struct qemud_network *network,
xmlNodePtr node) {
xmlNodePtr cur;
cur = node->children;
while (cur != NULL) {
struct qemud_dhcp_range_def *range;
xmlChar *start, *end;
if (cur->type != XML_ELEMENT_NODE ||
!xmlStrEqual(cur->name, BAD_CAST "range")) {
cur = cur->next;
continue;
}
if (!(range = calloc(1, sizeof(struct qemud_dhcp_range_def)))) {
qemudReportError(server, VIR_ERR_NO_MEMORY, "range");
return 0;
}
start = xmlGetProp(cur, BAD_CAST "start");
end = xmlGetProp(cur, BAD_CAST "end");
if (start && start[0] && end && end[0]) {
strncpy(range->start, (const char *)start, BR_INET_ADDR_MAXLEN-1);
range->start[BR_INET_ADDR_MAXLEN-1] = '\0';
strncpy(range->end, (const char *)end, BR_INET_ADDR_MAXLEN-1);
range->end[BR_INET_ADDR_MAXLEN-1] = '\0';
range->next = network->def.ranges;
network->def.ranges = range;
network->def.nranges++;
} else {
free(range);
}
if (start)
xmlFree(start);
if (end)
xmlFree(end);
cur = cur->next;
}
return 1;
}
static int qemudParseInetXML(struct qemud_server *server ATTRIBUTE_UNUSED,
struct qemud_network *network,
xmlNodePtr node) {
xmlChar *address, *netmask;
xmlNodePtr cur;
address = xmlGetProp(node, BAD_CAST "address");
if (address != NULL) {
@ -1199,6 +1255,15 @@ static int qemudParseInetXML(struct qemud_server *server ATTRIBUTE_UNUSED,
netmask = NULL;
}
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE &&
xmlStrEqual(cur->name, BAD_CAST "dhcp") &&
!qemudParseDhcpRangesXML(server, network, cur))
return 0;
cur = cur->next;
}
return 1;
}
@ -1724,7 +1789,24 @@ char *qemudGenerateNetworkXML(struct qemud_server *server,
qemudBufferPrintf(&buf, " netmask='%s'", network->def.netmask) < 0)
goto no_memory;
if (qemudBufferAdd(&buf, "/>\n") < 0)
if (qemudBufferAdd(&buf, ">\n") < 0)
goto no_memory;
if (network->def.ranges) {
struct qemud_dhcp_range_def *range = network->def.ranges;
if (qemudBufferAdd(&buf, " <dhcp>\n") < 0)
goto no_memory;
while (range) {
if (qemudBufferPrintf(&buf, " <range start='%s' end='%s' />\n",
range->start, range->end) < 0)
goto no_memory;
range = range->next;
}
if (qemudBufferAdd(&buf, " </dhcp>\n") < 0)
goto no_memory;
}
if (qemudBufferAdd(&buf, " </ip>\n") < 0)
goto no_memory;
}

View File

@ -200,6 +200,14 @@ struct qemud_vm {
struct qemud_vm *next;
};
/* Store start and end addresses of a dhcp range */
struct qemud_dhcp_range_def {
char start[BR_INET_ADDR_MAXLEN];
char end[BR_INET_ADDR_MAXLEN];
struct qemud_dhcp_range_def *next;
};
/* Virtual Network main configuration */
struct qemud_network_def {
unsigned char uuid[QEMUD_UUID_RAW_LEN];
@ -211,6 +219,9 @@ struct qemud_network_def {
char ipAddress[BR_INET_ADDR_MAXLEN];
char netmask[BR_INET_ADDR_MAXLEN];
int nranges;
struct qemud_dhcp_range_def *ranges;
};
/* Virtual Network runtime state */
@ -220,6 +231,7 @@ struct qemud_network {
struct qemud_network_def def;
char bridge[BR_IFNAME_MAXLEN];
int dnsmasqPid;
unsigned int active : 1;

View File

@ -703,6 +703,105 @@ static int qemudDispatchVMFailure(struct qemud_server *server, struct qemud_vm *
return 0;
}
static int
qemudBuildDnsmasqArgv(struct qemud_server *server,
struct qemud_network *network,
char ***argv) {
int i, len;
char buf[BR_INET_ADDR_MAXLEN * 2];
struct qemud_dhcp_range_def *range;
len =
1 + /* dnsmasq */
1 + /* --keep-in-foreground */
1 + /* --bind-interfaces */
2 + /* --pid-file "" */
2 + /* --conf-file "" */
2 + /* --except-interface lo */
2 + /* --listen-address 10.0.0.1 */
(2 * network->def.nranges) + /* --dhcp-range 10.0.0.2,10.0.0.254 */
1; /* NULL */
if (!(*argv = malloc(len * sizeof(char *))))
goto no_memory;
memset(*argv, 0, len * sizeof(char *));
#define APPEND_ARG(v, n, s) do { \
if (!((v)[(n)] = strdup(s))) \
goto no_memory; \
} while (0)
i = 0;
APPEND_ARG(*argv, i++, "dnsmasq");
APPEND_ARG(*argv, i++, "--keep-in-foreground");
APPEND_ARG(*argv, i++, "--bind-interfaces");
APPEND_ARG(*argv, i++, "--pid-file");
APPEND_ARG(*argv, i++, "");
APPEND_ARG(*argv, i++, "--conf-file");
APPEND_ARG(*argv, i++, "");
APPEND_ARG(*argv, i++, "--except-interface");
APPEND_ARG(*argv, i++, "lo");
APPEND_ARG(*argv, i++, "--listen-address");
APPEND_ARG(*argv, i++, network->def.ipAddress);
range = network->def.ranges;
while (range) {
snprintf(buf, sizeof(buf), "%s,%s",
range->start, range->end);
APPEND_ARG(*argv, i++, "--dhcp-range");
APPEND_ARG(*argv, i++, buf);
range = range->next;
}
#undef APPEND_ARG
return 0;
no_memory:
if (argv) {
for (i = 0; (*argv)[i]; i++)
free((*argv)[i]);
free(*argv);
}
qemudReportError(server, VIR_ERR_NO_MEMORY, "dnsmasq argv");
return -1;
}
static int
dhcpStartDhcpDaemon(struct qemud_server *server,
struct qemud_network *network)
{
char **argv;
int ret, i;
if (network->def.ipAddress[0] == '\0') {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"cannot start dhcp daemon without IP address for server");
return -1;
}
argv = NULL;
if (qemudBuildDnsmasqArgv(server, network, &argv) < 0)
return -1;
ret = qemudExec(server, argv, &network->dnsmasqPid, NULL, NULL);
for (i = 0; argv[i]; i++)
free(argv[i]);
free(argv);
return ret;
}
int qemudStartNetworkDaemon(struct qemud_server *server,
struct qemud_network *network) {
@ -758,10 +857,21 @@ int qemudStartNetworkDaemon(struct qemud_server *server,
goto err_delbr;
}
if (network->def.ranges &&
dhcpStartDhcpDaemon(server, network) < 0)
goto err_delbr1;
network->active = 1;
return 0;
err_delbr1:
if (network->def.ipAddress[0] &&
(err = brSetInterfaceUp(server->brctl, network->bridge, 0))) {
printf("Damn! Failed to bring down bridge '%s' : %s\n",
network->bridge, strerror(err));
}
err_delbr:
if ((err = brDeleteBridge(server->brctl, network->bridge))) {
printf("Damn! Couldn't delete bridge '%s' : %s\n",
@ -780,6 +890,9 @@ int qemudShutdownNetworkDaemon(struct qemud_server *server,
if (!network->active)
return 0;
if (network->dnsmasqPid > 0)
kill(network->dnsmasqPid, SIGTERM);
if (network->def.ipAddress[0] &&
(err = brSetInterfaceUp(server->brctl, network->bridge, 0))) {
printf("Damn! Failed to bring down bridge '%s' : %s\n",
@ -812,7 +925,15 @@ int qemudShutdownNetworkDaemon(struct qemud_server *server,
curr = curr->next;
}
if (network->dnsmasqPid > 0 &&
waitpid(network->dnsmasqPid, NULL, WNOHANG) != network->dnsmasqPid) {
kill(network->dnsmasqPid, SIGKILL);
if (waitpid(network->dnsmasqPid, NULL, 0) != network->dnsmasqPid)
printf("Got unexpected pid for dnsmasq, damn\n");
}
network->bridge[0] = '\0';
network->dnsmasqPid = -1;
network->active = 0;
return 0;