[libvirt] [PATCHv4 0/3] Transport Open vSwitch per-port data during live migration
by Laine Stump
This is an update of Kyle Mestery's patch series v3 by the same name:
https://www.redhat.com/archives/libvir-list/2012-October/msg00014.html
I've updated it according to the comments in the review of patch 1/3
of that series:
https://www.redhat.com/archives/libvir-list/2012-October/msg01224.html
It now needs a counter-review from Kyle, along with verification that
it actually works (since I don't have the proper setup to test it
handy).
******************************************
This series of commits has the end goal of allowing per-port data stored
in the Open vSwitch DB to be transported during live migration. This is
done by first providing a generic infrastructure for transporting network
data, adding some utility functions specific to Open vSwitch, and hooking
the two together.
The framework provided is generic in that other networking data could be
transferred as well by simply adding in additional hooks as needed.
Kyle Mestery (3):
Add the ability for the Qemu V3 migration protocol to include
transporting network configuration. A generic framework is proposed
with this patch to allow for the transfer of opaque data.
Add utility functions for Open vSwitch to both save per-port data
before a live migration, and restore the per-port data after a
live migration.
Transport Open vSwitch per-port data during live migration by
using the utility functions
virNetDevOpenvswitchGetMigrateData() and
virNetDevOpenvswitchSetMigrateData().
12 years, 1 month
[libvirt] [PATCH] xml: omit domain name from comment if it contains double hyphen
by Ján Tomko
We put a comment containing "virsh edit <domain_name>" at the start of
the XML. W3C recommendation forbids the use of "--" in comments [1] and
libvirt can't parse it either. This patch omits the domain name if it
contains a double hyphen.
[1] http://www.w3.org/TR/REC-xml/#sec-comments
---
src/util/xml.c | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/src/util/xml.c b/src/util/xml.c
index 39bc111..f3dc256 100644
--- a/src/util/xml.c
+++ b/src/util/xml.c
@@ -807,12 +807,16 @@ or other application using the libvirt API.\n\
if (safewrite(fd, cmd, len) != len)
return -1;
- if (safewrite(fd, " ", 1) != 1)
- return -1;
+ /* Omit the domain name if it contains a double hyphen
+ * because they aren't allowed in XML comments */
+ if (!strstr(name, "--")) {
+ if (safewrite(fd, " ", 1) != 1)
+ return -1;
- len = strlen(name);
- if (safewrite(fd, name, len) != len)
- return -1;
+ len = strlen(name);
+ if (safewrite(fd, name, len) != len)
+ return -1;
+ }
len = strlen(epilogue);
if (safewrite(fd, epilogue, len) != len)
--
1.7.8.6
12 years, 1 month
[libvirt] [PATCH] storage: don't shadow global 'wait' declaration
by Ján Tomko
Rename the 'wait' parameter to 'loop'.
This silences the warning:
storage/storage_backend.c:1348:34: error: declaration of 'wait' shadows
a global declaration [-Werror=shadow]
and fixes the build with -Werror.
--
Note: loop is pool backwards.
---
src/storage/storage_backend.c | 8 ++++----
src/storage/storage_backend.h | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index 85b8287..75a3667 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -1339,13 +1339,13 @@ virStorageBackendDetectBlockVolFormatFD(virStorageVolTargetPtr target,
* Typically target.path is one of the /dev/disk/by-XXX dirs
* with stable paths.
*
- * If 'wait' is true, we use a timeout loop to give dynamic paths
+ * If 'loop' is true, we use a timeout loop to give dynamic paths
* a change to appear.
*/
char *
virStorageBackendStablePath(virStoragePoolObjPtr pool,
const char *devpath,
- bool wait)
+ bool loop)
{
DIR *dh;
struct dirent *dent;
@@ -1376,7 +1376,7 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool,
reopen:
if ((dh = opendir(pool->def->target.path)) == NULL) {
opentries++;
- if (wait && errno == ENOENT && opentries < 50) {
+ if (loop && errno == ENOENT && opentries < 50) {
usleep(100 * 1000);
goto reopen;
}
@@ -1415,7 +1415,7 @@ virStorageBackendStablePath(virStoragePoolObjPtr pool,
VIR_FREE(stablepath);
}
- if (wait && ++retry < 100) {
+ if (loop && ++retry < 100) {
usleep(100 * 1000);
goto retry;
}
diff --git a/src/storage/storage_backend.h b/src/storage/storage_backend.h
index 71935a7..29cad9d 100644
--- a/src/storage/storage_backend.h
+++ b/src/storage/storage_backend.h
@@ -131,7 +131,7 @@ virStorageBackendDetectBlockVolFormatFD(virStorageVolTargetPtr target,
char *virStorageBackendStablePath(virStoragePoolObjPtr pool,
const char *devpath,
- bool wait);
+ bool loop);
typedef int (*virStorageBackendListVolRegexFunc)(virStoragePoolObjPtr pool,
char **const groups,
--
1.7.8.6
12 years, 1 month
[libvirt] Add device operations support for libvirt (lxc)
by Heiher
Hello,
Currently, libvirt is not support device operations for lxc.
This is a patch that add device operations support for libvirt 0.10.2.
1. lxcDomainAttachDevice
2. lxcDomainAttachDeviceFlags
3. lxcDomainDetachDevice
4. lxcDomainDetachDeviceFlags
5. lxcDomainUpdateDeviceFlags
In live mode, set devices.allow/deny to instance's cgroup and insert
disk config into current domain.
In config mode, just insert disk config into current domain.
This is part of 'Fix up attach/detach volume for nova (openstack)'.
Please see: https://bugzilla.redhat.com/show_bug.cgi?id=869259
--
Best regards!
Heiher
https://heiher.info
12 years, 1 month
[libvirt] RFC: advertising graphics support (vnc, spice, sdl)
by Doug Goldstein
Currently consumers of libvirt's APIs must assume/attempt to define a
VM that uses spice, vnc, or sdl without knowing if the actual
hypervisor supports it. Obviously my discussion is very QEMU oriented
but it would be good to leave expansion for the future. I was thinking
that under the <guest> element for the capabilities we can add
something like:
<graphics>
<spice/>
<vnc/>
<sdl/>
</graphics>
It would be at the same level as <arch> and <features>. But before I
implemented this I wanted a sanity check if people think this is the
best place or the best naming convention.
Thanks.
--
Doug Goldstein
12 years, 1 month
[libvirt] [PATCH] qemu: Report errors from iohelper
by Michal Privoznik
Currently, we use iohelper when saving/restoring a domain.
However, if there's some kind of error (like I/O) it is not
propagated to libvirt. Since it is not qemu who is doing
the actual write() it will not get error. The iohelper does.
Therefore we should check for iohelper errors as it makes
libvirt more user friendly.
---
src/libvirt_private.syms | 1 +
src/qemu/qemu_driver.c | 7 ++++-
src/util/virfile.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/virfile.h | 2 +
4 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 60f9c7f..26eb7b1 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1332,6 +1332,7 @@ virDomainListSnapshots;
virFileLoopDeviceAssociate;
virFileClose;
virFileDirectFdFlag;
+virFileWrapperFdCatchError;
virFileWrapperFdClose;
virFileWrapperFdFree;
virFileWrapperFdNew;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8af316f..c8e97cf 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2945,6 +2945,7 @@ endjob:
if (rc < 0)
VIR_WARN("Unable to resume guest CPUs after save failure");
}
+ virFileWrapperFdCatchError(wrapperFd);
}
if (qemuDomainObjEndAsyncJob(driver, vm) == 0)
vm = NULL;
@@ -3282,9 +3283,11 @@ doCoreDump(struct qemud_driver *driver,
cleanup:
VIR_FORCE_CLOSE(fd);
- virFileWrapperFdFree(wrapperFd);
- if (ret != 0)
+ if (ret != 0) {
+ virFileWrapperFdCatchError(wrapperFd);
unlink(path);
+ }
+ virFileWrapperFdFree(wrapperFd);
return ret;
}
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 5b00ead..4d7538e 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -135,6 +135,7 @@ virFileDirectFdFlag(void)
* read-write is not supported, just a single direction. */
struct _virFileWrapperFd {
virCommandPtr cmd; /* Child iohelper process to do the I/O. */
+ int err_fd; /* FD to read stderr of @cmd */
};
#ifndef WIN32
@@ -229,6 +230,14 @@ virFileWrapperFdNew(int *fd, const char *name, unsigned int flags)
virCommandAddArg(ret->cmd, "0");
}
+ /* In order to catch iohelper stderr, we must:
+ * - pass a FD to virCommand (-1 to auto-allocate one)
+ * - change iohelper's env so virLog functions print to stderr
+ */
+ ret->err_fd = -1;
+ virCommandSetErrorFD(ret->cmd, &ret->err_fd);
+ virCommandAddEnvPair(ret->cmd, "LIBVIRT_LOG_OUTPUTS", "1:stderr");
+
if (virCommandRunAsync(ret->cmd, NULL) < 0)
goto error;
@@ -280,6 +289,42 @@ virFileWrapperFdClose(virFileWrapperFdPtr wfd)
return virCommandWait(wfd->cmd, NULL);
}
+
+/**
+ * virFileWrapperFdCatchError:
+ * @wfd: fd wrapper, or NULL
+ *
+ * Read the stderr of iohelper and VIR_WARN() about it.
+ */
+void
+virFileWrapperFdCatchError(virFileWrapperFdPtr wfd)
+{
+ char *err = NULL;
+ char ebuf[1024];
+ size_t nread = 0;
+ size_t err_size = 0;
+
+ if (!wfd)
+ return;
+
+ while ((nread = saferead(wfd->err_fd, ebuf, sizeof(ebuf)))) {
+ if (VIR_REALLOC_N(err, err_size + nread + 1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ memcpy(err + err_size, ebuf, nread);
+ err_size += nread;
+ err[err_size] = '\0';
+ }
+
+ if (err)
+ VIR_WARN("iohelper reports: %s", err);
+
+cleanup:
+ VIR_FREE(err);
+}
+
+
/**
* virFileWrapperFdFree:
* @wfd: fd wrapper, or NULL
@@ -295,6 +340,8 @@ virFileWrapperFdFree(virFileWrapperFdPtr wfd)
if (!wfd)
return;
+ VIR_FORCE_CLOSE(wfd->err_fd);
+
virCommandFree(wfd->cmd);
VIR_FREE(wfd);
}
diff --git a/src/util/virfile.h b/src/util/virfile.h
index c885b73..80daf86 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -90,6 +90,8 @@ int virFileWrapperFdClose(virFileWrapperFdPtr dfd);
void virFileWrapperFdFree(virFileWrapperFdPtr dfd);
+void virFileWrapperFdCatchError(virFileWrapperFdPtr dfd);
+
int virFileLock(int fd, bool shared, off_t start, off_t len);
int virFileUnlock(int fd, off_t start, off_t len);
--
1.7.8.6
12 years, 1 month
[libvirt] [PATCH] build: use correct printf types for uid/gid
by Eric Blake
Fixes a build failure on cygwin:
cc1: warnings being treated as errors
security/security_dac.c: In function 'virSecurityDACSetProcessLabel':
security/security_dac.c:862:5: error: format '%u' expects type 'unsigned int', but argument 7 has type 'uid_t' [-Wformat]
security/security_dac.c:862:5: error: format '%u' expects type 'unsigned int', but argument 8 has type 'gid_t' [-Wformat]
* src/security/security_dac.c (virSecurityDACSetProcessLabel)
(virSecurityDACGenLabel): Use proper casts.
---
Pushing under the build-breaker rule. See src/util/util.c for other
cases where we do the same.
src/security/security_dac.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index a67f5d6..a1aa0ef 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -859,7 +859,8 @@ virSecurityDACSetProcessLabel(virSecurityManagerPtr mgr,
if (virSecurityDACGetIds(def, priv, &user, &group))
return -1;
- VIR_DEBUG("Dropping privileges of DEF to %u:%u", user, group);
+ VIR_DEBUG("Dropping privileges of DEF to %u:%u",
+ (unsigned int) user, (unsigned int) group);
if (virSetUIDGID(user, group) < 0)
return -1;
@@ -920,7 +921,9 @@ virSecurityDACGenLabel(virSecurityManagerPtr mgr,
}
break;
case VIR_DOMAIN_SECLABEL_DYNAMIC:
- if (virAsprintf(&seclabel->label, "%d:%d", priv->user, priv->group) < 0) {
+ if (virAsprintf(&seclabel->label, "%d:%d",
+ (unsigned int) priv->user,
+ (unsigned int) priv->group) < 0) {
virReportOOMError();
return rc;
}
--
1.7.11.7
12 years, 1 month
[libvirt] [PATCH v2] put dnsmasq parameters into a file instead of the command line
by Gene Czarcinski
This patch changes the way parameters are passed to dnsmasq. They are
put into a conf-file instead of being on the dnsmasq command line.
**NOTE ** This has updated the related tests for the new
data format, etc.
**NOTE** This patch does NOT include specifying interface=
The command line now contains --conf-file=<filename> and a new
parameter --conf-dir=<directoryname> has been added.
The new file and directory are put in the same directory as the
leases file.
---
.gnulib | 2 +-
src/network/bridge_driver.c | 179 ++++++++++++++-------
src/network/bridge_driver.h | 8 +-
tests/networkxml2argvdata/isolated-network.argv | 24 +--
.../networkxml2argvdata/nat-network-dns-hosts.argv | 14 +-
.../nat-network-dns-srv-record-minimal.argv | 35 ++--
.../nat-network-dns-srv-record.argv | 35 ++--
.../nat-network-dns-txt-record.argv | 29 ++--
tests/networkxml2argvdata/nat-network.argv | 27 ++--
tests/networkxml2argvdata/netboot-network.argv | 28 ++--
.../networkxml2argvdata/netboot-proxy-network.argv | 25 +--
tests/networkxml2argvdata/routed-network.argv | 12 +-
tests/networkxml2argvtest.c | 44 +----
13 files changed, 265 insertions(+), 197 deletions(-)
diff --git a/.gnulib b/.gnulib
index d245e6d..2a9edc6 160000
--- a/.gnulib
+++ b/.gnulib
@@ -1 +1 @@
-Subproject commit d245e6ddd6ab2624d0d83acd8f111454f984f50f
+Subproject commit 2a9edc6f2b02a05553d266117ddee80b3e0a3749
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 8837843..873a051 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -136,6 +136,16 @@ networkDnsmasqLeaseFileNameFunc networkDnsmasqLeaseFileName =
networkDnsmasqLeaseFileNameDefault;
static char *
+networkDnsmasqConfigFileName(const char *netname)
+{
+ char *conffile;
+
+ ignore_value(virAsprintf(&conffile, DNSMASQ_STATE_DIR "/%s.conf",
+ netname));
+ return conffile;
+}
+
+static char *
networkRadvdPidfileBasename(const char *netname)
{
/* this is simple but we want to be sure it's consistently done */
@@ -559,23 +569,25 @@ networkBuildDnsmasqHostsfile(dnsmasqContext *dctx,
return 0;
}
-
+ /* build the dnsmasq conf file contents */
static int
-networkBuildDnsmasqArgv(virNetworkObjPtr network,
+networkDnsmasqConfContents(virNetworkObjPtr network,
virNetworkIpDefPtr ipdef,
const char *pidfile,
- virCommandPtr cmd,
+ char **configstr,
dnsmasqContext *dctx)
{
- int r, ret = -1;
+ virBuffer configbuf = VIR_BUFFER_INITIALIZER;;
+ int r, ret = -1, ii;
int nbleases = 0;
- int ii;
char *record = NULL;
char *recordPort = NULL;
char *recordWeight = NULL;
char *recordPriority = NULL;
virNetworkIpDefPtr tmpipdef;
+ *configstr = NULL;
+
/*
* NB, be careful about syntax for dnsmasq options in long format.
*
@@ -595,28 +607,22 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
* very explicit on this.
*/
- /*
- * Needed to ensure dnsmasq uses same algorithm for processing
- * multiple namedriver entries in /etc/resolv.conf as GLibC.
- */
- virCommandAddArgList(cmd, "--strict-order", "--bind-interfaces", NULL);
-
+ /* create dnsmasq config file appropriate for this network */
+ virBufferAsprintf(&configbuf, "# dnsmasq conf file created by libvirt\n"
+ "strict-order\n"
+ "bind-interfaces\n"
+ "except-interface=lo\n"
+ "domain-needed\n"
+ "local=/%s/\n",
+ network->def->domain ? network->def->domain : "");
if (network->def->domain)
- virCommandAddArgPair(cmd, "--domain", network->def->domain);
- /* need to specify local even if no domain specified */
- virCommandAddArgFormat(cmd, "--local=/%s/",
- network->def->domain ? network->def->domain : "");
- virCommandAddArg(cmd, "--domain-needed");
+ virBufferAsprintf(&configbuf,
+ "domain=%s\n"
+ "expand-hosts\n",
+ network->def->domain);
if (pidfile)
- virCommandAddArgPair(cmd, "--pid-file", pidfile);
-
- /* *no* conf file */
- virCommandAddArg(cmd, "--conf-file=");
-
- virCommandAddArgList(cmd,
- "--except-interface", "lo",
- NULL);
+ virBufferAsprintf(&configbuf, "pid-file=%s\n", pidfile);
/* If this is an isolated network, set the default route option
* (3) to be empty to avoid setting a default route that's
@@ -626,16 +632,21 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
* to build a connection to the outside).
*/
if (network->def->forwardType == VIR_NETWORK_FORWARD_NONE) {
- virCommandAddArgList(cmd, "--dhcp-option=3",
- "--no-resolv", NULL);
+ virBufferAsprintf(&configbuf, "dhcp-option=3\n"
+ "no-resolv\n");
}
+ /*
+ * Needed to ensure dnsmasq uses same algorithm for processing
+ * multiple namedriver entries in /etc/resolv.conf as GLibC.
+ */
+
if (network->def->dns != NULL) {
virNetworkDNSDefPtr dns = network->def->dns;
int i;
for (i = 0; i < dns->ntxtrecords; i++) {
- virCommandAddArgFormat(cmd, "--txt-record=%s,%s",
+ virBufferAsprintf(&configbuf, "txt-record=%s,%s\n",
dns->txtrecords[i].name,
dns->txtrecords[i].value);
}
@@ -673,7 +684,7 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
goto cleanup;
}
- virCommandAddArgPair(cmd, "--srv-host", record);
+ virBufferAsprintf(&configbuf, "srv-host=%s\n", record);
VIR_FREE(record);
VIR_FREE(recordPort);
VIR_FREE(recordWeight);
@@ -682,21 +693,14 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
}
}
- /*
- * --interface does not actually work with dnsmasq < 2.47,
- * due to DAD for ipv6 addresses on the interface.
- *
- * virCommandAddArgList(cmd, "--interface", ipdef->bridge, NULL);
- *
- * So listen on all defined IPv[46] addresses
- */
for (ii = 0;
(tmpipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, ii));
- ii++) {
+ ii++)
+ {
char *ipaddr = virSocketAddrFormat(&tmpipdef->address);
if (!ipaddr)
goto cleanup;
- virCommandAddArgList(cmd, "--listen-address", ipaddr, NULL);
+ virBufferAsprintf(&configbuf, "listen-address=%s\n", ipaddr);
VIR_FREE(ipaddr);
}
@@ -710,8 +714,8 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
VIR_FREE(saddr);
goto cleanup;
}
- virCommandAddArg(cmd, "--dhcp-range");
- virCommandAddArgFormat(cmd, "%s,%s", saddr, eaddr);
+ virBufferAsprintf(&configbuf, "dhcp-range=%s,%s\n",
+ saddr, eaddr);
VIR_FREE(saddr);
VIR_FREE(eaddr);
nbleases += virSocketAddrGetRange(&ipdef->ranges[r].start,
@@ -727,8 +731,7 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
char *bridgeaddr = virSocketAddrFormat(&ipdef->address);
if (!bridgeaddr)
goto cleanup;
- virCommandAddArg(cmd, "--dhcp-range");
- virCommandAddArgFormat(cmd, "%s,static", bridgeaddr);
+ virBufferAsprintf(&configbuf, "dhcp-range=%s,static\n", bridgeaddr);
VIR_FREE(bridgeaddr);
}
@@ -736,17 +739,13 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
char *leasefile = networkDnsmasqLeaseFileName(network->def->name);
if (!leasefile)
goto cleanup;
- virCommandAddArgFormat(cmd, "--dhcp-leasefile=%s", leasefile);
+ virBufferAsprintf(&configbuf, "dhcp-leasefile=%s\n", leasefile);
VIR_FREE(leasefile);
- virCommandAddArgFormat(cmd, "--dhcp-lease-max=%d", nbleases);
+ virBufferAsprintf(&configbuf, "dhcp-lease-max=%d\n", nbleases);
}
if (ipdef->nranges || ipdef->nhosts)
- virCommandAddArg(cmd, "--dhcp-no-override");
-
- /* add domain to any non-qualified hostnames in /etc/hosts or addn-hosts */
- if (network->def->domain)
- virCommandAddArg(cmd, "--expand-hosts");
+ virBufferAsprintf(&configbuf, "dhcp-no-override\n");
if (networkBuildDnsmasqHostsfile(dctx, ipdef, network->def->dns) < 0)
goto cleanup;
@@ -756,38 +755,42 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
* file to allow for runtime additions.
*/
if (ipdef->nranges || ipdef->nhosts)
- virCommandAddArgPair(cmd, "--dhcp-hostsfile",
+ virBufferAsprintf(&configbuf, "dhcp-hostsfile=%s\n",
dctx->hostsfile->path);
/* Likewise, always create this file and put it on the commandline, to allow for
* for runtime additions.
*/
- virCommandAddArgPair(cmd, "--addn-hosts",
+ virBufferAsprintf(&configbuf, "addn-hosts=%s\n",
dctx->addnhostsfile->path);
if (ipdef->tftproot) {
- virCommandAddArgList(cmd, "--enable-tftp",
- "--tftp-root", ipdef->tftproot,
- NULL);
+ virBufferAsprintf(&configbuf, "enable-tftp\n");
+ virBufferAsprintf(&configbuf, "tftp-root=%s\n", ipdef->tftproot);
}
if (ipdef->bootfile) {
- virCommandAddArg(cmd, "--dhcp-boot");
if (VIR_SOCKET_ADDR_VALID(&ipdef->bootserver)) {
char *bootserver = virSocketAddrFormat(&ipdef->bootserver);
if (!bootserver)
goto cleanup;
- virCommandAddArgFormat(cmd, "%s%s%s",
+ virBufferAsprintf(&configbuf, "dhcp-boot=%s%s%s\n",
ipdef->bootfile, ",,", bootserver);
VIR_FREE(bootserver);
} else {
- virCommandAddArg(cmd, ipdef->bootfile);
+ virBufferAsprintf(&configbuf, "dhcp-boot=%s\n", ipdef->bootfile);
}
}
}
+ if (!(*configstr = virBufferContentAndReset(&configbuf))) {
+ virReportOOMError();
+ goto cleanup;
+ }
ret = 0;
+
cleanup:
+ virBufferFreeAndReset(&configbuf);
VIR_FREE(record);
VIR_FREE(recordPort);
VIR_FREE(recordWeight);
@@ -795,13 +798,18 @@ cleanup:
return ret;
}
+ /* build the dnsmasq command line */
int
networkBuildDhcpDaemonCommandLine(virNetworkObjPtr network, virCommandPtr *cmdout,
- char *pidfile, dnsmasqContext *dctx)
+ char *pidfile, dnsmasqContext *dctx,
+ char *configdir,
+ int testOnly, char **testConfigStr)
{
virCommandPtr cmd = NULL;
int ret = -1, ii;
virNetworkIpDefPtr ipdef;
+ char *configfile = NULL;
+ char *configstr = NULL;
network->dnsmasqPid = -1;
@@ -825,15 +833,41 @@ networkBuildDhcpDaemonCommandLine(virNetworkObjPtr network, virCommandPtr *cmdou
if (!virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, 0))
return 0;
- cmd = virCommandNew(DNSMASQ);
- if (networkBuildDnsmasqArgv(network, ipdef, pidfile, cmd, dctx) < 0) {
+ if (networkDnsmasqConfContents(network, ipdef, pidfile, &configstr, dctx) < 0)
+ goto cleanup;
+ if (!configstr)
+ goto cleanup;
+
+ if (testOnly) {
+ *testConfigStr = configstr;
+ return 0;
+ }
+
+ /* construct the filename */
+ if (!(configfile = networkDnsmasqConfigFileName(network->def->name))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ /* Write the file */
+ if (virFileWriteStr(configfile, configstr, 0600) < 0) {
+ virReportSystemError(errno,
+ _("couldn't write dnsmasq config file '%s'"),
+ configfile);
goto cleanup;
}
+ VIR_INFO("dnsmasq conf file %s written", configfile);
+
+ cmd = virCommandNew(DNSMASQ);
+ virCommandAddArgFormat(cmd, "--conf-file=%s", configfile);
+ virCommandAddArgFormat(cmd, "--conf-dir=%s", configdir);
if (cmdout)
*cmdout = cmd;
ret = 0;
cleanup:
+ VIR_FREE(configstr);
+ VIR_FREE(configfile);
if (ret < 0)
virCommandFree(cmd);
return ret;
@@ -844,9 +878,12 @@ networkStartDhcpDaemon(virNetworkObjPtr network)
{
virCommandPtr cmd = NULL;
char *pidfile = NULL;
+ char *testconfigstr = NULL;
+ char *configdir = NULL;
int ret = -1;
dnsmasqContext *dctx = NULL;
+ VIR_INFO("starting dhcp daemon (dnsmasq)");
if (!virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, 0)) {
/* no IPv6 addresses, so we don't need to run radvd */
ret = 0;
@@ -882,7 +919,18 @@ networkStartDhcpDaemon(virNetworkObjPtr network)
if (dctx == NULL)
goto cleanup;
- ret = networkBuildDhcpDaemonCommandLine(network, &cmd, pidfile, dctx);
+ ignore_value(virAsprintf(&configdir, DNSMASQ_STATE_DIR "/%s.d",
+ network->def->name));
+ if (virFileMakePath(configdir) < 0) {
+ virReportSystemError(errno,
+ _("cannot create directory %s"),
+ configdir);
+ goto cleanup;
+ }
+
+
+ ret = networkBuildDhcpDaemonCommandLine(network, &cmd, pidfile, dctx,
+ configdir, 0, &testconfigstr);
if (ret < 0)
goto cleanup;
@@ -911,6 +959,7 @@ networkStartDhcpDaemon(virNetworkObjPtr network)
ret = 0;
cleanup:
VIR_FREE(pidfile);
+ VIR_FREE(configdir);
virCommandFree(cmd);
dnsmasqContextFree(dctx);
return ret;
@@ -2841,6 +2890,14 @@ static int networkUndefine(virNetworkPtr net) {
}
}
+ {
+ char *configfile = networkDnsmasqConfigFileName(network->def->name);
+ if (!configfile)
+ goto cleanup;
+ unlink(configfile);
+ VIR_FREE(configfile);
+ }
+
if (dhcp_present) {
char *leasefile;
dnsmasqContext *dctx = dnsmasqContextNew(network->def->name, DNSMASQ_STATE_DIR);
diff --git a/src/network/bridge_driver.h b/src/network/bridge_driver.h
index 0fae275..00675c4 100644
--- a/src/network/bridge_driver.h
+++ b/src/network/bridge_driver.h
@@ -48,15 +48,17 @@ int networkGetNetworkAddress(const char *netname, char **netaddr)
int networkBuildDhcpDaemonCommandLine(virNetworkObjPtr network,
virCommandPtr *cmdout, char *pidfile,
- dnsmasqContext *dctx)
- ;
+ dnsmasqContext *dctx,
+ char *configdir,
+ int testOnly, char **testConfigStr);
# else
/* Define no-op replacements that don't drag in any link dependencies. */
# define networkAllocateActualDevice(iface) 0
# define networkNotifyActualDevice(iface) 0
# define networkReleaseActualDevice(iface) 0
# define networkGetNetworkAddress(netname, netaddr) (-2)
-# define networkBuildDhcpDaemonCommandLine(network, cmdout, pidfile, dctx) 0
+# define networkBuildDhcpDaemonCommandLine(network, cmdout, pidfile, \
+ dctx, configdir, testOnly, testConfigStr) 0
# endif
typedef char *(*networkDnsmasqLeaseFileNameFunc)(const char *netname);
diff --git a/tests/networkxml2argvdata/isolated-network.argv b/tests/networkxml2argvdata/isolated-network.argv
index 13e77b2..042158b 100644
--- a/tests/networkxml2argvdata/isolated-network.argv
+++ b/tests/networkxml2argvdata/isolated-network.argv
@@ -1,9 +1,15 @@
-@DNSMASQ@ --strict-order --bind-interfaces \
---local=// --domain-needed --conf-file= \
---except-interface lo --dhcp-option=3 --no-resolv \
---listen-address 192.168.152.1 \
---dhcp-range 192.168.152.2,192.168.152.254 \
---dhcp-leasefile=/var/lib/libvirt/dnsmasq/private.leases --dhcp-lease-max=253 \
---dhcp-no-override \
---dhcp-hostsfile=/var/lib/libvirt/dnsmasq/private.hostsfile \
---addn-hosts=/var/lib/libvirt/dnsmasq/private.addnhosts\
+# dnsmasq conf file created by libvirt
+strict-order
+bind-interfaces
+except-interface=lo
+domain-needed
+local=//
+dhcp-option=3
+no-resolv
+listen-address=192.168.152.1
+dhcp-range=192.168.152.2,192.168.152.254
+dhcp-leasefile=/var/lib/libvirt/dnsmasq/private.leases
+dhcp-lease-max=253
+dhcp-no-override
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/private.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/private.addnhosts
diff --git a/tests/networkxml2argvdata/nat-network-dns-hosts.argv b/tests/networkxml2argvdata/nat-network-dns-hosts.argv
index 03a0676..91eb682 100644
--- a/tests/networkxml2argvdata/nat-network-dns-hosts.argv
+++ b/tests/networkxml2argvdata/nat-network-dns-hosts.argv
@@ -1,4 +1,10 @@
-@DNSMASQ@ --strict-order --bind-interfaces --domain=example.com \
---local=/example.com/ --domain-needed \
---conf-file= --except-interface lo --listen-address 192.168.122.1 \
---expand-hosts --addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\
+# dnsmasq conf file created by libvirt
+strict-order
+bind-interfaces
+except-interface=lo
+domain-needed
+local=/example.com/
+domain=example.com
+expand-hosts
+listen-address=192.168.122.1
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
diff --git a/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv b/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv
index 210a60c..d92497b 100644
--- a/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv
+++ b/tests/networkxml2argvdata/nat-network-dns-srv-record-minimal.argv
@@ -1,17 +1,18 @@
-@DNSMASQ@ \
---strict-order \
---bind-interfaces \
---local=// --domain-needed --conf-file= \
---except-interface lo \
---srv-host=name.tcp.,,,, \
---listen-address 192.168.122.1 \
---listen-address 192.168.123.1 \
---listen-address 2001:db8:ac10:fe01::1 \
---listen-address 2001:db8:ac10:fd01::1 \
---listen-address 10.24.10.1 \
---dhcp-range 192.168.122.2,192.168.122.254 \
---dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
---dhcp-lease-max=253 \
---dhcp-no-override \
---dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \
---addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\
+# dnsmasq conf file created by libvirt
+strict-order
+bind-interfaces
+except-interface=lo
+domain-needed
+local=//
+srv-host=name.tcp.,,,,
+listen-address=192.168.122.1
+listen-address=192.168.123.1
+listen-address=2001:db8:ac10:fe01::1
+listen-address=2001:db8:ac10:fd01::1
+listen-address=10.24.10.1
+dhcp-range=192.168.122.2,192.168.122.254
+dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases
+dhcp-lease-max=253
+dhcp-no-override
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
diff --git a/tests/networkxml2argvdata/nat-network-dns-srv-record.argv b/tests/networkxml2argvdata/nat-network-dns-srv-record.argv
index 833d3cd..d8846c2 100644
--- a/tests/networkxml2argvdata/nat-network-dns-srv-record.argv
+++ b/tests/networkxml2argvdata/nat-network-dns-srv-record.argv
@@ -1,17 +1,18 @@
-@DNSMASQ@ \
---strict-order \
---bind-interfaces \
---local=// --domain-needed --conf-file= \
---except-interface lo \
---srv-host=name.tcp.test-domain-name,.,1024,10,10 \
---listen-address 192.168.122.1 \
---listen-address 192.168.123.1 \
---listen-address 2001:db8:ac10:fe01::1 \
---listen-address 2001:db8:ac10:fd01::1 \
---listen-address 10.24.10.1 \
---dhcp-range 192.168.122.2,192.168.122.254 \
---dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
---dhcp-lease-max=253 \
---dhcp-no-override \
---dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \
---addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\
+# dnsmasq conf file created by libvirt
+strict-order
+bind-interfaces
+except-interface=lo
+domain-needed
+local=//
+srv-host=name.tcp.test-domain-name,.,1024,10,10
+listen-address=192.168.122.1
+listen-address=192.168.123.1
+listen-address=2001:db8:ac10:fe01::1
+listen-address=2001:db8:ac10:fd01::1
+listen-address=10.24.10.1
+dhcp-range=192.168.122.2,192.168.122.254
+dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases
+dhcp-lease-max=253
+dhcp-no-override
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
diff --git a/tests/networkxml2argvdata/nat-network-dns-txt-record.argv b/tests/networkxml2argvdata/nat-network-dns-txt-record.argv
index 3481507..bf00513 100644
--- a/tests/networkxml2argvdata/nat-network-dns-txt-record.argv
+++ b/tests/networkxml2argvdata/nat-network-dns-txt-record.argv
@@ -1,11 +1,18 @@
-@DNSMASQ@ --strict-order --bind-interfaces \
---local=// --domain-needed --conf-file= \
---except-interface lo '--txt-record=example,example value' \
---listen-address 192.168.122.1 --listen-address 192.168.123.1 \
---listen-address 2001:db8:ac10:fe01::1 \
---listen-address 2001:db8:ac10:fd01::1 --listen-address 10.24.10.1 \
---dhcp-range 192.168.122.2,192.168.122.254 \
---dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
---dhcp-lease-max=253 --dhcp-no-override \
---dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \
---addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\
+# dnsmasq conf file created by libvirt
+strict-order
+bind-interfaces
+except-interface=lo
+domain-needed
+local=//
+txt-record=example,example value
+listen-address=192.168.122.1
+listen-address=192.168.123.1
+listen-address=2001:db8:ac10:fe01::1
+listen-address=2001:db8:ac10:fd01::1
+listen-address=10.24.10.1
+dhcp-range=192.168.122.2,192.168.122.254
+dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases
+dhcp-lease-max=253
+dhcp-no-override
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
diff --git a/tests/networkxml2argvdata/nat-network.argv b/tests/networkxml2argvdata/nat-network.argv
index 37fd2fc..d542bbc 100644
--- a/tests/networkxml2argvdata/nat-network.argv
+++ b/tests/networkxml2argvdata/nat-network.argv
@@ -1,10 +1,17 @@
-@DNSMASQ@ --strict-order --bind-interfaces \
---local=// --domain-needed --conf-file= \
---except-interface lo --listen-address 192.168.122.1 \
---listen-address 192.168.123.1 --listen-address 2001:db8:ac10:fe01::1 \
---listen-address 2001:db8:ac10:fd01::1 --listen-address 10.24.10.1 \
---dhcp-range 192.168.122.2,192.168.122.254 \
---dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases \
---dhcp-lease-max=253 --dhcp-no-override \
---dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile \
---addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts\
+# dnsmasq conf file created by libvirt
+strict-order
+bind-interfaces
+except-interface=lo
+domain-needed
+local=//
+listen-address=192.168.122.1
+listen-address=192.168.123.1
+listen-address=2001:db8:ac10:fe01::1
+listen-address=2001:db8:ac10:fd01::1
+listen-address=10.24.10.1
+dhcp-range=192.168.122.2,192.168.122.254
+dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases
+dhcp-lease-max=253
+dhcp-no-override
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
diff --git a/tests/networkxml2argvdata/netboot-network.argv b/tests/networkxml2argvdata/netboot-network.argv
index 5408eb7..4f5fedd 100644
--- a/tests/networkxml2argvdata/netboot-network.argv
+++ b/tests/networkxml2argvdata/netboot-network.argv
@@ -1,10 +1,18 @@
-@DNSMASQ@ --strict-order --bind-interfaces --domain=example.com \
---local=/example.com/ --domain-needed --conf-file= \
---except-interface lo --listen-address 192.168.122.1 \
---dhcp-range 192.168.122.2,192.168.122.254 \
---dhcp-leasefile=/var/lib/libvirt/dnsmasq/netboot.leases \
---dhcp-lease-max=253 --dhcp-no-override --expand-hosts \
---dhcp-hostsfile=/var/lib/libvirt/dnsmasq/netboot.hostsfile \
---addn-hosts=/var/lib/libvirt/dnsmasq/netboot.addnhosts \
---enable-tftp \
---tftp-root /var/lib/tftproot --dhcp-boot pxeboot.img\
+# dnsmasq conf file created by libvirt
+strict-order
+bind-interfaces
+except-interface=lo
+domain-needed
+local=/example.com/
+domain=example.com
+expand-hosts
+listen-address=192.168.122.1
+dhcp-range=192.168.122.2,192.168.122.254
+dhcp-leasefile=/var/lib/libvirt/dnsmasq/netboot.leases
+dhcp-lease-max=253
+dhcp-no-override
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/netboot.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/netboot.addnhosts
+enable-tftp
+tftp-root=/var/lib/tftproot
+dhcp-boot=pxeboot.img
diff --git a/tests/networkxml2argvdata/netboot-proxy-network.argv b/tests/networkxml2argvdata/netboot-proxy-network.argv
index 21e01e3..8b9c03a 100644
--- a/tests/networkxml2argvdata/netboot-proxy-network.argv
+++ b/tests/networkxml2argvdata/netboot-proxy-network.argv
@@ -1,9 +1,16 @@
-@DNSMASQ@ --strict-order --bind-interfaces --domain=example.com \
---local=/example.com/ --domain-needed --conf-file= \
---except-interface lo --listen-address 192.168.122.1 \
---dhcp-range 192.168.122.2,192.168.122.254 \
---dhcp-leasefile=/var/lib/libvirt/dnsmasq/netboot.leases \
---dhcp-lease-max=253 --dhcp-no-override --expand-hosts \
---dhcp-hostsfile=/var/lib/libvirt/dnsmasq/netboot.hostsfile \
---addn-hosts=/var/lib/libvirt/dnsmasq/netboot.addnhosts \
---dhcp-boot pxeboot.img,,10.20.30.40\
+# dnsmasq conf file created by libvirt
+strict-order
+bind-interfaces
+except-interface=lo
+domain-needed
+local=/example.com/
+domain=example.com
+expand-hosts
+listen-address=192.168.122.1
+dhcp-range=192.168.122.2,192.168.122.254
+dhcp-leasefile=/var/lib/libvirt/dnsmasq/netboot.leases
+dhcp-lease-max=253
+dhcp-no-override
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/netboot.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/netboot.addnhosts
+dhcp-boot=pxeboot.img,,10.20.30.40
diff --git a/tests/networkxml2argvdata/routed-network.argv b/tests/networkxml2argvdata/routed-network.argv
index 9fedb2b..ad9e121 100644
--- a/tests/networkxml2argvdata/routed-network.argv
+++ b/tests/networkxml2argvdata/routed-network.argv
@@ -1,4 +1,8 @@
-@DNSMASQ@ --strict-order --bind-interfaces \
---local=// --domain-needed --conf-file= \
---except-interface lo --listen-address 192.168.122.1 \
---addn-hosts=/var/lib/libvirt/dnsmasq/local.addnhosts\
+# dnsmasq conf file created by libvirt
+strict-order
+bind-interfaces
+except-interface=lo
+domain-needed
+local=//
+listen-address=192.168.122.1
+addn-hosts=/var/lib/libvirt/dnsmasq/local.addnhosts
diff --git a/tests/networkxml2argvtest.c b/tests/networkxml2argvtest.c
index 87519e4..78ac8cf 100644
--- a/tests/networkxml2argvtest.c
+++ b/tests/networkxml2argvtest.c
@@ -15,37 +15,6 @@
#include "memory.h"
#include "network/bridge_driver.h"
-/* Replace all occurrences of @token in @buf by @replacement and adjust size of
- * @buf accordingly. Returns 0 on success and -1 on out-of-memory errors. */
-static int replaceTokens(char **buf, const char *token, const char *replacement) {
- size_t token_start, token_end;
- size_t buf_len, rest_len;
- const size_t token_len = strlen(token);
- const size_t replacement_len = strlen(replacement);
- const int diff = replacement_len - token_len;
-
- buf_len = rest_len = strlen(*buf) + 1;
- token_end = 0;
- for (;;) {
- char *match = strstr(*buf + token_end, token);
- if (match == NULL)
- break;
- token_start = match - *buf;
- rest_len -= token_start + token_len - token_end;
- token_end = token_start + token_len;
- buf_len += diff;
- if (diff > 0)
- if (VIR_REALLOC_N(*buf, buf_len) < 0)
- return -1;
- if (diff != 0)
- memmove(*buf + token_end + diff, *buf + token_end, rest_len);
- memcpy(*buf + token_start, replacement, replacement_len);
- token_end += diff;
- }
- /* if diff < 0, we could shrink the buffer here... */
- return 0;
-}
-
static int testCompareXMLToArgvFiles(const char *inxml, const char *outargv) {
char *inXmlData = NULL;
char *outArgvData = NULL;
@@ -55,6 +24,7 @@ static int testCompareXMLToArgvFiles(const char *inxml, const char *outargv) {
virNetworkObjPtr obj = NULL;
virCommandPtr cmd = NULL;
char *pidfile = NULL;
+ char *configdir = NULL;
dnsmasqContext *dctx = NULL;
if (virtTestLoadFile(inxml, &inXmlData) < 0)
@@ -62,10 +32,6 @@ static int testCompareXMLToArgvFiles(const char *inxml, const char *outargv) {
if (virtTestLoadFile(outargv, &outArgvData) < 0)
goto fail;
-
- if (replaceTokens(&outArgvData, "@DNSMASQ@", DNSMASQ))
- goto fail;
-
if (!(dev = virNetworkDefParseString(inXmlData)))
goto fail;
@@ -78,12 +44,9 @@ static int testCompareXMLToArgvFiles(const char *inxml, const char *outargv) {
if (dctx == NULL)
goto fail;
- if (networkBuildDhcpDaemonCommandLine(obj, &cmd, pidfile, dctx) < 0)
- goto fail;
-
- if (!(actual = virCommandToString(cmd)))
+ if (networkBuildDhcpDaemonCommandLine(obj, &cmd, pidfile,
+ dctx, configdir, 1, &actual) < 0)
goto fail;
-
if (STRNEQ(outArgvData, actual)) {
virtTestDifference(stderr, outArgvData, actual);
goto fail;
@@ -147,7 +110,6 @@ mymain(void)
if (virtTestRun("Network XML-2-Argv " name, \
1, testCompareXMLToArgvHelper, (name)) < 0) \
ret = -1
-
DO_TEST("isolated-network");
DO_TEST("routed-network");
DO_TEST("nat-network");
--
1.7.11.7
12 years, 1 month
[libvirt] patch option needs clarification
by Gene Czarcinski
I am pretty much complete creating a patch which changes how dnsmasq is
started by moving the command line parameters into a conf file. This new
file is placed into the same directory and the lease file.
The test for the command line arguments now checks the contents of the
conf-file and there is no longer any tests for the command line
parameters which are now two.
The first command line parameter is (naturally) --conf-file=<filename>.
The second parameter adds new functionality and is
--conf-dir=<directory>. This directory is placed into the same
directory as the conf-file and the lease file. The name of this
directory is "<net-name>.d". This was added to make testing/debugging of
new dnsmasq options easier since it no longer requires rebuilding the
binaries. This is also useful for adding log-dhcp and/or log-queries
for a specific network.
Now the option question. I can submit the patch assuming the my
previously submitted patch to add --interface to the command line has
been applied or I can assume that it has not been applied. In either
case, the new code adds a interface=<dev-name> to the conf-file.
All development and testing was done with 0.10.2 libvirt src.rpm on
Fedora 17.
The patch will be submitted based on git.
Gene
12 years, 1 month