diff --git a/ChangeLog b/ChangeLog index ce19e508f7..ae3e3aec21 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed Sep 3 10:57:00 EST 2008 Cole Robinson + + * src/domain_conf.c src/domain_conf.h src/qemu_driver.c: + Update domain xml after usb device hotplug. + Wed Sep 3 10:42:00 EST 2008 Cole Robinson * src/qemu_driver.c: scrape media eject output to determine failure @@ -9,6 +14,11 @@ Wed Sep 3 09:58:00 EST 2008 Cole Robinson * tests/xml2sexprdata/xml2sexpr-fv-v2.sexpr: fix for disk ordering * tests/xml2sexprdata/xml2sexpr-fv-vncunused.sexpr: fix for disk ordering +Wed Sep 3 14:51:03 CEST 2008 Daniel Veillard + + * src/qemu_driver.c: patch from Cole Robinson to avoid a segfault + on KVM CD eject + Wed Sep 3 14:37:06 CEST 2008 Daniel Veillard * src/virsh.c: patch from Cole Robinson to add output on attach diff --git a/src/domain_conf.c b/src/domain_conf.c index 3c61039350..dc5eb0cad4 100644 --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -481,8 +481,8 @@ void virDomainRemoveInactive(virDomainObjPtr *doms, } #ifndef PROXY -static int virDomainDiskCompare(virDomainDiskDefPtr a, - virDomainDiskDefPtr b) { +int virDomainDiskCompare(virDomainDiskDefPtr a, + virDomainDiskDefPtr b) { if (a->bus == b->bus) return virDiskNameToIndex(a->dst) - virDiskNameToIndex(b->dst); else diff --git a/src/domain_conf.h b/src/domain_conf.h index b98f7f34aa..cfa2a9033a 100644 --- a/src/domain_conf.h +++ b/src/domain_conf.h @@ -526,6 +526,8 @@ char *virDomainCpuSetFormat(virConnectPtr conn, char *cpuset, int maxcpu); +int virDomainDiskCompare(virDomainDiskDefPtr a, + virDomainDiskDefPtr b); int virDomainSaveConfig(virConnectPtr conn, const char *configDir, diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 649a0a5adb..295522b8f6 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -62,6 +62,7 @@ #include "capabilities.h" #include "memory.h" #include "uuid.h" +#include "domain_conf.h" /* For storing short-lived temporary files. */ #define TEMPDIR LOCAL_STATE_DIR "/cache/libvirt" @@ -3034,6 +3035,7 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi virDomainObjPtr vm = virDomainFindByUUID(driver->domains, dom->uuid); int ret; char *cmd, *reply; + virDomainDiskDefPtr *dest, *prev, ptr; if (!vm) { qemudReportError(dom->conn, dom, NULL, VIR_ERR_INVALID_DOMAIN, @@ -3041,6 +3043,28 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi return -1; } + /* Find spot in domain definition where we will put the disk */ + ptr = vm->def->disks; + prev = &(vm->def->disks); + while (ptr) { + if (STREQ(dev->data.disk->dst, ptr->dst)) { + qemudReportError(dom->conn, dom, NULL, VIR_ERR_INTERNAL_ERROR, + _("duplicate disk target '%s'"), + dev->data.disk->dst); + return -1; + } + if (virDomainDiskCompare(dev->data.disk, ptr) < 0) { + dest = &(ptr); + break; + } + prev = &(ptr->next); + ptr = ptr->next; + } + + if (!ptr) { + dest = prev; + } + ret = asprintf(&cmd, "usb_add disk:%s", dev->data.disk->src); if (ret == -1) { qemudReportError(dom->conn, NULL, NULL, VIR_ERR_NO_MEMORY, NULL); @@ -3049,7 +3073,7 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi if (qemudMonitorCommand(driver, vm, cmd, &reply) < 0) { qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, - "%s", _("cannot attach usb device")); + "%s", _("cannot attach usb disk")); VIR_FREE(cmd); return -1; } @@ -3060,11 +3084,16 @@ static int qemudDomainAttachUsbMassstorageDevice(virDomainPtr dom, virDomainDevi if (strstr(reply, "Could not add ")) { qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, "%s", - _("adding usb device failed")); + _("adding usb disk failed")); VIR_FREE(reply); VIR_FREE(cmd); return -1; } + + /* Actually update the xml */ + dev->data.disk->next = *dest; + *prev = dev->data.disk; + VIR_FREE(reply); VIR_FREE(cmd); return 0; @@ -3115,6 +3144,11 @@ static int qemudDomainAttachHostDevice(virDomainPtr dom, virDomainDeviceDefPtr d VIR_FREE(cmd); return -1; } + + /* Update xml */ + dev->data.hostdev->next = vm->def->hostdevs; + vm->def->hostdevs = dev->data.hostdev; + VIR_FREE(reply); VIR_FREE(cmd); return 0; @@ -3157,7 +3191,7 @@ static int qemudDomainAttachDevice(virDomainPtr dom, ret = qemudDomainAttachHostDevice(dom, dev); } else { qemudReportError(dom->conn, dom, NULL, VIR_ERR_NO_SUPPORT, - "%s", _("this devicetype cannot be attached")); + "%s", _("this device type cannot be attached")); ret = -1; }