[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH]: file backed usb massstorage #4



On Fri, Aug 08, 2008 at 02:07:49PM +0200, Jim Meyering wrote:
> Guido Günther <agx sigxcpu org> wrote:
[..snip..] 
> > +static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDeviceDefPtr dev)
> > +{
> > +    struct qemud_driver *driver = (struct qemud_driver *)dom->conn->privateData;
> > +    virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid);
> 
> This should handle the case in which vm == NULL.
> Otherwise, qemudMonitorCommand will dereference NULL.
> ...
The function gets called from qemudDomainAttachDevice which does the
same call to virDomainFindbyUUid and checks for vm == NULL already but
you're right: better safe than sorry.

[..snip..] 
> Please add a newline and split the long line:
> 
>   /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi \
>     -boot c -hda /dev/HostVG/QEMUGuest1 -usbdevice disk:/tmp/usbdisk.img \
>     -net none -serial none -parallel none -usb
I'd rather not since this breaks the testcase, it compares the exact
output. 

New patches attached. Patches apply on top of the hostdev patches.
 -- Guido
>From 72df28ae2eb476d56c51963c660650a344265c76 Mon Sep 17 00:00:00 2001
From: Guido Guenther <agx sigxcpu org>
Date: Sun, 3 Aug 2008 01:07:00 +0200
Subject: [PATCH] usbmass: use files as usbdisks

works in QEMU/KVM
---
 src/domain_conf.c |    3 ++-
 src/domain_conf.h |    1 +
 src/qemu_conf.c   |   37 ++++++++++++++++++++++++++++++++++++-
 src/qemu_driver.c |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 85 insertions(+), 2 deletions(-)

diff --git a/src/domain_conf.c b/src/domain_conf.c
index 922cf76..237579f 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 46bb9f4..3b65b65 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,16 @@ int qemudBuildCommandLine(virConnectPtr conn,
             goto no_memory;                                             \
     } while (0)
 
+#define ADD_USBDISK(thisarg)                                            \
+    do {                                                                \
+        ADD_ARG_LIT("-usbdevice");                                      \
+        ADD_ARG_SPACE;                                                  \
+        if ((asprintf(&qargv[qargc++], "disk:%s", thisarg)) == -1) {    \
+            qargv[qargc-1] = NULL;                                      \
+            goto no_memory;                                             \
+        }                                                               \
+    } while (0)
+
     snprintf(memory, sizeof(memory), "%lu", vm->def->memory/1024);
     snprintf(vcpus, sizeof(vcpus), "%lu", vm->def->vcpus);
 
@@ -883,6 +894,18 @@ int qemudBuildCommandLine(virConnectPtr conn,
             int idx = virDiskNameToIndex(disk->dst);
             const char *bus = virDomainDiskQEMUBusTypeToString(disk->bus);
 
+            if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
+                if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
+                    ADD_USBDISK(disk->src);
+                } else {
+                    qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                                     _("unsupported usb disk type for '%s'"), disk->src);
+                    goto error;
+                } 
+                disk = disk->next;
+                continue;
+            }
+
             if (idx < 0) {
                 qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
                                  _("unsupported disk type '%s'"), disk->dst);
@@ -922,6 +945,18 @@ int qemudBuildCommandLine(virConnectPtr conn,
             char dev[NAME_MAX];
             char file[PATH_MAX];
 
+            if (disk->bus == VIR_DOMAIN_DISK_BUS_USB) {
+                if (disk->device == VIR_DOMAIN_DISK_DEVICE_DISK) {
+                    ADD_USBDISK(disk->src);
+                } else {
+                    qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                                     _("unsupported usb disk type for '%s'"), disk->src);
+                    goto error;
+                }
+                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 3c6d7c0..a432e79 100644
--- a/src/qemu_driver.c
+++ b/src/qemu_driver.c
@@ -2984,6 +2984,48 @@ 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;
+
+    if (!vm) {
+        qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN,
+                         "%s", _("no domain with matching uuid"));
+        return -1;
+    }
+
+    ret = asprintf(&cmd, "usb_add disk:%s", dev->data.disk->src);
+    if (ret == -1) {
+        qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL);
+        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;
@@ -3061,6 +3103,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

>From b17af0fdb9138acb28eae12803abf22257aef345 Mon Sep 17 00:00:00 2001
From: Guido Guenther <agx sigxcpu org>
Date: Thu, 7 Aug 2008 18:48:48 +0200
Subject: [PATCH] usbmass: allow usb as target dist type in libvirt.rng

---
 docs/libvirt.rng |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/docs/libvirt.rng b/docs/libvirt.rng
index 60e181f..81ec33b 100644
--- a/docs/libvirt.rng
+++ b/docs/libvirt.rng
@@ -412,6 +412,7 @@
              <value>virtio</value>
              <value>fdc</value>
              <value>xen</value>
+             <value>usb</value>
            </choice>
          </attribute>
       </optional>
-- 
1.5.6.3

>From e6dec1a63b5c7698ddffa68b9c39a50d80f75635 Mon Sep 17 00:00:00 2001
From: Guido Guenther <agx sigxcpu org>
Date: Thu, 7 Aug 2008 14:39:35 +0200
Subject: [PATCH] usbmass: testcase for file src

---
 tests/qemuxml2argvdata/qemuxml2argv-disk-usb.args |    1 +
 tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml  |   26 +++++++++++++++++++++
 tests/qemuxml2argvtest.c                          |    1 +
 tests/qemuxml2xmltest.c                           |    1 +
 4 files changed, 29 insertions(+), 0 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-usb.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml

diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.args
new file mode 100644
index 0000000..60a8317
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.args
@@ -0,0 +1 @@
+/usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor pty -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usbdevice disk:/tmp/usbdisk.img -net none -serial none -parallel none -usb
\ No newline at end of file
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml
new file mode 100644
index 0000000..d59e1c0
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml
@@ -0,0 +1,26 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+    </disk>
+    <disk type='file' device='disk'>
+      <source file='/tmp/usbdisk.img'/>
+      <target dev='sda' bus='usb'/>
+    </disk>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 458201b..757d804 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -156,6 +156,7 @@ mymain(int argc, char **argv)
             QEMUD_CMD_FLAG_DRIVE_BOOT);
     DO_TEST("disk-drive-boot-cdrom", QEMUD_CMD_FLAG_DRIVE |
             QEMUD_CMD_FLAG_DRIVE_BOOT);
+    DO_TEST("disk-usb", 0);
     DO_TEST("graphics-vnc", 0);
     DO_TEST("graphics-sdl", 0);
     DO_TEST("input-usbmouse", 0);
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 536c9bd..c810f78 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -95,6 +95,7 @@ mymain(int argc, char **argv)
     DO_TEST("disk-floppy");
     DO_TEST("disk-many");
     DO_TEST("disk-xenvbd");
+    DO_TEST("disk-usb");
     DO_TEST("graphics-vnc");
     DO_TEST("graphics-sdl");
     DO_TEST("input-usbmouse");
-- 
1.5.6.3


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]