[libvirt] [PATCH] qemu: read backing chain names from qemu
by Eric Blake
https://bugzilla.redhat.com/show_bug.cgi?id=1199182 documents that
after a series of disk snapshots into existing destination images,
followed by active commits of the top image, it is possible for
qemu 2.2 and earlier to end up tracking a different name for the
image than what it would have had when opening the chain afresh.
That is, when starting with the chain 'a <- b <- c', the name
associated with 'b' is how it was spelled in the metadata of 'c',
but when starting with 'a', taking two snapshots into 'a <- b <- c',
then committing 'c' back into 'b', the name associated with 'b' is
now the name used when taking the first snapshot.
Sadly, older qemu doesn't know how to treat different spellings of
the same filename as identical files (it uses strcmp() instead of
checking for the same inode), which means libvirt's attempt to
commit an image using solely the names learned from qcow2 metadata
fails with a cryptic:
error: internal error: unable to execute QEMU command 'block-commit': Top image file /tmp/images/c/../b/b not found
even though the file exists. Trying to teach libvirt the rules on
which name qemu will expect is not worth the effort (besides, we'd
have to remember it across libvirtd restarts, and track whether a
file was opened via metadata or via snapshot creation for a given
qemu process); it is easier to just always directly ask qemu what
string it expects to see in the first place.
* src/qemu/qemu_monitor.h (qemuMonitorDiskNameLookup): New
prototype.
* src/qemu/qemu_monitor_json.h (qemuMonitorJSONDiskNameLookup):
Likewise.
* src/qemu/qemu_monitor.c (qemuMonitorDiskNameLookup): New function.
* src/qemu/qemu_monitor_json.c (qemuMonitorJSONDiskNameLookup)
(qemuMonitorJSONDiskNameLookupOne): Likewise.
* src/qemu/qemu_driver.c (qemuDomainBlockCommit)
(qemuDomainBlockJobImpl): Use it.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Adam, since you reported the issue, let me know if you need a
scratch binary to test this patch on. Jeff, thanks for the idea
on how to solve the problem without touching qemu (of course, it
would still be nice to teach qemu to respect inode equivalence
rather than relying on streq, and even nicer for libvirt to use
node names instead of file names, but those can be later patches
without holding up VDSM now).
src/qemu/qemu_driver.c | 28 +++++++-------
src/qemu/qemu_monitor.c | 20 +++++++++-
src/qemu/qemu_monitor.h | 8 +++-
src/qemu/qemu_monitor_json.c | 87 +++++++++++++++++++++++++++++++++++++++++++-
src/qemu/qemu_monitor_json.h | 9 ++++-
5 files changed, 134 insertions(+), 18 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 51b30b7..e540001 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15932,9 +15932,6 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
goto endjob;
if (baseSource) {
- if (qemuGetDriveSourceString(baseSource, NULL, &basePath) < 0)
- goto endjob;
-
if (flags & VIR_DOMAIN_BLOCK_REBASE_RELATIVE) {
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CHANGE_BACKING_FILE)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
@@ -15972,8 +15969,12 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
}
qemuDomainObjEnterMonitor(driver, vm);
- ret = qemuMonitorBlockJob(priv->mon, device, basePath, backingPath,
- speed, mode, async);
+ if (baseSource)
+ basePath = qemuMonitorDiskNameLookup(priv->mon, device, disk->src,
+ baseSource);
+ if (!baseSource || basePath)
+ ret = qemuMonitorBlockJob(priv->mon, device, basePath, backingPath,
+ speed, mode, async);
if (qemuDomainObjExitMonitor(driver, vm) < 0)
ret = -1;
if (ret < 0) {
@@ -16703,12 +16704,6 @@ qemuDomainBlockCommit(virDomainPtr dom,
VIR_DISK_CHAIN_READ_WRITE) < 0))
goto endjob;
- if (qemuGetDriveSourceString(topSource, NULL, &topPath) < 0)
- goto endjob;
-
- if (qemuGetDriveSourceString(baseSource, NULL, &basePath) < 0)
- goto endjob;
-
if (flags & VIR_DOMAIN_BLOCK_COMMIT_RELATIVE &&
topSource != disk->src) {
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CHANGE_BACKING_FILE)) {
@@ -16739,9 +16734,14 @@ qemuDomainBlockCommit(virDomainPtr dom,
disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT;
}
qemuDomainObjEnterMonitor(driver, vm);
- ret = qemuMonitorBlockCommit(priv->mon, device,
- topPath, basePath, backingPath,
- speed);
+ basePath = qemuMonitorDiskNameLookup(priv->mon, device, disk->src,
+ baseSource);
+ topPath = qemuMonitorDiskNameLookup(priv->mon, device, disk->src,
+ topSource);
+ if (basePath && topPath)
+ ret = qemuMonitorBlockCommit(priv->mon, device,
+ topPath, basePath, backingPath,
+ speed);
if (qemuDomainObjExitMonitor(driver, vm) < 0) {
ret = -1;
goto endjob;
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index d869a72..cf7dc5e 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -1,7 +1,7 @@
/*
* qemu_monitor.c: interaction with QEMU monitor console
*
- * Copyright (C) 2006-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2015 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -3458,6 +3458,24 @@ qemuMonitorSupportsActiveCommit(qemuMonitorPtr mon)
}
+/* Determine the name that qemu is using for tracking the backing
+ * element TARGET within the chain starting at TOP. */
+char *
+qemuMonitorDiskNameLookup(qemuMonitorPtr mon,
+ const char *device,
+ virStorageSourcePtr top,
+ virStorageSourcePtr target)
+{
+ if (!mon->json) {
+ virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+ _("JSON monitor is required"));
+ return NULL;
+ }
+
+ return qemuMonitorJSONDiskNameLookup(mon, device, top, target);
+}
+
+
/* Use the block-job-complete monitor command to pivot a block copy
* job. */
int
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index b30da34..e67d800 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1,7 +1,7 @@
/*
* qemu_monitor.h: interaction with QEMU monitor console
*
- * Copyright (C) 2006-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2015 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -734,6 +734,12 @@ int qemuMonitorBlockCommit(qemuMonitorPtr mon,
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
ATTRIBUTE_NONNULL(4);
bool qemuMonitorSupportsActiveCommit(qemuMonitorPtr mon);
+char *qemuMonitorDiskNameLookup(qemuMonitorPtr mon,
+ const char *device,
+ virStorageSourcePtr top,
+ virStorageSourcePtr target)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+ ATTRIBUTE_NONNULL(4);
int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
const char *cmd,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index c16f3ca..7759365 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -1,7 +1,7 @@
/*
* qemu_monitor_json.c: interaction with QEMU monitor console
*
- * Copyright (C) 2006-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2015 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -3883,6 +3883,91 @@ qemuMonitorJSONDrivePivot(qemuMonitorPtr mon, const char *device,
}
+static char *
+qemuMonitorJSONDiskNameLookupOne(virJSONValuePtr image,
+ virStorageSourcePtr top,
+ virStorageSourcePtr target)
+{
+ virJSONValuePtr backing;
+ char *ret;
+
+ if (!top)
+ return NULL;
+ if (top != target) {
+ backing = virJSONValueObjectGet(image, "backing-image");
+ return qemuMonitorJSONDiskNameLookupOne(backing, top->backingStore,
+ target);
+ }
+ ignore_value(VIR_STRDUP(ret,
+ virJSONValueObjectGetString(image, "filename")));
+ return ret;
+}
+
+
+char *
+qemuMonitorJSONDiskNameLookup(qemuMonitorPtr mon,
+ const char *device,
+ virStorageSourcePtr top,
+ virStorageSourcePtr target)
+{
+ char *ret = NULL;
+ virJSONValuePtr cmd = NULL;
+ virJSONValuePtr reply = NULL;
+ virJSONValuePtr devices;
+ size_t i;
+
+ cmd = qemuMonitorJSONMakeCommand("query-block", NULL);
+ if (!cmd)
+ return NULL;
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ goto cleanup;
+
+ devices = virJSONValueObjectGet(reply, "return");
+ if (!devices || devices->type != VIR_JSON_TYPE_ARRAY) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("block info reply was missing device list"));
+ goto cleanup;
+ }
+
+ for (i = 0; i < virJSONValueArraySize(devices); i++) {
+ virJSONValuePtr dev = virJSONValueArrayGet(devices, i);
+ virJSONValuePtr inserted;
+ virJSONValuePtr image;
+ const char *thisdev;
+
+ if (!dev || dev->type != VIR_JSON_TYPE_OBJECT) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("block info device entry was not in expected format"));
+ goto cleanup;
+ }
+
+ if ((thisdev = virJSONValueObjectGetString(dev, "device")) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("block info device entry was not in expected format"));
+ goto cleanup;
+ }
+
+ if (STRNEQ(thisdev, device) ||
+ !(inserted = virJSONValueObjectGet(dev, "inserted")) ||
+ !(image = virJSONValueObjectGet(inserted, "image"))) {
+ continue;
+ }
+ ret = qemuMonitorJSONDiskNameLookupOne(image, top, target);
+ break;
+ }
+ if (!ret)
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unable to find backing name for device %s"),
+ device);
+
+ cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+
+ return ret;
+}
+
+
int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
const char *cmd_str,
char **reply_str,
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 8ceea8a..49392b6 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -1,7 +1,7 @@
/*
* qemu_monitor_json.h: interaction with QEMU monitor console
*
- * Copyright (C) 2006-2009, 2011-2014 Red Hat, Inc.
+ * Copyright (C) 2006-2009, 2011-2015 Red Hat, Inc.
* Copyright (C) 2006 Daniel P. Berrange
*
* This library is free software; you can redistribute it and/or
@@ -277,6 +277,13 @@ int qemuMonitorJSONBlockCommit(qemuMonitorPtr mon,
unsigned long long bandwidth)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+char *qemuMonitorJSONDiskNameLookup(qemuMonitorPtr mon,
+ const char *device,
+ virStorageSourcePtr top,
+ virStorageSourcePtr target)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+ ATTRIBUTE_NONNULL(4);
+
int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
const char *cmd_str,
char **reply_str,
--
2.1.0
9 years, 8 months
[libvirt] [PATCH] vmx: add e1000e to supported NIC models.
by Dawid Zamirski
From: Dawid Zamirski <dzamirski(a)dattobackup.com>
This NIC model is supported on hardware version 8 and newer and libvirt
ESX driver does support those.
---
src/vmx/vmx.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index ac2542a..fe6b883 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -2536,10 +2536,11 @@ virVMXParseEthernet(virConfPtr conf, int controller, virDomainNetDefPtr *def)
if (STRCASENEQ(virtualDev, "vlance") &&
STRCASENEQ(virtualDev, "vmxnet") &&
STRCASENEQ(virtualDev, "vmxnet3") &&
- STRCASENEQ(virtualDev, "e1000")) {
+ STRCASENEQ(virtualDev, "e1000") &&
+ STRCASENEQ(virtualDev, "e1000e")) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Expecting VMX entry '%s' to be 'vlance' or 'vmxnet' or "
- "'vmxnet3' or 'e1000' but found '%s'"), virtualDev_name,
+ "'vmxnet3' or 'e1000e' or 'e1000e' but found '%s'"), virtualDev_name,
virtualDev);
goto cleanup;
}
@@ -3592,11 +3593,12 @@ virVMXFormatEthernet(virDomainNetDefPtr def, int controller,
STRCASENEQ(def->model, "vmxnet") &&
STRCASENEQ(def->model, "vmxnet2") &&
STRCASENEQ(def->model, "vmxnet3") &&
- STRCASENEQ(def->model, "e1000")) {
+ STRCASENEQ(def->model, "e1000") &&
+ STRCASENEQ(def->model, "e1000e")) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Expecting domain XML entry 'devices/interface/model' "
"to be 'vlance' or 'vmxnet' or 'vmxnet2' or 'vmxnet3' "
- "or 'e1000' but found '%s'"), def->model);
+ "or 'e1000' or 'e1000e' but found '%s'"), def->model);
return -1;
}
--
2.1.0
9 years, 8 months
[libvirt] [PATCH] vbox: use user cache dir when screenshotting.
by Dawid Zamirski
For VBOX it's most likely that the connection is vbox:///session and it
runs with local non-root account. This caused permission denied when
LOCALSTATEDIR was used to create temp file. This patch makes use of the
virGetUserCacheDirectory to address this problem for non-root users.
---
src/vbox/vbox_common.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index 55d3624..a548252 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -7254,8 +7254,10 @@ vboxDomainScreenshot(virDomainPtr dom,
IMachine *machine = NULL;
nsresult rc;
char *tmp;
+ char *cacheDir;
int tmp_fd = -1;
unsigned int max_screen;
+ uid_t uid = geteuid();
char *ret = NULL;
if (!data->vboxObj)
@@ -7288,8 +7290,18 @@ vboxDomainScreenshot(virDomainPtr dom,
return NULL;
}
- if (virAsprintf(&tmp, "%s/cache/libvirt/vbox.screendump.XXXXXX", LOCALSTATEDIR) < 0) {
+ if (uid != 0)
+ cacheDir = virGetUserCacheDirectory();
+ else {
+ if (virAsprintf(&cacheDir, "%s/cache/libvirt", LOCALSTATEDIR) < 0) {
+ VBOX_RELEASE(machine);
+ return NULL;
+ }
+ }
+
+ if (cacheDir && virAsprintf(&tmp, "%s/vbox.screendump.XXXXXX", cacheDir) < 0) {
VBOX_RELEASE(machine);
+ VIR_FREE(cacheDir);
return NULL;
}
@@ -7368,6 +7380,7 @@ vboxDomainScreenshot(virDomainPtr dom,
VIR_FORCE_CLOSE(tmp_fd);
unlink(tmp);
VIR_FREE(tmp);
+ VIR_FREE(cacheDir);
VBOX_RELEASE(machine);
vboxIIDUnalloc(&iid);
return ret;
--
2.1.0
9 years, 8 months
[libvirt] [PATCH v2] virnetdev: fix build with old kernel
by Pavel Hrdina
Commit c9027d8f added a detection of NIC HW features, but some of them
are not available in old kernel. Very old kernels lack enum
ethtool_flags and even if this enum is present, not all values are
available for all kernels. To be sure that we have everything in kernel
that we need, we must check for existence of most of that flags, because
only few of them were defined at first.
Also to successfully build libvirt with older kernel we need to include
<linux/types.h> before <linux/ethtool.h> to have __u32 and friends
defined.
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
configure.ac | 5 +++++
src/util/virnetdev.c | 43 +++++++++++++++++++++++++++----------------
2 files changed, 32 insertions(+), 16 deletions(-)
diff --git a/configure.ac b/configure.ac
index e071813..2fedd1a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -383,6 +383,11 @@ AC_CHECK_TYPE([struct ifreq],
#include <net/if.h>
]])
+AC_CHECK_DECLS([ETH_FLAG_TXVLAN, ETH_FLAG_NTUPLE, ETH_FLAG_RXHASH, ETH_FLAG_LRO,
+ ETHTOOL_GGSO, ETHTOOL_GGRO, ETHTOOL_GFLAGS],
+ [], [], [[#include <linux/ethtool.h>
+ ]])
+
dnl Our only use of libtasn1.h is in the testsuite, and can be skipped
dnl if the header is not present. Assume -ltasn1 is present if the
dnl header could be found.
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index 971db43..093c99c 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -48,6 +48,7 @@
#endif
#if defined(SIOCETHTOOL) && defined(HAVE_STRUCT_IFREQ)
+# include <linux/types.h>
# include <linux/ethtool.h>
#endif
@@ -2800,9 +2801,7 @@ int
virNetDevGetFeatures(const char *ifname,
virBitmapPtr *out)
{
- int ret = -1;
size_t i = -1;
- size_t j = -1;
struct ethtool_value cmd = { 0 };
struct elem{
@@ -2815,20 +2814,16 @@ virNetDevGetFeatures(const char *ifname,
{ETHTOOL_GTXCSUM, VIR_NET_DEV_FEAT_GTXCSUM},
{ETHTOOL_GSG, VIR_NET_DEV_FEAT_GSG},
{ETHTOOL_GTSO, VIR_NET_DEV_FEAT_GTSO},
+# if HAVE_DECL_ETHTOOL_GGSO
{ETHTOOL_GGSO, VIR_NET_DEV_FEAT_GGSO},
+# endif
+# if HAVE_DECL_ETHTOOL_GGRO
{ETHTOOL_GGRO, VIR_NET_DEV_FEAT_GGRO},
- };
- /* ethtool masks */
- struct elem flags[] = {
- {ETH_FLAG_LRO, VIR_NET_DEV_FEAT_LRO},
- {ETH_FLAG_RXVLAN, VIR_NET_DEV_FEAT_RXVLAN},
- {ETH_FLAG_TXVLAN, VIR_NET_DEV_FEAT_TXVLAN},
- {ETH_FLAG_NTUPLE, VIR_NET_DEV_FEAT_NTUPLE},
- {ETH_FLAG_RXHASH, VIR_NET_DEV_FEAT_RXHASH},
+# endif
};
if (!(*out = virBitmapNew(VIR_NET_DEV_FEAT_LAST)))
- goto cleanup;
+ return -1;
for (i = 0; i < ARRAY_CARDINALITY(cmds); i++) {
cmd.cmd = cmds[i].cmd;
@@ -2836,6 +2831,25 @@ virNetDevGetFeatures(const char *ifname,
ignore_value(virBitmapSetBit(*out, cmds[i].feat));
}
+# if HAVE_DECL_ETHTOOL_GFLAGS
+ size_t j = -1;
+ /* ethtool masks */
+ struct elem flags[] = {
+# if HAVE_DECL_ETH_FLAG_LRO
+ {ETH_FLAG_LRO, VIR_NET_DEV_FEAT_LRO},
+# endif
+# if HAVE_DECL_ETH_FLAG_TXVLAN
+ {ETH_FLAG_RXVLAN, VIR_NET_DEV_FEAT_RXVLAN},
+ {ETH_FLAG_TXVLAN, VIR_NET_DEV_FEAT_TXVLAN},
+# endif
+# if HAVE_DECL_ETH_FLAG_NTUBLE
+ {ETH_FLAG_NTUPLE, VIR_NET_DEV_FEAT_NTUPLE},
+# endif
+# if HAVE_DECL_ETH_FLAG_RXHASH
+ {ETH_FLAG_RXHASH, VIR_NET_DEV_FEAT_RXHASH},
+# endif
+ };
+
cmd.cmd = ETHTOOL_GFLAGS;
if (virNetDevFeatureAvailable(ifname, &cmd)) {
for (j = 0; j < ARRAY_CARDINALITY(flags); j++) {
@@ -2843,12 +2857,9 @@ virNetDevGetFeatures(const char *ifname,
ignore_value(virBitmapSetBit(*out, flags[j].feat));
}
}
+# endif
- ret = 0;
- cleanup:
-
- return ret;
-
+ return 0;
}
#else
int
--
2.0.5
9 years, 8 months
[libvirt] [PATCH] parallels: add VIR_ARCH_I686 capability to parallels driver
by Maxim Nestratov
as soon as x32 architecture is also supported
---
src/parallels/parallels_driver.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c
index 650b790..0b3761d 100644
--- a/src/parallels/parallels_driver.c
+++ b/src/parallels/parallels_driver.c
@@ -99,6 +99,13 @@ parallelsBuildCapabilities(void)
NULL, 0, NULL)) == NULL)
goto error;
+ if ((guest = virCapabilitiesAddGuest(caps, "hvm",
+ VIR_ARCH_I686,
+ "parallels",
+ NULL, 0, NULL)) == NULL)
+ goto error;
+
+
if (virCapabilitiesAddGuestDomain(guest,
"parallels", NULL, NULL, 0, NULL) == NULL)
goto error;
--
1.7.1
9 years, 8 months
[libvirt] [PATCH] Clarify the meaning of version in redirdev filters
by Ján Tomko
The version attribute in redirdev filters refers to the revision
of the device, not the version of the USB protocol.
Explicitly state that this is not the USB protocol and remove references
to those round version numbers that resemble USB protocol versions.
https://bugzilla.redhat.com/show_bug.cgi?id=1177237
---
docs/formatdomain.html.in | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index ede20de..40e2b29 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3320,7 +3320,7 @@
<boot order='1'/>
</redirdev>
<redirfilter>
- <usbdev class='0x08' vendor='0x1234' product='0xbeef' version='2.00' allow='yes'/>
+ <usbdev class='0x08' vendor='0x1234' product='0xbeef' version='2.56' allow='yes'/>
<usbdev allow='no'/>
</redirfilter>
</devices>
@@ -3363,7 +3363,8 @@
<code>class</code> attribute is the USB Class code, for example,
0x08 represents mass storage devices. The USB device can be addressed by
vendor / product id using the <code>vendor</code> and <code>product</code> attributes.
- <code>version</code> is the bcdDevice value of USB device, such as 1.00, 1.10 and 2.00.
+ <code>version</code> is the device revision from the bcdDevice field (not
+ the version of the USB protocol).
These four attributes are optional and <code>-1</code> can be used to allow
any value for them. <code>allow</code> attribute is mandatory,
'yes' means allow, 'no' for deny.
--
2.0.5
9 years, 8 months
[libvirt] [PATCH v3 00/15] Drop network driver lock
by Michal Privoznik
Well, this is interesting. I've turned the virNetworkObjList into
using a virHash. And even though the performance in my testing
(using the very same test program as in previous versions of the
patch set) increased. Without these patches, the test program
took 56s to finish. With these patches (that is with virHash
table) it takes 46s, which is better. But previously, with
network objects stored in flat array I was able to get somewhere
around 23s! I wonder what may be the cause.
NB, nearly all patches in the series have been ACKed already, but
since I'm switching the virNetworkObjList internals, I'm posting
them again.
Michal Privoznik (15):
virNetworkObjListPtr: Turn list into a hash table
network_conf: Make virNetworkObj actually virObject
network_conf: Introduce virNetworkObjEndAPI
bridge_driver: Use virNetworkObjEndAPI
test_driver: Use virNetworkObjEndAPI
parallels_network: Use virNetworkObjEndAPI
virNetworkObjList: Derive from virObjectLockableClass
network_conf: Introduce locked versions of lookup functions
virNetworkObjListPtr: Make APIs self-locking
virNetworkObjFindBy*: Return an reference to found object
struct _virNetworkDriverState: Annotate items
bridge_driver: Drop networkDriverLock() from everywhere
test_driver: Drop testDriverLock() from almost everywhere
parallels_network: Drop parallelsDriverLock() from everywhere.
bridge_driver: Use more of networkObjFromNetwork
cfg.mk | 2 -
src/conf/network_conf.c | 545 +++++++++++++++++++++++------------
src/conf/network_conf.h | 13 +-
src/libvirt_private.syms | 7 +-
src/network/bridge_driver.c | 197 +++----------
src/network/bridge_driver_platform.h | 5 +-
src/parallels/parallels_network.c | 62 +---
src/test/test_driver.c | 108 ++-----
tests/networkxml2conftest.c | 4 +-
tests/objectlocking.ml | 4 -
10 files changed, 441 insertions(+), 506 deletions(-)
--
2.0.5
9 years, 8 months
[libvirt] [libvirt-test-API][PATCH] Rewrite case for listAllInterfaces() API
by jiahu
Using actual python API to validate test case, rather than use
virsh iface-* command lines.
---
cases/basic_interface.conf | 12 ++
repos/interface/iface_list.py | 299 ++++++++++++------------------------------
2 files changed, 99 insertions(+), 212 deletions(-)
diff --git a/cases/basic_interface.conf b/cases/basic_interface.conf
index e2125bb..43e37e8 100644
--- a/cases/basic_interface.conf
+++ b/cases/basic_interface.conf
@@ -15,3 +15,15 @@ interface:define
interface:create
ifacename
$testnic
+
+interface:iface_list
+ flags
+ all
+
+interface:iface_list
+ flags
+ active
+
+interface:iface_list
+ flags
+ inactive
diff --git a/repos/interface/iface_list.py b/repos/interface/iface_list.py
index 49f0c05..85f9df9 100644
--- a/repos/interface/iface_list.py
+++ b/repos/interface/iface_list.py
@@ -1,65 +1,26 @@
#!/usr/bin/env python
+# test listAllInterfaces() API
import os
-import sys
-import re
-import commands
+import libvirt
-required_params = ('ifaceopt',)
-optional_params = {}
-
-VIRSH_QUIET_IFACE_LIST = "virsh --quiet iface-list %s | awk '{print ""$%s""}'"
-NETWORK_CONFIG = "/etc/sysconfig/network-scripts/"
-IFCONFIG_DRIVER = "ifconfig %s | sed 's/[ \t].*//;/^$/d'"
-GET_MAC = "ip link show %s |sed -n '2p'| awk '{print $2}'"
-VIRSH_IFACE_LIST = "virsh iface-list %s"
-
-names = []
-state = []
-macs = []
-
-def get_option_list(params):
- """return options we need to test
- """
- logger = params['logger']
- option_list=[]
+from libvirt import libvirtError
+from src import sharedmod
+from utils import utils
- value = params['ifaceopt']
- if value == 'all':
- option_list = [' ', '--all', '--inactive']
- elif value == '--all' or value == '--inactive':
- option_list.append(value)
- else:
- logger.error("value %s is not supported" % value)
- return 1, option_list
+required_params = ('flags',)
+optional_params = {}
- return 0, option_list
+NETWORK_CONFIG = "/etc/sysconfig/network-scripts/"
+IFCONFIG_DRIVER = "ifconfig %s | sed 's/[ \t].*//;/^$/d'| cut -d \":\" -f -1"
-def get_output(command, logger):
- """execute shell command
+def get_inteface_list_from_ifcfg(logger):
+ """
+ return host interface list from ifcfg-*
"""
- status, ret = commands.getstatusoutput(command)
- if status:
- logger.error("executing "+ "\"" + command + "\"" + " failed")
- logger.error(ret)
- return status, ret
-
-def get_interface_list(option, logger):
- """ return active host interface list """
- interface_list = []
- status, interface_str = get_output(IFCONFIG_DRIVER % option, logger)
- if not status:
- interface_list = interface_str.split('\n')
- return interface_list
- else:
- logger.error("\"" + IFCONFIG_DRIVER % option + "\"" + "error")
- logger.error(interface_str)
- return interface_list
-
-def check_ifacename(names, option, logger):
- """ verify the validity of output data """
ifcfg_files = []
+ nic_names = []
for f in os.listdir(NETWORK_CONFIG):
if f.startswith("ifcfg-"):
f_path = os.path.join(NETWORK_CONFIG, f)
@@ -67,18 +28,6 @@ def check_ifacename(names, option, logger):
ifcfg_files.append(f_path)
else:
logger.warn("%s is not a regular file" % f_path)
-
- interface_active = get_interface_list('', logger)
- logger.debug("list of active host interface: %s" % interface_active)
- if interface_active == None:
- return 1
-
- interface_all = get_interface_list('-a', logger)
- logger.debug("list of all host interface: %s" % interface_all)
- if interface_all == None:
- return 1
-
-
for ifcfg_file in ifcfg_files:
fp = open(ifcfg_file, 'r')
fp.seek(0,0)
@@ -87,165 +36,91 @@ def check_ifacename(names, option, logger):
device_str = eachLine.rstrip()
nic_string = device_str.split("=")[1]
if nic_string.startswith("\""):
- nic_name = nic_string[1:-1]
+ nic_names = nic_string[1:-1]
else:
- nic_name = nic_string
+ nic_names.append(nic_string)
break
-
fp.close()
+ return list(set(nic_names))
- if option == ' ':
- if nic_name not in interface_active:
- continue
- else:
- if nic_name in names:
- logger.info("it contains interface %s in %s" % (nic_name, ifcfg_file))
- else:
- logger.error("interface %s in %s couldn't \n\
- be in the output of virsh iface-list with option %s" % \
- (nic_name, ifcfg_file, option))
- return 1
- elif option == '--all':
- if nic_name in names:
- logger.info("it contains interface %s in %s" % (nic_name, ifcfg_file))
- else:
- logger.error("interface %s in %s couldn't \n\
- be in the output of virsh iface-list with option %s" % \
- (nic_name, ifcfg_file, option))
-
- return 1
- elif option == '--inactive':
- if nic_name in interface_active:
- continue
- else:
- if nic_name in names:
- logger.info("it contains interface %s in %s" % (nic_name, ifcfg_file))
- else:
- logger.error("interface %s in %s couldn't \n\
- be in the output of virsh iface-list with option %s" % \
- (nic_name, ifcfg_file, option))
- return 1
-
- return 0
-
-def check_ifacestate(names, state, logger):
- """ check the state of give host interface """
-
- interface_active = get_interface_list('', logger)
- if interface_active == None:
- return 1
-
- interface_all = get_interface_list('-a', logger)
- if interface_all == None:
- return 1
-
- index = 0
- count = len(names)
- while(index < count):
- if names[index] in interface_active and state[index] == 'active':
- logger.info("interface %s is %s" % (names[index], state[index]))
- elif names[index] not in interface_active and \
- names[index] in interface_all and \
- state[index] == 'inactive':
- logger.info("interface %s is %s" % (names[index], state[index]))
- else:
- logger.error("interface %s is %s, but not we expected" % \
- (names[index], state[index]))
- return 1
-
- index = index + 1
-
- return 0
-
-def check_ifacemac(names, macs, logger):
- """ check if the mac corresponding to approriate name is correct """
- index = 0
- count = len(names)
- while(index < count):
- status, mac_shell = get_output(GET_MAC % names[index], logger)
- if not status:
- if mac_shell == macs[index]:
- logger.info("interface %s's mac address is %s" % \
- (names[index], macs[index]))
- else:
- logger.error("interface %s's mac address from iface-list: %s \
- is different from one from ip link show: %s" % \
- (name[index], macs[indesx], mac_shell))
- return 1
- index = index + 1
-
- return 0
-
-def iface_list_output(option, logger):
- """ check the output of virsh iface-list with appropriate option """
- global names, state, macs
-
- status, ret = get_output(VIRSH_QUIET_IFACE_LIST % (option, 1), logger)
- if not status:
- names = ret.split('\n')
- logger.info("interface names from option '%s' : %s" % (option, names))
-
- else:
- return 1
-
- status, ret = get_output(VIRSH_QUIET_IFACE_LIST % (option, 2), logger)
- if not status:
- state = ret.split('\n')
- logger.info("interface state from option '%s' : %s" % (option, state))
- else:
- return 1
-
- status, ret = get_output(VIRSH_QUIET_IFACE_LIST % (option, 3), logger)
+def get_interface_list(option, logger):
+ """
+ return host interface list
+ """
+ nic_names = []
+ status, nic_names = utils.exec_cmd(IFCONFIG_DRIVER % option, shell=True)
if not status:
- macs = ret.split('\n')
- logger.info("interface macs from option '%s' : %s" % (option, macs))
+ return nic_names
else:
- return 1
+ logger.error("\"" + IFCONFIG_DRIVER % option + "\"" + "error")
+ logger.error(nic_names)
+ return nic_names
- return 0
+def iface_list_output_from_ifconfig(flags, logger):
+ """
+ get all host interface using ifconfig command
+ """
+ nic_names = []
+ if flags == 0:
+ nic_names = get_interface_list('-a', logger)
+ elif flags == 1:
+ interface_all = get_interface_list('-a', logger)
+ interface_active = get_interface_list('', logger)
+ nic_names = list(set(interface_all) - set(interface_active))
+ elif flags == 2:
+ nic_names = get_interface_list('', logger)
+
+ if nic_names == None:
+ return False
+ return nic_names
+
+def iface_list_output_from_api(flags,logger):
+ """
+ get interface list using listAllInterfaces()
+ """
+ nic_names_api = []
+ for interface in conn.listAllInterfaces(flags):
+ nic_names_api.append(str(interface.name()))
+ return nic_names_api
def iface_list(params):
- """ test the validity of the output of iface_list with
- default, --all, --inactive option, including
- interface name, state, and mac
+ """
+ test listAllInterfaces() api
"""
+ global conn
logger = params['logger']
- ret, option_list = get_option_list(params)
- global names, state, macs
-
- if ret:
- return 1
-
- for option in option_list:
- logger.info("CHECK the output of virsh pool-list with option '%s'" % option)
- logger.info("get the name, corresponding state and mac address of interfaces")
- if iface_list_output(option, logger):
- logger.error("faied to name, state, and mac from iface-list")
- return 1
+ flags = params['flags']
+ conn = sharedmod.libvirtobj['conn']
+ logger.info("The given flags is %s " % flags)
+ if flags == "all":
+ flag = 0
+ elif flags == "inactive":
+ flag = 1
+ elif flags == "active":
+ flag = 2
+ try:
+ iface_list = iface_list_output_from_api(flag, logger)
+ iface_list_ifconfig = iface_list_output_from_ifconfig(flag, logger)
+ if iface_list_ifconfig == False:
+ return 1
+ ifcfg = get_inteface_list_from_ifcfg(logger)
+ logger.info("interface list from API: %s" % iface_list)
+ logger.debug("interface list from ifcfg: %s" % ifcfg)
+ for interface in iface_list_ifconfig:
+ if interface not in ifcfg:
+ iface_list_ifconfig.remove(interface)
+ logger.debug("%s has not regular ifcfg file" % interface)
+
+ logger.info("interface list from ifconfig cmd: %s" % iface_list_ifconfig)
+ for interface in iface_list:
+ if interface in iface_list_ifconfig:
+ logger.debug("%s :Pass" % interface)
else:
- logger.info("then, check the validity of these interface names")
- if check_ifacename(names, option, logger):
- logger.error("checking interface names FAILED")
- return 1
- else:
- logger.info("checking interface names SUCCESSFULLY")
-
- logger.info("check the state of these interfaces")
- if check_ifacestate(names, state, logger):
- logger.error("checking interface state FAILED")
- return 1
- else:
- logger.info("checking interface state SUCCESSFULLY")
-
- logger.info("check the interface mac address")
- if check_ifacemac(names, macs, logger):
- logger.error("checking interface mac address FAILED")
- return 1
- else:
- logger.info("checking interface mac address SUCESSFULLY")
-
- status, ret = get_output(VIRSH_IFACE_LIST % option, logger)
- if not status:
- logger.info("\n" + ret)
+ logger.debug("%s :Fail" % interface)
+ return 1
+
+ except libvirtError, e:
+ logger.error("API error message: %s" % e.message)
+ return 1
return 0
--
1.8.3.1
9 years, 8 months
[libvirt] [PATCH] Introduce virBitmapIsBitSet
by Ján Tomko
A helper that never returns an error and treats bits out of bitmap range
as false.
Use it everywhere we use ignore_value on virBitmapGetBit, or loop over
the bitmap size.
---
src/conf/domain_conf.c | 4 +---
src/conf/node_device_conf.c | 4 +---
src/conf/snapshot_conf.c | 6 ++----
src/conf/storage_conf.c | 4 +---
src/libvirt_private.syms | 1 +
src/libxl/libxl_domain.c | 4 +---
src/libxl/libxl_driver.c | 5 +----
src/nodeinfo.c | 6 +-----
src/qemu/qemu_capabilities.c | 7 +------
src/storage/storage_backend.c | 4 +---
src/util/virbitmap.c | 18 ++++++++++++++++++
src/util/virbitmap.h | 5 +++++
src/util/vircgroup.c | 4 +---
src/util/virdnsmasq.c | 6 +-----
src/util/virportallocator.c | 17 +++--------------
src/util/virprocess.c | 9 ++-------
src/xen/xen_driver.c | 4 +---
src/xen/xend_internal.c | 5 +----
18 files changed, 43 insertions(+), 70 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 127fc91..ae8688e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3107,7 +3107,6 @@ virDomainDefRejectDuplicateControllers(virDomainDefPtr def)
virDomainControllerDefPtr cont;
size_t nbitmaps = 0;
int ret = -1;
- bool b;
size_t i;
memset(max_idx, -1, sizeof(max_idx));
@@ -3133,8 +3132,7 @@ virDomainDefRejectDuplicateControllers(virDomainDefPtr def)
if (max_idx[cont->type] == -1)
continue;
- ignore_value(virBitmapGetBit(bitmaps[cont->type], cont->idx, &b));
- if (b) {
+ if (virBitmapIsBitSet(bitmaps[cont->type], cont->idx)) {
virReportError(VIR_ERR_XML_ERROR,
_("Multiple '%s' controllers with index '%d'"),
virDomainControllerTypeToString(cont->type),
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index f9c9b6f..2899a06 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -439,9 +439,7 @@ char *virNodeDeviceDefFormat(const virNodeDeviceDef *def)
virInterfaceLinkFormat(&buf, &data->net.lnk);
if (data->net.features) {
for (i = 0; i < VIR_NET_DEV_FEAT_LAST; i++) {
- bool b;
- ignore_value(virBitmapGetBit(data->net.features, i, &b));
- if (b) {
+ if (virBitmapIsBitSet(data->net.features, i)) {
virBufferAsprintf(&buf, "<feature name='%s'/>\n",
virNetDevFeatureTypeToString(i));
}
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
index a0667c2..dc5436f 100644
--- a/src/conf/snapshot_conf.c
+++ b/src/conf/snapshot_conf.c
@@ -465,7 +465,6 @@ virDomainSnapshotAlignDisks(virDomainSnapshotDefPtr def,
virBitmapPtr map = NULL;
size_t i;
int ndisks;
- bool inuse;
if (!def->dom) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -500,7 +499,7 @@ virDomainSnapshotAlignDisks(virDomainSnapshotDefPtr def,
goto cleanup;
}
- if (virBitmapGetBit(map, idx, &inuse) < 0 || inuse) {
+ if (virBitmapIsBitSet(map, idx)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("disk '%s' specified twice"),
disk->name);
@@ -553,8 +552,7 @@ virDomainSnapshotAlignDisks(virDomainSnapshotDefPtr def,
for (i = 0; i < def->dom->ndisks; i++) {
virDomainSnapshotDiskDefPtr disk;
- ignore_value(virBitmapGetBit(map, i, &inuse));
- if (inuse)
+ if (virBitmapIsBitSet(map, i))
continue;
disk = &def->disks[ndisks++];
if (VIR_ALLOC(disk->src) < 0)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 4c1f05d..b070448 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -1567,7 +1567,6 @@ virStorageVolTargetDefFormat(virStorageVolOptionsPtr options,
if (options->featureToString && def->features) {
size_t i;
- bool b;
bool empty = virBitmapIsAllClear(def->features);
if (empty) {
@@ -1578,8 +1577,7 @@ virStorageVolTargetDefFormat(virStorageVolOptionsPtr options,
}
for (i = 0; i < VIR_STORAGE_FILE_FEATURE_LAST; i++) {
- ignore_value(virBitmapGetBit(def->features, i, &b));
- if (b)
+ if (virBitmapIsBitSet(def->features, i))
virBufferAsprintf(buf, "<%s/>\n",
options->featureToString(i));
}
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 7262c95..b5fe88c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1070,6 +1070,7 @@ virBitmapFree;
virBitmapGetBit;
virBitmapIsAllClear;
virBitmapIsAllSet;
+virBitmapIsBitSet;
virBitmapLastSetBit;
virBitmapNew;
virBitmapNewCopy;
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index 9af5758..66ca988 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -1093,9 +1093,7 @@ libxlDomainSetVcpuAffinities(libxlDriverPrivatePtr driver, virDomainObjPtr vm)
cpumask = def->cputune.vcpupin[vcpu]->cpumask;
for (i = 0; i < virBitmapSize(cpumask); ++i) {
- bool bit;
- ignore_value(virBitmapGetBit(cpumask, i, &bit));
- if (bit)
+ if (virBitmapIsBitSet(cpumask, i))
VIR_USE_CPU(cpumap, i);
}
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 88fa6ff..d4a8b9d 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -2051,7 +2051,6 @@ libxlDomainGetVcpuPinInfo(virDomainPtr dom, int ncpumaps,
virBitmapPtr cpumask = NULL;
int maxcpu, hostcpus, vcpu, pcpu, n, ret = -1;
unsigned char *cpumap;
- bool pinned;
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -2100,9 +2099,7 @@ libxlDomainGetVcpuPinInfo(virDomainPtr dom, int ncpumaps,
cpumask = vcpupin_list[n]->cpumask;
cpumap = VIR_GET_CPUMAP(cpumaps, maplen, vcpu);
for (pcpu = 0; pcpu < maxcpu; pcpu++) {
- if (virBitmapGetBit(cpumask, pcpu, &pinned) < 0)
- goto cleanup;
- if (!pinned)
+ if (!virBitmapIsBitSet(cpumask, pcpu))
VIR_UNUSE_CPU(cpumap, pcpu);
}
}
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index 3a27c22..05256cc 100644
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -1911,11 +1911,7 @@ nodeCapsInitNUMA(virCapsPtr caps)
cpu = 0;
for (i = 0; i < virBitmapSize(cpumap); i++) {
- bool cpustate;
- if (virBitmapGetBit(cpumap, i, &cpustate) < 0)
- continue;
-
- if (cpustate) {
+ if (virBitmapIsBitSet(cpumap, i)) {
if (virNodeCapsFillCPUInfo(i, cpus + cpu++) < 0) {
topology_failed = true;
virResetLastError();
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index c513d46..ccf22f0 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2048,12 +2048,7 @@ bool
virQEMUCapsGet(virQEMUCapsPtr qemuCaps,
virQEMUCapsFlags flag)
{
- bool b;
-
- if (!qemuCaps || virBitmapGetBit(qemuCaps->flags, flag, &b) < 0)
- return false;
- else
- return b;
+ return qemuCaps && virBitmapIsBitSet(qemuCaps->flags, flag);
}
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index a4e75f5a5..9322571 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -807,7 +807,6 @@ virStorageBackendCreateQemuImgOpts(char **opts,
virBitmapPtr features)
{
virBuffer buf = VIR_BUFFER_INITIALIZER;
- bool b;
size_t i;
if (backingType)
@@ -823,8 +822,7 @@ virStorageBackendCreateQemuImgOpts(char **opts,
virBufferAsprintf(&buf, "compat=%s,", compat);
if (features && format == VIR_STORAGE_FILE_QCOW2) {
for (i = 0; i < VIR_STORAGE_FILE_FEATURE_LAST; i++) {
- ignore_value(virBitmapGetBit(features, i, &b));
- if (b) {
+ if (virBitmapIsBitSet(features, i)) {
switch ((virStorageFileFeature) i) {
case VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS:
if (STREQ_NULLABLE(compat, "0.10")) {
diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c
index b531be5..5322bce 100644
--- a/src/util/virbitmap.c
+++ b/src/util/virbitmap.c
@@ -179,6 +179,24 @@ static bool virBitmapIsSet(virBitmapPtr bitmap, size_t b)
}
/**
+ * virBitmapIsBitSet:
+ * @bitmap: Pointer to bitmap
+ * @b: bit position to get
+ *
+ * Get setting of bit position @b in @bitmap.
+ *
+ * If @b is in the range of @bitmap, returns the value of the bit.
+ * Otherwise false is returned.
+ */
+bool virBitmapIsBitSet(virBitmapPtr bitmap, size_t b)
+{
+ if (bitmap->max_bit <= b)
+ return false;
+
+ return virBitmapIsSet(bitmap, b);
+}
+
+/**
* virBitmapGetBit:
* @bitmap: Pointer to bitmap
* @b: bit position to get
diff --git a/src/util/virbitmap.h b/src/util/virbitmap.h
index 136e819..d326c6a 100644
--- a/src/util/virbitmap.h
+++ b/src/util/virbitmap.h
@@ -62,6 +62,11 @@ int virBitmapClearBit(virBitmapPtr bitmap, size_t b)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
/*
+ * Get bit @b in @bitmap. Returns false if b is out of range.
+ */
+bool virBitmapIsBitSet(virBitmapPtr bitmap, size_t b)
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
+/*
* Get setting of bit position @b in @bitmap and store in @result
*/
int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result)
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 6957e81..e54a079 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -3085,9 +3085,7 @@ virCgroupGetPercpuStats(virCgroupPtr group,
need_cpus = MIN(total_cpus, start_cpu + ncpus);
for (i = 0; i < need_cpus; i++) {
- bool present;
- ignore_value(virBitmapGetBit(cpumap, i, &present));
- if (!present) {
+ if (!virBitmapIsBitSet(cpumap, i)) {
cpu_time = 0;
} else if (virStrToLong_ull(pos, &pos, 10, &cpu_time) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
diff --git a/src/util/virdnsmasq.c b/src/util/virdnsmasq.c
index 97652c0..6a2a2fb 100644
--- a/src/util/virdnsmasq.c
+++ b/src/util/virdnsmasq.c
@@ -874,10 +874,6 @@ dnsmasqCapsGetVersion(dnsmasqCapsPtr caps)
bool
dnsmasqCapsGet(dnsmasqCapsPtr caps, dnsmasqCapsFlags flag)
{
- bool b;
- if (!caps || virBitmapGetBit(caps->flags, flag, &b) < 0)
- return false;
- else
- return b;
+ return caps && virBitmapIsBitSet(caps->flags, flag);
}
diff --git a/src/util/virportallocator.c b/src/util/virportallocator.c
index 578debf..fcd4f74 100644
--- a/src/util/virportallocator.c
+++ b/src/util/virportallocator.c
@@ -184,14 +184,7 @@ int virPortAllocatorAcquire(virPortAllocatorPtr pa,
for (i = pa->start; i <= pa->end && !*port; i++) {
bool used = false, v6used = false;
- if (virBitmapGetBit(pa->bitmap,
- i - pa->start, &used) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Failed to query port %zu"), i);
- goto cleanup;
- }
-
- if (used)
+ if (virBitmapIsBitSet(pa->bitmap, i - pa->start))
continue;
if (!(pa->flags & VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK)) {
@@ -269,12 +262,8 @@ int virPortAllocatorSetUsed(virPortAllocatorPtr pa,
}
if (value) {
- bool used = false;
- if (virBitmapGetBit(pa->bitmap, port - pa->start, &used) < 0)
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Failed to query port %d"), port);
-
- if (used || virBitmapSetBit(pa->bitmap, port - pa->start) < 0) {
+ if (virBitmapIsBitSet(pa->bitmap, port - pa->start) ||
+ virBitmapSetBit(pa->bitmap, port - pa->start) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Failed to reserve port %d"), port);
goto cleanup;
diff --git a/src/util/virprocess.c b/src/util/virprocess.c
index 342bf40..aa00a99 100644
--- a/src/util/virprocess.c
+++ b/src/util/virprocess.c
@@ -407,7 +407,6 @@ virProcessKillPainfully(pid_t pid, bool force)
int virProcessSetAffinity(pid_t pid, virBitmapPtr map)
{
size_t i;
- bool set = false;
VIR_DEBUG("Set process affinity on %lld\n", (long long)pid);
# ifdef CPU_ALLOC
/* New method dynamically allocates cpu mask, allowing unlimted cpus */
@@ -433,9 +432,7 @@ int virProcessSetAffinity(pid_t pid, virBitmapPtr map)
CPU_ZERO_S(masklen, mask);
for (i = 0; i < virBitmapSize(map); i++) {
- if (virBitmapGetBit(map, i, &set) < 0)
- return -1;
- if (set)
+ if (virBitmapIsBitSet(map, i))
CPU_SET_S(i, masklen, mask);
}
@@ -457,9 +454,7 @@ int virProcessSetAffinity(pid_t pid, virBitmapPtr map)
CPU_ZERO(&mask);
for (i = 0; i < virBitmapSize(map); i++) {
- if (virBitmapGetBit(map, i, &set) < 0)
- return -1;
- if (set)
+ if (virBitmapIsBitSet(map, i))
CPU_SET(i, &mask);
}
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 5e6ef68..7577881 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -232,9 +232,7 @@ xenDomainUsedCpus(virDomainPtr dom, virDomainDefPtr def)
cpumap, cpumaplen)) >= 0) {
for (n = 0; n < ncpus; n++) {
for (m = 0; m < priv->nbNodeCpus; m++) {
- bool used;
- ignore_value(virBitmapGetBit(cpulist, m, &used));
- if ((!used) &&
+ if (!virBitmapIsBitSet(cpulist, m) &&
(VIR_CPU_USABLE(cpumap, cpumaplen, n, m))) {
ignore_value(virBitmapSetBit(cpulist, m));
nb++;
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index ab03c1c..1722c3f 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -1089,10 +1089,7 @@ sexpr_to_xend_topology(const struct sexpr *root, virCapsPtr caps)
}
for (n = 0, cpu = 0; cpu < numCpus; cpu++) {
- bool used;
-
- ignore_value(virBitmapGetBit(cpuset, cpu, &used));
- if (used)
+ if (virBitmapIsBitSet(cpuset, cpu))
cpuInfo[n++].id = cpu;
}
virBitmapFree(cpuset);
--
2.0.5
9 years, 8 months
[libvirt] [libvirt-test-API][PATCH 0/2] Add connection_getAllDomainStats test case
by jiahu
The testing case will validate the getAllDomainStats API in class virConnect
jiahu (2):
Add connection_getAllDomainStats test case to linux_domain.conf
Add connection_getAllDomainStats test case
cases/linux_domain.conf | 6 +
repos/virconn/connection_getAllDomainStats.py | 528 ++++++++++++++++++++++++++
2 files changed, 534 insertions(+)
create mode 100644 repos/virconn/connection_getAllDomainStats.py
--
1.8.3.1
9 years, 8 months