+Fri Aug 8 16:53:24 CEST 2008 Daniel Veillard <veillard@redhat.com>
+
+ * src/domain_conf.c src/domain_conf.h src/qemu_conf.c
+ src/qemu_driver.c: patch from Guido Günther allowing to add
+ disk as USB devices
+ * docs/libvirt.rng: extend the schemas for the new value
+ * tests/qemuxml2argvdata/qemuxml2argv-disk-usb.args
+ tests/qemuxml2argvdata/qemuxml2argv-disk-usb.xml
+ tests/qemuxml2argvtest.c tests/qemuxml2xmltest.c: add a specific
+ test to the regression suite
+
Fri Aug 8 16:15:55 CEST 2008 Daniel Veillard <veillard@redhat.com>
* src/domain_conf.c src/domain_conf.h src/qemu_conf.c
<value>virtio</value>
<value>fdc</value>
<value>xen</value>
+ <value>usb</value>
</choice>
</attribute>
</optional>
"fdc",
"scsi",
"virtio",
- "xen")
+ "xen",
+ "usb")
VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST,
"mount",
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
};
"floppy",
"scsi",
"virtio",
- "xen")
+ "xen",
+ "usb")
#define qemudLog(level, msg...) fprintf(stderr, msg)
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);
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);
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) {
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;
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) {
--- /dev/null
+/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
--- /dev/null
+<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>
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);
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");