[libvirt] [PATCH] Update domain xml after usb hotplug

The recently added usb hostdev and mass storage device hotplug code doesn't append the devices to the running guests xml if the hotplug succeeds. The attached patch fixes this. Thanks, Cole commit 8df17db8b36a2c1e8efa430a0493f66825b6b80e Author: Cole (Work Acct) <crobinso@localhost.localdomain> Date: Thu Aug 21 23:08:04 2008 -0400 Add hotplugged usb devices to running domain xml. diff --git a/src/domain_conf.c b/src/domain_conf.c index 3c61039..dc5eb0c 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 b98f7f3..cfa2a90 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 769f34f..9a26375 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" @@ -3044,6 +3045,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, @@ -3051,6 +3053,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); @@ -3059,7 +3083,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; } @@ -3070,11 +3094,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; @@ -3125,6 +3154,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; @@ -3167,7 +3201,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; }

On Thu, Aug 21, 2008 at 11:21:33PM -0400, Cole Robinson wrote:
The recently added usb hostdev and mass storage device hotplug code doesn't append the devices to the running guests xml if the hotplug succeeds. The attached patch fixes this.
Yes, completely forgot about this when reviewing it before. ACK Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Thu, Aug 21, 2008 at 11:21:33PM -0400, Cole Robinson wrote:
The recently added usb hostdev and mass storage device hotplug code doesn't append the devices to the running guests xml if the hotplug succeeds. The attached patch fixes this.
IIRC there was some question about whether it should actually do this. I think it should -- a user would expect that when you attach a device to a domain, the device should appear in the XML (and be persistent too). So I ACK this patch. This code pattern:
+ /* Find spot in domain definition where we will put the disk */ + ptr = vm->def->disks; + prev = &(vm->def->disks); + while (ptr) { ....
appears at least twice. What we need is a Set abstract type. Implementing it as a red-black self-balancing tree would avoid any unexpected surprises when someone's guest has 100s of devices attached. Rich. Ob-OCaml-hack. The Set type in OCaml, implemented as an RB-tree, comes with a formal proof of correctness which runs to 5000 lines and took two man-months to complete. Along the way they found bugs in the original implementation. -- Richard Jones, Emerging Technologies, Red Hat http://et.redhat.com/~rjones virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into Xen guests. http://et.redhat.com/~rjones/virt-p2v
participants (3)
-
Cole Robinson
-
Daniel P. Berrange
-
Richard W.M. Jones