Bug 1195461 - Disk type=block converted to disk type=file after block copy
Summary: Disk type=block converted to disk type=file after block copy
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: libvirt
Version: 7.1
Hardware: Unspecified
OS: Linux
urgent
urgent
Target Milestone: rc
: ---
Assignee: Peter Krempa
QA Contact: Virtualization Bugs
URL:
Whiteboard:
Depends On:
Blocks: 1035038 1082754 1133060 1195848 1196066 1198128
TreeView+ depends on / blocked
 
Reported: 2015-02-23 21:28 UTC by Nir Soffer
Modified: 2015-11-19 06:15 UTC (History)
32 users (show)

Fixed In Version: libvirt-1.2.13-1.el7
Doc Type: Bug Fix
Doc Text:
The block copy operation has previously been adjusted to change the disk type of the copied disk to "file". However, using block copy for moving block-based storage thus converted the new target to an incorrect type. Consequently, if a virtual disk was backed by a block device rather than a file, libvirt did not report the allocation information necessary to track a thin-provisioned volume. This update introduces a libvirt flag that makes it possible to specify that the target will be treated as a block device. As a result, users can now perform a block copy to a block target correctly.
Clone Of: 1176673
: 1195848 1196066 (view as bug list)
Environment:
Last Closed: 2015-11-19 06:15:52 UTC
Target Upstream Version:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2015:2202 0 normal SHIPPED_LIVE libvirt bug fix and enhancement update 2015-11-19 08:17:58 UTC

Comment 1 Peter Krempa 2015-02-24 10:45:20 UTC
The "regression" was caused by libvirt's mishandling of the disk type when doing a block copy operation.

Previously libvirt didn't change the type of the disk when a copy job was finished thus a _TYPE_BLOCK disk remained _TYPE_BLOCK. This would have other implications for example when doing a copy from _TYPE_BLOCK to _TYPE_FILE or the other way around. The type would be incorrect. RHEV though never changed the type in this case and thus the _TYPE_BLOCK -> _TYPE_BLOCK would actually work for them.

In 7.1 though we started refactoring the block operations code base as it was a total mess and we needed to make it future-proof to allow copy operations of networked storage and others which require changing of the stored disk type. 

In commit:

commit 7b7bf001108b03c3b8983ca922f0e7727953910f
Author: Eric Blake <eblake@redhat.com>
Date:   Wed May 21 14:22:21 2014 -0600

    conf: store mirroring information in virStorageSource

the code was changed to store the disk type in the mirroring information although the type was incorrectly initialized to:

+    /* XXX Allow non-file mirror destinations */
+    mirror->type = VIR_STORAGE_TYPE_FILE;

as the assumption was that only file targets are supported.

Later on it became apparent that this is not entirely true and that _TYPE_BLOCK destinations are necessary too. This was achieved by:

commit b7e73585a8d96677695a52bafb156f26cbd48fb5
Author: Eric Blake <eblake@redhat.com>
Date:   Wed Aug 27 22:03:04 2014 -0600

    blockcopy: allow block device destination


That introduces a new flag VIR_DOMAIN_BLOCK_REBASE_COPY_DEV for the virDomainBlockRebase API that forces the type to be _TYPE_BLOCK for a copy job.

Unfortunately this was not backported to the 7.1 code base as we didn't backport any of the changes for the new block copy API.

In my opinion the correct approach will be to backport the libvirt patch to allow block destination and RHEV start to use the flag when appropriate.

Comment 8 Yang Yang 2015-05-18 03:09:17 UTC
Verified with libvirt-1.2.13-1.el7.x86_64
Test matrix
|before blockcopy 	  	               |after blockcopy|
|disk type|device type|blockcopy with blockdev?|disk type|device type|comment|
|file|disk| |file|disk| |
|file|disk|--blockdev|block|disk| | 
|block|disk| |file|disk| |
|block|disk|--blockdev|block|disk| | 	 
|block|lun| |--|--|BZ1209802, currently disk type is changed to file after blockcopy, but expected result is that blockcopy job should be disallowed|
|block|lun|--blockdev|block|lun| | 	 
|network|disk| |file|disk| |
|network|disk|--blockdev|block|disk| | 	 
|network|lun| |--|--|BZ1209802, currently disk type is changed to file after blockcopy, but expected result is that blockcopy job should be disallowed| 
|network|lun|--blockdev|block|lun| | 	 
|volume|disk| |file|disk| | 	 
|volume|disk|--blockdev|block|disk| | 	 

steps:
1. Prepare 3 lv

#lvs

LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert
vol1 HostVG wi-ao--- 200.00m
vol2 HostVG wi-ao--- 200.00m
vol3 HostVG wi-ao--- 200.00m

2. format vol3 to qcow2

#qemu-img create -f qcow2 /dev/HostVG/vol3 200M
Formatting '/dev/HostVG/vol3', fmt=qcow2 size=209715200 encryption=off cluster_size=65536 lazy_refcounts=off

#qemu-img info /dev/HostVG/vol3


image: /dev/HostVG/vol3
file format: qcow2
virtual size: 200M (209715200 bytes)
disk size: 0
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
corrupt: false

3. Prepare a transient vm with following xml

<disk type='block' device='disk'>
<driver name='qemu' type='qcow2'/>
<source dev='/dev/HostVG/vol2'/>
<backingStore/>
<target dev='vda' bus='virtio'/>
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
</disk>

4. do blockcopy with option blockdev, the destination is qcow2 format

# virsh blockcopy vm5 vda --blockdev /dev/HostVG/vol3
Block Copy started 

# virsh blockjob vm5 vda --info
Block Copy: [100 %]

#virsh dumpxml vm5 | grep disk -a10

<disk type='block' device='disk'>
<driver name='qemu' type='qcow2'/>
<source dev='/dev/HostVG/vol2'/>
<backingStore type='block' index='1'>
<format type='qcow2'/>
<source dev='/dev/HostVG/../HostVG/vol1'/>
<backingStore/>
</backingStore>
<mirror type='block' job='copy' ready='yes'>
<format type='qcow2'/>
<source dev='/dev/HostVG/vol3'/>
</mirror>
<target dev='vda' bus='virtio'/>
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
</disk>

pivot

#virsh blockjob vm5 vda --pivot

# virsh dumpxml vm5 | grep disk -a6

<disk type='block' device='disk'>
<driver name='qemu' type='qcow2'/>
<source dev='/dev/HostVG/vol3'/>
<backingStore/>
<target dev='vda' bus='virtio'/>
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
</disk>

#qemu-img info /dev/HostVG/vol3
image: /dev/HostVG/vol3
file format: qcow2
virtual size: 200M (209715200 bytes)
disk size: 0
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
corrupt: false

5. clean env

create a backing chain

#cd /dev/HostVG

#qemu-img rebase -f qcow2 -u -b ../HostVG/vol1 -F qcow2 vol2

repeat step 3

do blockcopy with option blockdev and reuse-external

#virsh blockcopy vm5 vda --blockdev --reuse-external /dev/HostVG/vol3 --shallow
Block Copy started
# virsh blockjob vm5 vda --info
BZ 1202704

#virsh dumpxml vm5 | grep disk -a6
<disk type='block' device='disk'>
<driver name='qemu' type='qcow2'/>
<source dev='/dev/HostVG/vol2'/>
<backingStore type='block' index='1'>
<format type='qcow2'/>
<source dev='/dev/HostVG/../HostVG/vol1'/>
<backingStore/>
</backingStore>
<mirror type='block' job='copy' ready='yes'>
<format type='qcow2'/>
<source dev='/dev/HostVG/vol3'/>
</mirror>
<target dev='vda' bus='virtio'/>
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
</disk>

After pivot

#virsh blockjob vm5 vda --pivot

#virsh dumpxml vm5 | grep disk -a10
<disk type='block' device='disk'>
<driver name='qemu' type='qcow2'/>
<source dev='/dev/HostVG/vol3'/>
<backingStore/>
<target dev='vda' bus='virtio'/>
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
</disk>

#qemu-img info /dev/HostVG/vol3

image: /dev/HostVG/vol3
file format: qcow2
virtual size: 200M (209715200 bytes)
disk size: 0
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
corrupt: false

6. clean env

create a backing chain

#cd /dev/HostVG

#qemu-img rebase -f qcow2 -u -b ../HostVG/vol1 -F qcow2 vol2

repeat step 3

do blockcopy with option blockdev, shallow and pivot

#virsh blockcopy vm5 vda --blockdev /dev/HostVG/vol3 --shallow --pivot
Successfully pivoted
# virsh dumpxml vm5 | grep disk -a6
<disk type='block' device='disk'>
<driver name='qemu' type='qcow2'/>
<source dev='/dev/HostVG/vol3'/>
<backingStore type='block' index='1'>
<format type='qcow2'/>
<source dev='/dev/HostVG/../HostVG/vol1'/>
<backingStore/>
</backingStore>
<target dev='vda' bus='virtio'/>
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
</disk>

Comment 10 errata-xmlrpc 2015-11-19 06:15:52 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


Note You need to log in before you can comment on or make changes to this bug.