diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 075406e399..95b71b74ab 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1926,6 +1926,10 @@ void qemuDomainObjCheckTaint(virQEMUDriverPtr driver, for (i = 0; i < obj->def->ndisks; i++) qemuDomainObjCheckDiskTaint(driver, obj, obj->def->disks[i], logFD); + for (i = 0; i < obj->def->nhostdevs; i++) + qemuDomainObjCheckHostdevTaint(driver, obj, obj->def->hostdevs[i], + logFD); + for (i = 0; i < obj->def->nnets; i++) qemuDomainObjCheckNetTaint(driver, obj, obj->def->nets[i], logFD); @@ -1953,6 +1957,20 @@ void qemuDomainObjCheckDiskTaint(virQEMUDriverPtr driver, } +void qemuDomainObjCheckHostdevTaint(virQEMUDriverPtr driver, + virDomainObjPtr obj, + virDomainHostdevDefPtr hostdev, + int logFD) +{ + virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi; + + if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI && + scsisrc->rawio == VIR_TRISTATE_BOOL_YES) + qemuDomainObjTaint(driver, obj, VIR_DOMAIN_TAINT_HIGH_PRIVILEGES, + logFD); +} + + void qemuDomainObjCheckNetTaint(virQEMUDriverPtr driver, virDomainObjPtr obj, virDomainNetDefPtr net, diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 4ae2c574f8..d21acd7510 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -301,6 +301,10 @@ void qemuDomainObjCheckDiskTaint(virQEMUDriverPtr driver, virDomainObjPtr obj, virDomainDiskDefPtr disk, int logFD); +void qemuDomainObjCheckHostdevTaint(virQEMUDriverPtr driver, + virDomainObjPtr obj, + virDomainHostdevDefPtr disk, + int logFD); void qemuDomainObjCheckNetTaint(virQEMUDriverPtr driver, virDomainObjPtr obj, virDomainNetDefPtr net, diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index f28082f7b5..b888b09f94 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -6581,6 +6581,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm, break; case VIR_DOMAIN_DEVICE_HOSTDEV: + qemuDomainObjCheckHostdevTaint(driver, vm, dev->data.hostdev, -1); ret = qemuDomainAttachHostDevice(dom->conn, driver, vm, dev->data.hostdev); if (!ret) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 43cf3961a0..13614e9307 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3983,6 +3983,7 @@ int qemuProcessStart(virConnectPtr conn, struct qemuProcessHookData hookData; unsigned long cur_balloon; size_t i; + bool rawio_set = false; char *nodeset = NULL; virBitmapPtr nodemask = NULL; unsigned int stop_flags; @@ -4360,6 +4361,7 @@ int qemuProcessStart(virConnectPtr conn, if (vm->def->disks[i]->rawio == VIR_TRISTATE_BOOL_YES) { #ifdef CAP_SYS_RAWIO virCommandAllowCap(cmd, CAP_SYS_RAWIO); + rawio_set = true; #else virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("Raw I/O is not supported on this platform")); @@ -4376,6 +4378,24 @@ int qemuProcessStart(virConnectPtr conn, goto cleanup; } + /* If rawio not already set, check hostdevs as well */ + if (!rawio_set) { + for (i = 0; i < vm->def->nhostdevs; i++) { + virDomainHostdevSubsysSCSIPtr scsisrc = + &vm->def->hostdevs[i]->source.subsys.u.scsi; + if (scsisrc->rawio == VIR_TRISTATE_BOOL_YES) { +#ifdef CAP_SYS_RAWIO + virCommandAllowCap(cmd, CAP_SYS_RAWIO); + break; +#else + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("Raw I/O is not supported on this platform")); + goto cleanup; +#endif + } + } + } + virCommandSetPreExecHook(cmd, qemuProcessHook, &hookData); virCommandSetMaxProcesses(cmd, cfg->maxProcesses); virCommandSetMaxFiles(cmd, cfg->maxFiles);