]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Implement startupPolicy for USB passed through devices
authorJiri Denemark <jdenemar@redhat.com>
Thu, 4 Oct 2012 14:18:16 +0000 (16:18 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Thu, 11 Oct 2012 13:11:42 +0000 (15:11 +0200)
src/qemu/qemu_cgroup.c
src/qemu/qemu_command.c
src/qemu/qemu_hostdev.c
src/qemu/qemu_hostdev.h
src/qemu/qemu_process.c

index 79faf8e165912f8fa6bf523305c01c1b2ae2030d..166f9b97b7845ecea680eecb209272548a864e6e 100644 (file)
@@ -289,6 +289,8 @@ int qemuSetupCgroup(struct qemud_driver *driver,
                 continue;
             if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
                 continue;
+            if (hostdev->missing)
+                continue;
 
             if ((usb = usbGetDevice(hostdev->source.subsys.u.usb.bus,
                                     hostdev->source.subsys.u.usb.device)) == NULL)
index 09f412e93d08587b76e48c5464cffbe8847fda16..d590df646b1545b11b2f399468af92b5e2361d8f 100644 (file)
@@ -3507,17 +3507,21 @@ qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev,
 {
     virBuffer buf = VIR_BUFFER_INITIALIZER;
 
-    if (!dev->source.subsys.u.usb.bus &&
+    if (!dev->missing &&
+        !dev->source.subsys.u.usb.bus &&
         !dev->source.subsys.u.usb.device) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("USB host device is missing bus/device information"));
         return NULL;
     }
 
-    virBufferAsprintf(&buf, "usb-host,hostbus=%d,hostaddr=%d,id=%s",
-                      dev->source.subsys.u.usb.bus,
-                      dev->source.subsys.u.usb.device,
-                      dev->info->alias);
+    virBufferAddLit(&buf, "usb-host");
+    if (!dev->missing) {
+        virBufferAsprintf(&buf, ",hostbus=%d,hostaddr=%d",
+                          dev->source.subsys.u.usb.bus,
+                          dev->source.subsys.u.usb.device);
+    }
+    virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
 
     if (qemuBuildDeviceAddressStr(&buf, dev->info, caps) < 0)
         goto error;
@@ -3577,6 +3581,12 @@ qemuBuildUSBHostdevUsbDevStr(virDomainHostdevDefPtr dev)
 {
     char *ret = NULL;
 
+    if (dev->missing) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("This QEMU doesn't not support missing USB devices"));
+        return NULL;
+    }
+
     if (!dev->source.subsys.u.usb.bus &&
         !dev->source.subsys.u.usb.device) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
index 32c858bd7c65ef628bb26d4786636727705b457a..90dfd28f9f3a8435ea894c8f49696fcc4eb08c62 100644 (file)
@@ -696,7 +696,8 @@ out:
 
 static int
 qemuPrepareHostUSBDevices(struct qemud_driver *driver,
-                          virDomainDefPtr def)
+                          virDomainDefPtr def,
+                          bool coldBoot)
 {
     int i, ret = -1;
     usbDeviceList *list;
@@ -716,6 +717,7 @@ qemuPrepareHostUSBDevices(struct qemud_driver *driver,
      */
     for (i = 0 ; i < nhostdevs ; i++) {
         virDomainHostdevDefPtr hostdev = hostdevs[i];
+        bool required = true;
         usbDevice *usb;
 
         if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
@@ -723,10 +725,15 @@ qemuPrepareHostUSBDevices(struct qemud_driver *driver,
         if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
             continue;
 
-        if (qemuFindHostdevUSBDevice(hostdev, true, &usb) < 0)
+        if (hostdev->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_OPTIONAL ||
+            (hostdev->startupPolicy == VIR_DOMAIN_STARTUP_POLICY_REQUISITE &&
+             !coldBoot))
+            required = false;
+
+        if (qemuFindHostdevUSBDevice(hostdev, required, &usb) < 0)
             goto cleanup;
 
-        if (usbDeviceListAdd(list, usb) < 0) {
+        if (usb && usbDeviceListAdd(list, usb) < 0) {
             usbFreeDevice(usb);
             goto cleanup;
         }
@@ -756,7 +763,8 @@ cleanup:
 }
 
 int qemuPrepareHostDevices(struct qemud_driver *driver,
-                           virDomainDefPtr def)
+                           virDomainDefPtr def,
+                           bool coldBoot)
 {
     if (!def->nhostdevs)
         return 0;
@@ -764,7 +772,7 @@ int qemuPrepareHostDevices(struct qemud_driver *driver,
     if (qemuPrepareHostPCIDevices(driver, def) < 0)
         return -1;
 
-    if (qemuPrepareHostUSBDevices(driver, def) < 0)
+    if (qemuPrepareHostUSBDevices(driver, def, coldBoot) < 0)
         return -1;
 
     return 0;
@@ -891,6 +899,8 @@ qemuDomainReAttachHostUsbDevices(struct qemud_driver *driver,
             continue;
         if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB)
             continue;
+        if (hostdev->missing)
+            continue;
 
         usb = usbGetDevice(hostdev->source.subsys.u.usb.bus,
                            hostdev->source.subsys.u.usb.device);
index 74dd2ce7d6d97a91630d086c0abe049a48594022..0da25f9f2117097099132b5526a078b7f536fdae 100644 (file)
@@ -43,7 +43,8 @@ int qemuPrepareHostdevUSBDevices(struct qemud_driver *driver,
                                  const char *name,
                                  usbDeviceList *list);
 int qemuPrepareHostDevices(struct qemud_driver *driver,
-                           virDomainDefPtr def);
+                           virDomainDefPtr def,
+                           bool coldBoot);
 void qemuReattachPciDevice(pciDevice *dev, struct qemud_driver *driver);
 void qemuDomainReAttachHostdevDevices(struct qemud_driver *driver,
                                       const char *name,
index 8c4bd9e74bb01f0824f5439e9a5c1148318ee0df..bc3e1482aa4fd1eac069522a1434519680934737 100644 (file)
@@ -3384,7 +3384,7 @@ int qemuProcessStart(virConnectPtr conn,
 
     /* Must be run before security labelling */
     VIR_DEBUG("Preparing host devices");
-    if (qemuPrepareHostDevices(driver, vm->def) < 0)
+    if (qemuPrepareHostDevices(driver, vm->def, !migrateFrom) < 0)
         goto cleanup;
 
     VIR_DEBUG("Preparing chr devices");