[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 3/3] Make dnsmasq started from libvirtd with --dhcp-hostsfile option



This patch makes dnsmasq daemon started from libvirtd with a
--dhcp-hostsfile option instead of --dhcp-host options for each
'//ip/dhcp/host' entries.


NOTE: I'm not sure where and when to save the dnsmasq hostsfile so that
make it saved in dnsmasq's local statedir when network is defined or
started in the meantime. Especially, I would like to get some advices
for this.  (I'm afraid that NETWORK_STATE_DIR is inappropriate as
dnsmasq process will run as nobody and it will not be able to
read the saved hostsfile.) 


Signed-off-by: Satoru SATOH <satoru satoh gmail com>
---

 src/network/bridge_driver.c |   76 +++++++++++++++++++++++++++++++++---------
 1 files changed, 59 insertions(+), 17 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 83ab00e..65ffc8b 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -57,10 +57,13 @@
 #include "iptables.h"
 #include "bridge.h"
 #include "logging.h"
+#include "dnsmasq.h"
 
 #define NETWORK_PID_DIR LOCAL_STATE_DIR "/run/libvirt/network"
 #define NETWORK_STATE_DIR LOCAL_STATE_DIR "/lib/libvirt/network"
 
+#define DNSMASQ_STATE_DIR LOCAL_STATE_DIR "/lib/dnsmasq"
+
 #define VIR_FROM_THIS VIR_FROM_NETWORK
 
 #define networkReportError(code, ...)                                   \
@@ -361,6 +364,29 @@ networkShutdown(void) {
 
 
 static int
+networkSaveDnsmasqHostsfile(virNetworkObjPtr network,
+                            dnsmasqContext *dnsmasqctx,
+                            int force)
+{
+    int r;
+
+    if (!force && virFileExists(dnsmasqctx->hostsfile->path))
+        return 1;
+
+    for (r = 0 ; r < network->def->nhosts ; r++) {
+        virNetworkDHCPHostDefPtr host = &(network->def->hosts[r]);
+        if ((host->mac) && (host->ip) && (host->name))
+            dnsmasqAddDhcpHost(dnsmasqctx, host->mac, host->ip, host->name);
+    }
+
+    if (! dnsmasqSave(dnsmasqctx))
+        return 0;
+
+    return 1;
+}
+
+
+static int
 networkBuildDnsmasqArgv(virNetworkObjPtr network,
                         const char *pidfile,
                         const char ***argv) {
@@ -401,8 +427,8 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
         (2 * network->def->nranges) + /* --dhcp-range 10.0.0.2,10.0.0.254 */
         /* --dhcp-lease-max=xxx if needed */
         (network->def->nranges ? 0 : 1) +
-        /*  --dhcp-host 01:23:45:67:89:0a,hostname,10.0.0.3 */
-        (2 * network->def->nhosts) +
+        /* --dhcp-hostsfile=/var/lib/libvirt/network/$netname.hostsfile */
+        (network->def->nhosts > 0 ? 1 : 0) +
         /* --enable-tftp --tftp-root /srv/tftp */
         (network->def->tftproot ? 3 : 0) +
         /* --dhcp-boot pxeboot.img[,,12.34.56.78] */
@@ -473,22 +499,20 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
         APPEND_ARG(*argv, i++, buf);
     }
 
-    for (r = 0 ; r < network->def->nhosts ; r++) {
-        virNetworkDHCPHostDefPtr host = &(network->def->hosts[r]);
-        if ((host->mac) && (host->name)) {
-            snprintf(buf, sizeof(buf), "%s,%s,%s",
-                     host->mac, host->name, host->ip);
-        } else if (host->mac) {
-            snprintf(buf, sizeof(buf), "%s,%s",
-                     host->mac, host->ip);
-        } else if (host->name) {
-            snprintf(buf, sizeof(buf), "%s,%s",
-                     host->name, host->ip);
-        } else
-            continue;
+    if (network->def->nhosts > 0) {
+        dnsmasqContext *dctx = dnsmasqContextNew(network->def->name, DNSMASQ_STATE_DIR);
+        char *hostsfileArg;
 
-        APPEND_ARG(*argv, i++, "--dhcp-host");
-        APPEND_ARG(*argv, i++, buf);
+        if (dctx == NULL)
+            goto no_memory;
+
+        if (networkSaveDnsmasqHostsfile(network, dctx, 0)) {
+            if (virAsprintf(&hostsfileArg, "--dhcp-hostsfile=%s", dctx->hostsfile->path) < 0)
+                goto no_memory;
+            APPEND_ARG_LIT(*argv, i++, hostsfileArg);
+        }
+
+        dnsmasqContextFree(dctx);
     }
 
     if (network->def->tftproot) {
@@ -1294,6 +1318,15 @@ static virNetworkPtr networkDefine(virConnectPtr conn, const char *xml) {
         goto cleanup;
     }
 
+    if (network->def->nhosts > 0) {
+        dnsmasqContext *dctx = dnsmasqContextNew(network->def->name, DNSMASQ_STATE_DIR);
+        if (dctx == NULL)
+            goto cleanup;
+
+        networkSaveDnsmasqHostsfile(network, dctx, 1);
+        dnsmasqContextFree(dctx);
+    }
+
     ret = virGetNetwork(conn, network->def->name, network->def->uuid);
 
 cleanup:
@@ -1329,6 +1362,15 @@ static int networkUndefine(virNetworkPtr net) {
                                network) < 0)
         goto cleanup;
 
+    if (network->def->nhosts > 0) {
+        dnsmasqContext *dctx = dnsmasqContextNew(network->def->name, DNSMASQ_STATE_DIR);
+        if (dctx == NULL)
+            goto cleanup;
+
+        dnsmasqDelete(dctx);
+        dnsmasqContextFree(dctx);
+    }
+
     virNetworkRemoveInactive(&driver->networks,
                              network);
     network = NULL;
-- 
1.6.6.1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]