[libvirt] [PATCH 1/3] Add dnsmasq module

Satoru SATOH satoru.satoh at gmail.com
Fri Apr 2 18:26:50 UTC 2010


This patch adds the files implements dnsmasq (hostsfile) module.

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

 src/util/dnsmasq.c |  296 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/dnsmasq.h |   54 ++++++++++
 2 files changed, 350 insertions(+), 0 deletions(-)
 create mode 100644 src/util/dnsmasq.c
 create mode 100644 src/util/dnsmasq.h

diff --git a/src/util/dnsmasq.c b/src/util/dnsmasq.c
new file mode 100644
index 0000000..8760c7c
--- /dev/null
+++ b/src/util/dnsmasq.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2010 Satoru SATOH <satoru.satoh at gmail.com>
+ * Copyright (C) 2007-2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Based on iptables.c
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+
+#include "internal.h"
+#include "dnsmasq.h"
+#include "util.h"
+#include "memory.h"
+#include "virterror_internal.h"
+#include "logging.h"
+
+static void
+hostsfileFree(dnsmasqHostfile *hostsfile)
+{
+    int i;
+
+    if (hostsfile->entries) {
+        for (i = 0; i < hostsfile->nentries; i++)
+            VIR_FREE(hostsfile->entries[i].entry);
+
+        VIR_FREE(hostsfile->entries);
+
+        hostsfile->nentries = 0;
+    }
+
+    hostsfile->path[0] = '\0';
+
+    VIR_FREE(hostsfile);
+}
+
+static dnsmasqHostfile *
+hostsfileNew(const char *name,
+             const char *config_dir)
+{
+    int err;
+    char ebuf[1024];
+
+    dnsmasqHostfile *hostsfile;
+
+    if (VIR_ALLOC(hostsfile) < 0)
+        return NULL;
+
+    hostsfile->entries = NULL;
+    hostsfile->nentries = 0;
+
+    if ((err = virFileMakePath(config_dir))) {
+        VIR_WARN(_("Failed to create directory %s : %s"), config_dir,
+            virStrerror(err, ebuf, sizeof ebuf));
+        goto error;
+    }
+
+    if (virFileBuildPath(config_dir, name, ".hostsfile", hostsfile->path,
+            sizeof(hostsfile->path)) < 0)
+        goto error;
+
+    return hostsfile;
+
+ error:
+    hostsfileFree(hostsfile);
+    return NULL;
+}
+
+static int
+hostsfileAdd(dnsmasqHostfile *hostsfile,
+             const char *mac,
+             const char *ip,
+             const char *name)
+{
+    if (VIR_REALLOC_N(hostsfile->entries, hostsfile->nentries+1) < 0)
+        return ENOMEM;
+
+    if (virAsprintf(&hostsfile->entries[hostsfile->nentries].entry,
+            "%s,%s,%s", mac, name, ip) < 0) {
+        return ENOMEM;
+    }
+
+    hostsfile->nentries++;
+
+    return 0;
+}
+
+static int
+hostsfileWrite(const char *path,
+               const dhcpHostEntry *entries,
+               int nentries)
+{
+    char tmp[PATH_MAX];
+    FILE *f;
+    int istmp;
+    int i;
+
+    if (nentries == 0 && unlink(path) == 0)
+        return 0;
+
+    if (snprintf(tmp, PATH_MAX, "%s.new", path) >= PATH_MAX)
+        return EINVAL;
+
+    istmp = 1;
+
+    if (!(f = fopen(tmp, "w"))) {
+        istmp = 0;
+        if (!(f = fopen(path, "w")))
+            return errno;
+    }
+
+    for (i = 0; i < nentries; i++) {
+        if (fputs(entries[i].entry, f) == EOF ||
+            fputc('\n', f) == EOF) {
+            fclose(f);
+            if (istmp)
+                unlink(tmp);
+            return errno;
+        }
+    }
+
+    fclose(f);
+
+    if (istmp && rename(tmp, path) < 0) {
+        unlink(tmp);
+        return errno;
+    }
+
+    if (istmp)
+        unlink(tmp);
+
+    return 0;
+}
+
+static int
+hostsfileSave(const dnsmasqContext *ctx)
+{
+    if (hostsfileWrite(ctx->hostsfile->path, ctx->hostsfile->entries,
+            ctx->hostsfile->nentries) < 0) {
+        VIR_WARN(_("cannot write config file '%s'\n"), ctx->hostsfile->path);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int
+hostsfileDelete(const dnsmasqContext *ctx)
+{
+    if (! virFileExists(ctx->hostsfile->path))
+        return 0;
+
+    if (unlink(ctx->hostsfile->path) < 0) {
+        VIR_WARN(_("cannot remove config file '%s'\n"), ctx->hostsfile->path);
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * dnsmasqContextNew:
+ *
+ * Create a new Dnsmasq context
+ *
+ * Returns a pointer to the new structure or NULL in case of error
+ */
+dnsmasqContext *
+dnsmasqContextNew(const char *network_name,
+                  const char *config_dir)
+{
+    dnsmasqContext *ctx;
+
+    if (VIR_ALLOC(ctx) < 0)
+        return NULL;
+
+    if (!(ctx->hostsfile = hostsfileNew(network_name, config_dir)))
+        goto error;
+
+    return ctx;
+
+ error:
+    dnsmasqContextFree(ctx);
+    return NULL;
+}
+
+/**
+ * dnsmasqContextFree:
+ * @ctx: pointer to the dnsmasq context
+ *
+ * Free the resources associated with an dnsmasq context
+ */
+void
+dnsmasqContextFree(dnsmasqContext *ctx)
+{
+    if (ctx->hostsfile)
+        hostsfileFree(ctx->hostsfile);
+    VIR_FREE(ctx);
+}
+
+/**
+ * dnsmasqAddDhcpHost:
+ * @ctx: pointer to the dnsmasq context for each network
+ * @mac: pointer to the string contains mac address of the host
+ * @ip: pointer to the string contains ip address of the host
+ * @name: pointer to the string contains hostname of the host
+ *
+ * Add host entries.
+ */
+void
+dnsmasqAddDhcpHost(dnsmasqContext *ctx,
+                   const char *mac,
+                   const char *ip,
+                   const char *name)
+{
+    if (hostsfileAdd(ctx->hostsfile, mac, ip, name))
+        VIR_WARN(_("Failed to add host: mac=%s, ip=%s, name=%s\n"), mac, ip, name);
+}
+
+/**
+ * dnsmasqSave:
+ * @ctx: pointer to the dnsmasq context for each network
+ *
+ * Saves all the configurations associated with a context to disk.
+ */
+int
+dnsmasqSave(const dnsmasqContext *ctx)
+{
+    if (hostsfileSave(ctx) < 0)
+        return 0;
+
+    return 1;
+}
+
+
+/**
+ * dnsmasqDelete:
+ * @ctx: pointer to the dnsmasq context for each network
+ *
+ * Delete all the configuration files associated with a context.
+ */
+int
+dnsmasqDelete(const dnsmasqContext *ctx)
+{
+    if (hostsfileDelete(ctx) < 0)
+        return 0;
+
+    return 1;
+}
+
+/**
+ * dnsmasqReload:
+ * @ctx: pointer to the dnsmasq context
+ *
+ * Reloads all the configurations associated to a context
+ */
+int
+dnsmasqReload(pid_t pid)
+{
+    if (kill(pid, SIGHUP) != 0) {
+        VIR_WARN(_("Failed to make dnsmasq (PID: %d) reloading config files.\n"), pid);
+        return 0;
+    }
+
+    return 1;
+}
+
diff --git a/src/util/dnsmasq.h b/src/util/dnsmasq.h
new file mode 100644
index 0000000..4343ed9
--- /dev/null
+++ b/src/util/dnsmasq.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Satoru SATOH <satoru.satoh at gmail.com>
+ * Copyright (C) 2007, 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * based on iptables.h
+ */
+
+#ifndef __DNSMASQ_H__
+#define __DNSMASQ_H__
+
+typedef struct
+{
+    char *entry;  /* "<mac>,<hostname>,<ip>", ex. "01:23:45:67:89:0a,foo,10.0.0.3" */
+} dhcpHostEntry;
+
+typedef struct
+{
+    int            nentries;
+    dhcpHostEntry *entries;
+
+    char  path[PATH_MAX];
+} dnsmasqHostfile;
+
+typedef struct
+{
+    dnsmasqHostfile *hostsfile;
+} dnsmasqContext;
+
+dnsmasqContext * dnsmasqContextNew(const char *network_name,
+                                   const char *config_dir);
+void             dnsmasqContextFree(dnsmasqContext *ctx);
+void             dnsmasqAddDhcpHost(dnsmasqContext *ctx,
+                                    const char *mac,
+                                    const char *ip,
+                                    const char *name);
+int              dnsmasqSave(const dnsmasqContext *ctx);
+int              dnsmasqDelete(const dnsmasqContext *ctx);
+int              dnsmasqReload(pid_t pid);
+
+#endif /* __DNSMASQ_H__ */
-- 
1.6.6.1




More information about the libvir-list mailing list