diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index fd04fcece3a876c0183ca267af166b59d57364f0..a6af44fe1ccf658c5188fb5402ec9bc9e7808e21 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2218,9 +2218,11 @@ virHostCPUGetMSR; virHostCPUGetOnline; virHostCPUGetOnlineBitmap; virHostCPUGetPresentBitmap; +virHostCPUGetSignature; virHostCPUGetStats; virHostCPUGetThreadsPerSubcore; virHostCPUHasBitmap; +virHostCPUReadSignature; virHostCPUStatsAssign; diff --git a/src/util/virhostcpu.c b/src/util/virhostcpu.c index 721d959d465182754b9ee3d9f564e752c4921ae8..bfef022f64fdd4c8fdaf4e8268d74e7b1af81870 100644 --- a/src/util/virhostcpu.c +++ b/src/util/virhostcpu.c @@ -1416,3 +1416,40 @@ virHostCPUGetTscInfo(void) #endif /* HAVE_LINUX_KVM_H && defined(KVM_GET_MSRS) && \ (defined(__i386__) || defined(__x86_64__)) && \ (defined(__linux__) || defined(__FreeBSD__)) */ + +int +virHostCPUReadSignature(virArch arch G_GNUC_UNUSED, + FILE *cpuinfo G_GNUC_UNUSED, + char **signature G_GNUC_UNUSED) +{ + return 0; +} + +#ifdef __linux__ + +int +virHostCPUGetSignature(char **signature) +{ + g_autoptr(FILE) cpuinfo = NULL; + + *signature = NULL; + + if (!(cpuinfo = fopen(CPUINFO_PATH, "r"))) { + virReportSystemError(errno, _("Failed to open cpuinfo file '%s'"), + CPUINFO_PATH); + return -1; + } + + return virHostCPUReadSignature(virArchFromHost(), cpuinfo, signature); +} + +#else + +int +virHostCPUGetSignature(char **signature) +{ + *signature = NULL; + return 0; +} + +#endif /* __linux__ */ diff --git a/src/util/virhostcpu.h b/src/util/virhostcpu.h index 9be2e51a38715889313ded311cced66197b26433..48b1431ca459387d79a35cd7592041b3908e1d04 100644 --- a/src/util/virhostcpu.h +++ b/src/util/virhostcpu.h @@ -79,3 +79,5 @@ int virHostCPUGetMSR(unsigned long index, uint64_t *msr); virHostCPUTscInfoPtr virHostCPUGetTscInfo(void); + +int virHostCPUGetSignature(char **signature); diff --git a/src/util/virhostcpupriv.h b/src/util/virhostcpupriv.h index afb415f9eaa25569976d549e795f2f522c13e3cb..f7b1e7c93c959a7d7b9e41c6328619090728c30e 100644 --- a/src/util/virhostcpupriv.h +++ b/src/util/virhostcpupriv.h @@ -42,3 +42,7 @@ int virHostCPUGetStatsLinux(FILE *procstat, virNodeCPUStatsPtr params, int *nparams); #endif + +int virHostCPUReadSignature(virArch arch, + FILE *cpuinfo, + char **signature); diff --git a/tests/virhostcputest.c b/tests/virhostcputest.c index 70a723098b4dc9cfa9ad9c9cc3b419f605fdc66e..62bacddefbf0a4a85bbb34051b7ab588aacb5912 100644 --- a/tests/virhostcputest.c +++ b/tests/virhostcputest.c @@ -1,6 +1,7 @@ #include #include +#include #include "testutils.h" #include "internal.h" @@ -193,6 +194,38 @@ linuxTestHostCPU(const void *opaque) return result; } + +static int +hostCPUSignature(const void *opaque) +{ + const struct linuxTestHostCPUData *data = opaque; + const char *arch = virArchToString(data->arch); + g_autofree char *cpuinfo = NULL; + g_autofree char *expected = NULL; + g_autofree char *signature = NULL; + g_autoptr(FILE) f = NULL; + + cpuinfo = g_strdup_printf("%s/virhostcpudata/linux-%s-%s.cpuinfo", + abs_srcdir, arch, data->testName); + expected = g_strdup_printf("%s/virhostcpudata/linux-%s-%s.signature", + abs_srcdir, arch, data->testName); + + if (!(f = fopen(cpuinfo, "r"))) { + virReportSystemError(errno, + "Failed to open cpuinfo file '%s'", cpuinfo); + return -1; + } + + if (virHostCPUReadSignature(data->arch, f, &signature) < 0) + return -1; + + if (!signature && !virFileExists(expected)) + return 0; + + return virTestCompareToFile(signature, expected); +} + + struct nodeCPUStatsData { const char *name; int ncpus; @@ -268,10 +301,17 @@ mymain(void) if (virInitialize() < 0) return EXIT_FAILURE; - for (i = 0; i < G_N_ELEMENTS(nodeData); i++) + for (i = 0; i < G_N_ELEMENTS(nodeData); i++) { + g_autofree char *sigTest = NULL; + if (virTestRun(nodeData[i].testName, linuxTestHostCPU, &nodeData[i]) != 0) ret = -1; + sigTest = g_strdup_printf("%s CPU signature", nodeData[i].testName); + if (virTestRun(sigTest, hostCPUSignature, &nodeData[i]) != 0) + ret = -1; + } + # define DO_TEST_CPU_STATS(name, ncpus, shouldFail) \ do { \ static struct nodeCPUStatsData data = { name, ncpus, shouldFail}; \