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 * src/virsh.c: Re-name some of the VSH_DOMBYFOO stuff
to VSH_BYFOO in order to re-use it for the network 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 * src/hash.c, src/internal.h: Re-name virConnect->domains_mux
to virConnect->hashes_mux since it will also be used to to virConnect->hashes_mux since it will also be used to
protect the networks hash. 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 * qemud/conf.c: qemudSaveConfig() will always report a
more specific error, so we should avoid overwriting more specific error, so we should avoid overwriting
this error. 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 * qemud/qemud.c: Re-factor out qemudExec() so that it can
be used to launch dnsmasq. 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() * qemud/conf.c: don't return argc from qemudBuildCommandLine()
as exec() doesn't need it. 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: * 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() - split qemudScanConfigDir() out so that qemudScanConfigs()
can scan multiple configDirs 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, * qemud/conf.c: handle an unspecified MAC address,
fix the argv freeing code in qemudBuildCommandLine() fix the argv freeing code in qemudBuildCommandLine()
and fix copy and paste error in qemudGenerateXML() 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 * src/internal.h: add virConnect->qemud_fd so that
xen and qemu don't share the handle member. xen and qemu don't share the handle member.
* src/hash.c, src/qemu_internal.c: update * 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/conf.c, qemud/dispatch.c, qemud/driver.c,
qemud/qemud.c: include autoconf's config.h 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 * conf.[ch]: rename from config.[ch] so we can use
autoconf's config.h 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. * 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 * autogen.sh: run autoheader

View File

@ -1099,6 +1099,12 @@ struct qemud_vm *qemudLoadConfigXML(struct qemud_server *server,
void qemudFreeNetwork(struct qemud_network *network) { 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); free(network);
} }
@ -1177,11 +1183,61 @@ static int qemudParseBridgeXML(struct qemud_server *server ATTRIBUTE_UNUSED,
return 1; 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, static int qemudParseInetXML(struct qemud_server *server ATTRIBUTE_UNUSED,
struct qemud_network *network, struct qemud_network *network,
xmlNodePtr node) { xmlNodePtr node) {
xmlChar *address, *netmask; xmlChar *address, *netmask;
xmlNodePtr cur;
address = xmlGetProp(node, BAD_CAST "address"); address = xmlGetProp(node, BAD_CAST "address");
if (address != NULL) { if (address != NULL) {
@ -1199,6 +1255,15 @@ static int qemudParseInetXML(struct qemud_server *server ATTRIBUTE_UNUSED,
netmask = NULL; 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; return 1;
} }
@ -1724,7 +1789,24 @@ char *qemudGenerateNetworkXML(struct qemud_server *server,
qemudBufferPrintf(&buf, " netmask='%s'", network->def.netmask) < 0) qemudBufferPrintf(&buf, " netmask='%s'", network->def.netmask) < 0)
goto no_memory; 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; goto no_memory;
} }

View File

@ -200,6 +200,14 @@ struct qemud_vm {
struct qemud_vm *next; 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 */ /* Virtual Network main configuration */
struct qemud_network_def { struct qemud_network_def {
unsigned char uuid[QEMUD_UUID_RAW_LEN]; unsigned char uuid[QEMUD_UUID_RAW_LEN];
@ -211,6 +219,9 @@ struct qemud_network_def {
char ipAddress[BR_INET_ADDR_MAXLEN]; char ipAddress[BR_INET_ADDR_MAXLEN];
char netmask[BR_INET_ADDR_MAXLEN]; char netmask[BR_INET_ADDR_MAXLEN];
int nranges;
struct qemud_dhcp_range_def *ranges;
}; };
/* Virtual Network runtime state */ /* Virtual Network runtime state */
@ -220,6 +231,7 @@ struct qemud_network {
struct qemud_network_def def; struct qemud_network_def def;
char bridge[BR_IFNAME_MAXLEN]; char bridge[BR_IFNAME_MAXLEN];
int dnsmasqPid;
unsigned int active : 1; unsigned int active : 1;

View File

@ -703,6 +703,105 @@ static int qemudDispatchVMFailure(struct qemud_server *server, struct qemud_vm *
return 0; 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, int qemudStartNetworkDaemon(struct qemud_server *server,
struct qemud_network *network) { struct qemud_network *network) {
@ -758,10 +857,21 @@ int qemudStartNetworkDaemon(struct qemud_server *server,
goto err_delbr; goto err_delbr;
} }
if (network->def.ranges &&
dhcpStartDhcpDaemon(server, network) < 0)
goto err_delbr1;
network->active = 1; network->active = 1;
return 0; 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: err_delbr:
if ((err = brDeleteBridge(server->brctl, network->bridge))) { if ((err = brDeleteBridge(server->brctl, network->bridge))) {
printf("Damn! Couldn't delete bridge '%s' : %s\n", printf("Damn! Couldn't delete bridge '%s' : %s\n",
@ -780,6 +890,9 @@ int qemudShutdownNetworkDaemon(struct qemud_server *server,
if (!network->active) if (!network->active)
return 0; return 0;
if (network->dnsmasqPid > 0)
kill(network->dnsmasqPid, SIGTERM);
if (network->def.ipAddress[0] && if (network->def.ipAddress[0] &&
(err = brSetInterfaceUp(server->brctl, network->bridge, 0))) { (err = brSetInterfaceUp(server->brctl, network->bridge, 0))) {
printf("Damn! Failed to bring down bridge '%s' : %s\n", printf("Damn! Failed to bring down bridge '%s' : %s\n",
@ -812,7 +925,15 @@ int qemudShutdownNetworkDaemon(struct qemud_server *server,
curr = curr->next; 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->bridge[0] = '\0';
network->dnsmasqPid = -1;
network->active = 0; network->active = 0;
return 0; return 0;