Mediated devices support hot-{plug,unplug} since their introduction in
kernel 4.10, however libvirt has still been missing support for this.
Signed-off-by: Erik Skultety <eskultet@redhat.com>
---
src/qemu/qemu_hotplug.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 49af4d4ff..92e4d1cc9 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2567,6 +2567,88 @@ qemuDomainAttachSCSIVHostDevice(virQEMUDriverPtr driver,
}
+static int
+qemuDomainAttachMediatedDevice(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr hostdev)
+{
+ int ret = -1;
+ char *devstr = NULL;
+ bool added = false;
+ bool teardowncgroup = false;
+ bool teardownlabel = false;
+ bool teardowndevice = false;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_HOSTDEV,
+ { .hostdev = hostdev } };
+
+ if (qemuDomainEnsurePCIAddress(vm, &dev, driver) < 0)
+ return -1;
+
+ if (qemuHostdevPrepareMediatedDevices(driver,
+ vm->def->name,
+ &hostdev,
+ 1) < 0)
+ goto cleanup;
+ added = true;
+
+ if (qemuDomainNamespaceSetupHostdev(vm, hostdev) < 0)
+ goto cleanup;
+ teardowndevice = true;
+
+ if (qemuSetupHostdevCgroup(vm, hostdev) < 0)
+ goto cleanup;
+ teardowncgroup = true;
+
+ if (qemuSecuritySetHostdevLabel(driver, vm, hostdev) < 0)
+ goto cleanup;
+ teardownlabel = true;
+
+ if (qemuAssignDeviceHostdevAlias(vm->def, &hostdev->info->alias, -1) < 0)
+ goto cleanup;
+
+ if (!(devstr = qemuBuildHostdevMediatedDevStr(vm->def, hostdev,
+ priv->qemuCaps)))
+ goto cleanup;
+
+ if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
+ goto cleanup;
+
+ qemuDomainObjEnterMonitor(driver, vm);
+ ret = qemuMonitorAddDevice(priv->mon, devstr);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+ ret = -1;
+ goto cleanup;
+ }
+
+ virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
+ if (ret < 0)
+ goto cleanup;
+
+ VIR_APPEND_ELEMENT_INPLACE(vm->def->hostdevs, vm->def->nhostdevs, hostdev);
+ ret = 0;
+ cleanup:
+ if (ret < 0) {
+ if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
+ VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
+ if (teardownlabel &&
+ qemuSecurityRestoreHostdevLabel(driver, vm, hostdev) < 0)
+ VIR_WARN("Unable to restore host device labelling on hotplug fail");
+ if (teardowndevice &&
+ qemuDomainNamespaceTeardownHostdev(vm, hostdev) < 0)
+ VIR_WARN("Unable to remove host device from /dev");
+ if (added)
+ qemuHostdevReAttachMediatedDevices(driver,
+ vm->def->name,
+ &hostdev,
+ 1);
+ qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
+ }
+ VIR_FREE(devstr);
+ return ret;
+}
+
+
int
qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
@@ -2602,6 +2684,10 @@ qemuDomainAttachHostDevice(virQEMUDriverPtr driver,
if (qemuDomainAttachSCSIVHostDevice(driver, vm, hostdev) < 0)
goto error;
break;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
+ if (qemuDomainAttachMediatedDevice(driver, vm, hostdev) < 0)
+ goto error;
+ break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
--
2.14.3
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Mediated devices support hot-{plug,unplug} since their introduction in
kernel 4.10, however libvirt has still been missing support for this.
Signed-off-by: Erik Skultety <eskultet@redhat.com>
---
src/qemu/qemu_hotplug.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 92e4d1cc9..ea94f7d2b 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4030,6 +4030,17 @@ qemuDomainRemoveSCSIVHostDevice(virQEMUDriverPtr driver,
qemuHostdevReAttachSCSIVHostDevices(driver, vm->def->name, &hostdev, 1);
}
+
+static void
+qemuDomainRemoveMediatedDevice(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr hostdev)
+{
+ qemuHostdevReAttachMediatedDevices(driver, vm->def->name, &hostdev, 1);
+ qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
+}
+
+
static int
qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
@@ -4132,6 +4143,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
qemuDomainRemoveSCSIVHostDevice(driver, vm, hostdev);
break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
+ qemuDomainRemoveMediatedDevice(driver, vm, hostdev);
break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST:
break;
@@ -5059,6 +5071,32 @@ qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver,
return ret;
}
+
+static int
+qemuDomainDetachMediatedDevice(virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ virDomainHostdevDefPtr detach)
+{
+ int ret = -1;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+
+ if (!detach->info->alias) {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("device cannot be detached without a device alias"));
+ return -1;
+ }
+
+ qemuDomainMarkDeviceForRemoval(vm, detach->info);
+
+ qemuDomainObjEnterMonitor(driver, vm);
+ ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
+ if (qemuDomainObjExitMonitor(driver, vm) < 0)
+ ret = -1;
+
+ return ret;
+}
+
+
static int
qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
@@ -5082,6 +5120,9 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
ret = qemuDomainDetachSCSIVHostDevice(driver, vm, detach);
break;
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
+ ret = qemuDomainDetachMediatedDevice(driver, vm, detach);
+ break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("hot unplug is not supported for hostdev subsys type '%s'"),
@@ -5111,6 +5152,7 @@ int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
virDomainHostdevSubsysUSBPtr usbsrc = &subsys->u.usb;
virDomainHostdevSubsysPCIPtr pcisrc = &subsys->u.pci;
virDomainHostdevSubsysSCSIPtr scsisrc = &subsys->u.scsi;
+ virDomainHostdevSubsysMediatedDevPtr mdevsrc = &subsys->u.mdev;
virDomainHostdevDefPtr detach = NULL;
int idx;
@@ -5159,6 +5201,11 @@ int qemuDomainDetachHostDevice(virQEMUDriverPtr driver,
}
break;
}
+ case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV:
+ virReportError(VIR_ERR_DEVICE_MISSING,
+ _("mediated device '%s' not found"),
+ mdevsrc->uuidstr);
+ break;
case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI_HOST:
break;
default:
--
2.14.3
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
Signed-off-by: Erik Skultety <eskultet@redhat.com>
---
docs/news.xml | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/docs/news.xml b/docs/news.xml
index 108889574..5f41208c2 100644
--- a/docs/news.xml
+++ b/docs/news.xml
@@ -92,6 +92,16 @@
previously started domains to 256, or restart them.
</description>
</change>
+ <change>
+ <summary>
+ qemu: Support hot plug and hot unplug of mediated devices
+ </summary>
+ <description>
+ Libvirt now allows mediated devices to be hot plugged and hot
+ unplugged from a guest rather than reporting an error that this isn't
+ supported. In fact, kernel has been supporting this since 4.10.
+ </description>
+ </change>
</section>
<section title="Bug fixes">
</section>
--
2.14.3
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2025 Red Hat, Inc.