This macro checks whether given number is an integer power of
two.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/internal.h | 10 +++++++++
src/qemu/qemu_validate.c | 46 +++++++++++++++++++++-------------------
src/util/virrandom.c | 2 +-
3 files changed, 35 insertions(+), 23 deletions(-)
diff --git a/src/internal.h b/src/internal.h
index ff94e7e53e..0a03dfc46f 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -237,6 +237,16 @@
(a) = (a) ^ (b); \
} while (0)
+
+/**
+ * VIR_IS_POW2:
+ *
+ * Returns true if given number is a power of two
+ */
+#define VIR_IS_POW2(x) \
+ ((x) && !((x) & ((x) - 1)))
+
+
/**
* virCheckFlags:
* @supported: an OR'ed set of supported flags
diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c
index e60d39a22f..6f4662b25a 100644
--- a/src/qemu/qemu_validate.c
+++ b/src/qemu/qemu_validate.c
@@ -1460,20 +1460,32 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
return -1;
}
- if (net->driver.virtio.rx_queue_size &&
- !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("virtio rx_queue_size option is not supported "
- "with this QEMU binary"));
- return -1;
+ if (net->driver.virtio.rx_queue_size) {
+ if (!VIR_IS_POW2(net->driver.virtio.rx_queue_size)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("rx_queue_size has to be a power of two"));
+ return -1;
+ }
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_RX_QUEUE_SIZE)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("virtio rx_queue_size option is not supported
"
+ "with this QEMU binary"));
+ return -1;
+ }
}
- if (net->driver.virtio.tx_queue_size &&
- !virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("virtio tx_queue_size option is not supported "
- "with this QEMU binary"));
- return -1;
+ if (net->driver.virtio.tx_queue_size) {
+ if (!VIR_IS_POW2(net->driver.virtio.tx_queue_size)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("tx_queue_size has to be a power of two"));
+ return -1;
+ }
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_NET_TX_QUEUE_SIZE)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("virtio tx_queue_size option is not supported
"
+ "with this QEMU binary"));
+ return -1;
+ }
}
if (net->mtu &&
@@ -1484,16 +1496,6 @@ qemuValidateDomainDeviceDefNetwork(const virDomainNetDef *net,
return -1;
}
- if (net->driver.virtio.rx_queue_size &
(net->driver.virtio.rx_queue_size - 1)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("rx_queue_size has to be a power of two"));
- return -1;
- }
- if (net->driver.virtio.tx_queue_size &
(net->driver.virtio.tx_queue_size - 1)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("tx_queue_size has to be a power of two"));
- return -1;
- }
if (qemuValidateDomainVirtioOptions(net->virtio, qemuCaps) < 0)
return -1;
}
diff --git a/src/util/virrandom.c b/src/util/virrandom.c
index 6417232e3a..3ae1297e6b 100644
--- a/src/util/virrandom.c
+++ b/src/util/virrandom.c
@@ -89,7 +89,7 @@ double virRandom(void)
*/
uint32_t virRandomInt(uint32_t max)
{
- if ((max & (max - 1)) == 0)
+ if (VIR_IS_POW2(max))
return virRandomBits(__builtin_ffs(max) - 1);
return virRandom() * max;
--
2.26.2