diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 951ba7f0ca..74e3479842 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2027,6 +2027,7 @@ virFileReadValueInt; virFileReadValueScaledInt; virFileReadValueString; virFileReadValueUint; +virFileReadValueUllong; virFileRelLinkPointsTo; virFileRemove; virFileRemoveLastComponent; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 540131eb41..e92e8b5318 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -20767,8 +20767,19 @@ qemuDomainGetStatsCpuCache(virQEMUDriverPtr driver, "cpu.cache.monitor.%zu.bank.%zu.id", i, j) < 0) goto cleanup; - if (virTypedParamListAddUInt(params, resdata[i]->stats[j]->vals[0], - "cpu.cache.monitor.%zu.bank.%zu.bytes", i, j) < 0) + /* 'resdata[i]->stats[j]->vals[0]' keeps the value of how many last + * level cache in bank j currently occupied by the vcpus listed in + * resource monitor i, in bytes. This value is reported through a + * 64 bit hardware counter, so it is better to be arranged with + * data type in 64 bit width, but considering the fact that + * physical cache on a CPU could never be designed to be bigger + * than 4G bytes in size, to keep the 'domstats' interface + * historically consistent, it is safe to report the value with a + * truncated 'UInt' data type here. */ + if (virTypedParamListAddUInt(params, + (unsigned int)resdata[i]->stats[j]->vals[0], + "cpu.cache.monitor.%zu.bank.%zu.bytes", + i, j) < 0) goto cleanup; } } diff --git a/src/util/virfile.c b/src/util/virfile.c index 4fc872ef1d..5acac85bb9 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -4123,6 +4123,46 @@ virFileReadValueUint(unsigned int *value, const char *format, ...) } +/** + * virFileReadValueUllong: + * @value: pointer to unsigned long long to be filled in with the value + * @format, ...: file to read from + * + * Read unsigned int from @format and put it into @value. + * + * Return -2 for non-existing file, -1 on other errors and 0 if everything went + * fine. + */ +int +virFileReadValueUllong(unsigned long long *value, const char *format, ...) +{ + g_autofree char *str = NULL; + g_autofree char *path = NULL; + va_list ap; + + va_start(ap, format); + path = g_strdup_vprintf(format, ap); + va_end(ap); + + if (!virFileExists(path)) + return -2; + + if (virFileReadAll(path, INT_BUFSIZE_BOUND(*value), &str) < 0) + return -1; + + virStringTrimOptionalNewline(str); + + if (virStrToLong_ullp(str, NULL, 10, value) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Invalid unsigned long long value '%s' in file '%s'"), + str, path); + return -1; + } + + return 0; +} + + /** * virFileReadValueScaledInt: * @value: pointer to unsigned long long int to be filled in with the value diff --git a/src/util/virfile.h b/src/util/virfile.h index c73f5252e4..c805d87b3f 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -338,6 +338,8 @@ int virFileReadValueInt(int *value, const char *format, ...) G_GNUC_PRINTF(2, 3); int virFileReadValueUint(unsigned int *value, const char *format, ...) G_GNUC_PRINTF(2, 3); +int virFileReadValueUllong(unsigned long long *value, const char *format, ...) + G_GNUC_PRINTF(2, 3); int virFileReadValueBitmap(virBitmapPtr *value, const char *format, ...) G_GNUC_PRINTF(2, 3); int virFileReadValueScaledInt(unsigned long long *value, const char *format, ...) diff --git a/src/util/virresctrl.c b/src/util/virresctrl.c index b78fded026..684d2ce398 100644 --- a/src/util/virresctrl.c +++ b/src/util/virresctrl.c @@ -2678,7 +2678,7 @@ virResctrlMonitorGetStats(virResctrlMonitorPtr monitor, int rv = -1; int ret = -1; size_t i = 0; - unsigned int val = 0; + unsigned long long val = 0; DIR *dirp = NULL; char *datapath = NULL; char *filepath = NULL; @@ -2734,8 +2734,8 @@ virResctrlMonitorGetStats(virResctrlMonitorPtr monitor, goto cleanup; for (i = 0; resources[i]; i++) { - rv = virFileReadValueUint(&val, "%s/%s/%s", datapath, - ent->d_name, resources[i]); + rv = virFileReadValueUllong(&val, "%s/%s/%s", datapath, + ent->d_name, resources[i]); if (rv == -2) { virReportError(VIR_ERR_INTERNAL_ERROR, _("File '%s/%s/%s' does not exist."), diff --git a/src/util/virresctrl.h b/src/util/virresctrl.h index 3dd7c96348..11f275acf4 100644 --- a/src/util/virresctrl.h +++ b/src/util/virresctrl.h @@ -204,7 +204,7 @@ struct _virResctrlMonitorStats { char **features; /* @vals store the statistical record values and @val[0] is the value for * @features[0], @val[1] for@features[1] ... respectively */ - unsigned int *vals; + unsigned long long *vals; /* The length of @vals array */ size_t nvals; };