/* cache whether /dev/kvm is usable as runUid:runGuid */
virTristateBool kvmUsable;
time_t kvmCtime;
+
+ /* qemu.conf allows masking out supported capabilities via
+ * 'capabilities_filter' configuration. 'maskedCaps' if non-NULL
+ * maps out which bits are to be removed */
+ virBitmap *maskedCaps;
};
typedef struct _virQEMUCapsCachePriv virQEMUCapsCachePriv;
g_free(priv->kernelVersion);
virCPUDataFree(priv->cpuData);
g_free(priv->hostCPUSignature);
+ virBitmapFree(priv->maskedCaps);
g_free(priv);
}
const char *hostCPUSignature,
unsigned int microcodeVersion,
const char *kernelVersion,
- virCPUData* cpuData)
+ virCPUData* cpuData,
+ virBitmap *maskedCaps)
{
g_autoptr(virQEMUCaps) qemuCaps = virQEMUCapsNewBinary(binary);
struct stat sb;
qemuCaps->libvirtCtime = virGetSelfLastChanged();
qemuCaps->libvirtVersion = LIBVIR_VERSION_NUMBER;
+ /* If we have capabilities masked out via qemu.conf apply them here */
+ if (maskedCaps)
+ virBitmapSubtract(qemuCaps->flags, maskedCaps);
+
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF))
priv->hostCPUSignature,
virHostCPUGetMicrocodeVersion(priv->hostArch),
priv->kernelVersion,
- priv->cpuData);
+ priv->cpuData,
+ priv->maskedCaps);
}
virQEMUCapsCacheNew(const char *libDir,
const char *cacheDir,
uid_t runUid,
- gid_t runGid)
+ gid_t runGid,
+ virBitmap *maskedCaps)
{
g_autofree char *capsCacheDir = NULL;
virFileCache *cache = NULL;
priv->kernelVersion = g_strdup_printf("%s %s", uts.release, uts.version);
priv->cpuData = virCPUDataGetHost();
+ priv->maskedCaps = maskedCaps;
return cache;
error:
+ virBitmapFree(maskedCaps);
virObjectUnref(cache);
return NULL;
}
virFileCache *virQEMUCapsCacheNew(const char *libDir,
const char *cacheDir,
uid_t uid,
- gid_t gid);
+ gid_t gid,
+ virBitmap *maskedCaps);
virQEMUCaps *virQEMUCapsCacheLookup(virFileCache *cache,
const char *binary);
virQEMUCaps *virQEMUCapsCacheLookupCopy(virFileCache *cache,
const char *hostCPUSignature,
unsigned int microcodeVersion,
const char *kernelVersion,
- virCPUData* cpuData);
+ virCPUData* cpuData,
+ virBitmap *maskedCaps);
int virQEMUCapsLoadCache(virArch hostArch,
virQEMUCaps *qemuCaps,
const char *defsecmodel = NULL;
g_autoptr(virIdentity) identity = virIdentityGetCurrent();
virDomainDriverAutoStartConfig autostartCfg;
+ g_autoptr(virBitmap) maskedCaps = NULL;
qemu_driver = g_new0(virQEMUDriver, 1);
run_gid = cfg->group;
}
+ if (cfg->capabilityfilters) {
+ int tmp;
+ char **next;
+
+ maskedCaps = virBitmapNew(0);
+
+ for (next = cfg->capabilityfilters; *next; next++) {
+ if ((tmp = virQEMUCapsTypeFromString(*next)) < 0) {
+ virReportError(VIR_ERR_CONF_SYNTAX,
+ _("invalid capability_filters capability '%1$s'"),
+ *next);
+ return -1;
+ }
+
+ virBitmapSetBitExpand(maskedCaps, tmp);
+ }
+ }
+
+
qemu_driver->qemuCapsCache = virQEMUCapsCacheNew(cfg->libDir,
cfg->cacheDir,
run_uid,
- run_gid);
+ run_gid,
+ g_steal_pointer(&maskedCaps));
if (!qemu_driver->qemuCapsCache)
goto error;
qemuProcessStartUpdateCustomCaps(virDomainObj *vm)
{
qemuDomainObjPrivate *priv = vm->privateData;
- g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver);
qemuDomainXmlNsDef *nsdef = vm->def->namespaceData;
- char **next;
- int tmp;
-
- if (cfg->capabilityfilters) {
- for (next = cfg->capabilityfilters; *next; next++) {
- if ((tmp = virQEMUCapsTypeFromString(*next)) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("invalid capability_filters capability '%1$s'"),
- *next);
- return -1;
- }
-
- virQEMUCapsClear(priv->qemuCaps, tmp);
- }
- }
if (nsdef) {
+ char **next;
+ int tmp;
+
for (next = nsdef->capsadd; next && *next; next++) {
if ((tmp = virQEMUCapsTypeFromString(*next)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
return EXIT_FAILURE;
if (!(caps = virQEMUCapsNewForBinaryInternal(VIR_ARCH_NONE, argv[1], "/tmp",
- -1, -1, NULL, 0, NULL, NULL)))
+ -1, -1, NULL, 0, NULL, NULL,
+ NULL)))
return EXIT_FAILURE;
host = virArchFromHost();
/* Using /dev/null for libDir and cacheDir automatically produces errors
* upon attempt to use any of them */
- driver->qemuCapsCache = virQEMUCapsCacheNew("/dev/null", "/dev/null", 0, 0);
+ driver->qemuCapsCache = virQEMUCapsCacheNew("/dev/null", "/dev/null",
+ 0, 0, NULL);
if (!driver->qemuCapsCache)
goto error;