#endif
}
+int
+nodeGetCPUCount(void)
+{
+#ifdef __linux__
+ /* XXX should we also work on older kernels, like RHEL5, that lack
+ * cpu/present and cpu/online files? Those kernels also lack cpu
+ * hotplugging, so it would be a matter of finding the largest
+ * cpu/cpuNN directory, and returning NN + 1 */
+ return linuxParseCPUmax(SYSFS_SYSTEM_PATH "/cpu/present");
+#else
+ virReportError(VIR_ERR_NO_SUPPORT, "%s",
+ _("host cpu counting not implemented on this platform"));
+ return -1;
+#endif
+}
+
virBitmapPtr
-nodeGetCPUBitmap(virConnectPtr conn ATTRIBUTE_UNUSED,
- int *max_id ATTRIBUTE_UNUSED)
+nodeGetCPUBitmap(int *max_id ATTRIBUTE_UNUSED)
{
#ifdef __linux__
virBitmapPtr cpumap;
#endif
}
-int nodeGetCPUMap(virConnectPtr conn,
- unsigned char **cpumap,
- unsigned int *online,
- unsigned int flags)
+int
+nodeGetCPUMap(virConnectPtr conn ATTRIBUTE_UNUSED,
+ unsigned char **cpumap,
+ unsigned int *online,
+ unsigned int flags)
{
virBitmapPtr cpus = NULL;
int maxpresent;
virCheckFlags(0, -1);
- if (!(cpus = nodeGetCPUBitmap(conn, &maxpresent)))
+ if (!(cpus = nodeGetCPUBitmap(&maxpresent)))
goto cleanup;
if (cpumap && virBitmapToData(cpus, cpumap, &dummy) < 0)
}
static int
-qemuDomainGetPercpuStats(virDomainPtr domain,
- virDomainObjPtr vm,
+qemuDomainGetPercpuStats(virDomainObjPtr vm,
virCgroupPtr group,
virTypedParameterPtr params,
unsigned int nparams,
int start_cpu,
unsigned int ncpus)
{
- virBitmapPtr map = NULL;
- virBitmapPtr map2 = NULL;
int rv = -1;
int i, id, max_id;
char *pos;
virTypedParameterPtr ent;
int param_idx;
unsigned long long cpu_time;
- bool result;
/* return the number of supported params */
if (nparams == 0 && ncpus != 0)
return QEMU_NB_PER_CPU_STAT_PARAM;
- /* To parse account file, we need bitmap of online cpus. */
- map = nodeGetCPUBitmap(domain->conn, &max_id);
- if (!map)
+ /* To parse account file, we need to know how many cpus are present. */
+ max_id = nodeGetCPUCount();
+ if (max_id < 0)
return rv;
if (ncpus == 0) { /* returns max cpu ID */
- rv = max_id + 1;
+ rv = max_id;
goto cleanup;
}
id = start_cpu + ncpus - 1;
for (i = 0; i <= id; i++) {
- if (virBitmapGetBit(map, i, &result) < 0)
- goto cleanup;
- if (!result) {
- cpu_time = 0;
- } else if (virStrToLong_ull(pos, &pos, 10, &cpu_time) < 0) {
+ if (virStrToLong_ull(pos, &pos, 10, &cpu_time) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cpuacct parse error"));
goto cleanup;
if (getSumVcpuPercpuStats(group, priv->nvcpupids, sum_cpu_time, n) < 0)
goto cleanup;
- /* Check that the mapping of online cpus didn't change mid-parse. */
- map2 = nodeGetCPUBitmap(domain->conn, &max_id);
- if (!map2 || !virBitmapEqual(map, map2)) {
- virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("the set of online cpus changed while reading"));
- goto cleanup;
- }
-
sum_cpu_pos = sum_cpu_time;
for (i = 0; i <= id; i++) {
- if (virBitmapGetBit(map, i, &result) < 0)
- goto cleanup;
- if (!result)
- cpu_time = 0;
- else
- cpu_time = *(sum_cpu_pos++);
+ cpu_time = *(sum_cpu_pos++);
if (i < start_cpu)
continue;
if (virTypedParameterAssign(¶ms[(i - start_cpu) * nparams +
cleanup:
VIR_FREE(sum_cpu_time);
VIR_FREE(buf);
- virBitmapFree(map);
- virBitmapFree(map2);
return rv;
}
if (start_cpu == -1)
ret = qemuDomainGetTotalcpuStats(group, params, nparams);
else
- ret = qemuDomainGetPercpuStats(domain, vm, group, params, nparams,
+ ret = qemuDomainGetPercpuStats(vm, group, params, nparams,
start_cpu, ncpus);
cleanup:
virCgroupFree(&group);