[libvirt] [PATCH] Fix python error reporting for some storage operations
by Cole Robinson
In the python bindings, all vir* classes expect to be
passed a virConnect object when instantiated. Before
the storage stuff, these classes were only instantiated
in virConnect methods, so the generator is hardcoded to
pass 'self' as the connection instance to these classes.
Problem is there are some methods that return pool or vol
instances which aren't called from virConnect: you can
lookup a storage volume's associated pool, and can lookup
volumes from a pool. In these cases passing 'self' doesn't
give the vir* instance a connection, so when it comes time
to raise an exception crap hits the fan.
Rather than rework the generator to accomodate this edge
case, I just fixed the init functions for virStorage* to
pull the associated connection out of the passed value
if it's not a virConnect instance.
Thanks,
Cole
diff --git a/python/generator.py b/python/generator.py
index 01a17da..c706b19 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -962,8 +962,12 @@ def buildWrappers():
list = reference_keepers[classname]
for ref in list:
classes.write(" self.%s = None\n" % ref[1])
- if classname in [ "virDomain", "virNetwork", "virStoragePool", "virStorageVol" ]:
+ if classname in [ "virDomain", "virNetwork" ]:
classes.write(" self._conn = conn\n")
+ elif classname in [ "virStorageVol", "virStoragePool" ]:
+ classes.write(" self._conn = conn\n" + \
+ " if not isinstance(conn, virConnect):\n" + \
+ " self._conn = conn._conn\n")
classes.write(" if _obj != None:self._o = _obj;return\n")
classes.write(" self._o = None\n\n");
destruct=None
3 weeks, 5 days
[libvirt] [PATCH] Fix compile error for stable 1.2.9
by Yang hongyang
Seems a backport miss. An extra member is passed to struct
virLXCBasicMountInfo.
Signed-off-by: Yang hongyang <hongyang.yang(a)easystack.cn>
---
src/lxc/lxc_container.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 28dabec..1c65fa9 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -760,7 +760,7 @@ typedef struct {
static const virLXCBasicMountInfo lxcBasicMounts[] = {
{ "proc", "/proc", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, false, false },
- { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, false, false, false },
+ { "/proc/sys", "/proc/sys", NULL, MS_BIND|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, false, false },
{ "sysfs", "/sys", "sysfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, false, false },
{ "securityfs", "/sys/kernel/security", "securityfs", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY, true, true },
#if WITH_SELINUX
--
1.7.1
1 year, 5 months
[libvirt] Supporting vhost-net and macvtap in libvirt for QEMU
by Anthony Liguori
Disclaimer: I am neither an SR-IOV nor a vhost-net expert, but I've CC'd
people that are who can throw tomatoes at me for getting bits wrong :-)
I wanted to start a discussion about supporting vhost-net in libvirt.
vhost-net has not yet been merged into qemu but I expect it will be soon
so it's a good time to start this discussion.
There are two modes worth supporting for vhost-net in libvirt. The
first mode is where vhost-net backs to a tun/tap device. This is
behaves in very much the same way that -net tap behaves in qemu today.
Basically, the difference is that the virtio backend is in the kernel
instead of in qemu so there should be some performance improvement.
Current, libvirt invokes qemu with -net tap,fd=X where X is an already
open fd to a tun/tap device. I suspect that after we merge vhost-net,
libvirt could support vhost-net in this mode by just doing -net
vhost,fd=X. I think the only real question for libvirt is whether to
provide a user visible switch to use vhost or to just always use vhost
when it's available and it makes sense. Personally, I think the later
makes sense.
The more interesting invocation of vhost-net though is one where the
vhost-net device backs directly to a physical network card. In this
mode, vhost should get considerably better performance than the current
implementation. I don't know the syntax yet, but I think it's
reasonable to assume that it will look something like -net
tap,dev=eth0. The effect will be that eth0 is dedicated to the guest.
On most modern systems, there is a small number of network devices so
this model is not all that useful except when dealing with SR-IOV
adapters. In that case, each physical device can be exposed as many
virtual devices (VFs). There are a few restrictions here though. The
biggest is that currently, you can only change the number of VFs by
reloading a kernel module so it's really a parameter that must be set at
startup time.
I think there are a few ways libvirt could support vhost-net in this
second mode. The simplest would be to introduce a new tag similar to
<source network='br0'>. In fact, if you probed the device type for the
network parameter, you could probably do something like <source
network='eth0'> and have it Just Work.
Another model would be to have libvirt see an SR-IOV adapter as a
network pool whereas it handled all of the VF management. Considering
how inflexible SR-IOV is today, I'm not sure whether this is the best model.
Has anyone put any more thought into this problem or how this should be
modeled in libvirt? Michael, could you share your current thinking for
-net syntax?
--
Regards,
Anthony Liguori
1 year, 5 months
[libvirt] [PATCH] qemu: Use iohelper during restore
by Shivaprasad G Bhat
Commit afe6e58 & c4caab53 made necessary changes to use io-helpers
during save and restore. The commit c4caab53 missed to remove the
redundant check in qemuDomainSaveImageOpen() because of which
virFileWrapperFdNew() is not called if bypass_cache is false.
Signed-off-by: Shivaprasad G Bhat <sbhat(a)linux.vnet.ibm.com>
---
src/qemu/qemu_driver.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 516a851..ac89372 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6150,9 +6150,11 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver,
virDomainDefPtr def = NULL;
int oflags = open_write ? O_RDWR : O_RDONLY;
virCapsPtr caps = NULL;
+ unsigned int wrapperFlags = VIR_FILE_WRAPPER_NON_BLOCKING;
if (bypass_cache) {
int directFlag = virFileDirectFdFlag();
+ wrapperFlags |= VIR_FILE_WRAPPER_BYPASS_CACHE;
if (directFlag < 0) {
virReportError(VIR_ERR_OPERATION_FAILED, "%s",
_("bypass cache unsupported by this system"));
@@ -6166,9 +6168,8 @@ qemuDomainSaveImageOpen(virQEMUDriverPtr driver,
if ((fd = qemuOpenFile(driver, NULL, path, oflags, NULL, NULL)) < 0)
goto error;
- if (bypass_cache &&
- !(*wrapperFd = virFileWrapperFdNew(&fd, path,
- VIR_FILE_WRAPPER_BYPASS_CACHE)))
+ if (wrapperFd &&
+ !(*wrapperFd = virFileWrapperFdNew(&fd, path, wrapperFlags)))
goto error;
if (saferead(fd, &header, sizeof(header)) != sizeof(header)) {
7 years, 9 months
[libvirt] [PATCH] qemu: fix crash on getting block stats for empty cdrom
by Nikolay Shirokovskiy
Looks like it was introduced in c5f61513. Before this commit handling empty cdrom
was correct becase physical sizes of non block disks are not updated.
Now when all types are supported we need to check for empty drives.
[1] crash backtrace
0 __strrchr_sse42 () at ../sysdeps/x86_64/multiarch/strrchr.S:138
1 0x00007ffff7242192 in virFileIsSharedFSType (path=0x0, fstypes=63) at util/virfile.c:3351
2 0x00007ffff7242a5b in virFileIsSharedFS (path=0x0) at util/virfile.c:3557
3 0x00007fffdb835443 in qemuOpenFileAs (fallback_uid=0, fallback_gid=107, dynamicOwnership=true, path=0x0,
oflags=0, needUnlink=0x0, bypassSecurityDriver=0x0) at qemu/qemu_driver.c:2927
4 0x00007fffdb83539b in qemuOpenFile (driver=0x7fffcc1062f0, vm=0x7fffcc25aa50, path=0x0, oflags=0,
needUnlink=0x0, bypassSecurityDriver=0x0) at qemu/qemu_driver.c:2908
5 0x00007fffdb84d2d3 in qemuDomainStorageOpenStat (driver=0x7fffcc1062f0, cfg=0x7fffcc188880, vm=0x7fffcc25aa50,
src=0x7fffcc256920, ret_fd=0x7fffe6a49488, ret_sb=0x7fffe6a49490) at qemu/qemu_driver.c:11266
6 0x00007fffdb84d4ff in qemuDomainStorageUpdatePhysical (driver=0x7fffcc1062f0, cfg=0x7fffcc188880,
vm=0x7fffcc25aa50, src=0x7fffcc256920) at qemu/qemu_driver.c:11319
7 0x00007fffdb8661e7 in qemuDomainGetStatsOneBlock (driver=0x7fffcc1062f0, cfg=0x7fffcc188880, dom=0x7fffcc25aa50,
record=0x7fffa8000e70, maxparams=0x7fffe6a49790, disk=0x7fffcc2565a0, src=0x7fffcc256920, block_idx=7,
backing_idx=0, stats=0x7fffa8000e90) at qemu/qemu_driver.c:19223
8 0x00007fffdb86652b in qemuDomainGetStatsBlock (driver=0x7fffcc1062f0, dom=0x7fffcc25aa50, record=0x7fffa8000e70,
maxparams=0x7fffe6a49790, privflags=1) at qemu/qemu_driver.c:19282
9 0x00007fffdb8669f7 in qemuDomainGetStats (conn=0x7fffb80009a0, dom=0x7fffcc25aa50, stats=127,
record=0x7fffe6a49870, flags=1) at qemu/qemu_driver.c:19444
10 0x00007fffdb866dc8 in qemuConnectGetAllDomainStats (conn=0x7fffb80009a0, doms=0x0, ndoms=0, stats=127,
retStats=0x7fffe6a499a0, flags=1) at qemu/qemu_driver.c:19534
11 0x00007ffff7388376 in virConnectGetAllDomainStats (conn=0x7fffb80009a0, stats=0, retStats=0x7fffe6a499a0,
flags=1) at libvirt-domain.c:11311
---
src/qemu/qemu_driver.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index bc5e448..16b435a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19170,6 +19170,7 @@ qemuDomainGetStatsOneBlock(virQEMUDriverPtr driver,
QEMU_ADD_NAME_PARAM(record, maxparams, "block", "name", block_idx,
disk->dst);
+
if (virStorageSourceIsLocalStorage(src) && src->path)
QEMU_ADD_NAME_PARAM(record, maxparams, "block", "path",
block_idx, src->path);
@@ -19216,7 +19217,7 @@ qemuDomainGetStatsOneBlock(virQEMUDriverPtr driver,
if (entry->capacity)
QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, block_idx,
"capacity", entry->capacity);
- if (entry->physical) {
+ if (entry->physical || virStorageSourceIsEmpty(src)) {
QEMU_ADD_BLOCK_PARAM_ULL(record, maxparams, block_idx,
"physical", entry->physical);
} else {
--
1.8.3.1
7 years, 11 months
[libvirt] [PATCH] leasetime support per <dhcp> and <host>
by Alberto Ruiz
Support for custom dhcp wide and per host leasetime.
It is specified as a child tag for <dhcp>:
<dhcp>
<leasetime>24h</leasetime>
...
</dhcp>
And as an attribute for <host>:
<dhcp>
<host leasetime="7d" .../>
</dhcp>
These are the different notations:
-1 (infinite/unlimited lease)
120 (seconds are the default unit, 120 seconds is the minimum, if less is
specified it will use 120)
300s (seconds)
5m (minutes)
24h (hours)
7d (days)
---
docs/schemas/basictypes.rng | 5 +
docs/schemas/network.rng | 8 ++
src/conf/network_conf.c | 86 +++++++++++++-
src/conf/network_conf.h | 4 +-
src/libvirt_private.syms | 1 +
src/network/bridge_driver.c | 132
+++++++++++++++++----
src/network/bridge_driver.h | 1 +
src/util/virdnsmasq.c | 106 +++++++++++------
src/util/virdnsmasq.h | 2 +
.../dhcp6-nat-network.hostsfile | 7 ++
tests/networkxml2confdata/dhcp6-network.hostsfile | 5 +
.../dhcp6host-routed-network.hostsfile | 7 ++
tests/networkxml2confdata/leasetime-days.conf | 17 +++
tests/networkxml2confdata/leasetime-days.xml | 18 +++
tests/networkxml2confdata/leasetime-host.conf | 16 +++
tests/networkxml2confdata/leasetime-host.hostsfile | 6 +
tests/networkxml2confdata/leasetime-host.xml | 22 ++++
tests/networkxml2confdata/leasetime-hours.conf | 17 +++
tests/networkxml2confdata/leasetime-hours.xml | 18 +++
tests/networkxml2confdata/leasetime-infinite.conf | 17 +++
tests/networkxml2confdata/leasetime-infinite.xml | 18 +++
tests/networkxml2confdata/leasetime-minutes.conf | 17 +++
tests/networkxml2confdata/leasetime-minutes.xml | 18 +++
tests/networkxml2confdata/leasetime-seconds.conf | 17 +++
tests/networkxml2confdata/leasetime-seconds.xml | 18 +++
tests/networkxml2confdata/leasetime.conf | 17 +++
tests/networkxml2confdata/leasetime.xml | 18 +++
.../nat-network-dns-srv-record-minimal.hostsfile | 2 +
.../nat-network-dns-srv-record.hostsfile | 2 +
.../nat-network-dns-txt-record.hostsfile | 2 +
.../nat-network-name-with-quotes.hostsfile | 2 +
tests/networkxml2confdata/nat-network.hostsfile | 2 +
tests/networkxml2conftest.c | 47 ++++++--
33 files changed, 597 insertions(+), 78 deletions(-)
create mode 100644 tests/networkxml2confdata/dhcp6-nat-network.hostsfile
create mode 100644 tests/networkxml2confdata/dhcp6-network.hostsfile
create mode 100644 tests/networkxml2confdata/dhcp6host-routed-network.
hostsfile
create mode 100644 tests/networkxml2confdata/leasetime-days.conf
create mode 100644 tests/networkxml2confdata/leasetime-days.xml
create mode 100644 tests/networkxml2confdata/leasetime-host.conf
create mode 100644 tests/networkxml2confdata/leasetime-host.hostsfile
create mode 100644 tests/networkxml2confdata/leasetime-host.xml
create mode 100644 tests/networkxml2confdata/leasetime-hours.conf
create mode 100644 tests/networkxml2confdata/leasetime-hours.xml
create mode 100644 tests/networkxml2confdata/leasetime-infinite.conf
create mode 100644 tests/networkxml2confdata/leasetime-infinite.xml
create mode 100644 tests/networkxml2confdata/leasetime-minutes.conf
create mode 100644 tests/networkxml2confdata/leasetime-minutes.xml
create mode 100644 tests/networkxml2confdata/leasetime-seconds.conf
create mode 100644 tests/networkxml2confdata/leasetime-seconds.xml
create mode 100644 tests/networkxml2confdata/leasetime.conf
create mode 100644 tests/networkxml2confdata/leasetime.xml
create mode 100644 tests/networkxml2confdata/nat-network-dns-srv-record-
minimal.hostsfile
create mode 100644 tests/networkxml2confdata/nat-network-dns-srv-record.
hostsfile
create mode 100644 tests/networkxml2confdata/nat-network-dns-txt-record.
hostsfile
create mode 100644 tests/networkxml2confdata/nat-network-name-with-quotes.
hostsfile
create mode 100644 tests/networkxml2confdata/nat-network.hostsfile
diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng
index 1b4f980..11fbe2b 100644
--- a/docs/schemas/basictypes.rng
+++ b/docs/schemas/basictypes.rng
@@ -518,4 +518,9 @@
</element>
</define>
+ <define name="leaseTime">
+ <data type="string">
+ <param name="pattern">-?[0-9]*[smhd]?</param>
+ </data>
+ </define>
</grammar>
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 1a18e64..e6ddb63 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -340,6 +340,11 @@
<!-- Define the range(s) of IP addresses that the DHCP
server should hand out -->
<element name="dhcp">
+ <optional>
+ <element name="leasetime">
+ <ref name="leaseTime"/>
+ </element>
+ </optional>
<zeroOrMore>
<element name="range">
<attribute name="start"><ref
name="ipAddr"/></attribute>
@@ -361,6 +366,9 @@
<attribute name="name"><text/></attribute>
</choice>
<attribute name="ip"><ref name="ipAddr"/></attribute>
+ <optional>
+ <attribute name="leasetime"><ref
name="leaseTime"/></attribute>
+ </optional>
</element>
</zeroOrMore>
<optional>
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index aa39776..bcc4bbb 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -30,6 +30,8 @@
#include <fcntl.h>
#include <string.h>
#include <dirent.h>
+#include <stdlib.h>
+#include <inttypes.h>
#include "virerror.h"
#include "datatypes.h"
@@ -911,16 +913,83 @@ virSocketAddrRangeParseXML(const char *networkName,
return ret;
}
+static int64_t
+virNetworkDHCPDefGetLeaseTime (xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ const char* query,
+ bool *error)
+{
+ int64_t multiplier = 1, result = -1;
+ char *leaseString;
+ xmlNodePtr save;
+ size_t len;
+
+ *error = 0;
+
+ save = ctxt->node;
+ ctxt->node = node;
+
+ leaseString = virXPathString (query, ctxt);
+
+ /* If value is not present we set the value to -2 */
+ if (leaseString == NULL) {
+ result = -2;
+ goto cleanup;
+ }
+
+ len = strlen (leaseString) - 1;
+
+ if (leaseString[len] == 'm')
+ multiplier = 60;
+ else if (leaseString[len] == 'h')
+ multiplier = 60 * 60;
+ else if (leaseString[len] == 'd')
+ multiplier = 60 * 60 * 24;
+
+ /* Remove the time unit suffix */
+ if (leaseString[len] < 48 || leaseString[len] > 57)
+ leaseString[len] = '\0';
+
+ errno = 0;
+ result = (int64_t) strtoll((const char*)leaseString, NULL, 10);
+
+ /* Report any errors parsing the string */
+ if (errno != 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("<leasetime> value could not be converted to a
signed integer: %s"),
+ leaseString);
+ *error = 1;
+ goto cleanup;
+ }
+
+ result = result * multiplier;
+
+ if (result > UINT32_MAX || result < -1) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("<leasetime> value cannot be greater than the
equivalent of %" PRIo32 " seconds or less than -1: %" PRId64),
+ UINT32_MAX, result);
+ *error = 1;
+ }
+
+cleanup:
+ VIR_FREE(leaseString);
+ ctxt->node = save;
+ return result;
+}
+
static int
virNetworkDHCPHostDefParseXML(const char *networkName,
virNetworkIPDefPtr def,
xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
virNetworkDHCPHostDefPtr host,
bool partialOkay)
{
char *mac = NULL, *name = NULL, *ip = NULL, *id = NULL;
virMacAddr addr;
virSocketAddr inaddr;
+ int64_t leasetime;
+ bool error;
int ret = -1;
mac = virXMLPropString(node, "mac");
@@ -1013,6 +1082,10 @@ virNetworkDHCPHostDefParseXML(const char
*networkName,
}
}
+ leasetime = virNetworkDHCPDefGetLeaseTime (node, ctxt,
"string(./@leasetime)", &error);
+ if (error)
+ goto cleanup;
+
host->mac = mac;
mac = NULL;
host->id = id;
@@ -1021,6 +1094,7 @@ virNetworkDHCPHostDefParseXML(const char *networkName,
name = NULL;
if (ip)
host->ip = inaddr;
+ host->leasetime = leasetime;
ret = 0;
cleanup:
@@ -1034,9 +1108,11 @@ virNetworkDHCPHostDefParseXML(const char
*networkName,
static int
virNetworkDHCPDefParseXML(const char *networkName,
xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
virNetworkIPDefPtr def)
{
int ret = -1;
+ bool error;
xmlNodePtr cur;
virSocketAddrRange range;
virNetworkDHCPHostDef host;
@@ -1044,6 +1120,10 @@ virNetworkDHCPDefParseXML(const char *networkName,
memset(&range, 0, sizeof(range));
memset(&host, 0, sizeof(host));
+ def->leasetime = virNetworkDHCPDefGetLeaseTime (node, ctxt,
"string(./leasetime/text())", &error);
+ if (error)
+ goto cleanup;
+
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE &&
@@ -1057,7 +1137,7 @@ virNetworkDHCPDefParseXML(const char *networkName,
} else if (cur->type == XML_ELEMENT_NODE &&
xmlStrEqual(cur->name, BAD_CAST "host")) {
- if (virNetworkDHCPHostDefParseXML(networkName, def, cur,
+ if (virNetworkDHCPHostDefParseXML(networkName, def, cur, ctxt,
&host, false) < 0)
goto cleanup;
if (VIR_APPEND_ELEMENT(def->hosts, def->nhosts, host) < 0)
@@ -1607,7 +1687,7 @@ virNetworkIPDefParseXML(const char *networkName,
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE &&
xmlStrEqual(cur->name, BAD_CAST "dhcp")) {
- if (virNetworkDHCPDefParseXML(networkName, cur, def) < 0)
+ if (virNetworkDHCPDefParseXML(networkName, cur, ctxt, def) < 0)
goto cleanup;
} else if (cur->type == XML_ELEMENT_NODE &&
xmlStrEqual(cur->name, BAD_CAST "tftp")) {
@@ -3659,7 +3739,7 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def,
if (!ipdef)
goto cleanup;
- if (virNetworkDHCPHostDefParseXML(def->name, ipdef, ctxt->node,
+ if (virNetworkDHCPHostDefParseXML(def->name, ipdef, ctxt->node, ctxt,
&host, partialOkay) < 0)
goto cleanup;
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 3b227db..df687df 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -96,6 +96,7 @@ struct _virNetworkDHCPHostDef {
char *id;
char *name;
virSocketAddr ip;
+ int64_t leasetime;
};
typedef struct _virNetworkDNSTxtDef virNetworkDNSTxtDef;
@@ -170,7 +171,8 @@ struct _virNetworkIPDef {
char *tftproot;
char *bootfile;
virSocketAddr bootserver;
- };
+ int64_t leasetime;
+};
typedef struct _virNetworkForwardIfDef virNetworkForwardIfDef;
typedef virNetworkForwardIfDef *virNetworkForwardIfDefPtr;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index b88e903..84fb62e 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1497,6 +1497,7 @@ dnsmasqCapsRefresh;
dnsmasqContextFree;
dnsmasqContextNew;
dnsmasqDelete;
+dnsmasqDhcpHostsToString;
dnsmasqReload;
dnsmasqSave;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 7b99aca..dccf743 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -41,6 +41,8 @@
#include <sys/ioctl.h>
#include <net/if.h>
#include <dirent.h>
+#include <inttypes.h>
+#include <stdint.h>
#if HAVE_SYS_SYSCTL_H
# include <sys/sysctl.h>
#endif
@@ -859,30 +861,6 @@ networkKillDaemon(pid_t pid, const char *daemonName,
const char *networkName)
return ret;
}
-/* the following does not build a file, it builds a list
- * which is later saved into a file
- */
-
-static int
-networkBuildDnsmasqDhcpHostsList(dnsmasqContext *dctx,
- virNetworkIPDefPtr ipdef)
-{
- size_t i;
- bool ipv6 = false;
-
- if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6))
- ipv6 = true;
- for (i = 0; i < ipdef->nhosts; i++) {
- virNetworkDHCPHostDefPtr host = &(ipdef->hosts[i]);
- if (VIR_SOCKET_ADDR_VALID(&host->ip))
- if (dnsmasqAddDhcpHost(dctx, host->mac, &host->ip,
- host->name, host->id, ipv6) < 0)
- return -1;
- }
-
- return 0;
-}
-
static int
networkBuildDnsmasqHostsList(dnsmasqContext *dctx,
virNetworkDNSDefPtr dnsdef)
@@ -903,11 +881,93 @@ networkBuildDnsmasqHostsList(dnsmasqContext *dctx,
return 0;
}
+/* translates the leasetime value into a dnsmasq configuration string for
dhcp-range/host */
+static char *
+networkDnsmasqConfLeaseValueToString (int64_t leasetime)
+{
+ char *result = NULL;
+ virBuffer leasebuf = VIR_BUFFER_INITIALIZER;
+
+ /* Leasetime parameter set on the XML */
+ /* Less than -1 means there was no value set */
+ if (leasetime < -1) {
+ virBufferAsprintf(&leasebuf, "%s", "");
+ }
+ /* -1 means no expiration */
+ else if (leasetime == -1)
+ virBufferAsprintf(&leasebuf, ",infinite");
+ /* Minimum expiry value is 120 */
+ /* TODO: Discuss if we should up as we do here or just forward
whatever value to dnsmasq */
+ else if (leasetime < 120)
+ virBufferAsprintf(&leasebuf, ",120");
+ /* DHCP value for lease time is a unsigned four octect integer */
+ else if (leasetime <= UINT32_MAX)
+ virBufferAsprintf(&leasebuf, ",%" PRId64, leasetime);
+ /* TODO: Discuss the use of "deprecated" for ipv6*/
+ /* TODO: Discuss what is the default value that we want as dnsmasq's
is 1 hour */
+ /* TODO: Discuss what to do if value exceeds maximum, use default
value for now */
+ else {
+ virBufferAsprintf(&leasebuf, "%s", "");
+ }
+
+ result = virBufferContentAndReset(&leasebuf);
+ virBufferFreeAndReset (&leasebuf);
+
+ return result;
+}
+
+/* the following does not build a file, it builds a list
+ * which is later saved into a file
+ */
+
+static int
+networkBuildDnsmasqDhcpHostsList(dnsmasqContext *dctx,
+ virNetworkIPDefPtr ipdef)
+{
+ int ret = -1;
+ size_t i;
+ bool ipv6 = false;
+ char *leasetime = networkDnsmasqConfLeaseValueTo
String(ipdef->leasetime);
+
+ if (!leasetime)
+ goto cleanup;
+
+ if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6))
+ ipv6 = true;
+ for (i = 0; i < ipdef->nhosts; i++) {
+ virNetworkDHCPHostDefPtr host = &(ipdef->hosts[i]);
+ if (VIR_SOCKET_ADDR_VALID(&host->ip)) {
+ /* If the host has its own leasetime we get its specific
string */
+ if (host->leasetime > -2) {
+ char *hostlease = networkDnsmasqConfLeaseValueTo
String(host->leasetime);
+ if (!hostlease)
+ goto cleanup;
+ if (dnsmasqAddDhcpHost(dctx, host->mac, &host->ip,
+ host->name, host->id, hostlease,
ipv6) < 0) {
+ VIR_FREE(hostlease);
+ goto cleanup;
+ }
+ VIR_FREE(hostlease);
+ } else {
+ /* Otherwise we use the leasetime from dhcp */
+ if (dnsmasqAddDhcpHost(dctx, host->mac, &host->ip,
+ host->name, host->id, leasetime,
ipv6) < 0)
+ goto cleanup;
+ }
+ }
+ }
+
+ ret = 0;
+cleanup:
+ VIR_FREE(leasetime);
+ return ret;
+}
int
networkDnsmasqConfContents(virNetworkObjPtr network,
const char *pidfile,
char **configstr,
+ char **hostsfilestr,
dnsmasqContext *dctx,
dnsmasqCapsPtr caps ATTRIBUTE_UNUSED)
{
@@ -1213,6 +1273,7 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
}
for (r = 0; r < ipdef->nranges; r++) {
int thisRange;
+ char *leasestr;
if (!(saddr = virSocketAddrFormat(&ipdef->ranges[r].start)) ||
!(eaddr = virSocketAddrFormat(&ipdef->ranges[r].end)))
@@ -1220,12 +1281,22 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
virBufferAsprintf(&configbuf, "dhcp-range=%s,%s",
saddr, eaddr);
- if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6))
+
+ /* Add ipv6 prefix length parameter if needed */
+ if (ipdef == ipv6def)
virBufferAsprintf(&configbuf, ",%d", prefix);
+
+ leasestr = networkDnsmasqConfLeaseValueToString
(ipdef->leasetime);
+ if (!leasestr)
+ goto cleanup;
+ virBufferAsprintf(&configbuf, "%s", leasestr);
+
+ /* Add the newline */
virBufferAddLit(&configbuf, "\n");
VIR_FREE(saddr);
VIR_FREE(eaddr);
+ VIR_FREE(leasestr);
thisRange = virSocketAddrGetRange(&ipdef->ranges[r].start,
&ipdef->ranges[r].end,
&ipdef->address,
@@ -1256,6 +1327,15 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
if (networkBuildDnsmasqDhcpHostsList(dctx, ipdef) < 0)
goto cleanup;
+ /* Return the contents of the hostsfile if requested */
+ if (hostsfilestr) {
+ *hostsfilestr = dnsmasqDhcpHostsToString
(dctx->hostsfile->hosts,
+
dctx->hostsfile->nhosts);
+
+ if (!hostsfilestr)
+ goto cleanup;
+ }
+
/* Note: the following is IPv4 only */
if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) {
if (ipdef->nranges || ipdef->nhosts)
@@ -1355,7 +1435,7 @@
networkBuildDhcpDaemonCommandLine(virNetworkDriverStatePtr
driver,
network->dnsmasqPid = -1;
- if (networkDnsmasqConfContents(network, pidfile, &configstr,
+ if (networkDnsmasqConfContents(network, pidfile, &configstr, NULL,
dctx, dnsmasq_caps) < 0)
goto cleanup;
if (!configstr)
diff --git a/src/network/bridge_driver.h b/src/network/bridge_driver.h
index ff7f921..c653c50 100644
--- a/src/network/bridge_driver.h
+++ b/src/network/bridge_driver.h
@@ -53,6 +53,7 @@ int networkGetActualType(virDomainNetDefPtr iface)
int networkDnsmasqConfContents(virNetworkObjPtr network,
const char *pidfile,
char **configstr,
+ char **hostsfilestr,
dnsmasqContext *dctx,
dnsmasqCapsPtr caps);
diff --git a/src/util/virdnsmasq.c b/src/util/virdnsmasq.c
index 1b78c1f..94c9a3b 100644
--- a/src/util/virdnsmasq.c
+++ b/src/util/virdnsmasq.c
@@ -308,52 +308,47 @@ hostsfileAdd(dnsmasqHostsfile *hostsfile,
virSocketAddr *ip,
const char *name,
const char *id,
+ const char *leasetime,
bool ipv6)
{
+ int ret = -1;
char *ipstr = NULL;
+ virBuffer hostbuf = VIR_BUFFER_INITIALIZER;
+
if (VIR_REALLOC_N(hostsfile->hosts, hostsfile->nhosts + 1) < 0)
goto error;
if (!(ipstr = virSocketAddrFormat(ip)))
- return -1;
+ goto error;
/* the first test determines if it is a dhcpv6 host */
if (ipv6) {
- if (name && id) {
- if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host,
- "id:%s,%s,[%s]", id, name, ipstr) < 0)
- goto error;
- } else if (name && !id) {
- if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host,
- "%s,[%s]", name, ipstr) < 0)
- goto error;
- } else if (!name && id) {
- if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host,
- "id:%s,[%s]", id, ipstr) < 0)
- goto error;
- }
+ if (name && id)
+ virBufferAsprintf(&hostbuf, "id:%s,%s,[%s]", id, name, ipstr);
+ else if (name && !id)
+ virBufferAsprintf(&hostbuf, "%s,[%s]", name, ipstr);
+ else if (!name && id)
+ virBufferAsprintf(&hostbuf, "id:%s,[%s]", id, ipstr);
} else if (name && mac) {
- if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host,
"%s,%s,%s",
- mac, ipstr, name) < 0)
- goto error;
+ virBufferAsprintf(&hostbuf, "%s,%s,%s", mac, ipstr, name);
} else if (name && !mac) {
- if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, "%s,%s",
- name, ipstr) < 0)
- goto error;
+ virBufferAsprintf(&hostbuf, "%s,%s", name, ipstr);
} else {
- if (virAsprintf(&hostsfile->hosts[hostsfile->nhosts].host, "%s,%s",
- mac, ipstr) < 0)
- goto error;
+ virBufferAsprintf(&hostbuf, "%s,%s", mac, ipstr);
}
- VIR_FREE(ipstr);
- hostsfile->nhosts++;
+ /* The leasetime string already includes comma if there's any value at
all */
+ virBufferAsprintf(&hostbuf, "%s", leasetime);
- return 0;
+ if (!(hostsfile->hosts[hostsfile->nhosts].host =
virBufferContentAndReset (&hostbuf)))
+ goto error;
+ hostsfile->nhosts++;
+ ret = 0;
error:
+ virBufferFreeAndReset(&hostbuf);
VIR_FREE(ipstr);
- return -1;
+ return ret;
}
static dnsmasqHostsfile *
@@ -391,10 +386,9 @@ hostsfileWrite(const char *path,
dnsmasqDhcpHost *hosts,
unsigned int nhosts)
{
- char *tmp;
+ char *tmp, *content = NULL;
FILE *f;
bool istmp = true;
- size_t i;
int rc = 0;
/* even if there are 0 hosts, create a 0 length file, to allow
@@ -412,17 +406,21 @@ hostsfileWrite(const char *path,
}
}
- for (i = 0; i < nhosts; i++) {
- if (fputs(hosts[i].host, f) == EOF || fputc('\n', f) == EOF) {
- rc = -errno;
- VIR_FORCE_FCLOSE(f);
+ if (!(content = dnsmasqDhcpHostsToString(hosts, nhosts))) {
+ rc = -ENOMEM;
+ goto cleanup;
+ }
- if (istmp)
- unlink(tmp);
+ if (fputs(content, f) == EOF) {
+ rc = -errno;
+ VIR_FORCE_FCLOSE(f);
+
+ if (istmp)
+ unlink(tmp);
+
+ goto cleanup;
+ }
- goto cleanup;
- }
- }
if (VIR_FCLOSE(f) == EOF) {
rc = -errno;
@@ -436,6 +434,7 @@ hostsfileWrite(const char *path,
}
cleanup:
+ VIR_FREE(content);
VIR_FREE(tmp);
return rc;
@@ -524,9 +523,10 @@ dnsmasqAddDhcpHost(dnsmasqContext *ctx,
virSocketAddr *ip,
const char *name,
const char *id,
+ const char *leasetime,
bool ipv6)
{
- return hostsfileAdd(ctx->hostsfile, mac, ip, name, id, ipv6);
+ return hostsfileAdd(ctx->hostsfile, mac, ip, name, id, leasetime,
ipv6);
}
/*
@@ -892,3 +892,31 @@ dnsmasqCapsGet(dnsmasqCapsPtr caps, dnsmasqCapsFlags
flag)
return caps && virBitmapIsBitSet(caps->flags, flag);
}
+
+/** dnsmasqDhcpHostsToString:
+ *
+ * Turns a vector of dnsmasqDhcpHost into the string that is ought to be
+ * stored in the hostsfile, this functionality is split to make
hostsfiles
+ * testable. Returs NULL if nhosts is 0.
+ */
+char *
+dnsmasqDhcpHostsToString (dnsmasqDhcpHost *hosts,
+ unsigned int nhosts)
+{
+ int i;
+ char *result = NULL;
+ virBuffer hostsfilebuf = VIR_BUFFER_INITIALIZER;
+
+ if (nhosts == 0)
+ goto cleanup;
+
+ for (i = 0; i < nhosts; i++) {
+ virBufferAsprintf(&hostsfilebuf, "%s\n", hosts[i].host);
+ }
+
+ result = virBufferContentAndReset(&hostsfilebuf);
+
+cleanup:
+ virBufferFreeAndReset(&hostsfilebuf);
+ return result;
+}
diff --git a/src/util/virdnsmasq.h b/src/util/virdnsmasq.h
index f47bea3..1795bc8 100644
--- a/src/util/virdnsmasq.h
+++ b/src/util/virdnsmasq.h
@@ -88,6 +88,7 @@ int dnsmasqAddDhcpHost(dnsmasqContext *ctx,
virSocketAddr *ip,
const char *name,
const char *id,
+ const char *leastime,
bool ipv6);
int dnsmasqAddHost(dnsmasqContext *ctx,
virSocketAddr *ip,
@@ -105,6 +106,7 @@ int dnsmasqCapsRefresh(dnsmasqCapsPtr *caps, const char
*binaryPath);
bool dnsmasqCapsGet(dnsmasqCapsPtr caps, dnsmasqCapsFlags flag);
const char *dnsmasqCapsGetBinaryPath(dnsmasqCapsPtr caps);
unsigned long dnsmasqCapsGetVersion(dnsmasqCapsPtr caps);
+char *dnsmasqDhcpHostsToString(dnsmasqDhcpHost *hosts, unsigned int
nhosts);
# define DNSMASQ_DHCPv6_MAJOR_REQD 2
# define DNSMASQ_DHCPv6_MINOR_REQD 64
diff --git a/tests/networkxml2confdata/dhcp6-nat-network.hostsfile
b/tests/networkxml2confdata/dhcp6-nat-network.hostsfile
new file mode 100644
index 0000000..de659b9
--- /dev/null
+++ b/tests/networkxml2confdata/dhcp6-nat-network.hostsfile
@@ -0,0 +1,7 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
+id:0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63,[
2001:db8:ac10:fd01::1:20]
+paul,[2001:db8:ac10:fd01::1:21]
+id:0:3:0:1:0:16:3e:11:22:33,peter.xyz,[2001:db8:ac10:fd01::1:22]
+id:0:3:0:1:0:16:3e:44:55:33,[2001:db8:ac10:fd01::1:23]
+id:0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66,badbob,[2001:db8:ac10:fd01::1:24]
diff --git a/tests/networkxml2confdata/dhcp6-network.hostsfile
b/tests/networkxml2confdata/dhcp6-network.hostsfile
new file mode 100644
index 0000000..9dfb172
--- /dev/null
+++ b/tests/networkxml2confdata/dhcp6-network.hostsfile
@@ -0,0 +1,5 @@
+id:0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63,[
2001:db8:ac10:fd01::1:20]
+paul,[2001:db8:ac10:fd01::1:21]
+id:0:3:0:1:0:16:3e:11:22:33,peter.xyz,[2001:db8:ac10:fd01::1:22]
+id:0:3:0:1:0:16:3e:44:55:33,[2001:db8:ac10:fd01::1:23]
+id:0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66,badbob,[2001:db8:ac10:fd01::1:24]
diff --git a/tests/networkxml2confdata/dhcp6host-routed-network.hostsfile
b/tests/networkxml2confdata/dhcp6host-routed-network.hostsfile
new file mode 100644
index 0000000..de659b9
--- /dev/null
+++ b/tests/networkxml2confdata/dhcp6host-routed-network.hostsfile
@@ -0,0 +1,7 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
+id:0:4:7e:7d:f0:7d:a8:bc:c5:d2:13:32:11:ed:16:ea:84:63,[
2001:db8:ac10:fd01::1:20]
+paul,[2001:db8:ac10:fd01::1:21]
+id:0:3:0:1:0:16:3e:11:22:33,peter.xyz,[2001:db8:ac10:fd01::1:22]
+id:0:3:0:1:0:16:3e:44:55:33,[2001:db8:ac10:fd01::1:23]
+id:0:1:0:1:18:aa:62:fe:0:16:3e:44:55:66,badbob,[2001:db8:ac10:fd01::1:24]
diff --git a/tests/networkxml2confdata/leasetime-days.conf
b/tests/networkxml2confdata/leasetime-days.conf
new file mode 100644
index 0000000..9501e2f
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime-days.conf
@@ -0,0 +1,17 @@
+##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
+##OVERWRITTEN AND LOST. Changes to this configuration should be made
using:
+## virsh net-edit default
+## or other application using the libvirt API.
+##
+## dnsmasq conf file created by libvirt
+strict-order
+except-interface=lo
+bind-dynamic
+interface=virbr0
+dhcp-range=192.168.122.2,192.168.122.254,86400
+dhcp-no-override
+dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64,86400
+dhcp-lease-max=493
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
+enable-ra
diff --git a/tests/networkxml2confdata/leasetime-days.xml
b/tests/networkxml2confdata/leasetime-days.xml
new file mode 100644
index 0000000..1a507d5
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime-days.xml
@@ -0,0 +1,18 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'/>
+ <bridge name='virbr0' stp='on' delay='0'/>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <leasetime>1d</leasetime>
+ <range start='192.168.122.2' end='192.168.122.254'/>
+ </dhcp>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+ <dhcp>
+ <leasetime>1d</leasetime>
+ <range start='2001:db8:ac10:fd01::1:10'
end='2001:db8:ac10:fd01::1:ff'/>
+ </dhcp>
+ </ip>
+</network>
diff --git a/tests/networkxml2confdata/leasetime-host.conf
b/tests/networkxml2confdata/leasetime-host.conf
new file mode 100644
index 0000000..7bd2054
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime-host.conf
@@ -0,0 +1,16 @@
+##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
+##OVERWRITTEN AND LOST. Changes to this configuration should be made
using:
+## virsh net-edit default
+## or other application using the libvirt API.
+##
+## dnsmasq conf file created by libvirt
+strict-order
+except-interface=lo
+bind-dynamic
+interface=virbr0
+srv-host=_name._tcp
+dhcp-range=192.168.122.2,192.168.122.254
+dhcp-no-override
+dhcp-lease-max=253
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
diff --git a/tests/networkxml2confdata/leasetime-host.hostsfile
b/tests/networkxml2confdata/leasetime-host.hostsfile
new file mode 100644
index 0000000..fd20ca2
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime-host.hostsfile
@@ -0,0 +1,6 @@
+00:16:3e:3e:a9:01,192.168.122.11,a.example.com,3600
+00:16:3e:3e:a9:02,192.168.122.12,b.example.com,3600
+00:16:3e:3e:a9:03,192.168.122.13,c.example.com,3600
+00:16:3e:3e:a9:04,192.168.122.14,d.example.com,86400
+00:16:3e:3e:a9:05,192.168.122.15,e.example.com,3600
+00:16:3e:3e:a9:06,192.168.122.16,f.example.com,infinite
diff --git a/tests/networkxml2confdata/leasetime-host.xml
b/tests/networkxml2confdata/leasetime-host.xml
new file mode 100644
index 0000000..276d3e5
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime-host.xml
@@ -0,0 +1,22 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'>
+ <interface dev='eth1'/>
+ </forward>
+ <bridge name='virbr0' stp='on' delay='0'/>
+ <dns>
+ <srv service='name' protocol='tcp'/>
+ </dns>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <range start='192.168.122.2' end='192.168.122.254'/>
+ <host mac='00:16:3e:3e:a9:1a' name='a.example.com'
ip='192.168.122.11' leasetime="3600s"/>
+ <host mac='00:16:3e:3e:a9:1b' name='b.example.com'
ip='192.168.122.12' leasetime="60m"/>
+ <host mac='00:16:3e:3e:a9:1c' name='c.example.com'
ip='192.168.122.13' leasetime="1h"/>
+ <host mac='00:16:3e:3e:a9:1d' name='d.example.com'
ip='192.168.122.14' leasetime="1d"/>
+ <host mac='00:16:3e:3e:a9:1e' name='e.example.com'
ip='192.168.122.15' leasetime="3600"/>
+ <host mac='00:16:3e:3e:a9:1f' name='f.example.com'
ip='192.168.122.16' leasetime="-1"/>
+ </dhcp>
+ </ip>
+</network>
diff --git a/tests/networkxml2confdata/leasetime-hours.conf
b/tests/networkxml2confdata/leasetime-hours.conf
new file mode 100644
index 0000000..021a769
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime-hours.conf
@@ -0,0 +1,17 @@
+##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
+##OVERWRITTEN AND LOST. Changes to this configuration should be made
using:
+## virsh net-edit default
+## or other application using the libvirt API.
+##
+## dnsmasq conf file created by libvirt
+strict-order
+except-interface=lo
+bind-dynamic
+interface=virbr0
+dhcp-range=192.168.122.2,192.168.122.254,3600
+dhcp-no-override
+dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64,3600
+dhcp-lease-max=493
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
+enable-ra
diff --git a/tests/networkxml2confdata/leasetime-hours.xml
b/tests/networkxml2confdata/leasetime-hours.xml
new file mode 100644
index 0000000..36dc600
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime-hours.xml
@@ -0,0 +1,18 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'/>
+ <bridge name='virbr0' stp='on' delay='0'/>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <leasetime>1h</leasetime>
+ <range start='192.168.122.2' end='192.168.122.254'/>
+ </dhcp>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+ <dhcp>
+ <leasetime>1h</leasetime>
+ <range start='2001:db8:ac10:fd01::1:10'
end='2001:db8:ac10:fd01::1:ff'/>
+ </dhcp>
+ </ip>
+</network>
diff --git a/tests/networkxml2confdata/leasetime-infinite.conf
b/tests/networkxml2confdata/leasetime-infinite.conf
new file mode 100644
index 0000000..cc21135
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime-infinite.conf
@@ -0,0 +1,17 @@
+##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
+##OVERWRITTEN AND LOST. Changes to this configuration should be made
using:
+## virsh net-edit default
+## or other application using the libvirt API.
+##
+## dnsmasq conf file created by libvirt
+strict-order
+except-interface=lo
+bind-dynamic
+interface=virbr0
+dhcp-range=192.168.122.2,192.168.122.254,infinite
+dhcp-no-override
+dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64,infinite
+dhcp-lease-max=493
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
+enable-ra
diff --git a/tests/networkxml2confdata/leasetime-infinite.xml
b/tests/networkxml2confdata/leasetime-infinite.xml
new file mode 100644
index 0000000..bc8740e
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime-infinite.xml
@@ -0,0 +1,18 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'/>
+ <bridge name='virbr0' stp='on' delay='0'/>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <leasetime>-1</leasetime>
+ <range start='192.168.122.2' end='192.168.122.254'/>
+ </dhcp>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+ <dhcp>
+ <leasetime>-1</leasetime>
+ <range start='2001:db8:ac10:fd01::1:10'
end='2001:db8:ac10:fd01::1:ff'/>
+ </dhcp>
+ </ip>
+</network>
diff --git a/tests/networkxml2confdata/leasetime-minutes.conf
b/tests/networkxml2confdata/leasetime-minutes.conf
new file mode 100644
index 0000000..db68895
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime-minutes.conf
@@ -0,0 +1,17 @@
+##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
+##OVERWRITTEN AND LOST. Changes to this configuration should be made
using:
+## virsh net-edit default
+## or other application using the libvirt API.
+##
+## dnsmasq conf file created by libvirt
+strict-order
+except-interface=lo
+bind-dynamic
+interface=virbr0
+dhcp-range=192.168.122.2,192.168.122.254,300
+dhcp-no-override
+dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64,300
+dhcp-lease-max=493
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
+enable-ra
diff --git a/tests/networkxml2confdata/leasetime-minutes.xml
b/tests/networkxml2confdata/leasetime-minutes.xml
new file mode 100644
index 0000000..7c1df25
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime-minutes.xml
@@ -0,0 +1,18 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'/>
+ <bridge name='virbr0' stp='on' delay='0'/>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <leasetime>5m</leasetime>
+ <range start='192.168.122.2' end='192.168.122.254'/>
+ </dhcp>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+ <dhcp>
+ <leasetime>5m</leasetime>
+ <range start='2001:db8:ac10:fd01::1:10'
end='2001:db8:ac10:fd01::1:ff'/>
+ </dhcp>
+ </ip>
+</network>
diff --git a/tests/networkxml2confdata/leasetime-seconds.conf
b/tests/networkxml2confdata/leasetime-seconds.conf
new file mode 100644
index 0000000..635896b
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime-seconds.conf
@@ -0,0 +1,17 @@
+##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
+##OVERWRITTEN AND LOST. Changes to this configuration should be made
using:
+## virsh net-edit default
+## or other application using the libvirt API.
+##
+## dnsmasq conf file created by libvirt
+strict-order
+except-interface=lo
+bind-dynamic
+interface=virbr0
+dhcp-range=192.168.122.2,192.168.122.254,125
+dhcp-no-override
+dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64,125
+dhcp-lease-max=493
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
+enable-ra
diff --git a/tests/networkxml2confdata/leasetime-seconds.xml
b/tests/networkxml2confdata/leasetime-seconds.xml
new file mode 100644
index 0000000..dcb3f91
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime-seconds.xml
@@ -0,0 +1,18 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'/>
+ <bridge name='virbr0' stp='on' delay='0'/>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <leasetime>125s</leasetime>
+ <range start='192.168.122.2' end='192.168.122.254'/>
+ </dhcp>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+ <dhcp>
+ <leasetime>125s</leasetime>
+ <range start='2001:db8:ac10:fd01::1:10'
end='2001:db8:ac10:fd01::1:ff'/>
+ </dhcp>
+ </ip>
+</network>
diff --git a/tests/networkxml2confdata/leasetime.conf
b/tests/networkxml2confdata/leasetime.conf
new file mode 100644
index 0000000..72a2f69
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime.conf
@@ -0,0 +1,17 @@
+##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
+##OVERWRITTEN AND LOST. Changes to this configuration should be made
using:
+## virsh net-edit default
+## or other application using the libvirt API.
+##
+## dnsmasq conf file created by libvirt
+strict-order
+except-interface=lo
+bind-dynamic
+interface=virbr0
+dhcp-range=192.168.122.2,192.168.122.254,122
+dhcp-no-override
+dhcp-range=2001:db8:ac10:fd01::1:10,2001:db8:ac10:fd01::1:ff,64,121
+dhcp-lease-max=493
+dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
+enable-ra
diff --git a/tests/networkxml2confdata/leasetime.xml
b/tests/networkxml2confdata/leasetime.xml
new file mode 100644
index 0000000..fdbb15f
--- /dev/null
+++ b/tests/networkxml2confdata/leasetime.xml
@@ -0,0 +1,18 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
+ <forward dev='eth1' mode='nat'/>
+ <bridge name='virbr0' stp='on' delay='0'/>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ <dhcp>
+ <leasetime>122</leasetime>
+ <range start='192.168.122.2' end='192.168.122.254'/>
+ </dhcp>
+ </ip>
+ <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
+ <dhcp>
+ <leasetime>121</leasetime>
+ <range start='2001:db8:ac10:fd01::1:10'
end='2001:db8:ac10:fd01::1:ff'/>
+ </dhcp>
+ </ip>
+</network>
diff --git a/tests/networkxml2confdata/nat-network-dns-srv-record-minimal.hostsfile
b/tests/networkxml2confdata/nat-network-dns-srv-record-minimal.hostsfile
new file mode 100644
index 0000000..deb3f00
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network-dns-srv-record-minimal.hostsfile
@@ -0,0 +1,2 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
diff --git a/tests/networkxml2confdata/nat-network-dns-srv-record.hostsfile
b/tests/networkxml2confdata/nat-network-dns-srv-record.hostsfile
new file mode 100644
index 0000000..deb3f00
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network-dns-srv-record.hostsfile
@@ -0,0 +1,2 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
diff --git a/tests/networkxml2confdata/nat-network-dns-txt-record.hostsfile
b/tests/networkxml2confdata/nat-network-dns-txt-record.hostsfile
new file mode 100644
index 0000000..deb3f00
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network-dns-txt-record.hostsfile
@@ -0,0 +1,2 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
diff --git a/tests/networkxml2confdata/nat-network-name-with-quotes.hostsfile
b/tests/networkxml2confdata/nat-network-name-with-quotes.hostsfile
new file mode 100644
index 0000000..deb3f00
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network-name-with-quotes.hostsfile
@@ -0,0 +1,2 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
diff --git a/tests/networkxml2confdata/nat-network.hostsfile
b/tests/networkxml2confdata/nat-network.hostsfile
new file mode 100644
index 0000000..deb3f00
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network.hostsfile
@@ -0,0 +1,2 @@
+00:16:3e:77:e2:ed,192.168.122.10,a.example.com
+00:16:3e:3e:a9:1a,192.168.122.11,b.example.com
diff --git a/tests/networkxml2conftest.c b/tests/networkxml2conftest.c
index 65a0e32..8e1f8be 100644
--- a/tests/networkxml2conftest.c
+++ b/tests/networkxml2conftest.c
@@ -19,9 +19,13 @@
#define VIR_FROM_THIS VIR_FROM_NONE
static int
-testCompareXMLToConfFiles(const char *inxml, const char *outconf,
dnsmasqCapsPtr caps)
+testCompareXMLToConfFiles(const char *inxml,
+ const char *outconf,
+ const char *outhostsfile,
+ dnsmasqCapsPtr caps)
{
- char *actual = NULL;
+ char *actualconf = NULL;
+ char *actualhosts = NULL;
int ret = -1;
virNetworkDefPtr dev = NULL;
virNetworkObjPtr obj = NULL;
@@ -41,17 +45,30 @@ testCompareXMLToConfFiles(const char *inxml, const char
*outconf, dnsmasqCapsPtr
if (dctx == NULL)
goto fail;
- if (networkDnsmasqConfContents(obj, pidfile, &actual,
+ if (networkDnsmasqConfContents(obj, pidfile, &actualconf, &actualhosts,
dctx, caps) < 0)
goto fail;
- if (virTestCompareToFile(actual, outconf) < 0)
+ if (virTestCompareToFile(actualconf, outconf) < 0)
goto fail;
+ if (virFileExists(outhostsfile)) {
+ if (!actualhosts) {
+ fprintf(stderr, "%s: hostsfile exists but the configuration
did not specify any host", outhostsfile);
+ goto fail;
+ } else if (virTestCompareToFile(actualhosts, outhostsfile) < 0) {
+ goto fail;
+ }
+ } else if (actualhosts) {
+ fprintf(stderr, "%s: file does not exist but actual data was
expected", outhostsfile);
+ goto fail;
+ }
+
ret = 0;
fail:
- VIR_FREE(actual);
+ VIR_FREE(actualconf);
+ VIR_FREE(actualhosts);
VIR_FREE(pidfile);
virCommandFree(cmd);
virObjectUnref(obj);
@@ -70,20 +87,24 @@ testCompareXMLToConfHelper(const void *data)
int result = -1;
const testInfo *info = data;
char *inxml = NULL;
- char *outxml = NULL;
+ char *outconf = NULL;
+ char *outhostsfile = NULL;
if (virAsprintf(&inxml, "%s/networkxml2confdata/%s.xml",
abs_srcdir, info->name) < 0 ||
- virAsprintf(&outxml, "%s/networkxml2confdata/%s.conf",
+ virAsprintf(&outconf, "%s/networkxml2confdata/%s.conf",
+ abs_srcdir, info->name) < 0 ||
+ virAsprintf(&outhostsfile, "%s/networkxml2confdata/%s.hostsfile",
abs_srcdir, info->name) < 0) {
goto cleanup;
}
- result = testCompareXMLToConfFiles(inxml, outxml, info->caps);
+ result = testCompareXMLToConfFiles(inxml, outconf, outhostsfile,
info->caps);
cleanup:
VIR_FREE(inxml);
- VIR_FREE(outxml);
+ VIR_FREE(outconf);
+ VIR_FREE(outhostsfile);
return result;
}
@@ -129,6 +150,14 @@ mymain(void)
DO_TEST("dhcp6-network", dhcpv6);
DO_TEST("dhcp6-nat-network", dhcpv6);
DO_TEST("dhcp6host-routed-network", dhcpv6);
+ DO_TEST("leasetime", dhcpv6);
+ DO_TEST("leasetime-seconds", dhcpv6);
+ DO_TEST("leasetime-hours", dhcpv6);
+ DO_TEST("leasetime-minutes", dhcpv6);
+ DO_TEST("leasetime-hours", dhcpv6);
+ DO_TEST("leasetime-days", dhcpv6);
+ DO_TEST("leasetime-infinite", dhcpv6);
+ DO_TEST("leasetime-host", dhcpv6);
virObjectUnref(dhcpv6);
virObjectUnref(full);
--
2.9.3
--
Alberto Ruiz
Associate Engineering Manager - Desktop Management Tools
Red Hat
7 years, 12 months
[libvirt] libvirt-python bug: custom event loop impl calls ff callback from *Remove(Handle|Timeout)Func
by Wojtek Porczyk
Hello libvirt-list,
As of current libvirt-python.git, according to libvirt-override.c, if
implementing custom event loop in Python, ff callback is called from
libvirt_virEventRemoveHandleFunc, which is a C glue between
virEventRegisterImpl and actual removeHandle function written in Python:
> result = PyEval_CallObject(removeHandleObj, pyobj_args);
> if (!result) {
> PyErr_Print();
> PyErr_Clear();
> } else if (!PyTuple_Check(result) || PyTuple_Size(result) != 3) {
> DEBUG("%s: %s must return opaque obj registered with %s"
> "to avoid leaking libvirt memory\n",
> __FUNCTION__, NAME(removeHandle), NAME(addHandle));
> } else {
> opaque = PyTuple_GetItem(result, 1);
> ff = PyTuple_GetItem(result, 2);
> cff = PyvirFreeCallback_Get(ff);
> if (cff)
> (*cff)(PyvirVoidPtr_Get(opaque));
> retval = 0;
> }
This is exactly what one shoud not be doing according to documentation [1]:
> If the opaque user data requires free'ing when the handle is unregistered,
> then a 2nd callback can be supplied for this purpose. This callback needs to
> be invoked from a clean stack. If 'ff' callbacks are invoked directly from the
> virEventRemoveHandleFunc they will likely deadlock in libvirt.
[1] https://libvirt.org/html/libvirt-libvirt-event.html#virEventAddHandleFunc
This is true, the deadlock occurs. When the "result" tuple is mangled to have
None as third item ("ff"), then cff = PyvirFreeCallback_Get(ff) is NULL and
the deadlock does not happen.
That's also why script examples/event-test.py does not deadlock, because it
does not return anything (that is, returns None) from Python, so the second if
block happens and the ff callback, if any, is not executed (and probably
something leaks, but I didn't check for that).
Everything also applies to to timeouts (libvirt_virEventRemoteTimeoutFunc).
--
pozdrawiam / best regards _.-._
Wojtek Porczyk .-^' '^-.
Invisible Things Lab |'-.-^-.-'|
| | | |
I do not fear computers, | '-.-' |
I fear lack of them. '-._ : ,-'
-- Isaac Asimov `^-^-_>
8 years
[libvirt] [PATCH] Make use of PERF_COUNT_HW_REF_CPU_CYCLES conditional
by Daniel P. Berrange
The PERF_COUNT_HW_REF_CPU_CYCLES constant is not available
on all Linux distros libvirt targets, so its use must be
made conditional. Other constant have existed long enough
that we can assume they exist, as we don't support very
old distros like RHEL-5 any more.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/util/virperf.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/util/virperf.c b/src/util/virperf.c
index 49ec258..f64692b 100644
--- a/src/util/virperf.c
+++ b/src/util/virperf.c
@@ -104,8 +104,14 @@ static struct virPerfEventAttr attrs[] = {
.attrType = PERF_TYPE_HARDWARE,
.attrConfig = PERF_COUNT_HW_STALLED_CYCLES_BACKEND},
{.type = VIR_PERF_EVENT_REF_CPU_CYCLES,
+# ifdef PERF_COUNT_HW_REF_CPU_CYCLES
.attrType = PERF_TYPE_HARDWARE,
- .attrConfig = PERF_COUNT_HW_REF_CPU_CYCLES},
+ .attrConfig = PERF_COUNT_HW_REF_CPU_CYCLES
+# else
+ .attrType = 0,
+ .attrConfig = 0,
+# endif
+ },
};
typedef struct virPerfEventAttr *virPerfEventAttrPtr;
--
2.9.3
8 years
[libvirt] [PATCH] network: don't use dhcp-authoritative on static networks
by Martin Wilck
"Static" DHCP networks are those where no dynamic DHCP range is
defined, only a list of host entries is used to serve permanent
IP addresses. On such networks, we don't want dnsmasq to reply
to other requests than those statically defined. But
"dhcp-authoritative" will cause dnsmasq to do just that.
Therefore we can't use "dhcp-authoritative" for static networks.
Fixes: 4ac20b3ae "network: add dnsmasq option 'dhcp-authoritative'"
Signed-off-by: Martin Wilck <mwilck(a)suse.com>
---
src/network/bridge_driver.c | 9 ++++++++-
tests/networkxml2confdata/dhcp6host-routed-network.conf | 1 -
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index ae1589d8c..17c6f3a0f 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -1355,7 +1355,14 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET)) {
if (ipdef->nranges || ipdef->nhosts) {
virBufferAddLit(&configbuf, "dhcp-no-override\n");
- virBufferAddLit(&configbuf, "dhcp-authoritative\n");
+ /*
+ * Use "dhcp-authoritative" only for dynamic DHCP.
+ * In a static-only network, it would cause dnsmasq
+ * to reply to requests from other hosts than those
+ * statically defined.
+ */
+ if (ipdef->nranges || !ipdef->nhosts)
+ virBufferAddLit(&configbuf, "dhcp-authoritative\n");
}
if (ipdef->tftproot) {
diff --git a/tests/networkxml2confdata/dhcp6host-routed-network.conf b/tests/networkxml2confdata/dhcp6host-routed-network.conf
index 87a149880..5728ee430 100644
--- a/tests/networkxml2confdata/dhcp6host-routed-network.conf
+++ b/tests/networkxml2confdata/dhcp6host-routed-network.conf
@@ -10,7 +10,6 @@ bind-dynamic
interface=virbr1
dhcp-range=192.168.122.1,static
dhcp-no-override
-dhcp-authoritative
dhcp-range=2001:db8:ac10:fd01::1,static,64
dhcp-hostsfile=/var/lib/libvirt/dnsmasq/local.hostsfile
addn-hosts=/var/lib/libvirt/dnsmasq/local.addnhosts
--
2.11.0
8 years