mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
util: virhostcpu: factor out frequency parsing
All different architectures use the same copy-pasted code to parse processor frequency information from /proc/cpuinfo. Let's extract that code into a function to avoid repetition. We now also tolerate if the parsing of /proc/cpuinfo is not successful and just report a warning instead of bailing out and abandoning the rest of the CPU information. Reviewed-by: Marc Hartmayer <mhartmay@linux.vnet.ibm.com> Reviewed-by: Boris Fiuczynski <fiuczy@linux.vnet.ibm.com> Reviewed-by: Andrea Bolognani <abologna@redhat.com> Reviewed-by: John Ferlan <jferlan@redhat.com> Signed-off-by: Bjoern Walk <bwalk@linux.vnet.ibm.com>
This commit is contained in:
parent
9ce97d0f7d
commit
0764fc8ad1
@ -508,6 +508,68 @@ virHostCPUHasValidSubcoreConfiguration(int threads_per_subcore)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virHostCPUParseFrequencyString(const char *str,
|
||||
const char *prefix,
|
||||
unsigned int *mhz)
|
||||
{
|
||||
char *p;
|
||||
unsigned int ui;
|
||||
|
||||
if (!STRPREFIX(str, prefix))
|
||||
return 1;
|
||||
|
||||
str += strlen(prefix);
|
||||
|
||||
while (*str && c_isspace(*str))
|
||||
str++;
|
||||
|
||||
if (*str != ':' || !str[1]) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("parsing cpu MHz from cpuinfo"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virStrToLong_ui(str + 1, &p, 10, &ui) == 0 &&
|
||||
/* Accept trailing fractional part. */
|
||||
(*p == '\0' || *p == '.' || c_isspace(*p)))
|
||||
*mhz = ui;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virHostCPUParseFrequency(FILE *cpuinfo,
|
||||
virArch arch,
|
||||
unsigned int *mhz)
|
||||
{
|
||||
const char *prefix = NULL;
|
||||
char line[1024];
|
||||
|
||||
if (ARCH_IS_X86(arch))
|
||||
prefix = "cpu MHz";
|
||||
else if (ARCH_IS_PPC(arch))
|
||||
prefix = "clock";
|
||||
else if (ARCH_IS_ARM(arch))
|
||||
prefix = "BogoMIPS";
|
||||
|
||||
if (!prefix) {
|
||||
VIR_WARN("Your architecture is not supported by the %s parser",
|
||||
CPUINFO_PATH);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (fgets(line, sizeof(line), cpuinfo) != NULL) {
|
||||
if (virHostCPUParseFrequencyString(line, prefix, mhz) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
|
||||
virArch arch,
|
||||
@ -520,7 +582,6 @@ virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
|
||||
{
|
||||
virBitmapPtr present_cpus_map = NULL;
|
||||
virBitmapPtr online_cpus_map = NULL;
|
||||
char line[1024];
|
||||
DIR *nodedir = NULL;
|
||||
struct dirent *nodedirent = NULL;
|
||||
int nodecpus, nodecores, nodesockets, nodethreads, offline = 0;
|
||||
@ -535,83 +596,9 @@ virHostCPUGetInfoPopulateLinux(FILE *cpuinfo,
|
||||
*cpus = *nodes = *sockets = *cores = *threads = 0;
|
||||
|
||||
/* Start with parsing CPU clock speed from /proc/cpuinfo */
|
||||
while (fgets(line, sizeof(line), cpuinfo) != NULL) {
|
||||
if (ARCH_IS_X86(arch)) {
|
||||
char *buf = line;
|
||||
if (STRPREFIX(buf, "cpu MHz")) {
|
||||
char *p;
|
||||
unsigned int ui;
|
||||
|
||||
buf += 7;
|
||||
while (*buf && c_isspace(*buf))
|
||||
buf++;
|
||||
|
||||
if (*buf != ':' || !buf[1]) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("parsing cpu MHz from cpuinfo"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0 &&
|
||||
/* Accept trailing fractional part. */
|
||||
(*p == '\0' || *p == '.' || c_isspace(*p)))
|
||||
*mhz = ui;
|
||||
}
|
||||
} else if (ARCH_IS_PPC(arch)) {
|
||||
char *buf = line;
|
||||
if (STRPREFIX(buf, "clock")) {
|
||||
char *p;
|
||||
unsigned int ui;
|
||||
|
||||
buf += 5;
|
||||
while (*buf && c_isspace(*buf))
|
||||
buf++;
|
||||
|
||||
if (*buf != ':' || !buf[1]) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("parsing cpu MHz from cpuinfo"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0 &&
|
||||
/* Accept trailing fractional part. */
|
||||
(*p == '\0' || *p == '.' || c_isspace(*p)))
|
||||
*mhz = ui;
|
||||
/* No other interesting infos are available in /proc/cpuinfo.
|
||||
* However, there is a line identifying processor's version,
|
||||
* identification and machine, but we don't want it to be caught
|
||||
* and parsed in next iteration, because it is not in expected
|
||||
* format and thus lead to error. */
|
||||
}
|
||||
} else if (ARCH_IS_ARM(arch)) {
|
||||
char *buf = line;
|
||||
if (STRPREFIX(buf, "BogoMIPS")) {
|
||||
char *p;
|
||||
unsigned int ui;
|
||||
|
||||
buf += 8;
|
||||
while (*buf && c_isspace(*buf))
|
||||
buf++;
|
||||
|
||||
if (*buf != ':' || !buf[1]) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
"%s", _("parsing cpu MHz from cpuinfo"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0
|
||||
/* Accept trailing fractional part. */
|
||||
&& (*p == '\0' || *p == '.' || c_isspace(*p)))
|
||||
*mhz = ui;
|
||||
}
|
||||
} else if (ARCH_IS_S390(arch)) {
|
||||
/* s390x has no realistic value for CPU speed,
|
||||
* assign a value of zero to signify this */
|
||||
*mhz = 0;
|
||||
} else {
|
||||
VIR_WARN("Parser for /proc/cpuinfo needs to be adapted for your architecture");
|
||||
break;
|
||||
}
|
||||
if (virHostCPUParseFrequency(cpuinfo, arch, mhz) < 0) {
|
||||
VIR_WARN("Unable to parse CPU frequency information from %s",
|
||||
CPUINFO_PATH);
|
||||
}
|
||||
|
||||
/* Get information about what CPUs are present in the host and what
|
||||
|
Loading…
x
Reference in New Issue
Block a user