From 9d92f533f86b287eafa6bc1786cde3556b82a792 Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Thu, 9 Feb 2017 11:01:29 +0100 Subject: [PATCH] qemuSetupHostdevCgroup: Use qemuDomainGetHostdevPath MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since these two functions are nearly identical (with qemuSetupHostdevCgroup actually calling virCgroupAllowDevicePath) we can have one function call the other and thus de-duplicate some code. Signed-off-by: Michal Privoznik Reviewed-by: Marc-André Lureau --- src/qemu/qemu_cgroup.c | 147 ++++------------------------------------- src/qemu/qemu_domain.c | 31 +++++++-- src/qemu/qemu_domain.h | 4 ++ 3 files changed, 43 insertions(+), 139 deletions(-) diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 89854b5bd0..19832c2092 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -264,147 +264,26 @@ int qemuSetupHostdevCgroup(virDomainObjPtr vm, virDomainHostdevDefPtr dev) { - int ret = -1; qemuDomainObjPrivatePtr priv = vm->privateData; - virDomainHostdevSubsysUSBPtr usbsrc = &dev->source.subsys.u.usb; - virDomainHostdevSubsysPCIPtr pcisrc = &dev->source.subsys.u.pci; - virDomainHostdevSubsysSCSIPtr scsisrc = &dev->source.subsys.u.scsi; - virDomainHostdevSubsysSCSIVHostPtr hostsrc = &dev->source.subsys.u.scsi_host; - virPCIDevicePtr pci = NULL; - virUSBDevicePtr usb = NULL; - virSCSIDevicePtr scsi = NULL; - virSCSIVHostDevicePtr host = NULL; char *path = NULL; - int rv; + int perms; + int ret = -1; - /* currently this only does something for PCI devices using vfio - * for device assignment, but it is called for *all* hostdev - * devices. - */ + if (qemuDomainGetHostdevPath(dev, &path, &perms) < 0) + goto cleanup; - if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) - return 0; - - if (dev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { - - switch ((virDomainHostdevSubsysType) dev->source.subsys.type) { - case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: - if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) { - pci = virPCIDeviceNew(pcisrc->addr.domain, - pcisrc->addr.bus, - pcisrc->addr.slot, - pcisrc->addr.function); - if (!pci) - goto cleanup; - - if (!(path = virPCIDeviceGetIOMMUGroupDev(pci))) - goto cleanup; - - VIR_DEBUG("Cgroup allow %s for PCI device assignment", path); - rv = virCgroupAllowDevicePath(priv->cgroup, path, - VIR_CGROUP_DEVICE_RW, false); - virDomainAuditCgroupPath(vm, priv->cgroup, - "allow", path, "rw", rv == 0); - if (rv < 0) - goto cleanup; - } - break; - - case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: - /* NB: hostdev->missing wasn't previously checked in the - * case of hotplug, only when starting a domain. Now it is - * always checked, and the cgroup setup skipped if true. - */ - if (dev->missing) - break; - if ((usb = virUSBDeviceNew(usbsrc->bus, usbsrc->device, - NULL)) == NULL) { - goto cleanup; - } - - if (VIR_STRDUP(path, virUSBDeviceGetPath(usb)) < 0) - goto cleanup; - - VIR_DEBUG("Process path '%s' for USB device", path); - rv = virCgroupAllowDevicePath(priv->cgroup, path, - VIR_CGROUP_DEVICE_RW, false); - virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path, "rw", rv == 0); - if (rv < 0) - goto cleanup; - break; - - case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: { - if (scsisrc->protocol == - VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI) { - virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = &scsisrc->u.iscsi; - /* Follow qemuSetupDiskCgroup() and qemuSetImageCgroupInternal() - * which does nothing for non local storage - */ - VIR_DEBUG("Not updating cgroups for hostdev iSCSI path '%s'", - iscsisrc->path); - } else { - virDomainHostdevSubsysSCSIHostPtr scsihostsrc = - &scsisrc->u.host; - if ((scsi = virSCSIDeviceNew(NULL, - scsihostsrc->adapter, - scsihostsrc->bus, - scsihostsrc->target, - scsihostsrc->unit, - dev->readonly, - dev->shareable)) == NULL) - goto cleanup; - - if (VIR_STRDUP(path, virSCSIDeviceGetPath(scsi)) < 0) - goto cleanup; - - VIR_DEBUG("Process path '%s' for SCSI device", path); - rv = virCgroupAllowDevicePath(priv->cgroup, path, - virSCSIDeviceGetReadonly(scsi) ? - VIR_CGROUP_DEVICE_READ : - VIR_CGROUP_DEVICE_RW, false); - - virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path, - virSCSIDeviceGetReadonly(scsi) ? "r" : "rw", - rv == 0); - if (rv < 0) - goto cleanup; - } - break; - } - - case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST: { - if (hostsrc->protocol == - VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_VHOST) { - if (!(host = virSCSIVHostDeviceNew(hostsrc->wwpn))) - goto cleanup; - - if (VIR_STRDUP(path, virSCSIVHostDeviceGetPath(host)) < 0) - goto cleanup; - - VIR_DEBUG("Process path '%s' for scsi_host device", path); - - rv = virCgroupAllowDevicePath(priv->cgroup, path, - VIR_CGROUP_DEVICE_RW, false); - - virDomainAuditCgroupPath(vm, priv->cgroup, - "allow", path, "rw", rv == 0); - if (rv < 0) - goto cleanup; - } - break; - } - - case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST: - break; - } + if (!path) { + /* There's no path that we need to allow. Claim success. */ + ret = 0; + goto cleanup; } - ret = 0; + VIR_DEBUG("Cgroup allow %s perms=%d", path, perms); + ret = virCgroupAllowDevicePath(priv->cgroup, path, perms, false); + virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path, + virCgroupGetDevicePermsString(perms), ret == 0); + cleanup: - virPCIDeviceFree(pci); - virUSBDeviceFree(usb); - virSCSIDeviceFree(scsi); - virSCSIVHostDeviceFree(host); VIR_FREE(path); return ret; } diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index be44843e59..48c414ec14 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -6843,9 +6843,21 @@ qemuDomainSupportsVideoVga(virDomainVideoDefPtr video, } -static int +/** + * qemuDomainGetHostdevPath: + * @dev: host device definition + * @path: resulting path to @dev + * @perms: Optional pointer to VIR_CGROUP_DEVICE_* perms + * + * For given device @dev fetch its host path and store it at @path. Optionally, + * caller can get @perms on the path (e.g. rw/ro). + * + * Returns 0 on success, -1 otherwise. + */ +int qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev, - char **path) + char **path, + int *perms) { int ret = -1; virDomainHostdevSubsysUSBPtr usbsrc = &dev->source.subsys.u.usb; @@ -6876,6 +6888,8 @@ qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev, if (!(tmpPath = virPCIDeviceGetIOMMUGroupDev(pci))) goto cleanup; freeTmpPath = true; + if (perms) + *perms = VIR_CGROUP_DEVICE_RW; } break; @@ -6890,6 +6904,8 @@ qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev, if (!(tmpPath = (char *) virUSBDeviceGetPath(usb))) goto cleanup; + if (perms) + *perms = VIR_CGROUP_DEVICE_RW; break; case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI: @@ -6914,6 +6930,9 @@ qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev, if (!(tmpPath = (char *) virSCSIDeviceGetPath(scsi))) goto cleanup; + if (perms) + *perms = virSCSIDeviceGetReadonly(scsi) ? + VIR_CGROUP_DEVICE_READ : VIR_CGROUP_DEVICE_RW; } break; @@ -6925,6 +6944,8 @@ qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev, if (!(tmpPath = (char *) virSCSIVHostDeviceGetPath(host))) goto cleanup; + if (perms) + *perms = VIR_CGROUP_DEVICE_RW; } break; } @@ -7350,7 +7371,7 @@ qemuDomainSetupHostdev(virQEMUDriverPtr driver ATTRIBUTE_UNUSED, int ret = -1; char *path = NULL; - if (qemuDomainGetHostdevPath(dev, &path) < 0) + if (qemuDomainGetHostdevPath(dev, &path, NULL) < 0) goto cleanup; if (!path) { @@ -8002,7 +8023,7 @@ qemuDomainNamespaceSetupHostdev(virQEMUDriverPtr driver, if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) return 0; - if (qemuDomainGetHostdevPath(hostdev, &path) < 0) + if (qemuDomainGetHostdevPath(hostdev, &path, NULL) < 0) goto cleanup; if (!path) { @@ -8033,7 +8054,7 @@ qemuDomainNamespaceTeardownHostdev(virQEMUDriverPtr driver, if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT)) return 0; - if (qemuDomainGetHostdevPath(hostdev, &path) < 0) + if (qemuDomainGetHostdevPath(hostdev, &path, NULL) < 0) goto cleanup; if (!path) { diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 524a6729c2..55868ce179 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -802,6 +802,10 @@ int qemuDomainCheckMonitor(virQEMUDriverPtr driver, bool qemuDomainSupportsVideoVga(virDomainVideoDefPtr video, virQEMUCapsPtr qemuCaps); +int qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev, + char **path, + int *perms); + int qemuDomainBuildNamespace(virQEMUDriverPtr driver, virDomainObjPtr vm);