mirror of https://gitee.com/openkylin/libvirt.git
qemu: Refresh caps cache after booting a different kernel
Whenever a different kernel is booted, some capabilities related to KVM (such as CPUID bits) may change. We need to refresh the cache to see the changes. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
7ce8ff0f88
commit
52b7d910b6
|
@ -52,6 +52,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||||
|
|
||||||
|
@ -510,6 +511,7 @@ struct _virQEMUCaps {
|
||||||
unsigned int libvirtVersion;
|
unsigned int libvirtVersion;
|
||||||
unsigned int microcodeVersion;
|
unsigned int microcodeVersion;
|
||||||
char *package;
|
char *package;
|
||||||
|
char *kernelVersion;
|
||||||
|
|
||||||
virArch arch;
|
virArch arch;
|
||||||
|
|
||||||
|
@ -2303,6 +2305,9 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
|
||||||
if (VIR_STRDUP(ret->package, qemuCaps->package) < 0)
|
if (VIR_STRDUP(ret->package, qemuCaps->package) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if (VIR_STRDUP(ret->kernelVersion, qemuCaps->kernelVersion) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
ret->arch = qemuCaps->arch;
|
ret->arch = qemuCaps->arch;
|
||||||
|
|
||||||
if (qemuCaps->kvmCPUModels) {
|
if (qemuCaps->kvmCPUModels) {
|
||||||
|
@ -2363,6 +2368,7 @@ void virQEMUCapsDispose(void *obj)
|
||||||
virBitmapFree(qemuCaps->flags);
|
virBitmapFree(qemuCaps->flags);
|
||||||
|
|
||||||
VIR_FREE(qemuCaps->package);
|
VIR_FREE(qemuCaps->package);
|
||||||
|
VIR_FREE(qemuCaps->kernelVersion);
|
||||||
VIR_FREE(qemuCaps->binary);
|
VIR_FREE(qemuCaps->binary);
|
||||||
|
|
||||||
VIR_FREE(qemuCaps->gicCapabilities);
|
VIR_FREE(qemuCaps->gicCapabilities);
|
||||||
|
@ -3834,6 +3840,7 @@ struct _virQEMUCapsCachePriv {
|
||||||
gid_t runGid;
|
gid_t runGid;
|
||||||
virArch hostArch;
|
virArch hostArch;
|
||||||
unsigned int microcodeVersion;
|
unsigned int microcodeVersion;
|
||||||
|
char *kernelVersion;
|
||||||
};
|
};
|
||||||
typedef struct _virQEMUCapsCachePriv virQEMUCapsCachePriv;
|
typedef struct _virQEMUCapsCachePriv virQEMUCapsCachePriv;
|
||||||
typedef virQEMUCapsCachePriv *virQEMUCapsCachePrivPtr;
|
typedef virQEMUCapsCachePriv *virQEMUCapsCachePrivPtr;
|
||||||
|
@ -3845,6 +3852,7 @@ virQEMUCapsCachePrivFree(void *privData)
|
||||||
virQEMUCapsCachePrivPtr priv = privData;
|
virQEMUCapsCachePrivPtr priv = privData;
|
||||||
|
|
||||||
VIR_FREE(priv->libDir);
|
VIR_FREE(priv->libDir);
|
||||||
|
VIR_FREE(priv->kernelVersion);
|
||||||
VIR_FREE(priv);
|
VIR_FREE(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3970,6 +3978,12 @@ virQEMUCapsLoadCache(virArch hostArch,
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (virXPathBoolean("boolean(./kernelVersion)", ctxt) > 0) {
|
||||||
|
qemuCaps->kernelVersion = virXPathString("string(./kernelVersion)", ctxt);
|
||||||
|
if (!qemuCaps->kernelVersion)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(str = virXPathString("string(./arch)", ctxt))) {
|
if (!(str = virXPathString("string(./arch)", ctxt))) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
_("missing arch in QEMU capabilities cache"));
|
_("missing arch in QEMU capabilities cache"));
|
||||||
|
@ -4248,6 +4262,10 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps)
|
||||||
virBufferAsprintf(&buf, "<package>%s</package>\n",
|
virBufferAsprintf(&buf, "<package>%s</package>\n",
|
||||||
qemuCaps->package);
|
qemuCaps->package);
|
||||||
|
|
||||||
|
if (qemuCaps->kernelVersion)
|
||||||
|
virBufferAsprintf(&buf, "<kernelVersion>%s</kernelVersion>\n",
|
||||||
|
qemuCaps->kernelVersion);
|
||||||
|
|
||||||
virBufferAsprintf(&buf, "<arch>%s</arch>\n",
|
virBufferAsprintf(&buf, "<arch>%s</arch>\n",
|
||||||
virArchToString(qemuCaps->arch));
|
virArchToString(qemuCaps->arch));
|
||||||
|
|
||||||
|
@ -4385,14 +4403,24 @@ virQEMUCapsIsValid(void *data,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM) &&
|
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
|
||||||
priv->microcodeVersion != qemuCaps->microcodeVersion) {
|
if (priv->microcodeVersion != qemuCaps->microcodeVersion) {
|
||||||
VIR_DEBUG("Outdated capabilities for '%s': microcode version changed "
|
VIR_DEBUG("Outdated capabilities for '%s': microcode version "
|
||||||
"(%u vs %u)",
|
"changed (%u vs %u)",
|
||||||
qemuCaps->binary,
|
qemuCaps->binary,
|
||||||
priv->microcodeVersion,
|
priv->microcodeVersion,
|
||||||
qemuCaps->microcodeVersion);
|
qemuCaps->microcodeVersion);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (STRNEQ_NULLABLE(priv->kernelVersion, qemuCaps->kernelVersion)) {
|
||||||
|
VIR_DEBUG("Outdated capabilities for '%s': kernel version changed "
|
||||||
|
"('%s' vs '%s')",
|
||||||
|
qemuCaps->binary,
|
||||||
|
priv->kernelVersion,
|
||||||
|
qemuCaps->kernelVersion);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -5228,6 +5256,7 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
|
||||||
uid_t runUid,
|
uid_t runUid,
|
||||||
gid_t runGid,
|
gid_t runGid,
|
||||||
unsigned int microcodeVersion,
|
unsigned int microcodeVersion,
|
||||||
|
const char *kernelVersion,
|
||||||
bool qmpOnly)
|
bool qmpOnly)
|
||||||
{
|
{
|
||||||
virQEMUCapsPtr qemuCaps;
|
virQEMUCapsPtr qemuCaps;
|
||||||
|
@ -5284,9 +5313,13 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
|
||||||
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
|
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
|
||||||
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
|
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_QEMU);
|
||||||
|
|
||||||
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
|
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
|
||||||
qemuCaps->microcodeVersion = microcodeVersion;
|
qemuCaps->microcodeVersion = microcodeVersion;
|
||||||
|
|
||||||
|
if (VIR_STRDUP(qemuCaps->kernelVersion, kernelVersion) < 0)
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(qmperr);
|
VIR_FREE(qmperr);
|
||||||
return qemuCaps;
|
return qemuCaps;
|
||||||
|
@ -5309,6 +5342,7 @@ virQEMUCapsNewData(const char *binary,
|
||||||
priv->runUid,
|
priv->runUid,
|
||||||
priv->runGid,
|
priv->runGid,
|
||||||
priv->microcodeVersion,
|
priv->microcodeVersion,
|
||||||
|
priv->kernelVersion,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5397,6 +5431,7 @@ virQEMUCapsCacheNew(const char *libDir,
|
||||||
char *capsCacheDir = NULL;
|
char *capsCacheDir = NULL;
|
||||||
virFileCachePtr cache = NULL;
|
virFileCachePtr cache = NULL;
|
||||||
virQEMUCapsCachePrivPtr priv = NULL;
|
virQEMUCapsCachePrivPtr priv = NULL;
|
||||||
|
struct utsname uts = { 0 };
|
||||||
|
|
||||||
if (virAsprintf(&capsCacheDir, "%s/capabilities", cacheDir) < 0)
|
if (virAsprintf(&capsCacheDir, "%s/capabilities", cacheDir) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -5417,6 +5452,10 @@ virQEMUCapsCacheNew(const char *libDir,
|
||||||
priv->runGid = runGid;
|
priv->runGid = runGid;
|
||||||
priv->microcodeVersion = microcodeVersion;
|
priv->microcodeVersion = microcodeVersion;
|
||||||
|
|
||||||
|
if (uname(&uts) == 0 &&
|
||||||
|
virAsprintf(&priv->kernelVersion, "%s %s", uts.release, uts.version) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(capsCacheDir);
|
VIR_FREE(capsCacheDir);
|
||||||
return cache;
|
return cache;
|
||||||
|
|
|
@ -37,6 +37,7 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
|
||||||
uid_t runUid,
|
uid_t runUid,
|
||||||
gid_t runGid,
|
gid_t runGid,
|
||||||
unsigned int microcodeVersion,
|
unsigned int microcodeVersion,
|
||||||
|
const char *kernelVersion,
|
||||||
bool qmpOnly);
|
bool qmpOnly);
|
||||||
|
|
||||||
int virQEMUCapsLoadCache(virArch hostArch,
|
int virQEMUCapsLoadCache(virArch hostArch,
|
||||||
|
|
|
@ -72,7 +72,7 @@ main(int argc, char **argv)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
if (!(caps = virQEMUCapsNewForBinaryInternal(VIR_ARCH_NONE, argv[1], "/tmp",
|
if (!(caps = virQEMUCapsNewForBinaryInternal(VIR_ARCH_NONE, argv[1], "/tmp",
|
||||||
-1, -1, 0, true)))
|
-1, -1, 0, NULL, true)))
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
virObjectUnref(caps);
|
virObjectUnref(caps);
|
||||||
|
|
Loading…
Reference in New Issue