[libvirt] [PATCH] qemu: Prevent detaching SCSI controller used by hostdev

John Ferlan jferlan at redhat.com
Tue Nov 29 19:29:45 UTC 2016


[...]

>>> If we attach/create a virtio-scsi hostdev device but forget to include
>>> a virtio-scsi controller, one is silently created for us.  (See
>>> qemuDomainFindOrCreateSCSIDiskController for context.)
>> So is this attach/create done to a guest with or without the above
>> controller?  Is the XML using a different controller (perhaps I'm
>> reading too much into the example ;-))
> 
> Haha, perhaps I tried to combine my example too much.  In the above
> paragraph, the controller tag is not present.
> 
>>
>>> Detaching the hostdev, followed by the controller, works well and the
>>> guest behaves appropriately.
>> OK I guess I'd expect that order to work.
>>
>>> If we detach the virtio-scsi controller device first, Libvirt silently
>>> detaches any associated hostdevs for us too.  But all is not well,
>>> as the guest is unable to receive new virtio-scsi devices (the attach
>>> commands succeed, but devices never appear within the guest), nor even
>>> be shutdown, after this point.
>> I think this is where you lost me...  Where does libvirt silently detach
>> the associated hostdevs?  qemuDomainDetachControllerDevice will detach
>> the controller for sure and qemuDomainRemoveHostDevice removes a
>> hostdev, but I'm not seeing the connection. What QEMU does is well
>> perhaps a different story!
> 
> Digging back through my notes...  You're right, this is a QEMU thing
> that I can recreate without libvirt.  So, bad wording in the commit
> message on my part.
> 

Given all this - can you just provide an updated commit message. I can
replace before pushing before the current release.

Tks -

John

>>
>>
>>> It appears that something is tied up in the host virtio layer.
>> But that wouldn't be the case with the patch, true? Not a very friendly
>> thing to do I suspect - remove a controller whilst some hostdev is still
>> using it...
> 
> Yup, very mean thing to do.
> 
>>
>>> While I investigate this, we can see if a controller is being used by
>>> any hostdevs, and prevent the detach if it would lead us down this path.
>> Shall I assume the following is your "disk" example?
> 
> Correct.  To tie the above XML into the files used below:
> 
> # cat scsicontroller.xml
>     <controller type='scsi' model='virtio-scsi' index='0'/>
> # cat scsidisk.xml
>     <hostdev mode='subsystem' type='scsi'>
>       <source>
>         <adapter name='scsi_host0'/>
>         <address bus='0' target='8' unit='1074151456'/>
>       </source>
>     </hostdev>
> 
> (I probably should've named the latter "scsihostdev.xml" but it's at
> least closer than some other scratch files I have.)
> 
>>
>>>    $ virsh detach-device guest_one_virtio_scsi scsicontroller.xml
>>>    error: Failed to detach device from scsicontroller.xml
>>>    error: operation failed: device cannot be detached: device is busy
>>>
>>>    $ virsh detach-device guest_one_virtio_scsi scsidisk.xml
>>>    Device detached successfully
>>>
>>>    $ virsh detach-device guest_one_virtio_scsi scsicontroller.xml
>>>    Device detached successfully
>>>
>>> Signed-off-by: Eric Farman <farman at linux.vnet.ibm.com>
>>> Reviewed-by: Bjoern Walk <bwalk at linux.vnet.ibm.com>
>>> Reviewed-by: Boris Fiuczynski <fiuczy at linux.vnet.ibm.com>
>>> ---
>>>   src/qemu/qemu_hotplug.c | 10 ++++++++++
>>>   1 file changed, 10 insertions(+)
>>>
>>> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
>>> index b03e618..5db7abf 100644
>>> --- a/src/qemu/qemu_hotplug.c
>>> +++ b/src/qemu/qemu_hotplug.c
>>> @@ -4443,6 +4443,7 @@ static bool
>>> qemuDomainDiskControllerIsBusy(virDomainObjPtr vm,
>>>   {
>>>       size_t i;
>>>       virDomainDiskDefPtr disk;
>>> +    virDomainHostdevDefPtr hostdev;
>>>         for (i = 0; i < vm->def->ndisks; i++) {
>>>           disk = vm->def->disks[i];
>>> @@ -4465,6 +4466,15 @@ static bool
>>> qemuDomainDiskControllerIsBusy(virDomainObjPtr vm,
>>>               return true;
>>>       }
>>>   +    for (i = 0; i < vm->def->nhostdevs; i++) {
>>> +        hostdev = vm->def->hostdevs[i];
>>> +        if (!virHostdevIsSCSIDevice(hostdev) ||
>>> +            detach->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI)
>>> +            continue;
>>> +        if (hostdev->info->addr.drive.controller == detach->idx)
>>> +            return true;
>>> +    }
>>> +
>> I certainly believe this should be added considering, but I want to make
>> sure I'm following the reasoning and order you've done the detach!
>>
>> Essentially you're trying to make sure there's no hostdev using the
>> controller before allowing it to be removed.
> 
> Yup, that's it in a nutshell.
> 
>>
>> I guess I'm just looking to clear up a few things in the commit message
>> before pushing...
>>
>> In particular, the bug being that libvirt will check *disks* using the
>> controller before allowing it to be detached/removed, but it doesn't
>> check *hostdevs* using the controller before allowing a controller
>> detach/remove to proceed.
> 
> Yup, exactly.
> 
> The patch I sent obviously focuses on SCSI hostdevs, because of the
> problem the guest then experiences.  I didn't give any consideration to
> PCI or USB hostdev's, and whether they should be protected from a
> similarly lazy/rude detach.  I honestly don't even know if the problem
> would exist in that configuration, or if it's tied up in virtio-scsi.
> 
>  - Eric
> 
>>
>> Thanks and great catch,
>>
>> John
>>>       return false;
>>>   }
>>>  
> 




More information about the libvir-list mailing list