Bug 1166024

Summary: do change-media --eject to a network cdrom will make guest disappear after restart libvirtd
Product: Red Hat Enterprise Linux 7 Reporter: Luyao Huang <lhuang>
Component: libvirtAssignee: Peter Krempa <pkrempa>
Status: CLOSED ERRATA QA Contact: Virtualization Bugs <virt-bugs>
Severity: medium Docs Contact:
Priority: medium    
Version: 7.1CC: dyuan, mzhan, pkrempa, rbalakri, xuzhang, yanyang
Target Milestone: rc   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: libvirt-1.2.14-1.el7 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-11-19 05:56:35 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 Luyao Huang 2014-11-20 09:55:19 UTC
description of problem:
do change-media --eject to a network cdrom will make guest disappear after restart libvirtd

Version-Release number of selected component (if applicable):
libvirt-1.2.8-7.el7.x86_64


How reproducible:
100%

Steps to Reproduce:

1.prepare a guest xml with :
# virsh list --all
 Id    Name                           State
----------------------------------------------------
 -     r6                             shut off

# virsh dumpxml r6
    <disk type='network' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <source protocol='gluster' name='gluster-vol1/rh6.img'>
        <host name='10.66.106.2'/>
      </source>
      <target dev='vdc' bus='virtio'/>
      <readonly/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
    </disk>

2.# virsh change-media r6 vdc --eject --config
succeeded to complete action eject on media

3.libvirt will set a invaild config
# virsh dumpxml r6
 <disk type='network' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <source protocol='gluster' name='gluster-vol1(null)'>
        <host name='10.66.106.2'/>
      </source>
      <target dev='vdc' bus='virtio'/>
      <readonly/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
    </disk>

4.restart libvirtd
# service libvirtd restart
Redirecting to /bin/systemctl restart  libvirtd.service


# virsh list --all
 Id    Name                           State
----------------------------------------------------


Actual results:
guest will disappear after libvirtd resatrt

Expected results:
report error when use change-media to a network cdrom

Additional info:

if do this command again will get error

[root@localhost qemu]# virsh change-media r7 vdc --eject --config
error: Failed to complete action eject on media
error: XML error: missing volume name or file name in gluster source
path 'gluster-vol1(null)'

and can get log from libvirtd.log:

2014-11-20 09:54:38.989+0000: 16792: error : virDomainDiskSourceParse:5348 : XML error: missing volume name or file name in gluster source path 'gluster-vol1(null)'

Comment 2 Peter Krempa 2015-03-17 16:17:06 UTC
Fixed upstream:

commit 7a8f54bf4c59a27c4ae0dd5a2c2eadd093c107ad
Author: Peter Krempa <pkrempa>
Date:   Thu Mar 12 17:33:09 2015 +0100

    conf: disk: Simplify checking if source definition was parsed
    
    Previously we had to check for 3 fields to see if the source was filled.
    Repurpose one of the variables as a boolean flag and use it instead of
    combining multiple sources.
    
    For the condition that checks that only CDROM/FLOPPY drives can be empty
    we can use the virStorageSourceIsEmpty() helper.

commit 158340e2fbab9a49013ee0de59af7236da014622
Author: Peter Krempa <pkrempa>
Date:   Thu Mar 12 17:53:01 2015 +0100

    util: storage: Fix check for empty storage device
    
    If the storage device type is parsed as network our parser still allows
    it to omit the <source> element. The empty drive check would not trigger
    on such device as it expects that every network storage source is valid.
    
    Use VIR_STORAGE_NET_PROTOCOL_NONE as a marker that the storage source is
    empty.

commit d0dc6c036914da4905c3f483be3036014a38fe9b
Author: Peter Krempa <pkrempa>
Date:   Thu Mar 12 17:12:12 2015 +0100

    qemu: driver: Fix cold-update of removable storage devices
    
    Only selected fields from the disk source were copied when cold updating
    source in a CDROM drive. When such drive was backed by a network file
    this resulted into corruption of the definition:
    
        <disk type='network' device='cdrom'>
          <driver name='qemu' type='raw' cache='none'/>
          <source protocol='gluster' name='gluster-vol1(null)'>
            <host name='localhost'/>
          </source>
          <target dev='vdc' bus='virtio'/>
          <readonly/>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
        </disk>
    
    Update the whole source instead of cherry-picking elements.
    
    Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1166024

commit e7974b4f80f320c9232ff31762fd1aa82a590f2e
Author: Peter Krempa <pkrempa>
Date:   Thu Mar 12 16:57:56 2015 +0100

    qemu: hotplug: Use checker function to check if disk is empty

commit f4b5f53027da4fed2250628e11bac40191803a15
Author: Peter Krempa <pkrempa>
Date:   Thu Mar 12 16:41:21 2015 +0100

    virsh: domain: Fix the change-media command
    
    The command did not modify the disk type and thus didn't allow to change
    media from a file image to a block backed image or vice versa. In
    addition when operating on a network backed removable devices the
    command would replace the while <source> subelement with an invalid one.
    
    This patch adds the --block option that allows to specify that the new
    image is block backed and assumes that without that option all images
    are file backed. Since network backends were always mangled it should
    not cause problems.

commit 4cbcaffb74c1f59734eb7379cd8165922345ec13
Author: Peter Krempa <pkrempa>
Date:   Thu Mar 12 16:04:00 2015 +0100

    virsh: domain: Add --print-xml flag for command change-media
    
    Allow printing the XML that would be used mostly for debugging purposes.

commit 1cc820937ac64d75d1a4ce090af7a928e30a7728
Author: Peter Krempa <pkrempa>
Date:   Thu Mar 12 11:51:51 2015 +0100

    virsh: domain: Don't use vshPrepareDiskXML for creating XML to detach disk
    
    Since cmdDetachDisk() calls into vshPrepareDiskXML() with
    type == VSH_PREPARE_DISK_XML_NONE && source == NULL this would result
    into skipping all the checks and effectively turn the function into a
    XML formatter.
    
    This patch changes the code to use the formatter directly so that the

Comment 4 Yang Yang 2015-06-05 10:35:47 UTC
Hi Peter,

change-media with option update always throw the following error out
# virsh change-media simple hda --update
error: New disk media source was not specified

However, as described in manual page, source is optional when specifying update. 

           If the
           device has source (e.g. <source file='media'>), and source is not
           specified, --update is equal to --eject.

So is it a regression issue?

Comment 5 Peter Krempa 2015-06-09 06:45:18 UTC
For a cdrom with media:
$ virsh dumpxml srcd | xmllint --xpath //disk - ; echo
<disk type="file" device="cdrom">
      <driver name="qemu" type="raw" cache="none"/>
      <source file="/var/lib/libvirt/images/systemrescuecd-x86-4.3.0.iso"/>
      <target dev="hdc" bus="ide"/>
      <readonly/>
      <address type="drive" controller="0" bus="1" target="0" unit="0"/>
    </disk>

$ tools/virsh change-media srcd hdc --eject --print-xml
<disk type="file" device="cdrom">
      <driver name="qemu" type="raw" cache="none"/>
      
      <target dev="hdc" bus="ide"/>
      <readonly/>
      <address type="drive" controller="0" bus="1" target="0" unit="0"/>
    </disk>
$ tools/virsh change-media srcd hdc --print-xml --update
<disk type="file" device="cdrom">
      <driver name="qemu" type="raw" cache="none"/>
      
      <target dev="hdc" bus="ide"/>
      <readonly/>
      <address type="drive" controller="0" bus="1" target="0" unit="0"/>
    </disk>

For an empty cdrom:
$ virsh dumpxml srcd-empty | xmllint --xpath //disk - ; echo
<disk type="file" device="cdrom">
      <driver name="qemu" type="raw" cache="none"/>
      <target dev="hdc" bus="ide"/>
      <readonly/>
      <address type="drive" controller="0" bus="1" target="0" unit="0"/>
    </disk>

$ tools/virsh change-media srcd-empty hdc --eject --print-xml
error: The disk device 'hdc' doesn't have media

$ tools/virsh change-media srcd-empty hdc --print-xml --update
error: No source is specified for updating media

Both --eject and --update without the source specified behave consistently when used on empty or full cdroms (except for a different error message, which makes sense though) so we fulfill the expectations set with the documentation so this is not a regression.

Comment 6 Peter Krempa 2015-06-09 07:06:02 UTC
Actually I was testing this on a bad version of libvirt:

This is the current behavior:

$ tools/virsh change-media srcd hdc --print-xml --update
error: New disk media source was not specified

So yes, this is a regression.

Comment 7 Yang Yang 2015-06-10 03:04:55 UTC
Verified on libvirt-1.2.16-1.el7.x86_64

Steps as following:
prepare a running guest with following xml
 <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1.qcow2'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </disk>
    <disk type='network' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <source protocol='gluster' name='gluster-vol1/aaa.iso'>
        <host name='10.66.4.164'/>
      </source>
      <backingStore/>
      <target dev='hda' bus='ide'/>
      <readonly/>
      <alias name='ide0-0-0'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>

1. eject
--eject --print-xml
# virsh change-media simple hda --eject --print-xml
<disk type="file" device="cdrom">
      <driver name="qemu" type="raw" cache="none"/>
      
      <backingStore/>
      <target dev="hda" bus="ide"/>
      <readonly/>
      <alias name="ide0-0-0"/>
      <address type="drive" controller="0" bus="0" target="0" unit="0"/>
    </disk>

--eject
# virsh change-media simple hda --eject
error: Failed to complete action eject on media
error: internal error: unable to execute QEMU command 'eject': Device 'drive-ide0-0-0' is locked

# virsh change-media simple hda --eject
Successfully ejected media.

#virsh dumpxml simple | grep disk -a6
<disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1.qcow2'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <backingStore/>
      <target dev='hda' bus='ide' tray='open'/>
      <readonly/>
      <alias name='ide0-0-0'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>

--eject --config --print-xml
# virsh change-media simple hda --eject --print-xml --config
<disk type="file" device="cdrom">
      <driver name="qemu" type="raw" cache="none"/>
      
      <target dev="hda" bus="ide"/>
      <readonly/>
      <address type="drive" controller="0" bus="0" target="0" unit="0"/>
    </disk>


--eject --config
# virsh change-media simple hda --eject --config
Successfully ejected media.

# virsh dumpxml simple | grep disk -a6
<disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1.qcow2'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </disk>
    <disk type='network' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <source protocol='gluster' name='gluster-vol1/aaa.iso'>
        <host name='10.66.4.164'/>
      </source>
      <backingStore/>
      <target dev='hda' bus='ide'/>
      <readonly/>
      <alias name='ide0-0-0'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>

# virsh dumpxml simple --inactive| grep disk -a6
<disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <target dev='hda' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>

--eject --live --print-xml
# virsh change-media simple hda --eject --live --print-xml
<disk type="file" device="cdrom">
      <driver name="qemu" type="raw" cache="none"/>
      
      <backingStore/>
      <target dev="hda" bus="ide"/>
      <readonly/>
      <alias name="ide0-0-0"/>
      <address type="drive" controller="0" bus="0" target="0" unit="0"/>
    </disk>

# virsh change-media simple hda --eject --live
error: Failed to complete action eject on media
error: internal error: unable to execute QEMU command 'eject': Device 'drive-ide0-0-0' is locked

#virsh dumpxml simple | grep disk -a6
<disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1.qcow2'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </disk>
    <disk type='network' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <source protocol='gluster' name='gluster-vol1/aaa.iso'>
        <host name='10.66.4.164'/>
      </source>
      <backingStore/>
      <target dev='hda' bus='ide' tray='open'/>
      <readonly/>
      <alias name='ide0-0-0'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>

# virsh change-media simple hda --eject --live
Successfully ejected media.

#virsh dumpxml simple | grep disk -a6
<disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1.qcow2'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <backingStore/>
      <target dev='hda' bus='ide' tray='open'/>
      <readonly/>
      <alias name='ide0-0-0'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>


--eject --current --print-xml
# virsh change-media simple hda --eject --current --print-xml
<disk type="file" device="cdrom">
      <driver name="qemu" type="raw" cache="none"/>
      
      <backingStore/>
      <target dev="hda" bus="ide"/>
      <readonly/>
      <alias name="ide0-0-0"/>
      <address type="drive" controller="0" bus="0" target="0" unit="0"/>
    </disk>

# virsh change-media simple hda --eject --current
error: Failed to complete action eject on media
error: internal error: unable to execute QEMU command 'eject': Device 'drive-ide0-0-0' is locked

# virsh dumpxml simple | grep disk -a6
<disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1.qcow2'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </disk>
    <disk type='network' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <source protocol='gluster' name='gluster-vol1/aaa.iso'>
        <host name='10.66.4.164'/>
      </source>
      <backingStore/>
      <target dev='hda' bus='ide' tray='open'/>
      <readonly/>
      <alias name='ide0-0-0'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>

# virsh change-media simple hda --eject --current
Successfully ejected media.

#virsh dumpxml simple | grep disk -a6
<disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1.qcow2'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <backingStore/>
      <target dev='hda' bus='ide' tray='open'/>
      <readonly/>
      <alias name='ide0-0-0'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>


--eject --force --print-xml
# virsh change-media simple hda --eject --force --print-xml
<disk type="file" device="cdrom">
      <driver name="qemu" type="raw" cache="none"/>
      
      <backingStore/>
      <target dev="hda" bus="ide"/>
      <readonly/>
      <alias name="ide0-0-0"/>
      <address type="drive" controller="0" bus="0" target="0" unit="0"/>
    </disk>

# virsh change-media simple hda --eject --force
Successfully ejected media.

# virsh dumpxml simple | grep disk -a6
<disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1.qcow2'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <backingStore/>
      <target dev='hda' bus='ide' tray='open'/>
      <readonly/>
      <alias name='ide0-0-0'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>

# virsh change-media simple hda --eject --live --config --print-xml
<disk type="file" device="cdrom">
      <driver name="qemu" type="raw" cache="none"/>
      
      <target dev="hda" bus="ide"/>
      <readonly/>
      <address type="drive" controller="0" bus="0" target="0" unit="0"/>
    </disk>

# virsh change-media simple hda --eject --live --config
error: Failed to complete action eject on media
error: internal error: unable to execute QEMU command 'eject': Device 'drive-ide0-0-0' is locked
# virsh dumpxml simple | grep disk -a6
<disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1.qcow2'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </disk>
    <disk type='network' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <source protocol='gluster' name='gluster-vol1/aaa.iso'>
        <host name='10.66.4.164'/>
      </source>
      <backingStore/>
      <target dev='hda' bus='ide' tray='open'/>
      <readonly/>
      <alias name='ide0-0-0'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>

# virsh change-media simple hda --eject --live --config
Successfully ejected media.
# virsh dumpxml simple | grep disk -a6
<disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1.qcow2'/>
      <backingStore/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <backingStore/>
      <target dev='hda' bus='ide' tray='open'/>
      <readonly/>
      <alias name='ide0-0-0'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>

# virsh dumpxml simple --inactive| grep disk -a6
<disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      <source file='/var/lib/libvirt/images/vm1.qcow2'/>
      <target dev='vda' bus='virtio'/>
      <boot order='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw' cache='none'/>
      <target dev='hda' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>

# virsh change-media simple hda --eject --live --config --force --print-xml
<disk type="file" device="cdrom">
      <driver name="qemu" type="raw" cache="none"/>
      
      <target dev="hda" bus="ide"/>
      <readonly/>
      <address type="drive" controller="0" bus="0" target="0" unit="0"/>
    </disk>

negative test
# virsh change-media simple hda --eject --live --config --force --print-xml --block
error: Options --eject and --block are mutually exclusive

# virsh change-media simple hda --eject --live --config --current --print-xml
error: Options --current and --live are mutually exclusive

# virsh change-media simple hda --update /var/lib/libvirt/images/bbb.iso --print-xml --live --current
error: Options --current and --live are mutually exclusive

# virsh change-media simple hda --update /var/lib/libvirt/images/bbb.iso --print-xml --config --current
error: Options --current and --config are mutually exclusive

Also tested option insert and update, both work well except a regression bz 1229592

Move it to verified status.

Comment 9 errata-xmlrpc 2015-11-19 05:56:35 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://rhn.redhat.com/errata/RHBA-2015-2202.html