virDomainHostdevDefPtr dev)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
- char **path = NULL;
- int *perms = NULL;
- size_t i, npaths = 0;
+ g_autofree char *path = NULL;
+ int perms;
int rv, ret = -1;
if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
return 0;
- if (qemuDomainGetHostdevPath(NULL, dev, false, &npaths, &path, &perms) < 0)
+ if (qemuDomainGetHostdevPath(dev, &path, &perms) < 0)
goto cleanup;
- for (i = 0; i < npaths; i++) {
- VIR_DEBUG("Cgroup allow %s perms=%d", path[i], perms[i]);
- rv = virCgroupAllowDevicePath(priv->cgroup, path[i], perms[i], false);
- virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path[i],
- virCgroupGetDevicePermsString(perms[i]),
- rv);
- if (rv < 0)
- goto cleanup;
- }
+ VIR_DEBUG("Cgroup allow %s perms=%d", path, perms);
+ rv = virCgroupAllowDevicePath(priv->cgroup, path, perms, false);
+ virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path,
+ virCgroupGetDevicePermsString(perms),
+ rv);
+ if (rv < 0)
+ goto cleanup;
if (qemuHostdevNeedsVFIO(dev)) {
VIR_DEBUG("Cgroup allow %s perms=%d", QEMU_DEV_VFIO, VIR_CGROUP_DEVICE_RW);
ret = 0;
cleanup:
- for (i = 0; i < npaths; i++)
- VIR_FREE(path[i]);
- VIR_FREE(path);
- VIR_FREE(perms);
return ret;
}
virDomainHostdevDefPtr dev)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
- char **path = NULL;
- size_t i, npaths = 0;
+ g_autofree char *path = NULL;
int rv, ret = -1;
if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
return 0;
- if (qemuDomainGetHostdevPath(vm->def, dev, true,
- &npaths, &path, NULL) < 0)
+ if (qemuDomainGetHostdevPath(dev, &path, NULL) < 0)
goto cleanup;
- for (i = 0; i < npaths; i++) {
- VIR_DEBUG("Cgroup deny %s", path[i]);
- rv = virCgroupDenyDevicePath(priv->cgroup, path[i],
- VIR_CGROUP_DEVICE_RWM, false);
- virDomainAuditCgroupPath(vm, priv->cgroup,
- "deny", path[i], "rwm", rv);
- if (rv < 0)
- goto cleanup;
- }
+ VIR_DEBUG("Cgroup deny %s", path);
+ rv = virCgroupDenyDevicePath(priv->cgroup, path,
+ VIR_CGROUP_DEVICE_RWM, false);
+ virDomainAuditCgroupPath(vm, priv->cgroup,
+ "deny", path, "rwm", rv);
+ if (rv < 0)
+ goto cleanup;
if (qemuHostdevNeedsVFIO(dev) &&
!qemuDomainNeedsVFIO(vm->def)) {
ret = 0;
cleanup:
- for (i = 0; i < npaths; i++)
- VIR_FREE(path[i]);
- VIR_FREE(path);
return ret;
}
/**
* qemuDomainGetHostdevPath:
- * @def: domain definition
* @dev: host device definition
- * @teardown: true if device will be removed
- * @npaths: number of items in @path and @perms arrays
* @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. If a device requires other paths to be present/allowed
- * they are stored in the @path array after the actual path.
- * Optionally, caller can get @perms on the path (e.g. rw/ro).
+ * @path. Optionally, caller can get @perms on the path (e.g.
+ * rw/ro).
*
- * The caller is responsible for freeing the memory.
+ * The caller is responsible for freeing the @path when no longer
+ * needed.
*
* Returns 0 on success, -1 otherwise.
*/
int
-qemuDomainGetHostdevPath(virDomainDefPtr def,
- virDomainHostdevDefPtr dev,
- bool teardown,
- size_t *npaths,
- char ***path,
- int **perms)
+qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev,
+ char **path,
+ int *perms)
{
int ret = -1;
virDomainHostdevSubsysUSBPtr usbsrc = &dev->source.subsys.u.usb;
g_autoptr(virSCSIDevice) scsi = NULL;
g_autoptr(virSCSIVHostDevice) host = NULL;
g_autofree char *tmpPath = NULL;
- bool includeVFIO = false;
- char **tmpPaths = NULL;
g_autofree int *tmpPerms = NULL;
- size_t tmpNpaths = 0;
int perm = 0;
- *npaths = 0;
-
switch ((virDomainHostdevMode) dev->mode) {
case VIR_DOMAIN_HOSTDEV_MODE_SUBSYS:
switch ((virDomainHostdevSubsysType)dev->source.subsys.type) {
goto cleanup;
perm = VIR_CGROUP_DEVICE_RW;
- if (teardown) {
- if (!virDomainDefHasVFIOHostdev(def))
- includeVFIO = true;
- } else {
- includeVFIO = true;
- }
}
break;
if (!(tmpPath = virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
goto cleanup;
- includeVFIO = true;
perm = VIR_CGROUP_DEVICE_RW;
break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
break;
}
- if (tmpPath) {
- size_t toAlloc = 1;
-
- if (includeVFIO)
- toAlloc = 2;
-
- if (VIR_ALLOC_N(tmpPaths, toAlloc) < 0 ||
- VIR_ALLOC_N(tmpPerms, toAlloc) < 0)
- goto cleanup;
- tmpPaths[0] = g_strdup(tmpPath);
- tmpNpaths = toAlloc;
- tmpPerms[0] = perm;
-
- if (includeVFIO) {
- tmpPaths[1] = g_strdup(QEMU_DEV_VFIO);
- tmpPerms[1] = VIR_CGROUP_DEVICE_RW;
- }
- }
-
- *npaths = tmpNpaths;
- tmpNpaths = 0;
- *path = tmpPaths;
- tmpPaths = NULL;
- if (perms) {
- *perms = tmpPerms;
- tmpPerms = NULL;
- }
+ *path = g_steal_pointer(&tmpPath);
+ if (perms)
+ *perms = perm;
ret = 0;
cleanup:
- virStringListFreeCount(tmpPaths, tmpNpaths);
return ret;
}
const struct qemuDomainCreateDeviceData *data)
{
int ret = -1;
- char **path = NULL;
- size_t i, npaths = 0;
+ g_autofree char *path = NULL;
- if (qemuDomainGetHostdevPath(NULL, dev, false, &npaths, &path, NULL) < 0)
+ if (qemuDomainGetHostdevPath(dev, &path, NULL) < 0)
goto cleanup;
- for (i = 0; i < npaths; i++) {
- if (qemuDomainCreateDevice(path[i], data, false) < 0)
- goto cleanup;
- }
+ if (qemuDomainCreateDevice(path, data, false) < 0)
+ goto cleanup;
if (qemuHostdevNeedsVFIO(dev) &&
qemuDomainCreateDevice(QEMU_DEV_VFIO, data, false) < 0)
ret = 0;
cleanup:
- for (i = 0; i < npaths; i++)
- VIR_FREE(path[i]);
- VIR_FREE(path);
return ret;
}
virDomainHostdevDefPtr hostdev)
{
int ret = -1;
- char **paths = NULL;
- size_t i, npaths = 0;
+ g_autofree char *path = NULL;
- if (qemuDomainGetHostdevPath(NULL, hostdev, false, &npaths, &paths, NULL) < 0)
+ if (qemuDomainGetHostdevPath(hostdev, &path, NULL) < 0)
goto cleanup;
- if (qemuDomainNamespaceMknodPaths(vm, (const char **)paths, npaths) < 0)
+ if (qemuDomainNamespaceMknodPath(vm, path) < 0)
goto cleanup;
if (qemuHostdevNeedsVFIO(hostdev) &&
ret = 0;
cleanup:
- for (i = 0; i < npaths; i++)
- VIR_FREE(paths[i]);
- VIR_FREE(paths);
return ret;
}
virDomainHostdevDefPtr hostdev)
{
int ret = -1;
- char **paths = NULL;
- size_t i, npaths = 0;
+ g_autofree char *path = NULL;
- if (qemuDomainGetHostdevPath(vm->def, hostdev, true,
- &npaths, &paths, NULL) < 0)
+ if (qemuDomainGetHostdevPath(hostdev, &path, NULL) < 0)
goto cleanup;
- if (qemuDomainNamespaceUnlinkPaths(vm, (const char **)paths, npaths) < 0)
+ if (qemuDomainNamespaceUnlinkPath(vm, path) < 0)
goto cleanup;
if (qemuHostdevNeedsVFIO(hostdev) &&
ret = 0;
cleanup:
- for (i = 0; i < npaths; i++)
- VIR_FREE(paths[i]);
- VIR_FREE(paths);
return ret;
}