[libvirt] [PATCH 6/6] Implement hotremove for SCSI disks

Wolfgang Mauerer wolfgang.mauerer at siemens.com
Mon Mar 1 14:29:20 UTC 2010


Daniel P. Berrange wrote:
> 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.

I haven't checked with the qemu source code (Gerd is CC'ed), but the
drive associated with a device seems to disappear when the device is
removed - the drive ID can be reused with a different backing
file after removing the device, and I suppose that's sufficient for
libvirt (or did I miss a use case?):

(Add controller, drive and device)

(qemu) device_add lsi,id=controller
(qemu) drive_add 0 if=none,file=test.img,id=drive0
OK
(qemu) info block
ide1-cd0: type=cdrom removable=1 locked=0 [not inserted]
floppy0: type=floppy removable=1 locked=0 [not inserted]
sd0: type=floppy removable=1 locked=0 [not inserted]
drive0: type=hd removable=0 file=test.img ro=0 drv=raw encrypted=0
(qemu) device_add driver=scsi-disk,drive=drive0,bus=controller.0,id=device0
###########
(Remove the device -> the associated drive disappears)

(qemu) device_del device0
(qemu) info block
ide1-cd0: type=cdrom removable=1 locked=0 [not inserted]
floppy0: type=floppy removable=1 locked=0 [not inserted]
sd0: type=floppy removable=1 locked=0 [not inserted]
###########
(Add a new drive with the same ID as before, but different
backing file)

(qemu) drive_add 0 if=none,file=test2.img,id=drive0
OK
(qemu) device_add driver=scsi-disk,drive=drive0,bus=controller.0,id=device0
(qemu) info block
ide1-cd0: type=cdrom removable=1 locked=0 [not inserted]
floppy0: type=floppy removable=1 locked=0 [not inserted]
sd0: type=floppy removable=1 locked=0 [not inserted]
drive0: type=hd removable=0 file=test2.img ro=0 drv=raw encrypted=0

Gerd: Are you intending to add the drive_del feature, or is
the approach outlined above sufficient for drive hotplug/remove?
Respectively can there be any problems if we remove a device
associated with a disk and then re-create a drive/device pair
with the same IDs as before, but with a different configuration?

Best regards,

Wolfgang
> 	
>> Signed-off-by: Wolfgang Mauerer <wolfgang.mauerer at siemens.com>
>> Signed-off-by: Jan Kiszka <jan.kiszka at 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




More information about the libvir-list mailing list