Hi,
attached is a second version of the usb massstorage patch:

Changes are:
* use sd* dummy dev names instead of usbdisk
* move the check for the "subtype" (hard disk/cdrom/...) into the driver

An example is:

<disk type='file' device='disk'>
     <target dev="sda" bus='usb'/>
     <source file='/foo/bar/usbmass.img'/>
</disk>

Patch is on top of the hostdev passthrough patch.
Cheers,
 -- Guido
[PATCH] usbdisk file support #2

---
 src/domain_conf.c |    3 ++-
 src/domain_conf.h |    1 +
 src/qemu_conf.c   |   24 +++++++++++++++++++++++-
 src/qemu_driver.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/src/domain_conf.c b/src/domain_conf.c
index ab2ee9f..0c704d6 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -84,7 +84,8 @@ VIR_ENUM_IMPL(virDomainDiskBus, VIR_DOMAIN_DISK_BUS_LAST,
               "fdc",
               "scsi",
               "virtio",
-              "xen")
+              "xen",
+              "usb")
 
 VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST,
               "mount",
diff --git a/src/domain_conf.h b/src/domain_conf.h
index 8a9d1db..9e7c524 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -72,6 +72,7 @@ enum virDomainDiskBus {
     VIR_DOMAIN_DISK_BUS_SCSI,
     VIR_DOMAIN_DISK_BUS_VIRTIO,
     VIR_DOMAIN_DISK_BUS_XEN,
+    VIR_DOMAIN_DISK_BUS_USB,
 
     VIR_DOMAIN_DISK_BUS_LAST
 };
diff --git a/src/qemu_conf.c b/src/qemu_conf.c
index 73039c5..331ff9d 100644
--- a/src/qemu_conf.c
+++ b/src/qemu_conf.c
@@ -55,7 +55,8 @@ VIR_ENUM_IMPL(virDomainDiskQEMUBus, VIR_DOMAIN_DISK_BUS_LAST,
               "floppy",
               "scsi",
               "virtio",
-              "xen")
+              "xen",
+              "usb")
 
 
 #define qemudLog(level, msg...) fprintf(stderr, msg)
@@ -772,6 +773,13 @@ int qemudBuildCommandLine(virConnectPtr conn,
             goto no_memory;                                             \
     } while (0)
 
+#define ADD_USBDISK(thisarg)                                            \
+    do {                                                                \
+        ADD_ARG_LIT("-usbdevice");                                      \
+        if ((asprintf(&qargv[qargc++], "disk:%s", thisarg)) == -1)      \
+            goto no_memory;                                             \
+    } while (0)
+
     snprintf(memory, sizeof(memory), "%lu", vm->def->memory/1024);
     snprintf(vcpus, sizeof(vcpus), "%lu", vm->def->vcpus);
 
@@ -883,6 +891,13 @@ int qemudBuildCommandLine(virConnectPtr conn,
             int idx = virDiskNameToIndex(disk->dst);
             const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
 
+            if (disk->bus == VIR_DOMAIN_DISK_BUS_USB &&
+                disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
+                ADD_USBDISK(disk->src);
+                disk = disk->next;
+                continue;
+            }
+
             if (idx < 0) {
                 qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                                  _("unsupported disk type '%s'"), disk->dst);
@@ -922,6 +937,13 @@ int qemudBuildCommandLine(virConnectPtr conn,
             char dev[NAME_MAX];
             char file[PATH_MAX];
 
+            if (disk->bus == VIR_DOMAIN_DISK_BUS_USB &&
+                disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
+                ADD_USBDISK(disk->src);
+                disk = disk->next;
+                continue;
+            }
+
             if (STREQ(disk->dst, "hdc") &&
                 disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
                 if (disk->src) {
diff --git a/src/qemu_driver.c b/src/qemu_driver.c
index 1aff53e..018046e 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -2978,6 +2978,44 @@ static int qemudDomainAttachCdromDevice(virDomainPtr dom,
     return 0;
 }
 
+static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDeviceDefPtr dev)
+{
+    struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
+    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
+    int ret;
+    char *cmd, *reply;
+
+    ret = asprintf(&cmd, "usb_add disk:%s", dev->data.disk->src);
+
+    if (ret == -1) {
+        qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+                         "%s", _("out of memory"));
+        return ret;
+    }
+
+    if (qemudMonitorCommand(driver, vm, cmd, &reply) < 0) {
+        qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+                         "%s", _("cannot attach usb device"));
+        VIR_FREE(cmd);
+        return -1;
+    }
+
+    DEBUG ("attach_usb reply: %s", reply);
+    /* If the command failed qemu prints:
+     * Could not add ... */
+    if (strstr(reply, "Could not add ")) {
+        qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
+                          "%s",
+                          _("adding usb device failed"));
+        VIR_FREE(reply);
+        VIR_FREE(cmd);
+        return -1;
+    }
+    VIR_FREE(reply);
+    VIR_FREE(cmd);
+    return 0;
+}
+
 static int qemudDomainAttachHostDevice(virDomainPtr dom, virDomainDeviceDefPtr dev)
 {
     struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
@@ -3050,6 +3088,10 @@ static int qemudDomainAttachDevice(virDomainPtr dom,
     if (dev->type == VIR_DOMAIN_DEVICE_DISK &&
         dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) {
 		ret = qemudDomainAttachCdromDevice(dom, dev);
+    } else if (dev->type == VIR_DOMAIN_DEVICE_DISK &&
+        dev->data.disk->device == VIR_DOMAIN_DEVICE_DISK &&
+        dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
+		ret = qemudDomainAttachUsbMassstorageDevice(dom, dev);
     } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
         dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
         dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
-- 
1.5.6.3

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to