On Fri, Feb 26, 2010 at 02:09:19PM +0100, Wolfgang Mauerer wrote:
Recent qemu versions allow us to add disks dynamically into the
system
via the drive_add/device_add mechanism. Removing them is now just a
matter of using device_del, and this patch adds the required bits
and pieces to libvirt.
There's one minor issue here, in that this removes the guest device,
but does not remove the host side QEMU block driver state. We're
still waiting for the 'drive_del' command to be implemented todo the
latter bit.
Signed-off-by: Wolfgang Mauerer <wolfgang.mauerer(a)siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka(a)siemens.com>
---
src/qemu/qemu_driver.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 57 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index d683b1c..ecbb23d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5494,6 +5494,60 @@ qemuDomainFindOrCreateSCSIDiskController(struct qemud_driver
*driver,
}
+static int qemudDomainDetachSCSIDisk(struct qemud_driver *driver,
+ virDomainObjPtr vm,
+ virDomainDeviceDefPtr dev,
+ unsigned int qemuCmdFlags)
+{
+ int i;
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ virDomainDiskDefPtr detach = NULL;
+
+ if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) {
+ return -1;
+ }
+
+ for (i = 0 ; i < vm->def->ndisks ; i++) {
+ if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) {
+ detach = vm->def->disks[i];
+ break;
+ }
+ }
+
+ if (!detach) {
+ qemuReportError(VIR_ERR_OPERATION_FAILED,
+ _("disk %s not found"), dev->data.disk->dst);
+ return -1;
+ }
+
+ qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ /* Note: drive_del does not exist, but device_del will
+ automatically erase the associated drive as well */
Are you sure about that ? I was under the impression that
device_del would leave the drive dangling unused.
+ if (qemuMonitorDelDevice(priv->mon, detach->info.alias))
{
+ qemuDomainObjExitMonitor(vm);
+ return -1;
+ }
+ qemuDomainObjExitMonitorWithDriver(driver, vm);
+
+ if (vm->def->ndisks > 1) {
+ memmove(vm->def->disks + i,
+ vm->def->disks + i + 1,
+ sizeof(*vm->def->disks) *
+ (vm->def->ndisks - (i + 1)));
+ vm->def->ndisks--;
+ if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks) < 0) {
+ /* ignore, harmless */
+ }
+ } else {
+ VIR_FREE(vm->def->disks);
+ vm->def->ndisks = 0;
+ }
+ virDomainDiskDefFree(detach);
+
+ return 0;
+}
+
+
static int qemudDomainAttachSCSIDisk(struct qemud_driver *driver,
virDomainObjPtr vm,
virDomainDiskDefPtr disk,
@@ -6563,6 +6617,9 @@ static int qemudDomainDetachDevice(virDomainPtr dom,
dev->data.disk->device == VIR_DOMAIN_DISK_DEVICE_DISK &&
dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) {
ret = qemudDomainDetachPciDiskDevice(driver, vm, dev);
+ } else if(dev->type == VIR_DOMAIN_DEVICE_DISK &&
+ dev->data.disk->bus == VIR_DOMAIN_DISK_BUS_SCSI) {
+ ret = qemudDomainDetachSCSIDisk(driver, vm, dev, qemuCmdFlags);
} else if (dev->type == VIR_DOMAIN_DEVICE_NET) {
ret = qemudDomainDetachNetDevice(driver, vm, dev);
} else if (dev->type == VIR_DOMAIN_DEVICE_CONTROLLER) {
Regards,
Daniel
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://deltacloud.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|