Re: [PATCH v5 4/5] Network: Add additional hosts internal infrastructure

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

 



On 06/14/2011 09:02 AM, Michal Novotny wrote:
Signed-off-by: Michal Novotny<minovotn@xxxxxxxxxx>
---
  docs/formatnetwork.html.in  |   14 ++
  src/libvirt_private.syms    |    1 +
  src/network/bridge_driver.c |    3 +
  src/util/dnsmasq.c          |  285 ++++++++++++++++++++++++++++++++++++++++---
  src/util/dnsmasq.h          |   22 +++-
  5 files changed, 305 insertions(+), 20 deletions(-)

diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index 62e1e08..a036545 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -218,6 +218,20 @@
          element is used.  The BOOTP options currently have to be the same
          for all address ranges and statically assigned addresses.<span
          class="since">Since 0.7.1 (<code>server</code>  since 0.7.3).</span>
+</dd>
+<dt><code>host</code></dt>
+<dd>The<code>host</code>  element is the definition of DNS hosts to be passed
+         to the DNS service. The IP address is identified by the<code>ip</code>  attribute
+         and the names for the IP addresses are identified in the<code>hostname</code>
+         subelements of the<code>host</code>  element.
+<span class="since">Since 0.9.1</span>
+</dd>
+<dt><code>host</code></dt>
+<dd>The<code>host</code>  element is the definition of DNS hosts to be passed
+        to the DNS service. The IP address is identified by the<code>ip</code>  attribute
+        and the names for the IP addresses are identified in the<code>hostname</code>
+        subelements of the<code>host</code>  element.
+<span class="since">Since 0.9.1</span>
        </dd>
      </dl>

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 737cd31..71ef9cc 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -194,6 +194,7 @@ virUnrefStream;

  # dnsmasq.h
  dnsmasqAddDhcpHost;
+dnsmasqAddHost;
  dnsmasqContextFree;
  dnsmasqContextNew;
  dnsmasqDelete;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 10bb928..f55f759 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -607,6 +607,9 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
              if (dctx->hostsfile->nhosts)
                  virCommandAddArgPair(cmd, "--dhcp-hostsfile",
                                       dctx->hostsfile->path);
+            if (dctx->addnhostsfile->nhosts)
+                virCommandAddArgPair(cmd, "--addn-hosts",
+                                     dctx->addnhostsfile->path);

              dnsmasqContextFree(dctx);
          }
diff --git a/src/util/dnsmasq.c b/src/util/dnsmasq.c
index 2ba9355..04a912a 100644
--- a/src/util/dnsmasq.c
+++ b/src/util/dnsmasq.c
@@ -48,6 +48,7 @@

  #define VIR_FROM_THIS VIR_FROM_NETWORK
  #define DNSMASQ_HOSTSFILE_SUFFIX "hostsfile"
+#define DNSMASQ_ADDNHOSTSFILE_SUFFIX "addnhosts"

  static void
  dhcphostFree(dnsmasqDhcpHost *host)
@@ -56,6 +57,235 @@ dhcphostFree(dnsmasqDhcpHost *host)
  }

  static void
+addnhostFree(dnsmasqAddnHost *host)
+{
+    int i;
+
+    for (i = 0; i<  host->nhostnames; i++)
+        VIR_FREE(host->hostnames[i]);
+    VIR_FREE(host->hostnames);
+    VIR_FREE(host->ip);
+}
+
+static void
+addnhostsFree(dnsmasqAddnHostsfile *addnhostsfile)
+{
+    unsigned int i;
+
+    if (addnhostsfile->hosts) {
+        for (i = 0; i<  addnhostsfile->nhosts; i++)
+            addnhostFree(&addnhostsfile->hosts[i]);
+
+        VIR_FREE(addnhostsfile->hosts);
+
+        addnhostsfile->nhosts = 0;
+    }
+
+    VIR_FREE(addnhostsfile->path);
+
+    VIR_FREE(addnhostsfile);
+}
+
+static int
+addnhostsAdd(dnsmasqAddnHostsfile *addnhostsfile,
+             virSocketAddr *ip,
+             const char *name)
+{
+    char *ipstr = NULL;
+    int idx = -1;
+    int i;
+
+    if (!(ipstr = virSocketFormatAddr(ip)))
+        return -1;
+
+    for (i = 0; i<  addnhostsfile->nhosts; i++) {
+        if (STREQ((const char *)addnhostsfile->hosts[i].ip, (const char *)ipstr)) {
+            idx = i;
+            break;
+        }
+    }
+
+    if (idx<  0) {
+        if (VIR_REALLOC_N(addnhostsfile->hosts, addnhostsfile->nhosts + 1)<  0)
+            goto alloc_error;
+
+        idx = addnhostsfile->nhosts;
+        if (VIR_ALLOC(addnhostsfile->hosts[idx].hostnames)<  0)
+            goto alloc_error;
+
+        if (virAsprintf(&addnhostsfile->hosts[idx].ip, "%s", ipstr)<  0)
+            goto alloc_error;
+
+        addnhostsfile->hosts[idx].nhostnames = 0;
+        addnhostsfile->nhosts++;
+    }
+
+    if (VIR_REALLOC_N(addnhostsfile->hosts[idx].hostnames, addnhostsfile->hosts[idx].nhostnames + 1)<  0)
+        goto alloc_error;
+
+    if (virAsprintf(&addnhostsfile->hosts[idx].hostnames[addnhostsfile->hosts[idx].nhostnames], "%s", name)<  0)
+        goto alloc_error;
+
+    VIR_FREE(ipstr);
+
+    addnhostsfile->hosts[idx].nhostnames++;
+
+    return 0;
+
+ alloc_error:
+    virReportOOMError();
+    VIR_FREE(ipstr);
+    return -1;
+}
+
+static dnsmasqAddnHostsfile *
+addnhostsNew(const char *name,
+             const char *config_dir)
+{
+    int err;
+    dnsmasqAddnHostsfile *addnhostsfile;
+
+    if (VIR_ALLOC(addnhostsfile)<  0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    addnhostsfile->hosts = NULL;
+    addnhostsfile->nhosts = 0;
+
+    if (virAsprintf(&addnhostsfile->path, "%s/%s.%s", config_dir, name,
+                    DNSMASQ_ADDNHOSTSFILE_SUFFIX)<  0) {
+        virReportOOMError();
+        goto error;
+    }
+
+    if ((err = virFileMakePath(config_dir))) {
+        virReportSystemError(err, _("cannot create config directory '%s'"),
+                             config_dir);
+        goto error;
+    }
+
+    return addnhostsfile;
+
+ error:
+    addnhostsFree(addnhostsfile);
+    return NULL;
+}
+
+static int
+addnhostsWrite(const char *path,
+               dnsmasqAddnHost *hosts,
+               unsigned int nhosts)
+{
+    char *tmp;
+    FILE *f;
+    bool istmp = true;
+    unsigned int i, ii;
+    int rc = 0;
+
+    if (nhosts == 0)
+        return rc;
+
+    if (virAsprintf(&tmp, "%s.new", path)<  0)
+        return -ENOMEM;
+
+    if (!(f = fopen(tmp, "w"))) {
+        istmp = false;
+        if (!(f = fopen(path, "w"))) {
+            rc = errno;
+            goto cleanup;
+        }
+    }
+
+    for (i = 0; i<  nhosts; i++) {
+        if (fputs(hosts[i].ip, f) == EOF || fputc('\t', f) == EOF) {
+            rc = errno;
+            VIR_FORCE_FCLOSE(f);
+
+            if (istmp)
+                unlink(tmp);
+
+            goto cleanup;
+        }
+
+        for (ii = 0; ii<  hosts[i].nhostnames; ii++) {
+            if (fputs(hosts[i].hostnames[ii], f) == EOF || fputc('\t', f) == EOF) {
+                rc = errno;
+                VIR_FORCE_FCLOSE(f);
+
+                if (istmp)
+                    unlink(tmp);
+
+                goto cleanup;
+            }
+        }
+
+        if (fputc('\n', f) == EOF) {
+            rc = errno;
+            VIR_FORCE_FCLOSE(f);
+
+            if (istmp)
+                unlink(tmp);
+
+            goto cleanup;
+        }
+    }
+
+    if (VIR_FCLOSE(f) == EOF) {
+        rc = errno;
+        goto cleanup;
+    }
+
+    if (istmp) {
+        if (rename(tmp, path)<  0) {
+            rc = errno;
+            unlink(tmp);
+            goto cleanup;
+        }
+
+        if (unlink(tmp)<  0) {
+            rc = errno;
+            goto cleanup;
+        }
+    }
+
+ cleanup:
+    VIR_FREE(tmp);
+
+    return rc;
+}
+
+static int
+addnhostsSave(dnsmasqAddnHostsfile *addnhostsfile)
+{
+    int err = addnhostsWrite(addnhostsfile->path, addnhostsfile->hosts,
+                             addnhostsfile->nhosts);
+
+    if (err<  0) {
+        virReportSystemError(err, _("cannot write config file '%s'"),
+                             addnhostsfile->path);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int
+genericFileDelete(char *path)
+{
+    if (!virFileExists(path))
+        return 0;
+
+    if (unlink(path)<  0) {
+        virReportSystemError(errno, _("cannot remove config file '%s'"),
+                             path);
+        return -1;
+    }
+
+    return 0;
+}
+
+static void
  hostsfileFree(dnsmasqHostsfile *hostsfile)
  {
      unsigned int i;
@@ -220,21 +450,6 @@ hostsfileSave(dnsmasqHostsfile *hostsfile)
      return 0;
  }

-static int
-hostsfileDelete(dnsmasqHostsfile *hostsfile)
-{
-    if (!virFileExists(hostsfile->path))
-        return 0;
-
-    if (unlink(hostsfile->path)<  0) {
-        virReportSystemError(errno, _("cannot remove config file '%s'"),
-                             hostsfile->path);
-        return -1;
-    }
-
-    return 0;
-}
-
  /**
   * dnsmasqContextNew:
   *
@@ -255,6 +470,8 @@ dnsmasqContextNew(const char *network_name,

      if (!(ctx->hostsfile = hostsfileNew(network_name, config_dir)))
          goto error;
+    if (!(ctx->addnhostsfile = addnhostsNew(network_name, config_dir)))
+        goto error;

      return ctx;

@@ -277,6 +494,8 @@ dnsmasqContextFree(dnsmasqContext *ctx)

      if (ctx->hostsfile)
          hostsfileFree(ctx->hostsfile);
+    if (ctx->addnhostsfile)
+        addnhostsFree(ctx->addnhostsfile);

      VIR_FREE(ctx);
  }
@@ -300,6 +519,24 @@ dnsmasqAddDhcpHost(dnsmasqContext *ctx,
          hostsfileAdd(ctx->hostsfile, mac, ip, name);
  }

+/*
+ * dnsmasqAddHost:
+ * @ctx: pointer to the dnsmasq context for each network
+ * @ip: pointer to the socket address contains ip of the host
+ * @name: pointer to the string contains hostname of the host
+ *
+ * Add additional host entry.
+ */
+
+void
+dnsmasqAddHost(dnsmasqContext *ctx,
+               virSocketAddr *ip,
+               const char *name)
+{
+    if (ctx->addnhostsfile)
+        addnhostsAdd(ctx->addnhostsfile, ip, name);
+}
+
  /**
   * dnsmasqSave:
   * @ctx: pointer to the dnsmasq context for each network
@@ -309,10 +546,16 @@ dnsmasqAddDhcpHost(dnsmasqContext *ctx,
  int
  dnsmasqSave(const dnsmasqContext *ctx)
  {
+    int ret = 0;
+
      if (ctx->hostsfile)
-        return hostsfileSave(ctx->hostsfile);
+        ret = hostsfileSave(ctx->hostsfile);
+    if (ret == 0) {
+        if (ctx->addnhostsfile)
+            ret = addnhostsSave(ctx->addnhostsfile);
+    }

-    return 0;
+    return ret;
  }


@@ -325,10 +568,14 @@ dnsmasqSave(const dnsmasqContext *ctx)
  int
  dnsmasqDelete(const dnsmasqContext *ctx)
  {
+    int ret = 0;
+
      if (ctx->hostsfile)
-        return hostsfileDelete(ctx->hostsfile);
+        ret = genericFileDelete(ctx->hostsfile->path);
+    if (ctx->addnhostsfile)
+        ret = genericFileDelete(ctx->addnhostsfile->path);

-    return 0;
+    return ret;
  }

  /**
diff --git a/src/util/dnsmasq.h b/src/util/dnsmasq.h
index 02a961f..3f6320a 100644
--- a/src/util/dnsmasq.h
+++ b/src/util/dnsmasq.h
@@ -44,7 +44,24 @@ typedef struct

  typedef struct
  {
-    dnsmasqHostsfile *hostsfile;
+    unsigned int    nhostnames;
+    char            *ip;
+    char            **hostnames;

The way you've defined your struct here is how you need to define virNetworkDNSHostsDef in the next patch.

+
+} dnsmasqAddnHost;
+
+typedef struct
+{
+    unsigned int     nhosts;
+    dnsmasqAddnHost *hosts;
+
+    char            *path;  /* Absolute path of dnsmasq's hostsfile. */
+} dnsmasqAddnHostsfile;
+
+typedef struct
+{
+    dnsmasqHostsfile     *hostsfile;
+    dnsmasqAddnHostsfile *addnhostsfile;
  } dnsmasqContext;

  dnsmasqContext * dnsmasqContextNew(const char *network_name,
@@ -54,6 +71,9 @@ void             dnsmasqAddDhcpHost(dnsmasqContext *ctx,
                                      const char *mac,
                                      virSocketAddr *ip,
                                      const char *name);
+void             dnsmasqAddHost(dnsmasqContext *ctx,
+                                virSocketAddr *ip,
+                                const char *name);
  int              dnsmasqSave(const dnsmasqContext *ctx);
  int              dnsmasqDelete(const dnsmasqContext *ctx);
  int              dnsmasqReload(pid_t pid);

ACK.

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]