[libvirt] [PATCH 0/3] virBitmapGetBit cleanups

Return bool instead of ignoring the return value almost everywhere. Ján Tomko (3): Use virBitmapNextClearBit in networkNextClassID Return bool in virBitmapGetBit Reverse the logic in virbitmaptest 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/libxl/libxl_domain.c | 4 +--- src/libxl/libxl_driver.c | 5 +---- src/network/bridge_driver.c | 8 +++----- src/nodeinfo.c | 6 +----- src/qemu/qemu_capabilities.c | 8 +++----- src/qemu/qemu_command.c | 12 +----------- src/qemu/qemu_driver.c | 15 +++------------ src/qemu/qemu_process.c | 13 ++++--------- src/storage/storage_backend.c | 4 +--- src/test/test_driver.c | 5 +---- src/util/virbitmap.c | 13 +++++-------- src/util/virbitmap.h | 6 +++--- src/util/vircgroup.c | 4 +--- src/util/virdnsmasq.c | 7 ++----- src/util/virportallocator.c | 14 ++------------ src/util/virprocess.c | 9 ++------- src/xen/xen_driver.c | 4 +--- src/xen/xend_internal.c | 5 +---- tests/virbitmaptest.c | 18 ++++-------------- tools/virsh-domain.c | 6 ++---- 24 files changed, 47 insertions(+), 137 deletions(-) -- 2.0.5

Instead of finding the next clear bit by calling virBitmapGetBit in a loop, use the virBitmapNextClearBit helper. --- src/network/bridge_driver.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 2a61991..b0c5c21 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -4711,13 +4711,11 @@ networkCheckBandwidth(virNetworkObjPtr net, static ssize_t networkNextClassID(virNetworkObjPtr net) { - size_t ret = 0; - bool is_set = false; + ssize_t ret = 0; - while (virBitmapGetBit(net->class_id, ret, &is_set) == 0 && is_set) - ret++; + ret = virBitmapNextClearBit(net->class_id, -1); - if (is_set || virBitmapSetBit(net->class_id, ret) < 0) + if (ret < 0 || virBitmapSetBit(net->class_id, ret) < 0) return -1; return ret; -- 2.0.5

On 03/06/2015 10:02 AM, Ján Tomko wrote:
Instead of finding the next clear bit by calling virBitmapGetBit in a loop, use the virBitmapNextClearBit helper. --- src/network/bridge_driver.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
ACK.
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 2a61991..b0c5c21 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -4711,13 +4711,11 @@ networkCheckBandwidth(virNetworkObjPtr net, static ssize_t networkNextClassID(virNetworkObjPtr net) { - size_t ret = 0; - bool is_set = false; + ssize_t ret = 0;
- while (virBitmapGetBit(net->class_id, ret, &is_set) == 0 && is_set) - ret++; + ret = virBitmapNextClearBit(net->class_id, -1);
- if (is_set || virBitmapSetBit(net->class_id, ret) < 0) + if (ret < 0 || virBitmapSetBit(net->class_id, ret) < 0) return -1;
return ret;
-- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Most of the callers use the pattern: bool b; ignore_value(virBitmapGetBit(.., &b)); if (b) { ... } And the rest treats the failure (which can only happen when the requested bit is out of bitmap bounds) the same as they treat a 'false' bit. --- 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/libxl/libxl_domain.c | 4 +--- src/libxl/libxl_driver.c | 5 +---- src/nodeinfo.c | 6 +----- src/qemu/qemu_capabilities.c | 8 +++----- src/qemu/qemu_command.c | 12 +----------- src/qemu/qemu_driver.c | 15 +++------------ src/qemu/qemu_process.c | 13 ++++--------- src/storage/storage_backend.c | 4 +--- src/test/test_driver.c | 5 +---- src/util/virbitmap.c | 13 +++++-------- src/util/virbitmap.h | 6 +++--- src/util/vircgroup.c | 4 +--- src/util/virdnsmasq.c | 7 ++----- src/util/virportallocator.c | 14 ++------------ src/util/virprocess.c | 9 ++------- src/xen/xen_driver.c | 4 +--- src/xen/xend_internal.c | 5 +---- tests/virbitmaptest.c | 16 +++------------- tools/virsh-domain.c | 6 ++---- 23 files changed, 43 insertions(+), 131 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 01a3fbc..dc612e9 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 (virBitmapGetBit(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..9dae710 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 (virBitmapGetBit(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..6692668 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 (virBitmapGetBit(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 (virBitmapGetBit(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..e00220b 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 (virBitmapGetBit(def->features, i)) virBufferAsprintf(buf, "<%s/>\n", options->featureToString(i)); } diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index 9af5758..1e2e87f 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 (virBitmapGetBit(cpumask, i)) VIR_USE_CPU(cpumap, i); } diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 88fa6ff..3709d64 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 (!virBitmapGetBit(cpumask, pcpu)) VIR_UNUSE_CPU(cpumap, pcpu); } } diff --git a/src/nodeinfo.c b/src/nodeinfo.c index 3a27c22..995ccbe 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 (virBitmapGetBit(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 8193805..2fa229f 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -2047,12 +2047,10 @@ bool virQEMUCapsGet(virQEMUCapsPtr qemuCaps, virQEMUCapsFlags flag) { - bool b; - - if (!qemuCaps || virBitmapGetBit(qemuCaps->flags, flag, &b) < 0) + if (!qemuCaps) return false; - else - return b; + + return virBitmapGetBit(qemuCaps->flags, flag); } diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1510797..df1d1e0 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4631,8 +4631,6 @@ qemuBuildMemoryBackendStr(unsigned long long size, if (pagesize == 0 || pagesize != system_page_size) { /* Find the huge page size we want to use */ for (i = 0; i < def->mem.nhugepages; i++) { - bool thisHugepage = false; - hugepage = &def->mem.hugepages[i]; if (!hugepage->nodemask) { @@ -4640,15 +4638,7 @@ qemuBuildMemoryBackendStr(unsigned long long size, continue; } - if (virBitmapGetBit(hugepage->nodemask, guestNode, - &thisHugepage) < 0) { - /* Ignore this error. It's not an error after all. Well, - * the nodemask for this <page/> can contain lower NUMA - * nodes than we are querying in here. */ - continue; - } - - if (thisHugepage) { + if (virBitmapGetBit(hugepage->nodemask, guestNode)) { /* Hooray, we've found the page size */ break; } diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b37474f..8da5abc 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -5102,7 +5102,6 @@ qemuDomainGetVcpuPinInfo(virDomainPtr dom, virDomainVcpuPinDefPtr *vcpupin_list; virBitmapPtr cpumask = NULL; unsigned char *cpumap; - bool pinned; virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | @@ -5157,9 +5156,7 @@ qemuDomainGetVcpuPinInfo(virDomainPtr dom, 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 (!virBitmapGetBit(cpumask, pcpu)) VIR_UNUSE_CPU(cpumap, pcpu); } } @@ -5366,7 +5363,6 @@ qemuDomainGetEmulatorPinInfo(virDomainPtr dom, int ret = -1; int maxcpu, hostcpus, pcpu; virBitmapPtr cpumask = NULL; - bool pinned; virCapsPtr caps = NULL; virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | @@ -5413,9 +5409,7 @@ qemuDomainGetEmulatorPinInfo(virDomainPtr dom, } for (pcpu = 0; pcpu < maxcpu; pcpu++) { - if (virBitmapGetBit(cpumask, pcpu, &pinned) < 0) - goto cleanup; - if (!pinned) + if (!virBitmapGetBit(cpumask, pcpu)) VIR_UNUSE_CPU(cpumaps, pcpu); } @@ -5670,7 +5664,6 @@ qemuDomainGetIOThreadsConfig(virDomainDefPtr targetDef, unsigned char *cpumap; int maxcpu, hostcpus, maplen; size_t i, pcpu; - bool pinned; int ret = -1; if (targetDef->iothreads == 0) @@ -5715,9 +5708,7 @@ qemuDomainGetIOThreadsConfig(virDomainDefPtr targetDef, cpumask = iothreadspin_list[i]->cpumask; for (pcpu = 0; pcpu < maxcpu; pcpu++) { - if (virBitmapGetBit(cpumask, pcpu, &pinned) < 0) - goto cleanup; - if (!pinned) + if (!virBitmapGetBit(cpumask, pcpu)) VIR_UNUSE_CPU(cpumap, pcpu); } } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index d1f089d..745a390 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2386,15 +2386,15 @@ qemuPrepareCpumap(virQEMUDriverPtr driver, for (i = 0; i < caps->host.nnumaCell; i++) { size_t j; int cur_ncpus = caps->host.numaCell[i]->ncpus; - bool result; - if (virBitmapGetBit(nodemask, caps->host.numaCell[i]->num, &result) < 0) { + if (caps->host.numaCell[i]->num < 0 || + caps->host.numaCell[i]->num >= virBitmapSize(nodemask)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to convert nodeset to cpuset")); virBitmapFree(cpumap); cpumap = NULL; goto cleanup; } - if (result) { + if (virBitmapGetBit(nodemask, caps->host.numaCell[i]->num)) { for (j = 0; j < cur_ncpus; j++) ignore_value(virBitmapSetBit(cpumap, caps->host.numaCell[i]->cpus[j].id)); @@ -2596,16 +2596,11 @@ qemuProcessSetSchedParams(int id, size_t nsp, virDomainThreadSchedParamPtr sp) { - bool val = false; size_t i = 0; virDomainThreadSchedParamPtr s = NULL; for (i = 0; i < nsp; i++) { - if (virBitmapGetBit(sp[i].ids, id, &val) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Cannot get bit from bitmap")); - } - if (val) { + if (virBitmapGetBit(sp[i].ids, id)) { s = &sp[i]; break; } diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index a4e75f5a5..f1629ae 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 (virBitmapGetBit(features, i)) { switch ((virStorageFileFeature) i) { case VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS: if (STREQ_NULLABLE(compat, "0.10")) { diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 9591b7c..a5b15b0 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -560,7 +560,6 @@ testDomainUpdateVCPU(virDomainObjPtr dom, virVcpuInfoPtr info = &privdata->vcpu_infos[vcpu]; unsigned char *cpumap = VIR_GET_CPUMAP(privdata->cpumaps, maplen, vcpu); size_t j; - bool cpu; memset(info, 0, sizeof(virVcpuInfo)); memset(cpumap, 0, maplen); @@ -572,9 +571,7 @@ testDomainUpdateVCPU(virDomainObjPtr dom, if (dom->def->cpumask) { for (j = 0; j < maxcpu && j < VIR_DOMAIN_CPUMASK_LEN; ++j) { - if (virBitmapGetBit(dom->def->cpumask, j, &cpu) < 0) - return -1; - if (cpu) { + if (virBitmapGetBit(dom->def->cpumask, j)) { VIR_USE_CPU(cpumap, j); info->cpu = j; } diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c index b531be5..bf11b33 100644 --- a/src/util/virbitmap.c +++ b/src/util/virbitmap.c @@ -182,20 +182,17 @@ static bool virBitmapIsSet(virBitmapPtr bitmap, size_t b) * virBitmapGetBit: * @bitmap: Pointer to bitmap * @b: bit position to get - * @result: bool pointer to receive bit setting * - * Get setting of bit position @b in @bitmap and store in @result + * Get setting of bit position @b in @bitmap. * - * On success, @result will contain the setting of @b and 0 is - * returned. On failure, -1 is returned and @result is unchanged. + * If the position is out of bitmap bounds, false will be returned. */ -int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result) +bool virBitmapGetBit(virBitmapPtr bitmap, size_t b) { if (bitmap->max_bit <= b) - return -1; + return false; - *result = virBitmapIsSet(bitmap, b); - return 0; + return virBitmapIsSet(bitmap, b); } /** diff --git a/src/util/virbitmap.h b/src/util/virbitmap.h index 136e819..22c8e3c 100644 --- a/src/util/virbitmap.h +++ b/src/util/virbitmap.h @@ -62,10 +62,10 @@ int virBitmapClearBit(virBitmapPtr bitmap, size_t b) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; /* - * Get setting of bit position @b in @bitmap and store in @result + * Get setting of bit position @b in @bitmap */ -int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result) - ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_RETURN_CHECK; +bool virBitmapGetBit(virBitmapPtr bitmap, size_t b) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; char *virBitmapString(virBitmapPtr bitmap) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index 6957e81..377c78d 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 (!virBitmapGetBit(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..af6ca0b 100644 --- a/src/util/virdnsmasq.c +++ b/src/util/virdnsmasq.c @@ -874,10 +874,7 @@ dnsmasqCapsGetVersion(dnsmasqCapsPtr caps) bool dnsmasqCapsGet(dnsmasqCapsPtr caps, dnsmasqCapsFlags flag) { - bool b; - - if (!caps || virBitmapGetBit(caps->flags, flag, &b) < 0) + if (!caps) return false; - else - return b; + return virBitmapGetBit(caps->flags, flag); } diff --git a/src/util/virportallocator.c b/src/util/virportallocator.c index 578debf..96a0e97 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 (virBitmapGetBit(pa->bitmap, i - pa->start)) continue; if (!(pa->flags & VIR_PORT_ALLOCATOR_SKIP_BIND_CHECK)) { @@ -269,10 +262,7 @@ 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); + bool used = virBitmapGetBit(pa->bitmap, port - pa->start); if (used || virBitmapSetBit(pa->bitmap, port - pa->start) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 342bf40..d2f53d9 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 (virBitmapGetBit(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 (virBitmapGetBit(map, i)) CPU_SET(i, &mask); } diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c index 5e6ef68..89c2657 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 (!virBitmapGetBit(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..b8de12a 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 (virBitmapGetBit(cpuset, cpu)) cpuInfo[n++].id = cpu; } virBitmapFree(cpuset); diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c index ac5f298..1df5987 100644 --- a/tests/virbitmaptest.c +++ b/tests/virbitmaptest.c @@ -32,7 +32,6 @@ test1(const void *data ATTRIBUTE_UNUSED) virBitmapPtr bitmap; int size; int bit; - bool result; int ret = -1; size = 1024; @@ -43,16 +42,10 @@ test1(const void *data ATTRIBUTE_UNUSED) if (virBitmapSetBit(bitmap, bit) < 0) goto error; - if (virBitmapGetBit(bitmap, bit, &result) < 0) + if (!virBitmapGetBit(bitmap, bit)) goto error; - if (!result) - goto error; - - if (virBitmapGetBit(bitmap, bit + 1, &result) < 0) - goto error; - - if (result) + if (virBitmapGetBit(bitmap, bit + 1)) goto error; ret = 0; @@ -69,12 +62,9 @@ testBit(virBitmapPtr bitmap, bool expected) { size_t i; - bool result; for (i = start; i <= end; i++) { - if (virBitmapGetBit(bitmap, i, &result) < 0) - return -1; - if (result == expected) + if (virBitmapGetBit(bitmap, i) == expected) return 0; } diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 1e9dfe5..4ba22d7 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -10496,7 +10496,6 @@ vshNodeIsSuperset(xmlNodePtr n1, xmlNodePtr n2) xmlAttrPtr attr; char *prop1, *prop2; bool found; - bool visited; bool ret = false; long n1_child_size, n2_child_size, n1_iter; virBitmapPtr bitmap; @@ -10555,12 +10554,11 @@ vshNodeIsSuperset(xmlNodePtr n1, xmlNodePtr n2) continue; } - if (virBitmapGetBit(bitmap, n1_iter, &visited) < 0) { + if (n1_iter >= n1_child_size) { vshError(NULL, "%s", _("Bad child elements counting.")); goto cleanup; } - - if (visited) { + if (virBitmapGetBit(bitmap, n1_iter)) { child1 = child1->next; n1_iter++; continue; -- 2.0.5

On 03/06/2015 10:02 AM, Ján Tomko wrote:
Most of the callers use the pattern: bool b; ignore_value(virBitmapGetBit(.., &b)); if (b) { ... }
And the rest treats the failure (which can only happen when the requested bit is out of bitmap bounds) the same as they treat a 'false' bit.
Blindly returning false for out of bounds may work for some (most?) callers, but I still wonder if we should expose the full bounds-checking version under a different name, and/or expose a variant that lets the caller specify the default value to return for an out-of-bounds reference. That is, while you've made the common case short, I wonder if we need the extra control for correctness elsewhere. I'm not outright rejecting this patch, but I'm also not sure if it is the right move to take - is our attempt at bounds-checking in order to prevent programming bugs helping us avoid bugs (then this patch is losing that safety), or is it just causing needless noise of boilerplate (most callers using ignore_value, in which case this patch is the right thing). Anyone else with an opinion? -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Fri, Mar 06, 2015 at 01:01:13PM -0700, Eric Blake wrote:
On 03/06/2015 10:02 AM, Ján Tomko wrote:
Most of the callers use the pattern: bool b; ignore_value(virBitmapGetBit(.., &b)); if (b) { ... }
And the rest treats the failure (which can only happen when the requested bit is out of bitmap bounds) the same as they treat a 'false' bit.
Blindly returning false for out of bounds may work for some (most?) callers, but I still wonder if we should expose the full bounds-checking version under a different name, and/or expose a variant that lets the caller specify the default value to return for an out-of-bounds reference. That is, while you've made the common case short, I wonder if we need the extra control for correctness elsewhere.
From the 23 callers in this patch: 10 explicitly ignore_value 5 are in a for loop from 0 to virBitmapSize (virProcessSetAffinity, nodeCapsInitNUMA, virDomainSnapshotAlignDisks, libxlDomainGetVcpuPinInfo) 1 checks the range before calling GetBit (virPortAllocatorSetUsed) 1 loops against the bitmap range (virPortAllocatorAcquired) I think these don't need any bounds-checking 2 of them take an enum as an argument (*CapsGet), I don't think we need a special case for QEMU_CAPS_LAST either. qemuBuildMemoryBackendStr admits to asking for out-of-range bits, so it would require checking the bounds up front, or a default of 'false'. In the rest of the callers, out-of-bounds queries are programming bugs, but since the origins of their indexes are not so straightforward, perhaps those should keep using the range-checking version. So there's only one caller where a default of 'false' makes sense. I think a function named virBitmapIsBitSet could return false on out-of-range (how can it be set if it's not in the bitmap?)
I'm not outright rejecting this patch, but I'm also not sure if it is the right move to take - is our attempt at bounds-checking in order to prevent programming bugs helping us avoid bugs (then this patch is losing that safety), or is it just causing needless noise of boilerplate (most callers using ignore_value, in which case this patch is the right thing). Anyone else with an opinion?
In the meantime I've pushed the other two acked patches. Jan

On Tue, Mar 10, 2015 at 13:52:31 +0100, Ján Tomko wrote:
On Fri, Mar 06, 2015 at 01:01:13PM -0700, Eric Blake wrote:
On 03/06/2015 10:02 AM, Ján Tomko wrote:
Most of the callers use the pattern: bool b; ignore_value(virBitmapGetBit(.., &b)); if (b) { ... }
And the rest treats the failure (which can only happen when the requested bit is out of bitmap bounds) the same as they treat a 'false' bit.
Blindly returning false for out of bounds may work for some (most?) callers, but I still wonder if we should expose the full bounds-checking version under a different name, and/or expose a variant that lets the caller specify the default value to return for an out-of-bounds reference. That is, while you've made the common case short, I wonder if we need the extra control for correctness elsewhere.
From the 23 callers in this patch: 10 explicitly ignore_value 5 are in a for loop from 0 to virBitmapSize (virProcessSetAffinity, nodeCapsInitNUMA, virDomainSnapshotAlignDisks, libxlDomainGetVcpuPinInfo) 1 checks the range before calling GetBit (virPortAllocatorSetUsed) 1 loops against the bitmap range (virPortAllocatorAcquired)
I think these don't need any bounds-checking
2 of them take an enum as an argument (*CapsGet), I don't think we need a special case for QEMU_CAPS_LAST either.
qemuBuildMemoryBackendStr admits to asking for out-of-range bits, so it would require checking the bounds up front, or a default of 'false'.
In the rest of the callers, out-of-bounds queries are programming bugs, but since the origins of their indexes are not so straightforward, perhaps those should keep using the range-checking version.
So there's only one caller where a default of 'false' makes sense. I think a function named virBitmapIsBitSet could return false on out-of-range (how can it be set if it's not in the bitmap?)
I think this solution would be okay to get rid of the cruft in cases we don't care about the range checks while we can keep the old impl for the cases where it's not certain. Peter

Test the whole range in testBit, not just the first bit. --- tests/virbitmaptest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c index 1df5987..6b40d74 100644 --- a/tests/virbitmaptest.c +++ b/tests/virbitmaptest.c @@ -64,11 +64,11 @@ testBit(virBitmapPtr bitmap, size_t i; for (i = start; i <= end; i++) { - if (virBitmapGetBit(bitmap, i) == expected) - return 0; + if (virBitmapGetBit(bitmap, i) != expected) + return -1; } - return -1; + return 0; } static int -- 2.0.5

On 03/06/2015 10:02 AM, Ján Tomko wrote:
Test the whole range in testBit, not just the first bit. --- tests/virbitmaptest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
ACK.
diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c index 1df5987..6b40d74 100644 --- a/tests/virbitmaptest.c +++ b/tests/virbitmaptest.c @@ -64,11 +64,11 @@ testBit(virBitmapPtr bitmap, size_t i;
for (i = start; i <= end; i++) { - if (virBitmapGetBit(bitmap, i) == expected) - return 0; + if (virBitmapGetBit(bitmap, i) != expected) + return -1; }
- return -1; + return 0; }
static int
-- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (3)
-
Eric Blake
-
Ján Tomko
-
Peter Krempa