qemu: Check for changes in qemu modules directory

Add a configuration option for specifying location of the qemu modules
directory, defaulting to /usr/lib64/qemu. Then use this location to
check for changes in the directory, indicating that a qemu module has
changed and capabilities need to be reprobed.

Signed-off-by: Jim Fehlig <jfehlig@suse.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Jim Fehlig 2020-08-20 15:52:17 -06:00
parent 6fab37da59
commit 2ad009eadd
3 changed files with 42 additions and 0 deletions

View File

@ -1761,6 +1761,12 @@ if not get_option('driver_qemu').disabled()
if use_qemu if use_qemu
conf.set('WITH_QEMU', 1) conf.set('WITH_QEMU', 1)
qemu_moddir = get_option('qemu_moddir')
if qemu_moddir == ''
qemu_moddir = '/usr' / libdir / 'qemu'
endif
conf.set_quoted('QEMU_MODDIR', qemu_moddir)
if host_machine.system() in ['freebsd', 'darwin'] if host_machine.system() in ['freebsd', 'darwin']
default_qemu_user = 'root' default_qemu_user = 'root'
default_qemu_group = 'wheel' default_qemu_group = 'wheel'

View File

@ -60,6 +60,7 @@ option('driver_openvz', type: 'feature', value: 'auto', description: 'OpenVZ dri
option('driver_qemu', type: 'feature', value: 'auto', description: 'QEMU/KVM driver') option('driver_qemu', type: 'feature', value: 'auto', description: 'QEMU/KVM driver')
option('qemu_user', type: 'string', value: '', description: 'username to run QEMU system instance as') option('qemu_user', type: 'string', value: '', description: 'username to run QEMU system instance as')
option('qemu_group', type: 'string', value: '', description: 'groupname to run QEMU system instance as') option('qemu_group', type: 'string', value: '', description: 'groupname to run QEMU system instance as')
option('qemu_moddir', type: 'string', value: '', description: 'set the directory where QEMU modules are located')
option('driver_remote', type: 'feature', value: 'enabled', description: 'remote driver') option('driver_remote', type: 'feature', value: 'enabled', description: 'remote driver')
option('remote_default_mode', type: 'combo', choices: ['legacy', 'direct'], value: 'legacy', description: 'remote driver default mode') option('remote_default_mode', type: 'combo', choices: ['legacy', 'direct'], value: 'legacy', description: 'remote driver default mode')
option('driver_secrets', type: 'feature', value: 'auto', description: 'local secrets management driver') option('driver_secrets', type: 'feature', value: 'auto', description: 'local secrets management driver')

View File

@ -677,6 +677,7 @@ struct _virQEMUCaps {
char *binary; char *binary;
time_t ctime; time_t ctime;
time_t libvirtCtime; time_t libvirtCtime;
time_t modDirMtime;
bool invalidation; bool invalidation;
virBitmapPtr flags; virBitmapPtr flags;
@ -4194,6 +4195,7 @@ virQEMUCapsParseSEVInfo(virQEMUCapsPtr qemuCaps, xmlXPathContextPtr ctxt)
* <qemuCaps> * <qemuCaps>
* <emulator>/some/path</emulator> * <emulator>/some/path</emulator>
* <qemuctime>234235253</qemuctime> * <qemuctime>234235253</qemuctime>
* <qemumoddirmtime>234235253</qemumoddirmtime>
* <selfctime>234235253</selfctime> * <selfctime>234235253</selfctime>
* <selfvers>1002016</selfvers> * <selfvers>1002016</selfvers>
* <flag name='foo'/> * <flag name='foo'/>
@ -4283,6 +4285,9 @@ virQEMUCapsLoadCache(virArch hostArch,
} }
qemuCaps->ctime = (time_t)l; qemuCaps->ctime = (time_t)l;
if (virXPathLongLong("string(./qemumoddirmtime)", ctxt, &l) == 0)
qemuCaps->modDirMtime = (time_t)l;
if ((n = virXPathNodeSet("./flag", ctxt, &nodes)) < 0) { if ((n = virXPathNodeSet("./flag", ctxt, &nodes)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("failed to parse qemu capabilities flags")); _("failed to parse qemu capabilities flags"));
@ -4615,6 +4620,10 @@ virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps)
qemuCaps->binary); qemuCaps->binary);
virBufferAsprintf(&buf, "<qemuctime>%llu</qemuctime>\n", virBufferAsprintf(&buf, "<qemuctime>%llu</qemuctime>\n",
(long long)qemuCaps->ctime); (long long)qemuCaps->ctime);
if (qemuCaps->modDirMtime > 0) {
virBufferAsprintf(&buf, "<qemumoddirmtime>%llu</qemumoddirmtime>\n",
(long long)qemuCaps->modDirMtime);
}
virBufferAsprintf(&buf, "<selfctime>%llu</selfctime>\n", virBufferAsprintf(&buf, "<selfctime>%llu</selfctime>\n",
(long long)qemuCaps->libvirtCtime); (long long)qemuCaps->libvirtCtime);
virBufferAsprintf(&buf, "<selfvers>%lu</selfvers>\n", virBufferAsprintf(&buf, "<selfvers>%lu</selfvers>\n",
@ -4881,6 +4890,23 @@ virQEMUCapsIsValid(void *data,
if (!qemuCaps->binary) if (!qemuCaps->binary)
return true; return true;
if (virFileExists(QEMU_MODDIR)) {
if (stat(QEMU_MODDIR, &sb) < 0) {
VIR_DEBUG("Failed to stat QEMU module directory '%s': %s",
QEMU_MODDIR,
g_strerror(errno));
return false;
}
if (sb.st_mtime != qemuCaps->modDirMtime) {
VIR_DEBUG("Outdated capabilities for '%s': QEMU modules "
"directory '%s' changed (%lld vs %lld)",
qemuCaps->binary, QEMU_MODDIR,
(long long)sb.st_mtime, (long long)qemuCaps->modDirMtime);
return false;
}
}
if (qemuCaps->libvirtCtime != virGetSelfLastChanged() || if (qemuCaps->libvirtCtime != virGetSelfLastChanged() ||
qemuCaps->libvirtVersion != LIBVIR_VERSION_NUMBER) { qemuCaps->libvirtVersion != LIBVIR_VERSION_NUMBER) {
VIR_DEBUG("Outdated capabilities for '%s': libvirt changed " VIR_DEBUG("Outdated capabilities for '%s': libvirt changed "
@ -5463,6 +5489,15 @@ virQEMUCapsNewForBinaryInternal(virArch hostArch,
goto error; goto error;
} }
if (virFileExists(QEMU_MODDIR)) {
if (stat(QEMU_MODDIR, &sb) < 0) {
virReportSystemError(errno, _("Cannot check QEMU module directory %s"),
QEMU_MODDIR);
goto error;
}
qemuCaps->modDirMtime = sb.st_mtime;
}
if (virQEMUCapsInitQMP(qemuCaps, libDir, runUid, runGid) < 0) if (virQEMUCapsInitQMP(qemuCaps, libDir, runUid, runGid) < 0)
goto error; goto error;