提交 52b7d910 编写于 作者: J Jiri Denemark

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: NJiri Denemark <jdenemar@redhat.com>
Reviewed-by: NDaniel P. Berrange <berrange@redhat.com>
上级 7ce8ff0f
...@@ -52,6 +52,7 @@ ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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 { ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册