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 |