|
|
6ae9ed |
From 758b25f47af79cd6da43a4bc13599b0bb64afef1 Mon Sep 17 00:00:00 2001
|
|
|
6ae9ed |
Message-Id: <758b25f47af79cd6da43a4bc13599b0bb64afef1@dist-git>
|
|
|
6ae9ed |
From: =?UTF-8?q?J=C3=A1n=20Tomko?= <jtomko@redhat.com>
|
|
|
6ae9ed |
Date: Thu, 21 Jul 2016 15:57:56 +0200
|
|
|
6ae9ed |
Subject: [PATCH] Assign addresses on USB device hotplug
|
|
|
6ae9ed |
MIME-Version: 1.0
|
|
|
6ae9ed |
Content-Type: text/plain; charset=UTF-8
|
|
|
6ae9ed |
Content-Transfer-Encoding: 8bit
|
|
|
6ae9ed |
|
|
|
6ae9ed |
USB disks, redirected devices, host devices and serial devices
|
|
|
6ae9ed |
are supported.
|
|
|
6ae9ed |
|
|
|
6ae9ed |
(cherry picked from commit f2a781ceb075073a6033b96649f41501148d3c0c)
|
|
|
6ae9ed |
Signed-off-by: Ján Tomko <jtomko@redhat.com>
|
|
|
6ae9ed |
|
|
|
6ae9ed |
https://bugzilla.redhat.com/show_bug.cgi?id=1215968
|
|
|
6ae9ed |
---
|
|
|
6ae9ed |
src/conf/domain_addr.c | 30 ++++++++++++++++++++++
|
|
|
6ae9ed |
src/conf/domain_addr.h | 5 ++++
|
|
|
6ae9ed |
src/libvirt_private.syms | 1 +
|
|
|
6ae9ed |
src/qemu/qemu_domain_address.c | 5 ++++
|
|
|
6ae9ed |
src/qemu/qemu_hotplug.c | 27 +++++++++++++++++++
|
|
|
6ae9ed |
.../qemuhotplug-hotplug-base-live+disk-usb.xml | 1 +
|
|
|
6ae9ed |
6 files changed, 69 insertions(+)
|
|
|
6ae9ed |
|
|
|
6ae9ed |
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
|
|
|
6ae9ed |
index 3b0c205..365ee40 100644
|
|
|
6ae9ed |
--- a/src/conf/domain_addr.c
|
|
|
6ae9ed |
+++ b/src/conf/domain_addr.c
|
|
|
6ae9ed |
@@ -1735,3 +1735,33 @@ virDomainUSBAddressEnsure(virDomainUSBAddressSetPtr addrs,
|
|
|
6ae9ed |
|
|
|
6ae9ed |
return 0;
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+int
|
|
|
6ae9ed |
+virDomainUSBAddressRelease(virDomainUSBAddressSetPtr addrs,
|
|
|
6ae9ed |
+ virDomainDeviceInfoPtr info)
|
|
|
6ae9ed |
+{
|
|
|
6ae9ed |
+ virDomainUSBAddressHubPtr targetHub = NULL;
|
|
|
6ae9ed |
+ char *portStr = NULL;
|
|
|
6ae9ed |
+ int targetPort;
|
|
|
6ae9ed |
+ int ret = -1;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB ||
|
|
|
6ae9ed |
+ !virDomainUSBAddressPortIsValid(info->addr.usb.port))
|
|
|
6ae9ed |
+ return 0;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ portStr = virDomainUSBAddressPortFormat(info->addr.usb.port);
|
|
|
6ae9ed |
+ VIR_DEBUG("Releasing USB addr bus=%u port=%s", info->addr.usb.bus, portStr);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (!(targetHub = virDomainUSBAddressFindPort(addrs, info, &targetPort,
|
|
|
6ae9ed |
+ portStr)))
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ ignore_value(virBitmapClearBit(targetHub->portmap, targetPort));
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ ret = 0;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ cleanup:
|
|
|
6ae9ed |
+ VIR_FREE(portStr);
|
|
|
6ae9ed |
+ return ret;
|
|
|
6ae9ed |
+}
|
|
|
6ae9ed |
diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h
|
|
|
6ae9ed |
index 633aa16..cc36aed 100644
|
|
|
6ae9ed |
--- a/src/conf/domain_addr.h
|
|
|
6ae9ed |
+++ b/src/conf/domain_addr.h
|
|
|
6ae9ed |
@@ -293,4 +293,9 @@ int
|
|
|
6ae9ed |
virDomainUSBAddressEnsure(virDomainUSBAddressSetPtr addrs,
|
|
|
6ae9ed |
virDomainDeviceInfoPtr info)
|
|
|
6ae9ed |
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+int
|
|
|
6ae9ed |
+virDomainUSBAddressRelease(virDomainUSBAddressSetPtr addrs,
|
|
|
6ae9ed |
+ virDomainDeviceInfoPtr info)
|
|
|
6ae9ed |
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
|
|
6ae9ed |
#endif /* __DOMAIN_ADDR_H__ */
|
|
|
6ae9ed |
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|
|
6ae9ed |
index 4727d39..e23bfe3 100644
|
|
|
6ae9ed |
--- a/src/libvirt_private.syms
|
|
|
6ae9ed |
+++ b/src/libvirt_private.syms
|
|
|
6ae9ed |
@@ -112,6 +112,7 @@ virDomainUSBAddressEnsure;
|
|
|
6ae9ed |
virDomainUSBAddressPortFormat;
|
|
|
6ae9ed |
virDomainUSBAddressPortFormatBuf;
|
|
|
6ae9ed |
virDomainUSBAddressPortIsValid;
|
|
|
6ae9ed |
+virDomainUSBAddressRelease;
|
|
|
6ae9ed |
virDomainUSBAddressReserve;
|
|
|
6ae9ed |
virDomainUSBAddressSetAddControllers;
|
|
|
6ae9ed |
virDomainUSBAddressSetAddHub;
|
|
|
6ae9ed |
diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c
|
|
|
6ae9ed |
index 21c2ecf..7499026 100644
|
|
|
6ae9ed |
--- a/src/qemu/qemu_domain_address.c
|
|
|
6ae9ed |
+++ b/src/qemu/qemu_domain_address.c
|
|
|
6ae9ed |
@@ -1772,4 +1772,9 @@ qemuDomainReleaseDeviceAddress(virDomainObjPtr vm,
|
|
|
6ae9ed |
virDomainVirtioSerialAddrRelease(priv->vioserialaddrs, info) < 0)
|
|
|
6ae9ed |
VIR_WARN("Unable to release virtio-serial address on %s",
|
|
|
6ae9ed |
NULLSTR(devstr));
|
|
|
6ae9ed |
+ if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB &&
|
|
|
6ae9ed |
+ priv->usbaddrs &&
|
|
|
6ae9ed |
+ virDomainUSBAddressRelease(priv->usbaddrs, info) < 0)
|
|
|
6ae9ed |
+ VIR_WARN("Unable to release USB address on %s",
|
|
|
6ae9ed |
+ NULLSTR(devstr));
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
|
|
|
6ae9ed |
index cba0e8c..36885a3 100644
|
|
|
6ae9ed |
--- a/src/qemu/qemu_hotplug.c
|
|
|
6ae9ed |
+++ b/src/qemu/qemu_hotplug.c
|
|
|
6ae9ed |
@@ -640,6 +640,13 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver,
|
|
|
6ae9ed |
char *devstr = NULL;
|
|
|
6ae9ed |
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
|
|
6ae9ed |
const char *src = virDomainDiskGetSource(disk);
|
|
|
6ae9ed |
+ bool releaseaddr = false;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
+ if (priv->usbaddrs) {
|
|
|
6ae9ed |
+ if (virDomainUSBAddressEnsure(priv->usbaddrs, &disk->info) < 0)
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+ releaseaddr = true;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
|
|
|
6ae9ed |
if (qemuDomainPrepareDisk(driver, vm, disk, NULL, false) < 0)
|
|
|
6ae9ed |
goto cleanup;
|
|
|
6ae9ed |
@@ -685,6 +692,8 @@ qemuDomainAttachUSBMassStorageDevice(virQEMUDriverPtr driver,
|
|
|
6ae9ed |
virDomainDiskInsertPreAlloced(vm->def, disk);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
cleanup:
|
|
|
6ae9ed |
+ if (ret < 0 && releaseaddr)
|
|
|
6ae9ed |
+ virDomainUSBAddressRelease(priv->usbaddrs, &disk->info);
|
|
|
6ae9ed |
VIR_FREE(devstr);
|
|
|
6ae9ed |
VIR_FREE(drivestr);
|
|
|
6ae9ed |
virObjectUnref(cfg);
|
|
|
6ae9ed |
@@ -1486,6 +1495,12 @@ qemuDomainAttachChrDeviceAssignAddr(qemuDomainObjPrivatePtr priv,
|
|
|
6ae9ed |
return -1;
|
|
|
6ae9ed |
return 1;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+ } else if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
|
|
|
6ae9ed |
+ chr->targetType == VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB) {
|
|
|
6ae9ed |
+ if (virDomainUSBAddressEnsure(priv->usbaddrs, &chr->info) < 0)
|
|
|
6ae9ed |
+ return -1;
|
|
|
6ae9ed |
+ return 1;
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
} else if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
|
|
|
6ae9ed |
chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO) {
|
|
|
6ae9ed |
if (virDomainVirtioSerialAddrAutoAssign(NULL, priv->vioserialaddrs,
|
|
|
6ae9ed |
@@ -1804,11 +1819,18 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
|
|
|
6ae9ed |
{
|
|
|
6ae9ed |
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
6ae9ed |
char *devstr = NULL;
|
|
|
6ae9ed |
+ bool releaseaddr = false;
|
|
|
6ae9ed |
bool added = false;
|
|
|
6ae9ed |
bool teardowncgroup = false;
|
|
|
6ae9ed |
bool teardownlabel = false;
|
|
|
6ae9ed |
int ret = -1;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
+ if (priv->usbaddrs) {
|
|
|
6ae9ed |
+ if (virDomainUSBAddressEnsure(priv->usbaddrs, hostdev->info) < 0)
|
|
|
6ae9ed |
+ goto cleanup;
|
|
|
6ae9ed |
+ releaseaddr = true;
|
|
|
6ae9ed |
+ }
|
|
|
6ae9ed |
+
|
|
|
6ae9ed |
if (qemuHostdevPrepareUSBDevices(driver, vm->def->name, &hostdev, 1, 0) < 0)
|
|
|
6ae9ed |
goto cleanup;
|
|
|
6ae9ed |
|
|
|
6ae9ed |
@@ -1854,6 +1876,8 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
|
|
|
6ae9ed |
VIR_WARN("Unable to restore host device labelling on hotplug fail");
|
|
|
6ae9ed |
if (added)
|
|
|
6ae9ed |
qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev, 1);
|
|
|
6ae9ed |
+ if (releaseaddr)
|
|
|
6ae9ed |
+ virDomainUSBAddressRelease(priv->usbaddrs, hostdev->info);
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
VIR_FREE(devstr);
|
|
|
6ae9ed |
return ret;
|
|
|
6ae9ed |
@@ -2851,6 +2875,8 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
|
|
|
6ae9ed |
dev.type = VIR_DOMAIN_DEVICE_DISK;
|
|
|
6ae9ed |
dev.data.disk = disk;
|
|
|
6ae9ed |
ignore_value(qemuRemoveSharedDevice(driver, &dev, vm->def->name));
|
|
|
6ae9ed |
+ if (priv->usbaddrs)
|
|
|
6ae9ed |
+ virDomainUSBAddressRelease(priv->usbaddrs, &disk->info);
|
|
|
6ae9ed |
|
|
|
6ae9ed |
virDomainDiskDefFree(disk);
|
|
|
6ae9ed |
return 0;
|
|
|
6ae9ed |
@@ -2947,6 +2973,7 @@ qemuDomainRemoveUSBHostDevice(virQEMUDriverPtr driver,
|
|
|
6ae9ed |
virDomainHostdevDefPtr hostdev)
|
|
|
6ae9ed |
{
|
|
|
6ae9ed |
qemuHostdevReAttachUSBDevices(driver, vm->def->name, &hostdev, 1);
|
|
|
6ae9ed |
+ qemuDomainReleaseDeviceAddress(vm, hostdev->info, NULL);
|
|
|
6ae9ed |
}
|
|
|
6ae9ed |
|
|
|
6ae9ed |
static void
|
|
|
6ae9ed |
diff --git a/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base-live+disk-usb.xml b/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base-live+disk-usb.xml
|
|
|
6ae9ed |
index 41039a4..cd686e6 100644
|
|
|
6ae9ed |
--- a/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base-live+disk-usb.xml
|
|
|
6ae9ed |
+++ b/tests/qemuhotplugtestdata/qemuhotplug-hotplug-base-live+disk-usb.xml
|
|
|
6ae9ed |
@@ -27,6 +27,7 @@
|
|
|
6ae9ed |
<readonly/>
|
|
|
6ae9ed |
<shareable/>
|
|
|
6ae9ed |
<alias name='usb-disk16'/>
|
|
|
6ae9ed |
+ <address type='usb' bus='0' port='1'/>
|
|
|
6ae9ed |
</disk>
|
|
|
6ae9ed |
<controller type='usb' index='0'>
|
|
|
6ae9ed |
<alias name='usb'/>
|
|
|
6ae9ed |
--
|
|
|
6ae9ed |
2.9.2
|
|
|
6ae9ed |
|