Bug 1576916

Summary: Detach device with partial XML that includes an alias
Product: Red Hat Enterprise Linux 7 Reporter: Arik <ahadas>
Component: libvirtAssignee: Michal Privoznik <mprivozn>
Status: CLOSED ERRATA QA Contact: jiyan <jiyan>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 7.5CC: dyuan, fjin, jiyan, lcheng, mprivozn, mzamazal, xuzhang, yalzhang
Target Milestone: rcKeywords: Upstream
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: libvirt-4.4.0-1.el7 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2018-10-30 09:55:31 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Arik 2018-05-10 17:35:39 UTC
Currently, the API of detach-device is too cumbersome to use by clients because it requires the client to provide a full XML specification of the device to be detached.

This requires clients to either (1) be able to reproduce exactly the same part of the device in the domain XML that was generated when starting the VM; or (2) cache the domain XML that was generated when starting the VM and extracting the device part from it.

It would be much simpler for clients to provide a partial XML that includes the device alias, which is supposed to be unique, for example:
<disk type='file' device='disk' snapshot='no'>
  <alias name='scsi0-0-0-2'/>
</disk>

The correlation between the provided XML and the device should be trivial to do on the libvirt side.

Comment 2 Michal Privoznik 2018-05-11 13:06:41 UTC
Problem with this approach is that not all drivers (as in hypervisors) have notion of aliases, for instance ESX doesn't. Also, inactive domains do not necessarily have aliases assigned. But I think if we document the limitations well this should be feasible.

Comment 3 Michal Privoznik 2018-05-21 16:10:59 UTC
Patches proposed upstream:

https://www.redhat.com/archives/libvir-list/2018-May/msg01530.html

After all, this will be a new API for couple of reasons:
1) it is easier to detect if libvirt supports detach via alias,
2) it is easier to implement because I don't have to care about compatibility with older libvirt versions,
3) it is not bending over the existing API.

Comment 5 Michal Privoznik 2018-05-28 11:45:38 UTC
Pushed upstream:

b29fa23ea9 news: Document new API introduction
150d0930f8 qemu: Implement virDomainDetachDeviceAlias
5c81c342a7 qemu_hotplug: Allow asynchronous detach
a7837f92cc qemuDomainDetachDeviceLiveAndConfig: Avoid overwriting @ret
604f3ff0c0 qemuDomainDetachDeviceLiveAndConfig: Don't use driver->caps directly
e73f6b4d66 qemu_hotplug: Use more gotos in qemuDomainDetach*Device
ee87e5de36 qemuDomainDetachWatchdog: Don't release watchdog address twice
c2fa7e7ffc qemuDomainDetachShmemDevice: Don't release shmem address twice
aac088d998 qemuDomainRemoveChrDevice: Release device address
856fb16492 virsh: Expose virDomainDetachDeviceAlias
18f2e9d500 remote: Implement virDomainDetachDeviceAlias
007f500a23 Introduce virDomainDetachDeviceAlias API

v4.3.0-334-gb29fa23ea9

Comment 7 jiyan 2018-06-19 02:43:30 UTC
Hi, Michal. Could you please give explanations to the following verifying scenarios? Thank you. :)

1> Since 'virsh detach-device-alias' has been supported in '4.4.0'. I think alias cen be the unique symbol to operate device. which means '<device-name> <alias/> </device-name>' is enough in XML file to detach a device. However, the following S1-1 and S1-2 does not act in this way.

2> In the following S2, even alias is different in XML file and Dumpxml, detaching operation can succeed, I do not think that behavior is as expected.

Version:
libvirt-4.4.0-2.el7.x86_64
qemu-kvm-rhev-2.12.0-3.el7.x86_64
kernel-3.10.0-906.el7.x86_64

S1-1: Detaching disk with partial XML that includes an alias does not work. 'source' and 'target' are needed.
# virsh domstate test1
shut off

# virsh start test1
Domain test1 started

# virsh dumpxml test1 |grep "<disk" -A8
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/bug.qcow2'/> **bootable img**
      <backingStore/>
      <target dev='sda' bus='scsi'/>
      <boot order='1'/>
      <alias name='ua-fb00b3f4-ec4b-4f39-95e8-04b78b405572'/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/attach.img'/>
      <backingStore/>
      <target dev='vdb' bus='virtio'/>
      <alias name='ua-1111b3f4-ec4b-4f39-95e8-04b78b405573'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
    </disk>

# cat disk-verify.xml 
<disk type='file' device='disk'>
<alias name='ua-1111b3f4-ec4b-4f39-95e8-04b78b405573'/>
</disk>

# virsh detach-device test1 disk-verify.xml 
error: Failed to detach device from disk-verify.xml
error: missing source information for device

# cat disk-verify.xml 
<disk type='file' device='disk'>
<source file='/var/lib/libvirt/images/attach.img'/>
<alias name='ua-1111b3f4-ec4b-4f39-95e8-04b78b405573'/>
</disk>

# virsh detach-device test1 disk-verify.xml 
error: Failed to detach device from disk-verify.xml
error: missing target information for device /var/lib/libvirt/images/attach.img

# cat disk-verify.xml 
<disk type='file' device='disk'>
<source file='/var/lib/libvirt/images/attach.img'/>
<alias name='ua-1111b3f4-ec4b-4f39-95e8-04b78b405573'/>
<target dev='vdb' bus='virtio'/>
</disk>

# virsh detach-device test1 disk-verify.xml 
Device detached successfully

# virsh dumpxml test1 |grep "<disk" -A8
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/bug.qcow2'/>
      <backingStore/>
      <target dev='sda' bus='scsi'/>
      <boot order='1'/>
      <alias name='ua-fb00b3f4-ec4b-4f39-95e8-04b78b405572'/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>

S1-2: Detach disk through 'virsh detach-device-alias'
# virsh domstate test1
shut off

# virsh start test1
Domain test1 started

# virsh dumpxml test1 |grep "<disk" -A8
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/bug.qcow2'/> **bootable img**
      <backingStore/>
      <target dev='sda' bus='scsi'/>
      <boot order='1'/>
      <alias name='ua-fb00b3f4-ec4b-4f39-95e8-04b78b405572'/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/attach.img'/>
      <backingStore/>
      <target dev='vdb' bus='virtio'/>
      <alias name='ua-1111b3f4-ec4b-4f39-95e8-04b78b405573'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
    </disk>
    <controller type='usb' index='0' model='nec-xhci' ports='15'>

# virsh detach-device-alias test1 ua-1111b3f4-ec4b-4f39-95e8-04b78b405573
Device detach request sent successfully

# virsh dumpxml test1 |grep "<disk" -A8
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/bug.qcow2'/>
      <backingStore/>
      <target dev='sda' bus='scsi'/>
      <boot order='1'/>
      <alias name='ua-fb00b3f4-ec4b-4f39-95e8-04b78b405572'/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>

According to S1-1 and S1-2, since detaching disk can succeed through 'detach-device-alias' in S1-2, maybe 'source' and 'target' in S1-1 should be not necessary for detaching.

S2: Detaching watchdog with different alias and same address in XML file can succeed. 
# virsh domstate test1
shut off

# virsh start test1
Domain test1 started

# virsh dumpxml test1 |grep "<watchdog" -A3
    <watchdog model='i6300esb' action='reset'>
      <alias name='ua-11111111-1111-1111-1111-111111111111'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/>
    </watchdog>

# cat watchdog-verify,xml 
    <watchdog model='i6300esb' action='reset'>
      <alias name='ua-22222222-2222-2222-2222-222222222222'/> ****
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0b' function='0x0'/>
    </watchdog>

# virsh detach-device test1 watchdog-verify,xml 
Device detached successfully

# virsh dumpxml test1 |grep "<watchdog" -A3
No output

In S2, alias is unique for device, so detaching operation in that scenario should not succeed.

Comment 8 Fangge Jin 2018-06-19 02:54:22 UTC
Hi jiyan

See comment 3, detach-device-alias is a new API, it doesn't affect existing APIs. So the above behiviors are expected.

Comment 9 Michal Privoznik 2018-06-19 04:36:51 UTC
(In reply to jiyan from comment #7)
> Hi, Michal. Could you please give explanations to the following verifying
> scenarios? Thank you. :)
> 

As Frangge says, there's new API which users are supposed to use when they want to detach using just an alias. The old APIs are not affected by this.

Comment 10 jiyan 2018-06-19 07:55:45 UTC
Version:
libvirt-4.4.0-2.el7.x86_64
qemu-kvm-rhev-2.12.0-3.el7.x86_64
kernel-3.10.0-906.el7.x86_64

There are the following bugs may block some scenarios.
Bug 1586027 - virsh detach-device-alias --config does not work
Bug 1591561 - libvirtd crash when detach serial device using 'virsh detach-device-alias --config'

Senarios:
S0: cmd help
# virsh detach-device-alias --help
  NAME
    detach-device-alias - detach device from an alias

  SYNOPSIS
    detach-device-alias <domain> <alias> [--config] [--live] [--current]

  DESCRIPTION
    Detach device identified by the given alias from a domain

  OPTIONS
    [--domain] <string>  domain name, id or uuid
    [--alias] <string>  device alias
    --config         affect next boot
    --live           affect running domain
    --current        affect current domain

S1: Detach disk
# virsh domstate test1
running

# virsh dumpxml test1 |grep "<disk" -A10
    <disk type='block' device='disk'>
      <driver name='qemu' type='raw'/>
      <source dev='/dev/sdc'/>
      <backingStore/>
      <target dev='vdb' bus='virtio'/>
      <alias name='ua-1111b3f4-ec4b-4f39-95e8-04b78b405573'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
    </disk>

# virsh domblklist test1
Target     Source
------------------------------------------------
sda        /var/lib/libvirt/images/bug.qcow2
vdb        /dev/sdc

# virsh detach-device-alias test1 ua-1111b3f4-ec4b-4f39-95e8-04b78b405573
Device detach request sent successfully

# virsh domblklist test1
Target     Source
------------------------------------------------
sda        /var/lib/libvirt/images/bug.qcow2


S2: Detach interface
# virsh domstate test1
running

# virsh dumpxml test1 |grep "<inter" -A7
    <interface type='network'>
      <mac address='52:54:00:cd:20:18'/>
      <source network='default' bridge='virbr0'/>
      <target dev='vnet0'/>
      <model type='rtl8139'/>
      <alias name='ua-fb00b3f4-ec4b-4f39-95e8-04b78b405573'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>

# virsh domiflist test1
Interface  Type       Source     Model       MAC
-------------------------------------------------------
vnet0      network    default    rtl8139     52:54:00:cd:20:18

# virsh detach-device-alias test1 ua-fb00b3f4-ec4b-4f39-95e8-04b78b405573
Device detach request sent successfully

# virsh domiflist test1
Interface  Type       Source     Model       MAC
-------------------------------------------------------


S3: Detach hostdev
# virsh domstate test1
running

# virsh dumpxml test1 |grep "<hostdev" -A10
    <hostdev mode='subsystem' type='usb' managed='no'>
      <source startupPolicy='optional' missing='yes'>
        <vendor id='0x1234'/>
        <product id='0xbeef'/>
      </source>
      <boot order='2'/>
      <alias name='ua-fb00b3f4-ec4b-4f39-95e8-04b78b4055720'/>
      <address type='usb' bus='0' port='1.1'/>
    </hostdev>

# virsh detach-device-alias test1 ua-fb00b3f4-ec4b-4f39-95e8-04b78b4055720
Device detach request sent successfully

# virsh dumpxml test1 |grep "<hostdev" -A10
No output


S4: Detach scsi controller
# virsh domstate test1
running

# virsh dumpxml test1 |grep "<controller" -A10
    <controller type='scsi' index='0' model='virtio-scsi'>
      <driver iothread='4'/>
      <alias name='ua-1b00b3f4-5678-4f39-95e8-04b78b405572'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </controller>

# virsh detach-device-alias test1 ua-1b00b3f4-5678-4f39-95e8-04b78b405572
Device detach request sent successfully

# virsh dumpxml test1 |grep "<controller" -A10
No output


S5: Detach redirected device
# virsh dumpxml test1 |grep "<redir" -A8
    <redirdev bus='usb' type='spicevmc'>
      <alias name='ua-fb00b3f4-ec4b-4f39-95e8-04b78b4055711'/>
      <address type='usb' bus='0' port='1.3'/>
    </redirdev>

# virsh detach-device-alias test1 ua-fb00b3f4-ec4b-4f39-95e8-04b78b4055711
Device detach request sent successfully

# virsh dumpxml test1 |grep "<redir" -A8
No output


S6: Detach channel devices
# virsh domstate test1
running

# virsh dumpxml test1 |grep "<channel"
    <channel type='spicevmc'>
      <target type='virtio' name='com.redhat.spice.0' state='disconnected'/>
      <alias name='ua-fb00b3f4-ec4b-4f39-95e8-04b78b405576'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>

# virsh detach-device-alias test1 ua-fb00b3f4-ec4b-4f39-95e8-04b78b405576
Device detach request sent successfully

# virsh dumpxml test1 |grep "<channel"
No output


S7: Detach rng device
# virsh domstate test1
running

# virsh dumpxml test1 |grep "<rng"
    <rng model='virtio'>
      <rate bytes='1234' period='2000'/>
      <backend model='random'>/dev/random</backend>
      <alias name='ua-fb00b3f4-ec4b-4f39-95e8-04b78b4055715'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0c' function='0x0'/>
    </rng>

# virsh detach-device-alias test1 ua-fb00b3f4-ec4b-4f39-95e8-04b78b4055715
Device detach request sent successfully

# virsh dumpxml test1 |grep "<rng" -A10
No output


S8: Detach mem
# virsh domstate test1
running

# virsh dumpxml test1 |grep "<mem"
    <memory model='dimm' discard='yes'>
      <target>
        <size unit='KiB'>2048</size>
        <node>0</node>
      </target>
      <alias name='ua-3b00b3f4-ec4b-4f39-95e8-04b78b4055713'/>
      <address type='dimm' slot='0' base='0x100000000'/>
    </memory>

# virsh detach-device-alias test1 ua-3b00b3f4-ec4b-4f39-95e8-04b78b4055713
Device detach request sent successfully

# virsh dumpxml test1 |grep "<mem"
No output

All the results are as expected, move this bug to be verified.

Comment 11 jiyan 2018-06-19 08:25:58 UTC
Tested the 8 scenarios for alias generated by libvirt, all succeed.
For example:
# virsh domstate test1
running

# virsh dumpxml test1 |grep "<disk" -A10
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/bug.qcow2'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <alias name='virtio-disk0'/>   ****
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
    </disk>
    <disk type='block' device='disk'>
      <driver name='qemu' type='raw'/>
      <source dev='/dev/sdc'/>
      <backingStore/>
      <target dev='vdb' bus='virtio'/>
      <alias name='virtio-disk1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0d' function='0x0'/>
    </disk>
    <controller type='pci' index='0' model='pci-root'>
      <alias name='pci.0'/>
    </controller>

# virsh detach-device-alias test1 virtio-disk1
Device detach request sent successfully

# virsh dumpxml test1 |grep "<disk" -A10
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/bug.qcow2'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
    </disk>
    <controller type='pci' index='0' model='pci-root'>
      <alias name='pci.0'/>

Comment 13 errata-xmlrpc 2018-10-30 09:55:31 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHSA-2018:3113