]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Tue Feb 14 16:04:48 IST 2007 Mark McLoughlin <markmc@redhat.com>
authorMark McLoughlin <markmc@redhat.com>
Wed, 14 Feb 2007 16:05:29 +0000 (16:05 +0000)
committerMark McLoughlin <markmc@redhat.com>
Wed, 14 Feb 2007 16:05:29 +0000 (16:05 +0000)
        * qemud/conf.c, qemud/internal.h: add dhcp config

        * qemud/qemud.c: start dnsmasq to provide dns/dhcp
        for virtual networks.

ChangeLog
qemud/conf.c
qemud/internal.h
qemud/qemud.c

index 21207d84c37f21721a1f62793c9920b636a4c4f6..7373e45b78ef929c848dd72476b227713568b48b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
-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
 
index da80dfc048dbc89fb2b9cfbe042a9385b42732a2..cbca964d4c6bb71b5a9630c316a39d07a6ffaa21 100644 (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;
     }
 
index 95528291233eb0624b6b522e9d131b43bf8ee12c..6f249f603ec6607e1501eb2f32ca343b27bd76e3 100644 (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;
 
index 061eaecd91a73c6d5b4be6b967fc3a19d7af62c3..32310966cb778508a89840c2ed109e6af9d89e00 100644 (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;