Skip to content

Commit 004804a

Browse files
author
Jiri Denemark
committed
qemu: Invalidate capabilities when host CPU changes
The host CPU related info stored in the capabilities cache is no longer valid after the host CPU changes. This is not a frequent situation in real world, but it can easily happen in nested scenarios when a disk image is started with various CPUs. https://bugzilla.redhat.com/show_bug.cgi?id=1778819 Signed-off-by: Jiri Denemark <[email protected]> Reviewed-by: Ján Tomko <[email protected]>
1 parent d3d87e0 commit 004804a

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

Diff for: src/qemu/qemu_capabilities.c

+24
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,7 @@ struct _virQEMUCaps {
669669
unsigned int kvmVersion;
670670
unsigned int libvirtVersion;
671671
unsigned int microcodeVersion;
672+
char *hostCPUSignature;
672673
char *package;
673674
char *kernelVersion;
674675

@@ -1908,6 +1909,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
19081909
ret->version = qemuCaps->version;
19091910
ret->kvmVersion = qemuCaps->kvmVersion;
19101911
ret->microcodeVersion = qemuCaps->microcodeVersion;
1912+
ret->hostCPUSignature = g_strdup(qemuCaps->hostCPUSignature);
19111913

19121914
ret->package = g_strdup(qemuCaps->package);
19131915
ret->kernelVersion = g_strdup(qemuCaps->kernelVersion);
@@ -1964,6 +1966,7 @@ void virQEMUCapsDispose(void *obj)
19641966
VIR_FREE(qemuCaps->package);
19651967
VIR_FREE(qemuCaps->kernelVersion);
19661968
VIR_FREE(qemuCaps->binary);
1969+
VIR_FREE(qemuCaps->hostCPUSignature);
19671970

19681971
VIR_FREE(qemuCaps->gicCapabilities);
19691972

@@ -4093,6 +4096,7 @@ struct _virQEMUCapsCachePriv {
40934096
virArch hostArch;
40944097
unsigned int microcodeVersion;
40954098
char *kernelVersion;
4099+
char *hostCPUSignature;
40964100

40974101
/* cache whether /dev/kvm is usable as runUid:runGuid */
40984102
virTristateBool kvmUsable;
@@ -4109,6 +4113,7 @@ virQEMUCapsCachePrivFree(void *privData)
41094113

41104114
VIR_FREE(priv->libDir);
41114115
VIR_FREE(priv->kernelVersion);
4116+
VIR_FREE(priv->hostCPUSignature);
41124117
VIR_FREE(priv);
41134118
}
41144119

@@ -4286,6 +4291,8 @@ virQEMUCapsLoadCache(virArch hostArch,
42864291
goto cleanup;
42874292
}
42884293

4294+
qemuCaps->hostCPUSignature = virXPathString("string(./hostCPUSignature)", ctxt);
4295+
42894296
if (virXPathBoolean("boolean(./package)", ctxt) > 0) {
42904297
qemuCaps->package = virXPathString("string(./package)", ctxt);
42914298
if (!qemuCaps->package)
@@ -4587,6 +4594,8 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps)
45874594

45884595
virBufferAsprintf(&buf, "<microcodeVersion>%u</microcodeVersion>\n",
45894596
qemuCaps->microcodeVersion);
4597+
virBufferEscapeString(&buf, "<hostCPUSignature>%s</hostCPUSignature>\n",
4598+
qemuCaps->hostCPUSignature);
45904599

45914600
if (qemuCaps->package)
45924601
virBufferAsprintf(&buf, "<package>%s</package>\n",
@@ -4814,6 +4823,15 @@ virQEMUCapsIsValid(void *data,
48144823
}
48154824

48164825
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
4826+
if (STRNEQ_NULLABLE(priv->hostCPUSignature, qemuCaps->hostCPUSignature)) {
4827+
VIR_DEBUG("Outdated capabilities for '%s': host CPU changed "
4828+
"('%s' vs '%s')",
4829+
qemuCaps->binary,
4830+
priv->hostCPUSignature,
4831+
qemuCaps->hostCPUSignature);
4832+
return false;
4833+
}
4834+
48174835
if (priv->microcodeVersion != qemuCaps->microcodeVersion) {
48184836
VIR_DEBUG("Outdated capabilities for '%s': microcode version "
48194837
"changed (%u vs %u)",
@@ -5286,6 +5304,7 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
52865304
const char *libDir,
52875305
uid_t runUid,
52885306
gid_t runGid,
5307+
const char *hostCPUSignature,
52895308
unsigned int microcodeVersion,
52905309
const char *kernelVersion)
52915310
{
@@ -5324,6 +5343,7 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
53245343
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
53255344

53265345
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
5346+
qemuCaps->hostCPUSignature = g_strdup(hostCPUSignature);
53275347
qemuCaps->microcodeVersion = microcodeVersion;
53285348

53295349
qemuCaps->kernelVersion = g_strdup(kernelVersion);
@@ -5349,6 +5369,7 @@ virQEMUCapsNewData(const char *binary,
53495369
priv->libDir,
53505370
priv->runUid,
53515371
priv->runGid,
5372+
priv->hostCPUSignature,
53525373
virHostCPUGetMicrocodeVersion(),
53535374
priv->kernelVersion);
53545375
}
@@ -5448,6 +5469,9 @@ virQEMUCapsCacheNew(const char *libDir,
54485469

54495470
priv->hostArch = virArchFromHost();
54505471

5472+
if (virHostCPUGetSignature(&priv->hostCPUSignature) < 0)
5473+
goto error;
5474+
54515475
priv->runUid = runUid;
54525476
priv->runGid = runGid;
54535477
priv->kvmUsable = VIR_TRISTATE_BOOL_ABSENT;

Diff for: src/qemu/qemu_capspriv.h

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
3333
const char *libDir,
3434
uid_t runUid,
3535
gid_t runGid,
36+
const char *hostCPUSignature,
3637
unsigned int microcodeVersion,
3738
const char *kernelVersion);
3839

Diff for: tests/qemucapsprobe.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ main(int argc, char **argv)
7777
return EXIT_FAILURE;
7878

7979
if (!(caps = virQEMUCapsNewForBinaryInternal(VIR_ARCH_NONE, argv[1], "/tmp",
80-
-1, -1, 0, NULL)))
80+
-1, -1, NULL, 0, NULL)))
8181
return EXIT_FAILURE;
8282

8383
virObjectUnref(caps);

0 commit comments

Comments
 (0)