Bug 1062142
Summary: | live snapshot merge (commit) of the active layer | |||
---|---|---|---|---|
Product: | Red Hat Enterprise Linux 7 | Reporter: | Peter Krempa <pkrempa> | |
Component: | libvirt | Assignee: | Eric Blake <eblake> | |
Status: | CLOSED ERRATA | QA Contact: | Virtualization Bugs <virt-bugs> | |
Severity: | unspecified | Docs Contact: | ||
Priority: | unspecified | |||
Version: | 7.0 | CC: | alitke, areis, bmcclain, bsarathy, dyuan, eblake, famz, iheim, jdenemar, juzhang, kchamart, knoel, mzhan, rbalakri, scohen, sdenham, sgordon, sherold, shu, shyu, virt-maint, xuzhang, yanyang | |
Target Milestone: | rc | Flags: | scohen:
needinfo+
scohen: needinfo+ scohen: needinfo+ |
|
Target Release: | --- | |||
Hardware: | Unspecified | |||
OS: | Unspecified | |||
Whiteboard: | ||||
Fixed In Version: | libvirt-1.2.8-1.el7 | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | ||
Clone Of: | 1041301 | |||
: | 1148201 (view as bug list) | Environment: | ||
Last Closed: | 2015-03-05 07:29:44 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: | ||||
Bug Depends On: | 1041301, 1130603 | |||
Bug Blocks: | 647386, 784395, 837916, 1002699, 1035038, 1045196, 1148201, 1150379, 1196199 |
Description
Peter Krempa
2014-02-06 10:04:08 UTC
blockjob-commit from the active layer requires us to terminate the job with "block-job-complete" after it finishes to pivot from the actual active image +++ b/qapi-schema.json @@ -1967,9 +1967,11 @@ # # @top: The file name of the backing image within the image chain, # which contains the topmost data to be committed down. -# Note, the active layer as 'top' is currently unsupported. # # If top == base, that is an error. +# If top == active, the job will not be completed by itself, +# user needs to complete the job with the block-job-complete +# command after getting the ready event. (Since 1.8) # A minor fix to the blockjob commit handling function is needed along with adding the termination step: commit 5d2691cc4c0b8d64440b072c93f157f641c37a72 Author: Peter Krempa <pkrempa> Date: Wed Feb 5 18:40:39 2014 +0100 qemu: blockjob: Print correct file name in error message When attempting a blockcommit from the top layer, the base argument passed is NULL. This will be dereferenced when attempting a commit with an empty image chain. Output the real volume path instead: virsh blockcommit --verbose --path vda --domain DOMNAME --wait error: invalid argument: top '/path/somefile' in chain for 'vda' has no backing file instead of: error: invalid argument: top '(null)' in chain for 'vda' has no backing file I've confirmed that qemu will support active layer commit in 7.0, and will get libvirt working with it as soon as I get a chance Reproduced on kernel: 3.10.0-95.el7.x86_64 libvirt-1.1.1-24.el7.x86_64 Steps: 1. Define and start a domain # virsh dumpxml qtest1 <domain type='kvm' id='15'> <name>qtest1</name> <uuid>9b76e092-3941-4e36-abf9-ed6817b467dd</uuid> <memory unit='KiB'>1048576</memory> <currentMemory unit='KiB'>1048576</currentMemory> <vcpu placement='static'>1</vcpu> <resource> <partition>/machine</partition> </resource> <os> <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type> <boot dev='hd'/> </os> <features> <acpi/> <apic/> <pae/> </features> <clock offset='utc'/> <on_poweroff>destroy</on_poweroff> <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> <devices> <emulator>/usr/libexec/qemu-kvm</emulator> <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/migration/qtest1.img'> <seclabel model='selinux' relabel='yes'/> </source> <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/> </disk> <controller type='virtio-serial' index='0'> <alias name='virtio-serial0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </controller> <controller type='usb' index='0'> <alias name='usb0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> </controller> <controller type='pci' index='0' model='pci-root'> <alias name='pci.0'/> </controller> <interface type='network'> <mac address='52:54:00:99:fe:f0'/> <source network='default'/> <target dev='vnet1'/> <model type='virtio'/> <alias name='net0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> </interface> <serial type='pty'> <source path='/dev/pts/3'/> <target port='0'/> <alias name='serial0'/> </serial> <console type='pty' tty='/dev/pts/3'> <source path='/dev/pts/3'/> <target type='serial' port='0'/> <alias name='serial0'/> </console> <channel type='spicevmc'> <target type='virtio' name='com.redhat.spice.0'/> <alias name='channel0'/> <address type='virtio-serial' controller='0' bus='0' port='1'/> </channel> <input type='tablet' bus='usb'> <alias name='input0'/> </input> <input type='mouse' bus='ps2'/> <graphics type='spice' port='5901' autoport='yes' listen='127.0.0.1'> <listen type='address' address='127.0.0.1'/> </graphics> <sound model='ich6'> <alias name='sound0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> </sound> <video> <model type='qxl' ram='65536' vram='65536' heads='1'/> <alias name='video0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/> </video> <memballoon model='virtio'> <alias name='balloon0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/> </memballoon> </devices> <seclabel type='dynamic' model='selinux' relabel='yes'> <label>system_u:system_r:svirt_t:s0:c361,c495</label> <imagelabel>system_u:object_r:svirt_image_t:s0:c361,c495</imagelabel> </seclabel> </domain> 2. Create 3 snapshots # virsh snapshot-create-as qtest1 Domain snapshot 1393410436 created #virsh snapshot-create-as qtest1 Domain snapshot 1393410489 created #virsh snapshot-create-as qtest1 Domain snapshot 1393410593 created 3. Check the snapshot list # virsh snapshot-list qtest1 1393410436 1393410489 1393410593 4. Do live commit # virsh blockcommit qtest1 vda 1393410436 1393410593 error: invalid argument: top '(null)' in chain for 'vda' has no backing file (In reply to yangyang from comment #4) Updated the steps > Reproduced on > kernel: 3.10.0-95.el7.x86_64 > libvirt-1.1.1-24.el7.x86_64 > > Steps: > 1. Define and start a domain > > # virsh dumpxml qtest1 > > <domain type='kvm' id='15'> > <name>qtest1</name> > <uuid>9b76e092-3941-4e36-abf9-ed6817b467dd</uuid> > <memory unit='KiB'>1048576</memory> > <currentMemory unit='KiB'>1048576</currentMemory> > <vcpu placement='static'>1</vcpu> > <resource> > <partition>/machine</partition> > </resource> > <os> > <type arch='x86_64' machine='pc-i440fx-rhel7.0.0'>hvm</type> > <boot dev='hd'/> > </os> > <features> > <acpi/> > <apic/> > <pae/> > </features> > <clock offset='utc'/> > <on_poweroff>destroy</on_poweroff> > <on_reboot>restart</on_reboot> > <on_crash>restart</on_crash> > <devices> > <emulator>/usr/libexec/qemu-kvm</emulator> > <disk type='file' device='disk'> > <driver name='qemu' type='qcow2' cache='none'/> > <source file='/migration/qtest1.img'> > <seclabel model='selinux' relabel='yes'/> > </source> > <target dev='vda' bus='virtio'/> > <alias name='virtio-disk0'/> > <address type='pci' domain='0x0000' bus='0x00' slot='0x06' > function='0x0'/> > </disk> > <controller type='virtio-serial' index='0'> > <alias name='virtio-serial0'/> > <address type='pci' domain='0x0000' bus='0x00' slot='0x05' > function='0x0'/> > </controller> > <controller type='usb' index='0'> > <alias name='usb0'/> > <address type='pci' domain='0x0000' bus='0x00' slot='0x01' > function='0x2'/> > </controller> > <controller type='pci' index='0' model='pci-root'> > <alias name='pci.0'/> > </controller> > <interface type='network'> > <mac address='52:54:00:99:fe:f0'/> > <source network='default'/> > <target dev='vnet1'/> > <model type='virtio'/> > <alias name='net0'/> > <address type='pci' domain='0x0000' bus='0x00' slot='0x03' > function='0x0'/> > </interface> > <serial type='pty'> > <source path='/dev/pts/3'/> > <target port='0'/> > <alias name='serial0'/> > </serial> > <console type='pty' tty='/dev/pts/3'> > <source path='/dev/pts/3'/> > <target type='serial' port='0'/> > <alias name='serial0'/> > </console> > <channel type='spicevmc'> > <target type='virtio' name='com.redhat.spice.0'/> > <alias name='channel0'/> > <address type='virtio-serial' controller='0' bus='0' port='1'/> > </channel> > <input type='tablet' bus='usb'> > <alias name='input0'/> > </input> > <input type='mouse' bus='ps2'/> > <graphics type='spice' port='5901' autoport='yes' listen='127.0.0.1'> > <listen type='address' address='127.0.0.1'/> > </graphics> > <sound model='ich6'> > <alias name='sound0'/> > <address type='pci' domain='0x0000' bus='0x00' slot='0x04' > function='0x0'/> > </sound> > <video> > <model type='qxl' ram='65536' vram='65536' heads='1'/> > <alias name='video0'/> > <address type='pci' domain='0x0000' bus='0x00' slot='0x02' > function='0x0'/> > </video> > <memballoon model='virtio'> > <alias name='balloon0'/> > <address type='pci' domain='0x0000' bus='0x00' slot='0x07' > function='0x0'/> > </memballoon> > </devices> > <seclabel type='dynamic' model='selinux' relabel='yes'> > <label>system_u:system_r:svirt_t:s0:c361,c495</label> > <imagelabel>system_u:object_r:svirt_image_t:s0:c361,c495</imagelabel> > </seclabel> > </domain> > 2. Create 3 external snapshots # cat snapshot1.xml <domainsnapshot> <description>Snapshot of OS install and updates</description> <disks> <disk name='/migration/qtest1.img'> <source file='/migaration/qtest1-1.img'/> </disk> </disks> </domainsnapshot> # virsh snapshot-create qtest1 --disk-only snapshot1.xml # cat snapshot2.xml <domainsnapshot> <description>Snapshot of OS install and updates</description> <disks> <disk name='/migration/qtest1-1.img'> <source file='/migaration/qtest1-2.img'/> </disk> </disks> </domainsnapshot> #virsh snapshot-create qtest1 --disk-only snapshot2.xml #cat snapshot3.xml <domainsnapshot> <description>Snapshot of OS install and updates</description> <disks> <disk name='/migration/qtest1-2.img'> <source file='/migaration/qtest1-3.img'/> </disk> </disks> </domainsnapshot> #virsh snapshot-create qtest1 --disk-only snapshot3.xml 3. # virsh blockcommit qtest1 --verbose --path vda --top /migration/qtest1-3.img --base /migration/qtest1-1.img --wait Block Commit: [100 %] The job cannot be terminated when it finished. Hi Eric, In order for a management application to provide feedback to a user regarding which image files can be merged we will need a way to check whether virDomainBlockCommit supports an active layer merge (@top == active layer). Do you have any thoughts on how this should be exposed via the libvirt API? (In reply to Adam Litke from comment #9) > Hi Eric, > > In order for a management application to provide feedback to a user > regarding which image files can be merged we will need a way to check > whether virDomainBlockCommit supports an active layer merge (@top == active > layer). Do you have any thoughts on how this should be exposed via the > libvirt API? Oddly enough, I do! https://www.redhat.com/archives/libvir-list/2014-May/msg00564.html I'm in the middle of patches to blockcommit so that attempts to commit the active layer will fail unless you specify a new flag, and where the new flag fails if qemu is too old to support an active merge. I'm on track to have the patches upstream for 1.2.5. I will probably also export a capability marker for whether qemu supports live commits, similar to what was done here: commit 85a3eb8a6d44e4501c00c9aeed0039ccaf29cdc5 Author: Francesco Romani <fromani> Date: Mon Mar 17 16:19:44 2014 +0100 qemu: export disk snapshot support in capabilities This patch adds an element to QEMU's capability XML, to show if the underlying QEMU binary supports the live disk snapshotting or not. This allows any client to know ahead of time if the feature is available. Without this information available, the only way to check for the snapshot support is to request one and check for errors. Signed-off-by: Francesco Romani <fromani> Thanks Eric. This should work well for us. Hi Eric, Would you be willing to commit to having the capability marker you mentioned in comment 11? If so, can we agree on the exact name so I can begin to check for it in vdsm? Capability XML proposal at: https://www.redhat.com/archives/libvir-list/2014-June/msg01097.html Finished upstream by v1.2.7-rc1-21-gcfb16b8: commit cfb16b8ed7bf5a082566e36b658945028cdffc59 Author: Eric Blake <eblake> Date: Wed Jun 18 17:16:27 2014 -0600 blockcommit: turn on active commit With this in place, I can (finally!) now do: virsh blockcommit $dom vda --shallow --verbose --pivot and watch qemu shorten the backing chain by one, followed by libvirt automatically updating the dumpxml output, effectively undoing the work of virsh snapshot-commit --no-metadata --disk-only. Commit is SOOOO much faster than blockpull, when I'm still fairly close in time to when the temporary qcow2 wrapper file was created via a snapshot operation! * src/qemu/qemu_driver.c (qemuDomainBlockCommit): Implement live commit. Signed-off-by: Eric Blake <eblake> commit 232a31bea3bfde7118bbb0c6594949b62b9bd2a0 Author: Eric Blake <eblake> Date: Mon Jul 28 21:46:44 2014 -0600 blockcommit: track job type in xml A future patch is going to wire up qemu active block commit jobs; but as they have similar events and are canceled/pivoted in the same way as block copy jobs, it is easiest to track all bookkeeping for the commit job by reusing the <mirror> element. This patch adds domain XML to track which job was responsible for creating a mirroring situation, and adds a job='copy' attribute to all existing uses of <mirror>. Along the way, it also massages the qemu monitor backend to read the new field in order to generate the correct type of libvirt job (even though it requires a future patch to actually cause a qemu event that can be reported as an active commit). It also prepares to update persistent XML to match changes made to live XML when a copy completes. * docs/schemas/domaincommon.rng: Enhance schema. * docs/formatdomain.html.in: Document it. * src/conf/domain_conf.h (_virDomainDiskDef): Add a field. * src/conf/domain_conf.c (virDomainBlockJobType): String conversion. (virDomainDiskDefParseXML): Parse job type. (virDomainDiskDefFormat): Output job type. * src/qemu/qemu_process.c (qemuProcessHandleBlockJob): Distinguish active from regular commit. * src/qemu/qemu_driver.c (qemuDomainBlockCopy): Set job type. (qemuDomainBlockPivot, qemuDomainBlockJobImpl): Clean up job type on completion. * tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-mirror-old.xml: Update tests. * tests/qemuxml2argvdata/qemuxml2argv-disk-mirror.xml: Likewise. * tests/qemuxml2argvdata/qemuxml2argv-disk-active-commit.xml: New file. * tests/qemuxml2xmltest.c (mymain): Drive new test. Signed-off-by: Eric Blake <eblake> Back to ASSIGNED - I found a pretty severe use-after-free bug that can crash libvirtd 1.2.7: https://www.redhat.com/archives/libvir-list/2014-August/msg00214.html Rebase to 1.2.8 will pick up: commit 265680c58ebbee30bb70369e7d9905a599afbd6a Author: Eric Blake <eblake> Date: Wed Aug 6 14:06:23 2014 -0600 blockjob: fix use-after-free in blockcopy Commit febf84c2 tried to delay in-memory modification of the actual domain disk structure until after the qemu event was received. However, I missed that the code for block pivot had been temporarily setting disk->src = disk->mirror prior to the qemu command, in order to label the backing chain of a reused external blockcopy disk; and calls into qemu while still in that state before finally undoing things at the cleanup label. Since the qemu event handler then does: virStorageSourceFree(disk->src); disk->src = disk->mirror; we have the sad race that a fast enough qemu event can cause a leak of the original disk->src, as well as a use-after-free of the disk->mirror contents, bad enough to crash libvirtd in some of my test runs, even though the common case of the qemu event being much later won't trip the race. I'll go wear the brown paper bag of shame, for introducing a crasher in between rc1 and rc2 of the freeze for 1.2.7 :( My only consolation is that virDomainBlockJobAbort requires the domain:write ACL, so it is not a CVE. The valgrind report when the race occurs looks like: ==25612== Invalid read of size 4 ==25612== at 0x50E7C90: virStorageSourceGetActualType (virstoragefile.c:1948) ==25612== by 0x209C0B18: qemuDomainDetermineDiskChain (qemu_domain.c:2473) ==25612== by 0x209D7F6A: qemuProcessHandleBlockJob (qemu_process.c:1087) ==25612== by 0x209F40C9: qemuMonitorEmitBlockJob (qemu_monitor.c:1357) ... ==25612== Address 0xe4b5610 is 0 bytes inside a block of size 200 free'd ==25612== at 0x4A07577: free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==25612== by 0x50839E9: virFree (viralloc.c:582) ==25612== by 0x50E7E51: virStorageSourceFree (virstoragefile.c:2015) ==25612== by 0x209D7EFF: qemuProcessHandleBlockJob (qemu_process.c:1073) ==25612== by 0x209F40C9: qemuMonitorEmitBlockJob (qemu_monitor.c:1357) * src/qemu/qemu_driver.c (qemuDomainBlockPivot): Don't corrupt disk->src, and only label chain for blockcopy. Signed-off-by: Eric Blake <eblake> Here's a thread detailing 28 patches needed to backport active commit for just files (no network support) to RHEL 7.0.z: http://post-office.corp.redhat.com/archives/rhvirt-patches/2014-August/msg00372.html Verify this bug with libvirt-1.2.8-11.el7.x86_64 scenario I with disk type is "file" 1. Domain use raw format file as source 1.1 Define/start a domain # virsh dumpxml r7|grep disk -A 6 <disk type='file' device='disk'> <driver name='qemu' type='raw' cache='none'/> <source file='/var/lib/libvirt/images/r7-raw.img'/> <backingStore/> <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </disk> 1.2 Create three external disk snapshot # for i in 1 2 3;do virsh snapshot-create-as r7 s$i --disk-only --quiesce;done Domain snapshot s1 created Domain snapshot s2 created Domain snapshot s3 created # virsh dumpxml r7 |grep disk -A 16 <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/r7-raw.s3'/> <backingStore type='file' index='1'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-raw.s2'/> <backingStore type='file' index='2'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-raw.s1'/> <backingStore type='file' index='3'> <format type='raw'/> <source file='/var/lib/libvirt/images/r7-raw.img'/> <backingStore/> </backingStore> </backingStore> </backingStore> <target dev='vda' bus='virtio'/> 1.3 Do active blockcommit from top to middle # virsh blockcommit r7 vda --active --base vda[1] --verbose --wait Block Commit: [100 %] Now in synchronized phase # virsh dumpxml r7 |grep mirror -A 4 -B 16 <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/r7-raw.s3'/> <backingStore type='file' index='1'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-raw.s2'/> <backingStore type='file' index='2'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-raw.s1'/> <backingStore type='file' index='3'> <format type='raw'/> <source file='/var/lib/libvirt/images/r7-raw.img'/> <backingStore/> </backingStore> </backingStore> </backingStore> <mirror type='file' job='active-commit' ready='yes'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-raw.s2'/> </mirror> # virsh blockjob r7 vda --pivot # virsh dumpxml r7 |grep disk -A 16 <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/r7-raw.s2'/> <backingStore type='file' index='1'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-raw.s1'/> <backingStore type='file' index='2'> <format type='raw'/> <source file='/var/lib/libvirt/images/r7-raw.img'/> <backingStore/> </backingStore> </backingStore> <target dev='vda' bus='virtio'/> 1.4 Do active blockcommit from top to base # virsh blockcommit r7 vda --active --verbose --wait Block Commit: [100 %] Now in synchronized phase # virsh dumpxml r7 |grep mirror -A 4 -B 12 <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/r7-raw.s2'/> <backingStore type='file' index='1'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-raw.s1'/> <backingStore type='file' index='2'> <format type='raw'/> <source file='/var/lib/libvirt/images/r7-raw.img'/> <backingStore/> </backingStore> </backingStore> <mirror type='file' job='active-commit' ready='yes'> <format type='raw'/> <source file='/var/lib/libvirt/images/r7-raw.img'/> </mirror> <target dev='vda' bus='virtio'/> # virsh blockjob r7 vda --pivot # virsh dumpxml r7 |grep disk -A 4 <disk type='file' device='disk'> <driver name='qemu' type='raw' cache='none'/> <source file='/var/lib/libvirt/images/r7-raw.img'/> <backingStore/> <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </disk> NB: cmd "virsh blockcommit r7 vda --active --verbose --wait --pivot" will achieve same result with combination two cmd "virsh blockcommit r7 vda --active" without --pivot and "virsh blockjob r7 vda --pivot" 2. Domain use qcow2 format file as source 2.1 Define/start a domain # virsh dumpxml r7|grep disk -A 6 <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/r7-qcow2.img'/> <backingStore/> <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </disk> 2.2 Create three external disk snapshot # for i in 1 2 3;do virsh snapshot-create-as r7 s$i --disk-only --quiesce;done Domain snapshot s1 created Domain snapshot s2 created Domain snapshot s3 created 2.3 Do active blockcommit from top to middle # virsh blockcommit r7 vda --active --base vda[1] --verbose --wait Block Commit: [100 %] Now in synchronized phase # virsh dumpxml r7 |grep mirror -A4 -B16 <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/r7-qcow2.s3'/> <backingStore type='file' index='1'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-qcow2.s2'/> <backingStore type='file' index='2'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-qcow2.s1'/> <backingStore type='file' index='3'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-qcow2.img'/> <backingStore/> </backingStore> </backingStore> </backingStore> <mirror type='file' job='active-commit' ready='yes'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-qcow2.s2'/> </mirror> <target dev='vda' bus='virtio'/> # virsh dumpxml r7|grep disk -A 12 <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/r7-qcow2.s2'/> <backingStore type='file' index='1'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-qcow2.s1'/> <backingStore type='file' index='2'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-qcow2.img'/> <backingStore/> </backingStore> </backingStore> <target dev='vda' bus='virtio'/> 2.4 Do active blockcommit from top to base # virsh blockcommit r7 vda --active --verbose --wait Block Commit: [100 %] Now in synchronized phase # virsh dumpxml r7 |grep mirror -A4 -B16 <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> <devices> <emulator>/usr/libexec/qemu-kvm</emulator> <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/r7-qcow2.s2'/> <backingStore type='file' index='1'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-qcow2.s1'/> <backingStore type='file' index='2'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-qcow2.img'/> <backingStore/> </backingStore> </backingStore> <mirror type='file' job='active-commit' ready='yes'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7-qcow2.img'/> </mirror> <target dev='vda' bus='virtio'/> # virsh blockjob r7 vda --pivot # virsh dumpxml r7|grep disk -A 12 <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/r7-qcow2.img'/> <backingStore/> <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </disk> scenario II with disk type is "block" 1. Domain use logical volume based on disk partition 1.1 Define/Start a domain # pvcreate /dev/sda7 Physical volume "/dev/sda7" successfully created # vgcreate VG01 /dev/sda7 Volume group "VG01" successfully created # lvcreate -L 10G -n LV01 VG01 Logical volume "LV01" created. # virsh dumpxml r7|grep disk -A 5 <disk type='block' device='disk'> <driver name='qemu' type='raw' cache='none'/> <source dev='/dev/VG01/LV01'/> <backingStore/> <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </disk> 1.2 Create three external disk snapshot # for i in 1 2 3 ;do virsh snapshot-create-as r7 s$i --disk-only --diskspec vda,snapshot=external,file=/var/lib/libvirt/images/r7.s$i; done Domain snapshot s1 created Domain snapshot s2 created Domain snapshot s3 created # virsh dumpxml r7 |grep disk -A 16 <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/r7.s3'/> <backingStore type='file' index='1'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7.s2'/> <backingStore type='file' index='2'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7.s1'/> <backingStore type='block' index='3'> <format type='raw'/> <source dev='/dev/VG01/LV01'/> <backingStore/> </backingStore> </backingStore> </backingStore> <target dev='vda' bus='virtio'/> 1.3 Do active blockcommit from top to middle # virsh blockcommit r7 vda --active --base vda[1] --verbose --wait Block Commit: [100 %] Now in synchronized phase # virsh dumpxml r7 |grep mirror -A4 -B16 <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/r7.s3'/> <backingStore type='file' index='1'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7.s2'/> <backingStore type='file' index='2'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7.s1'/> <backingStore type='block' index='3'> <format type='raw'/> <source dev='/dev/VG01/LV01'/> <backingStore/> </backingStore> </backingStore> </backingStore> <mirror type='file' job='active-commit' ready='yes'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7.s2'/> </mirror> # virsh blockjob r7 vda --pivot # virsh dumpxml r7 |grep disk -A 12 <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/r7.s2'/> <backingStore type='file' index='1'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7.s1'/> <backingStore type='block' index='2'> <format type='raw'/> <source dev='/dev/VG01/LV01'/> <backingStore/> </backingStore> </backingStore> <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </disk> 1.4 Do active blockcommit from top to base # virsh blockcommit r7 vda --active --verbose --wait Block Commit: [100 %] Now in synchronized phase # virsh dumpxml r7 |grep mirror -A4 -B16 <on_reboot>restart</on_reboot> <on_crash>restart</on_crash> <devices> <emulator>/usr/libexec/qemu-kvm</emulator> <disk type='file' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source file='/var/lib/libvirt/images/r7.s2'/> <backingStore type='file' index='1'> <format type='qcow2'/> <source file='/var/lib/libvirt/images/r7.s1'/> <backingStore type='block' index='2'> <format type='raw'/> <source dev='/dev/VG01/LV01'/> <backingStore/> </backingStore> </backingStore> <mirror type='block' job='active-commit' ready='yes'> <format type='raw'/> <source dev='/dev/VG01/LV01'/> </mirror> .. # virsh blockjob r7 vda --pivot # virsh dumpxml r7 |grep disk -A 12 <disk type='block' device='disk'> <driver name='qemu' type='raw' cache='none'/> <source dev='/dev/VG01/LV01'/> <backingStore/> <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </disk> scenario III with disk type is "network" 1. Domain use raw format file as source 1.1 Define/start a domain # virsh dumpxml r7|grep disk -A 6 <disk type='network' device='disk'> <driver name='qemu' type='raw' cache='none'/> <source protocol='gluster' name='gluster-vol1/r7-raw.img'> <host name='10.66.5.38'/> </source> <backingStore/> <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </disk> 1.2 Create three external disk snapshot # cat s1.xml <domainsnapshot> <name>SNAP</name> <disks> <disk name='vda' type='network'> <driver type='qcow2'/> <source protocol='gluster' name='gluster-vol1/r7.SNAP'> <host name='10.66.5.38'/> </source> </disk> </disks> </domainsnapshot> # for i in s1 s2 s3;do sed -e s/SNAP/$i/g s1.xml >$i-snap.xml;virsh snapshot-create r7 $i-snap.xml --disk-only;done Domain snapshot s1 created from 's1-snap.xml' Domain snapshot s2 created from 's2-snap.xml' Domain snapshot s3 created from 's3-snap.xml' # virsh dumpxml r7|grep disk -A24 <disk type='network' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source protocol='gluster' name='gluster-vol1/r7.s3'> <host name='10.66.5.38'/> </source> <backingStore type='network' index='1'> <format type='qcow2'/> <source protocol='gluster' name='gluster-vol1/r7.s2'> <host name='10.66.5.38'/> </source> <backingStore type='network' index='2'> <format type='qcow2'/> <source protocol='gluster' name='gluster-vol1/r7.s1'> <host name='10.66.5.38'/> </source> <backingStore type='network' index='3'> <format type='raw'/> <source protocol='gluster' name='gluster-vol1/r7-raw.img'> <host name='10.66.5.38'/> </source> <backingStore/> </backingStore> </backingStore> </backingStore> <target dev='vda' bus='virtio'/> .. 1.3 Do active blockcommit from top to middle # virsh blockcommit r7 vda --active --base vda[1] --verbose --wait Block Commit: [100 %] Now in synchronized phase # virsh dumpxml r7 |grep mirror -A4 -B24 <disk type='network' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source protocol='gluster' name='gluster-vol1/r7.s3'> <host name='10.66.5.38'/> </source> <backingStore type='network' index='1'> <format type='qcow2'/> <source protocol='gluster' name='gluster-vol1/r7.s2'> <host name='10.66.5.38'/> </source> <backingStore type='network' index='2'> <format type='qcow2'/> <source protocol='gluster' name='gluster-vol1/r7.s1'> <host name='10.66.5.38'/> </source> <backingStore type='network' index='3'> <format type='raw'/> <source protocol='gluster' name='gluster-vol1/r7-raw.img'> <host name='10.66.5.38'/> </source> <backingStore/> </backingStore> </backingStore> </backingStore> <mirror type='network' job='active-commit' ready='yes'> <format type='qcow2'/> <source protocol='gluster' name='gluster-vol1/r7.s2'> <host name='10.66.5.38'/> </source> </mirror> .. # virsh blockjob r7 vda --pivot # virsh dumpxml r7|grep disk -A24 <disk type='network' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source protocol='gluster' name='gluster-vol1/r7.s2'> <host name='10.66.5.38'/> </source> <backingStore type='network' index='1'> <format type='qcow2'/> <source protocol='gluster' name='gluster-vol1/r7.s1'> <host name='10.66.5.38'/> </source> <backingStore type='network' index='2'> <format type='raw'/> <source protocol='gluster' name='gluster-vol1/r7-raw.img'> <host name='10.66.5.38'/> </source> <backingStore/> </backingStore> </backingStore> <target dev='vda' bus='virtio'/> 1.4 Do active blockcommit from top to base # virsh blockcommit r7 vda --active --verbose --wait Block Commit: [100 %] Now in synchronized phase # virsh dumpxml r7|grep disk -A24 <disk type='network' device='disk'> <driver name='qemu' type='qcow2' cache='none'/> <source protocol='gluster' name='gluster-vol1/r7.s2'> <host name='10.66.5.38'/> </source> <backingStore type='network' index='1'> <format type='qcow2'/> <source protocol='gluster' name='gluster-vol1/r7.s1'> <host name='10.66.5.38'/> </source> <backingStore type='network' index='2'> <format type='raw'/> <source protocol='gluster' name='gluster-vol1/r7-raw.img'> <host name='10.66.5.38'/> </source> <backingStore/> </backingStore> </backingStore> <mirror type='network' job='active-commit' ready='yes'> <format type='raw'/> <source protocol='gluster' name='gluster-vol1/r7-raw.img'> <host name='10.66.5.38'/> </source> </mirror> <target dev='vda' bus='virtio'/> # virsh blockjob r7 vda --pivot # virsh dumpxml r7|grep disk -A6 <disk type='network' device='disk'> <driver name='qemu' type='raw' cache='none'/> <source protocol='gluster' name='gluster-vol1/r7-raw.img'> <host name='10.66.5.38'/> </source> <backingStore/> <target dev='vda' bus='virtio'/> <alias name='virtio-disk0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </disk> So, blockcommit on active layer works fine. I will change this bug to VERIFIED status *** Bug 1148201 has been marked as a duplicate of this bug. *** 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/RHSA-2015-0323.html |