}
-void
-virQEMUCapsSetInvalidation(virQEMUCapsPtr qemuCaps,
- bool enabled)
-{
- qemuCaps->invalidation = enabled;
-}
-
-
static int
virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
virQEMUCapsHostCPUDataPtr src)
* <machine name='pc-1.0' alias='pc' hotplugCpus='yes' maxCpus='4' default='yes' numaMemSupported='yes'/>
* ...
* </qemuCaps>
+ *
+ * Returns 0 on success, 1 if outdated, -1 on error
*/
int
virQEMUCapsLoadCache(virArch hostArch,
virQEMUCapsPtr qemuCaps,
- const char *filename)
+ const char *filename,
+ bool skipInvalidation)
{
xmlDocPtr doc = NULL;
int ret = -1;
goto cleanup;
}
+ if (virXPathLongLong("string(./selfctime)", ctxt, &l) < 0) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("missing selfctime in QEMU capabilities XML"));
+ goto cleanup;
+ }
+ qemuCaps->libvirtCtime = (time_t)l;
+
+ qemuCaps->libvirtVersion = 0;
+ if (virXPathULong("string(./selfvers)", ctxt, &lu) == 0)
+ qemuCaps->libvirtVersion = lu;
+
+ if (!skipInvalidation &&
+ (qemuCaps->libvirtCtime != virGetSelfLastChanged() ||
+ qemuCaps->libvirtVersion != LIBVIR_VERSION_NUMBER)) {
+ VIR_DEBUG("Outdated capabilities in %s: libvirt changed "
+ "(%lld vs %lld, %lu vs %lu), stopping load",
+ qemuCaps->binary,
+ (long long)qemuCaps->libvirtCtime,
+ (long long)virGetSelfLastChanged(),
+ (unsigned long)qemuCaps->libvirtVersion,
+ (unsigned long)LIBVIR_VERSION_NUMBER);
+ ret = 1;
+ goto cleanup;
+ }
+
if (!(str = virXPathString("string(./emulator)", ctxt))) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("missing emulator in QEMU capabilities cache"));
}
qemuCaps->ctime = (time_t)l;
- if (virXPathLongLong("string(./selfctime)", ctxt, &l) < 0) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("missing selfctime in QEMU capabilities XML"));
- goto cleanup;
- }
- qemuCaps->libvirtCtime = (time_t)l;
-
- qemuCaps->libvirtVersion = 0;
- if (virXPathULong("string(./selfvers)", ctxt, &lu) == 0)
- qemuCaps->libvirtVersion = lu;
-
if ((n = virXPathNodeSet("./flag", ctxt, &nodes)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("failed to parse qemu capabilities flags"));
if (virXPathBoolean("boolean(./kvmSupportsSecureGuest)", ctxt) > 0)
qemuCaps->kvmSupportsSecureGuest = true;
+ if (skipInvalidation)
+ qemuCaps->invalidation = false;
+
ret = 0;
cleanup:
VIR_FREE(str);
static void *
virQEMUCapsLoadFile(const char *filename,
const char *binary,
- void *privData)
+ void *privData,
+ bool *outdated)
{
virQEMUCapsPtr qemuCaps = virQEMUCapsNewBinary(binary);
virQEMUCapsCachePrivPtr priv = privData;
+ int ret;
if (!qemuCaps)
return NULL;
- if (virQEMUCapsLoadCache(priv->hostArch, qemuCaps, filename) < 0)
+ ret = virQEMUCapsLoadCache(priv->hostArch, qemuCaps, filename, false);
+ if (ret < 0)
goto error;
+ if (ret == 1) {
+ *outdated = true;
+ goto error;
+ }
return qemuCaps;
g_autofree char *file = NULL;
int ret = -1;
void *loadData = NULL;
+ bool outdated = false;
*data = NULL;
goto cleanup;
}
- if (!(loadData = cache->handlers.loadFile(file, name, cache->priv))) {
- VIR_WARN("Failed to load cached data from '%s' for '%s': %s",
- file, name, virGetLastErrorMessage());
- virResetLastError();
+ if (!(loadData = cache->handlers.loadFile(file, name, cache->priv, &outdated))) {
+ if (!outdated) {
+ VIR_WARN("Failed to load cached data from '%s' for '%s': %s",
+ file, name, virGetLastErrorMessage());
+ virResetLastError();
+ }
ret = 0;
goto cleanup;
}
* @filename: name of a file with cached data
* @name: name of the cached data
* @priv: private data created together with cache
+ * @outdated: set to true if data was outdated
*
- * Loads the cached data from a file @filename.
+ * Loads the cached data from a file @filename. If
+ * NULL is returned, then @oudated indicates whether
+ * this was due to the data being outdated, or an
+ * error loading the cache.
*
- * Returns cached data object or NULL on error.
+ * Returns cached data object or NULL on outdated data or error.
*/
typedef void *
(*virFileCacheLoadFilePtr)(const char *filename,
const char *name,
- void *priv);
+ void *priv,
+ bool *outdated);
/**
* virFileCacheSaveFilePtr: