Bug 1061827 - Maintain relative path to backing file image during live merge (block-commit)
Summary: Maintain relative path to backing file image during live merge (block-commit)
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: qemu-kvm-rhev
Version: 7.0
Hardware: Unspecified
OS: Unspecified
high
urgent
Target Milestone: rc
: ---
Assignee: Jeff Cody
QA Contact: Virtualization Bugs
URL:
Whiteboard:
Depends On:
Blocks: 1035038 1082754 647386 1083310 1099978 1122925 1150322 1196199
TreeView+ depends on / blocked
 
Reported: 2014-02-05 17:25 UTC by Federico Simoncelli
Modified: 2016-04-26 13:43 UTC (History)
16 users (show)

Fixed In Version: qemu 2.1
Doc Type: Bug Fix
Doc Text:
Clone Of:
: 1122925 (view as bug list)
Environment:
Last Closed: 2015-03-05 09:43:51 UTC


Attachments (Terms of Use)
live-merge-test.sh (885 bytes, text/plain)
2014-02-11 15:54 UTC, Federico Simoncelli
no flags Details


Links
System ID Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2015:0624 normal SHIPPED_LIVE Important: qemu-kvm-rhev security, bug fix, and enhancement update 2015-03-05 14:37:36 UTC

Description Federico Simoncelli 2014-02-05 17:25:19 UTC
Description of problem:
When live merge (block-commit) updates the backing file path of an image, it always uses an absolute path.
Given:

 [A] <- [B(bak=../a/img.raw)] <- [C(bak=../b/img.qcow)]

merging B into C would result in:

 [A] <- [B+C(bak=/nfs/a/img.raw)]

This is extremely problematic for image chains residing on NFS shares (as the mountpoint could change).

If the path that qemu needs to update is relative, it should be maintained relative:

 [A] <- [B+C(bak=../a/img.raw)]

Version-Release number of selected component (if applicable):
qemu-kvm-rhev-1.5.3-45.el7

Comment 1 Jeff Cody 2014-02-05 17:28:08 UTC
There were some patches floating around a while ago to address this (or something very similar).  I'll look into resurrecting those patches.

Comment 3 Shaolong Hu 2014-02-08 06:08:05 UTC
I try to reproduce this bug, merge B to C sounds more like block-stream,

boot guest with relative image:

-drive file=./RHEL-Server-7.0-64-virtio.qcow2, ...

create snapshot with relative image:

{ "execute": "blockdev-snapshot-sync", "arguments": { "device": "drive-virtio-disk0", "snapshot-file": "./sn1", "format": "qcow2", "mode": "absolute-paths" } }

{ "execute": "blockdev-snapshot-sync", "arguments": { "device": "drive-virtio-disk0", "snapshot-file": "./sn2", "format": "qcow2", "mode": "absolute-paths" } }

do block stream with relative path:

{ "execute": "block-stream", "arguments": { "device": "drive-virtio-disk0", "base": "./RHEL-Server-7.0-64-virtio.qcow2", "speed": 1000000000 } }

(qemu) info block
drive-virtio-disk0: removable=0 io-status=ok file=./sn2 backing_file=./RHEL-Server-7.0-64-virtio.qcow2 backing_file_depth=1 ro=0 drv=qcow2 encrypted=0 bps=0 bps_rd=0 bps_wr=0 iops=0 iops_rd=0 iops_wr=0

do block stream with absolute path:

{ "execute": "block-stream", "arguments": { "device": "drive-virtio-disk0", "base": "/root/RHEL-Server-7.0-64-virtio.qcow2", "speed": 1000000000 } }

(qemu) info block
drive-virtio-disk0: removable=0 io-status=ok file=./sn2 backing_file=/root/RHEL-Server-7.0-64-virtio.qcow2 backing_file_depth=1 ro=0 drv=qcow2 encrypted=0 bps=0 bps_rd=0 bps_wr=0 iops=0 iops_rd=0 iops_wr=0


So key is which kind of path we use for block stream command.

I also check block-commit, it keeps relative path backing file when commands use all relative path.

Comment 5 Federico Simoncelli 2014-02-11 15:54:57 UTC
Created attachment 861827 [details]
live-merge-test.sh

I am able to reproduce the issue with the attached script.
Given:

 base <- snap1 <- snap2

It performs a blockcommit in order to achieve:

 base+snap1 <- snap2

At the end of the operation snap2 points to base using an absolute path (instead of relative).

$ sh live-merge-test.sh 
Formatting 'base.img', fmt=raw size=1073741824 
Formatting 'snap1.img', fmt=qcow2 size=1073741824 backing_file='base.img' backing_fmt='raw' encryption=off cluster_size=65536 lazy_refcounts=off 
Formatting 'snap2.img', fmt=qcow2 size=1073741824 backing_file='snap1.img' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off 
image: /tmp/live-merge-test/snap2.img
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 196K
cluster_size: 65536
backing file: snap1.img (actual path: /tmp/live-merge-test/snap1.img)
backing file format: qcow2
Domain testvm1 created from /dev/stdin

Commit complete
Domain testvm1 destroyed

image: /tmp/live-merge-test/snap2.img
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 196K
cluster_size: 65536
backing file: /tmp/live-merge-test/base.img
backing file format: raw

Comment 10 Eric Blake 2014-03-04 22:16:33 UTC
(In reply to Federico Simoncelli from comment #0)
> Description of problem:
> When live merge (block-commit) updates the backing file path of an image, it
> always uses an absolute path.

Are you sure you meant block-commit and not block-pull?

> Given:
> 
>  [A] <- [B(bak=../a/img.raw)] <- [C(bak=../b/img.qcow)]
> 
> merging B into C would result in:
> 
>  [A] <- [B+C(bak=/nfs/a/img.raw)]

Libvirt doesn't (yet) support live block-commit (moving contents of C into B with live file now named "B" - see bug 1062142), but DOES support block-pull into the live image (moving contents of B into C with live file now named "C").

(In reply to Shaolong Hu from comment #3)
> I try to reproduce this bug, merge B to C sounds more like block-stream,
> 

> do block stream with relative path:
> 
> { "execute": "block-stream", "arguments": { "device": "drive-virtio-disk0",
> "base": "./RHEL-Server-7.0-64-virtio.qcow2", "speed": 1000000000 } }
> 
> (qemu) info block
> drive-virtio-disk0: removable=0 io-status=ok file=./sn2
> backing_file=./RHEL-Server-7.0-64-virtio.qcow2 backing_file_depth=1 ro=0
> drv=qcow2 encrypted=0 bps=0 bps_rd=0 bps_wr=0 iops=0 iops_rd=0 iops_wr=0
> 
> do block stream with absolute path:
> 
> { "execute": "block-stream", "arguments": { "device": "drive-virtio-disk0",
> "base": "/root/RHEL-Server-7.0-64-virtio.qcow2", "speed": 1000000000 } }
> 
> (qemu) info block
> drive-virtio-disk0: removable=0 io-status=ok file=./sn2
> backing_file=/root/RHEL-Server-7.0-64-virtio.qcow2 backing_file_depth=1 ro=0
> drv=qcow2 encrypted=0 bps=0 bps_rd=0 bps_wr=0 iops=0 iops_rd=0 iops_wr=0
> 
> 
> So key is which kind of path we use for block stream command.

Ah, so it matters what libvirt passes in to qemu.  Libvirt is sanitizing the user's input to validate that the pull is likely to succeed before even attempting the qemu command, and passing the sanitized name to qemu - but this means libvirt is not exposing the option to the end user on whether they want the new backing file recorded in the live file to be absolute or relative.

Comment 12 Eric Blake 2014-03-06 22:54:33 UTC
(In reply to Federico Simoncelli from comment #0)
> Description of problem:
> When live merge (block-commit) updates the backing file path of an image, it
> always uses an absolute path.
> Given:
> 
>  [A] <- [B(bak=../a/img.raw)] <- [C(bak=../b/img.qcow)]
> 
> merging B into C would result in:
> 
>  [A] <- [B+C(bak=/nfs/a/img.raw)]

This diagram does not quite match your script of comment 5, which sets up:

# base.img <- snap1.img <- snap2.img
qemu-img create -f raw base.img 1G
qemu-img create -f qcow2 -b base.img -o backing_fmt=raw snap1.img
qemu-img create -f qcow2 -b snap1.img -o backing_fmt=qcow2 snap2.img

or:

[base.img] <- [snap1.img(bak=base.img)] <- [snap2.img(bak=snap1.img)]

then executes:

virsh blockcommit testvm1 --path $PWD/snap2.img --base base.img --top snap1.img --wait

which is a request to collapse to:

[base.img[+snap1]] <- [snap2.img(bak=base.img)]


(In reply to Jeff Cody from comment #7)
> I don't know that this particular issue is qemu related.  Here is what I
> did, from QEMU:
> 
> 
> My base image: F18.qcow2
> 
> qemu-img create -f qcow2 -b F18.qcow2 snap1.qcow2
> qemu-img create -f qcow2 -b snap1.qcow2 snap2.qcow2
> 
> 
> qemu-kvm ... -drive file=./snap2.qcow2
> 
> QMP commands:
> { "execute": "qmp_capabilities" }
> {"return": {}}
> { "execute": "block-commit", "arguments": { "device": "virtio0", "top":
> "snap1.qcow2" } }
> {"return": {}}

You were testing with several differences from the example using libvirt.  First, libvirt ALWAYS passes an absolute filename to -drive file=...; starting qemu with an absolute path for the active layer instead of a relative path may make a difference to how operations on that backing chain behave.  For the example script in comment 5, this is the command libvirt actually issued:

{"execute":"block-commit", "arguments":{"device":"drive-virtio-disk0",
"speed":0, "top":"/home/eblake/snap1.img", "base":"/home/eblake/base.img"},
"id":"libvirt-9"}

So libvirt is definitely passing in absolute names.

Meanwhile, libvirt hasn't yet been fixed to allow live commits of the active layer (bug 1062142).  When that is addressed and we start doing commits with top==active, we might find even more corner cases.

[Note that libvirt is NOT sanitizing names passed to qemu's block-stream, although it should be - so that command will also need to be careful on whether it passes a relative or absolute name]

(In reply to Shaolong Hu from comment #3)
> I try to reproduce this bug, merge B to C sounds more like block-stream,

Indeed, that was my first thought when reading the original comment, but comment 5 makes it clear that we are talking about block-commit.

> So key is which kind of path we use for block stream command.
> 
> I also check block-commit, it keeps relative path backing file when commands
> use all relative path.

This part is probably still true - but right now, while libvirt passes relative names for block-stream, it passes absolute names for block-stream.

Comment 13 Eric Blake 2014-03-06 23:24:05 UTC
Reassigning to qemu.

I applied the following patch to libvirt to pass through relative names:

diff --git i/src/qemu/qemu_driver.c w/src/qemu/qemu_driver.c
index 9aad2dc..31adf78 100644
--- i/src/qemu/qemu_driver.c
+++ w/src/qemu/qemu_driver.c
@@ -15383,10 +15383,15 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base,
                                            VIR_DISK_CHAIN_READ_WRITE) < 0))
         goto endjob;

-    /* Start the commit operation.  */
+    /* Start the commit operation.  Pass the user's original spelling,
+     * if any, through to qemu, since qemu behaves differently
+     * depending on whether the input was specified as relative or
+     * absolute (that is, our absolute top_canon may do the wrong
+     * thing if the user specified a name). */
     qemuDomainObjEnterMonitor(driver, vm);
-    ret = qemuMonitorBlockCommit(priv->mon, device, top_canon, base_canon,
-                                 bandwidth);
+    ret = qemuMonitorBlockCommit(priv->mon, device,
+                                 top ? top : top_canon,
+                                 base ? base : base_canon, bandwidth);
     qemuDomainObjExitMonitor(driver, vm);

 endjob:

and verified that the QMP command generated by the test script of comment 5 changed to:

{"execute":"block-commit", "arguments":{"device":"drive-virtio-disk0",
"speed":0, "top":"snap1.img", "base":"base.img"},
"id":"libvirt-9"}

but even with that change, the end result is still an absolute backing file (at least, when using the qemu on Fedora 20; but I can set up to repeat on RHEL if needed):

backing file: /home/eblake/base.img

So my guess is that this has everything to do with the fact that libvirt starts qemu with -drive being absolute, and less to do with whether libvirt's use of block-commit passes absolute or relative names.  Qemu needs to do more investigation.

Comment 14 Eric Blake 2014-03-06 23:29:27 UTC
I wonder if qemu needs to add an optional parameter to block-commit that lets management specify the exact string that will be written to the backing_file metadata of the qcow2 file.  Particularly when we start playing with add-fd for passing in backing chains by fd reference, there may come a point where qemu has no idea what string to actually write into the file, because it was told to forcefully use /dev/fdset/nnn instead of the actual file name recorded in the qcow2 metadata.  But how would libvirt learn if qemu is new enough to support such an optional argument?

Comment 15 Eric Blake 2014-03-06 23:50:54 UTC
Libvirt patch to quit munging names is here:
https://www.redhat.com/archives/libvir-list/2014-March/msg00381.html
Still not sure if it needs to be applied, since we first need to solve what qemu does, but at least it's available to make testing things easier.

Note that there are multiple hueristic points to consider.  For the chain:

A <- B <- C <- D

where the block-commit command is used to squash C into A, we end up invalidating B and C, and making D point to A.  The decision on whether D's reference to A should be absolute or relative might depend on:

- whether D's original reference to C was absolute or relative
- whether B's reference to A was absolute or relative
- whether the base argument passed to 'block-commit' was absolute or relative
- any other ideas?

Comment 20 Eric Blake 2014-05-06 15:07:09 UTC
IRC conversation today says that maybe we just need a new transaction operation that can rewrite the backing string of a qcow2 file to anything the management desires; and be able to chain it with any other block operation in a transaction.  Jeff is working on a proposal to the upstream list.

Comment 21 Federico Simoncelli 2014-05-06 15:12:22 UTC
(In reply to Eric Blake from comment #20)
> IRC conversation today says that maybe we just need a new transaction
> operation that can rewrite the backing string of a qcow2 file to anything
> the management desires; and be able to chain it with any other block
> operation in a transaction.  Jeff is working on a proposal to the upstream
> list.

Does it mean that at the end of the block job we'll have to issue a second command to update the backing file path?
This is extremely problematic on our side because the entire machine can crash before updating the backing file path and the chain will remain broken on storage.

The optimal solution is that at the end of the block job either we have the previous backing file path (crash before changing it) or the new (correct) one.

Comment 22 Eric Blake 2014-05-06 16:14:07 UTC
(In reply to Federico Simoncelli from comment #21)
> (In reply to Eric Blake from comment #20)
> > IRC conversation today says that maybe we just need a new transaction
> > operation that can rewrite the backing string of a qcow2 file to anything
> > the management desires; and be able to chain it with any other block
> > operation in a transaction.  Jeff is working on a proposal to the upstream
> > list.
> 
> Does it mean that at the end of the block job we'll have to issue a second
> command to update the backing file path?

No.  The point of a transaction is that qemu does all the work to ensure that the rename happens as part of the single QMP command.

> The optimal solution is that at the end of the block job either we have the
> previous backing file path (crash before changing it) or the new (correct)
> one.

Correct - that's what you get with adding the backing file rename as part of the existing QMP 'transaction' command.

Comment 26 Jeff Cody 2014-07-15 20:21:37 UTC
The QEMU parts to support this have been accepted upstream, and will be in qemu 2.1.

Comment 33 Qian Guo 2014-08-28 07:04:49 UTC
Hi, Jeff

I am to reproduce and verify this bug, but when I tested it with both fix and unfixed build directly by qemu-kvm cli and qmp cmd, and did not via libvirt I get same result that 

Steps like followings:
1.Create chains:
# qemu-img create -f raw base.img 1G
Formatting 'base.img', fmt=raw size=1073741824 

# qemu-img create -f qcow2 -b base.img -o backing_fmt=raw snap1.img
Formatting 'snap1.img', fmt=qcow2 size=1073741824 backing_file='base.img' backing_fmt='raw' encryption=off cluster_size=65536 lazy_refcounts=off 

# qemu-img create -f qcow2 -b snap1.img -o backing_fmt=qcow2 snap2.img
Formatting 'snap2.img', fmt=qcow2 size=1073741824 backing_file='snap1.img' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off 

2.Check infos:
# qemu-img info ./snap2.img 
image: ./snap2.img
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 196K
cluster_size: 65536
backing file: snap1.img (actual path: ./snap1.img)
backing file format: qcow2
Format specific information:
    compat: 1.1
    lazy refcounts: false

3.Boot guest with snap2.img like this:
# /usr/libexec/qemu-kvm -device virtio-scsi-pci,bus=pci.0,addr=0x4,id=scsi0 -drive file=./snap2.img,if=none,id=drive-scsi0-0-0,media=disk,cache=none,format=qcow2,werror=stop,rerror=stop,aio=native -device scsi-hd,drive=drive-scsi0-0-0,bus=scsi0.0,scsi-id=0,lun=0,id=t -qmp unix:/tmp/q1,server,nowait -monitor stdio

4.Commit sn1>base.img
# nc -U /tmp/q1 
{"QMP": {"version": {"qemu": {"micro": 0, "minor": 1, "major": 2}, "package": " (qemu-kvm-2.1.0-2.el7)"}, "capabilities": []}}
{"execute":"qmp_capabilities"}
{"return": {}}
{ "execute": "block-commit", "arguments": { "device": "drive-scsi0-0-0", "base": "base.img", "top": "snap1.img" } }
{"return": {}}
{"timestamp": {"seconds": 1409207370, "microseconds": 497516}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "drive-scsi0-0-0", "len": 1073741824, "offset": 1073741824, "speed": 0, "type": "commit"}}

5.Recheck the infos:
# qemu-img info ./snap2.img 
image: ./snap2.img
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 196K
cluster_size: 65536
backing file: ./base.img (actual path: ././base.img)
backing file format: raw
Format specific information:
    compat: 1.1


Result, I tested both qemu-kvm-rhev-2.1.0-2.el7.x86_64 and qemu-kvm-rhev-1.5.3-59.el7ev.x86_64, same result, it keeps relative path backing file when commands use all relative path.

And I just sea the comments above, I just tested with the script as comment 5 with both builds, Results are still same that final the path was absolute one:

# sh cli.sh 
Formatting 'base.img', fmt=raw size=1073741824 
Formatting 'snap1.img', fmt=qcow2 size=1073741824 backing_file='base.img' backing_fmt='raw' encryption=off cluster_size=65536 lazy_refcounts=off 
Formatting 'snap2.img', fmt=qcow2 size=1073741824 backing_file='snap1.img' backing_fmt='qcow2' encryption=off cluster_size=65536 lazy_refcounts=off 
image: /home/snap2.img
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 196K
cluster_size: 65536
backing file: snap1.img (actual path: /home/snap1.img)
backing file format: qcow2
Format specific information:
    compat: 1.1
    lazy refcounts: false
Domain testvm1 created from /dev/stdin


Commit complete
Domain testvm1 destroyed

image: /home/snap2.img
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 196K
cluster_size: 65536
backing file: /home/base.img
backing file format: raw
Format specific information:
    compat: 1.1
    lazy refcounts: false


So, there's no change between the 2 builds, is there anything I misunderstand or could you help fix if I made mistake ?

Thanks

Comment 34 Jeff Cody 2014-09-02 20:21:59 UTC
Hi Qian,

You need to test this with libvirt.  The changes for QEMU are to allow libvirt to specify the backing file name, when performing the live merge (commit / stream).  That way libvirt can fix the backing file path, regardless of what the backing file is listed as in the image file.

So in order to verify this bug, the easiest method would be verifying it at the same time as its libvirt counterpart (BZ 1099978).

Comment 36 Qian Guo 2014-10-14 03:04:34 UTC
According to comment 35 and bug 1150322 comment 4 , set this bug as verified.

Comment 37 Qian Guo 2014-10-14 09:11:47 UTC
Verify this bug according to https://bugzilla.redhat.com/show_bug.cgi?id=1122925#c12 with qemu-kvm-rhev-2.1.2-3.el7.x86_64


Steps :
1. Create snapshots with Base->sn1->sn2->sn3:
qemu-img create -f qcow2 -b /home/nfs/rhel7u1cp1.qcow2 /home/sn1
qemu-img create -f qcow2 -b /home/sn1 /home/sn2
qemu-img create -f qcow2 -b /home/sn2 /home/sn3

2.Boot guest with /home/sn3:
/usr/libexec/qemu-kvm -device virtio-scsi-pci,bus=pci.0,addr=0x4,id=scsi0 -drive file=/home/sn3,if=none,id=drive-scsi0-0-0,media=disk,cache=none,format=qcow2,werror=stop,rerror=stop,aio=native -device scsi-hd,drive=drive-scsi0-0-0,bus=scsi0.0,scsi-id=0,lun=0,id=t -qmp unix:/tmp/q1,server,nowait -monitor stdio -nodefaults -nodefconfig

3.Check path before do live merge:
# qemu-img info sn3
image: sn3
file format: qcow2
virtual size: 50G (53687091200 bytes)
disk size: 196K
cluster_size: 65536
backing file: /home/sn2
Format specific information:
    compat: 1.1
    lazy refcounts: false

{ "execute": "query-block" }
{"return": [{"io-status": "ok", "device": "drive-scsi0-0-0", "locked": false, "removable": false, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"backing-image": {"backing-image": {"backing-image": {"virtual-size": 53687091200, "filename": "/home/nfs/rhel7u1cp1.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": 7207256064, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "backing-filename-format": "qcow2", "virtual-size": 53687091200, "filename": "/home/sn1", "cluster-size": 65536, "format": "qcow2", "actual-size": 200704, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "backing-filename": "/home/nfs/rhel7u1cp1.qcow2", "dirty-flag": false}, "backing-filename-format": "qcow2", "virtual-size": 53687091200, "filename": "/home/sn2", "cluster-size": 65536, "format": "qcow2", "actual-size": 200704, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "backing-filename": "/home/sn1", "dirty-flag": false}, "backing-filename-format": "qcow2", "virtual-size": 53687091200, "filename": "/home/sn3", "cluster-size": 65536, "format": "qcow2", "actual-size": 200704, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "backing-filename": "/home/sn2", "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 3, "drv": "qcow2", "iops": 0, "bps_wr": 0, "backing_file": "/home/sn2", "encrypted": false, "bps": 0, "bps_rd": 0, "file": "/home/sn3", "encryption_key_missing": false}, "type": "unknown"}]}

(qemu) info block
drive-scsi0-0-0: /home/sn3 (qcow2)
    Backing file:     /home/sn2 (chain depth: 3)
 
4.Do block-stream with absolute path of backing file:
{ "execute": "block-stream", "arguments": { "device": "drive-scsi0-0-0", "base": "/home/nfs/rhel7u1cp1.qcow2", "speed": 1000000000,  "backing-file": "/home/nfs/rhel7u1cp1.qcow2"} }

5.Then check as step3:
# qemu-img info sn3
image: sn3
file format: qcow2
virtual size: 50G (53687091200 bytes)
disk size: 196K
cluster_size: 65536
backing file: /home/nfs/rhel7u1cp1.qcow2   ------ absolute path
backing file format: qcow2
Format specific information:
    compat: 1.1
    lazy refcounts: false

(qemu) info block
drive-scsi0-0-0: /home/sn3 (qcow2)
    Backing file:     /home/nfs/rhel7u1cp1.qcow2 (chain depth: 1)  --- absolute 

{ "execute": "query-block" }
{"return": [{"io-status": "ok", "device": "drive-scsi0-0-0", "locked": false, "removable": false, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"backing-image": {"virtual-size": 53687091200, "filename": "/home/nfs/rhel7u1cp1.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": 7207256064, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "backing-filename-format": "qcow2", "virtual-size": 53687091200, "filename": "/home/sn3", "cluster-size": 65536, "format": "qcow2", "actual-size": 200704, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "backing-filename": "/home/nfs/rhel7u1cp1.qcow2", "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 1, "drv": "qcow2", "iops": 0, "bps_wr": 0, "backing_file": "/home/nfs/rhel7u1cp1.qcow2", "encrypted": false, "bps": 0, "bps_rd": 0, "file": "/home/sn3", "encryption_key_missing": false}, "type": "unknown"}]}



6. Do block-stream with relative path of backing file
{ "execute": "block-stream", "arguments": { "device": "drive-scsi0-0-0", "base": "/home/nfs/rhel7u1cp1.qcow2", "speed": 1000000000,  "backing-file": "./nfs/rhel7u1cp1.qcow2"} }

7.Then check as step3:
# qemu-img info sn3
image: sn3
file format: qcow2
virtual size: 50G (53687091200 bytes)
disk size: 196K
cluster_size: 65536
backing file: ./nfs/rhel7u1cp1.qcow2     -- relative 
backing file format: qcow2
Format specific information:
    compat: 1.1
    lazy refcounts: false


(qemu) info block
drive-scsi0-0-0: /home/sn3 (qcow2)
    Backing file:     /home/nfs/rhel7u1cp1.qcow2 (chain depth: 1)  -- absolute

{ "execute": "query-block" }
{"return": [{"io-status": "ok", "device": "drive-scsi0-0-0", "locked": false, "removable": false, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"backing-image": {"virtual-size": 53687091200, "filename": "/home/nfs/rhel7u1cp1.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": 7207256064, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "backing-filename-format": "qcow2", "virtual-size": 53687091200, "filename": "/home/sn3", "cluster-size": 65536, "format": "qcow2", "actual-size": 200704, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "backing-filename": "/home/nfs/rhel7u1cp1.qcow2", "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 1, "drv": "qcow2", "iops": 0, "bps_wr": 0, "backing_file": "/home/nfs/rhel7u1cp1.qcow2", "encrypted": false, "bps": 0, "bps_rd": 0, "file": "/home/sn3", "encryption_key_missing": false}, "type": "unknown"}]}


8.Do block-commit with absolute path of backing file
{ "execute": "block-commit", "arguments": { "device": "drive-scsi0-0-0", "base": "/home/nfs/rhel7u1cp1.qcow2", "top": "/home/sn2", "speed": 1000000000, "backing-file": "/home/nfs/rhel7u1cp1.qcow2"} }

9.Then check as step3:

# qemu-img info sn3
image: sn3
file format: qcow2
virtual size: 50G (53687091200 bytes)
disk size: 196K
cluster_size: 65536
backing file: /home/nfs/rhel7u1cp1.qcow2  -- absolute
backing file format: qcow2
Format specific information:
    compat: 1.1
    lazy refcounts: false

(qemu) info block
drive-scsi0-0-0: /home/sn3 (qcow2)
    Backing file:     /home/nfs/rhel7u1cp1.qcow2 (chain depth: 1) -- absolute

{ "execute": "query-block" }
{"return": [{"io-status": "ok", "device": "drive-scsi0-0-0", "locked": false, "removable": false, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"backing-image": {"virtual-size": 53687091200, "filename": "/home/nfs/rhel7u1cp1.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": 7207256064, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "backing-filename-format": "qcow2", "virtual-size": 53687091200, "filename": "/home/sn3", "cluster-size": 65536, "format": "qcow2", "actual-size": 200704, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "backing-filename": "/home/nfs/rhel7u1cp1.qcow2", "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 1, "drv": "qcow2", "iops": 0, "bps_wr": 0, "backing_file": "/home/nfs/rhel7u1cp1.qcow2", "encrypted": false, "bps": 0, "bps_rd": 0, "file": "/home/sn3", "encryption_key_missing": false}, "type": "unknown"}]}


10.Do block-commit with relative path of backing file

{ "execute": "block-commit", "arguments": { "device": "drive-scsi0-0-0", "base": "/home/nfs/rhel7u1cp1.qcow2", "top": "/home/sn2", "speed": 1000000000, "backing-file": "./nfs/rhel7u1cp1.qcow2"} }

11.Then check as step3:

# qemu-img info sn3
image: sn3
file format: qcow2
virtual size: 50G (53687091200 bytes)
disk size: 196K
cluster_size: 65536
backing file: ./nfs/rhel7u1cp1.qcow2     --- relative 
backing file format: qcow2
Format specific information:
    compat: 1.1
    lazy refcounts: false

(qemu) info block
drive-scsi0-0-0: /home/sn3 (qcow2)
    Backing file:     /home/nfs/rhel7u1cp1.qcow2 (chain depth: 1)   -- absolute 

{ "execute": "query-block" }
{"return": [{"io-status": "ok", "device": "drive-scsi0-0-0", "locked": false, "removable": false, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"backing-image": {"virtual-size": 53687091200, "filename": "/home/nfs/rhel7u1cp1.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": 7207256064, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "dirty-flag": false}, "backing-filename-format": "qcow2", "virtual-size": 53687091200, "filename": "/home/sn3", "cluster-size": 65536, "format": "qcow2", "actual-size": 200704, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false}}, "backing-filename": "/home/nfs/rhel7u1cp1.qcow2", "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 1, "drv": "qcow2", "iops": 0, "bps_wr": 0, "backing_file": "/home/nfs/rhel7u1cp1.qcow2", "encrypted": false, "bps": 0, "bps_rd": 0, "file": "/home/sn3", "encryption_key_missing": false}, "type": "unknown"}



According to above, qemu-img info can get the relative path but hmp and qmp can not, so set this bug as verified and filed a new bug against the hmp/qmp issue.
refer to bug 1152482

Comment 38 Qian Guo 2014-10-15 03:09:52 UTC
Additional infos:
From 
{ "execute": "query-commands"}
{"return": [{"name": "query-rx-filter"}, {"name": "blockdev-add"}, {"name": "chardev-remove"}, {"name": "chardev-add"}, {"name": "query-tpm-types"}, {"name": "query-tpm-models"}, {"name": "query-tpm"}, {"name": "query-target"}, {"name": "query-cpu-definitions"}, {"name": "query-machines"}, {"name": "device-list-properties"}, {"name": "qom-list-types"}, {"name": "change-vnc-password"}, {"name": "nbd-server-stop"}, {"name": "nbd-server-add"}, {"name": "nbd-server-start"}, {"name": "qom-get"}, {"name": "qom-set"}, {"name": "qom-list"}, {"name": "query-block-jobs"}, {"name": "query-balloon"}, {"name": "query-migrate-capabilities"}, {"name": "migrate-set-capabilities"}, {"name": "query-migrate"}, {"name": "query-command-line-options"}, {"name": "query-uuid"}, {"name": "query-name"}, {"name": "query-spice"}, {"name": "query-vnc"}, {"name": "query-mice"}, {"name": "query-status"}, {"name": "query-kvm"}, {"name": "query-pci"}, {"name": "query-cpus"}, {"name": "query-blockstats"}, {"name": "query-block"}, {"name": "query-chardev"}, {"name": "query-events"}, {"name": "query-commands"}, {"name": "query-version"}, {"name": "human-monitor-command"}, {"name": "qmp_capabilities"}, {"name": "add_client"}, {"name": "expire_password"}, {"name": "set_password"}, {"name": "block_set_io_throttle"}, {"name": "block_passwd"}, {"name": "query-fdsets"}, {"name": "remove-fd"}, {"name": "add-fd"}, {"name": "closefd"}, {"name": "getfd"}, {"name": "set_link"}, {"name": "balloon"}, {"name": "block-job-complete"}, {"name": "block-job-resume"}, {"name": "block-job-pause"}, {"name": "block-job-cancel"}, {"name": "block-job-set-speed"}, {"name": "block_resize"}, {"name": "netdev_del"}, {"name": "netdev_add"}, {"name": "dump-guest-memory"}, {"name": "client_migrate_info"}, {"name": "migrate_set_downtime"}, {"name": "migrate_set_speed"}, {"name": "query-migrate-cache-size"}, {"name": "migrate-set-cache-size"}, {"name": "migrate_cancel"}, {"name": "migrate"}, {"name": "xen-set-global-dirty-log"}, {"name": "xen-save-devices-state"}, {"name": "ringbuf-read"}, {"name": "ringbuf-write"}, {"name": "inject-nmi"}, {"name": "pmemsave"}, {"name": "memsave"}, {"name": "cpu-add"}, {"name": "cpu"}, {"name": "send-key"}, {"name": "device_del"}, {"name": "device_add"}, {"name": "system_powerdown"}, {"name": "system_reset"}, {"name": "system_wakeup"}, {"name": "cont"}, {"name": "stop"}, {"name": "__com.redhat_qxl_screendump"}, {"name": "screendump"}, {"name": "change"}, {"name": "__com.redhat_drive_del"}, {"name": "__com.redhat_drive_add"}, {"name": "eject"}, {"name": "quit"}]}


NO "__com.redhat_change-backing-file" command exist.

Comment 39 Qian Guo 2014-10-15 03:22:56 UTC
Please ignore comment 38, 

Re check the qmp command with qemu-kvm-rhev-2.1.2-3.el7.x86_64

{ "execute": "query-commands"}
{"return": [{"name": "rtc-reset-reinjection"}, {"name": "query-acpi-ospm-status"}, {"name": "query-memory-devices"}, {"name": "query-memdev"}, {"name": "query-named-block-nodes"}, {"name": "blockdev-add"}, {"name": "query-rx-filter"}, {"name": "chardev-remove"}, {"name": "chardev-add"}, {"name": "query-tpm-types"}, {"name": "query-tpm-models"}, {"name": "query-tpm"}, {"name": "query-target"}, {"name": "query-cpu-definitions"}, {"name": "query-machines"}, {"name": "device-list-properties"}, {"name": "qom-list-types"}, {"name": "change-vnc-password"}, {"name": "nbd-server-stop"}, {"name": "nbd-server-add"}, {"name": "nbd-server-start"}, {"name": "qom-get"}, {"name": "qom-set"}, {"name": "qom-list"}, {"name": "query-block-jobs"}, {"name": "query-balloon"}, {"name": "query-migrate-capabilities"}, {"name": "migrate-set-capabilities"}, {"name": "query-migrate"}, {"name": "query-command-line-options"}, {"name": "query-uuid"}, {"name": "query-name"}, {"name": "query-spice"}, {"name": "query-vnc"}, {"name": "query-mice"}, {"name": "query-status"}, {"name": "query-kvm"}, {"name": "query-pci"}, {"name": "query-iothreads"}, {"name": "query-cpus"}, {"name": "query-blockstats"}, {"name": "query-block"}, {"name": "query-chardev-backends"}, {"name": "query-chardev"}, {"name": "query-events"}, {"name": "query-commands"}, {"name": "query-version"}, {"name": "human-monitor-command"}, {"name": "qmp_capabilities"}, {"name": "add_client"}, {"name": "expire_password"}, {"name": "set_password"}, {"name": "block_set_io_throttle"}, {"name": "block_passwd"}, {"name": "query-fdsets"}, {"name": "remove-fd"}, {"name": "add-fd"}, {"name": "closefd"}, {"name": "getfd"}, {"name": "set_link"}, {"name": "balloon"}, {"name": "change-backing-file"}, {"name": "drive-mirror"}, {"name": "blockdev-snapshot-delete-internal-sync"}, {"name": "blockdev-snapshot-internal-sync"}, {"name": "blockdev-snapshot-sync"}, {"name": "transaction"}, {"name": "block-job-complete"}, {"name": "block-job-resume"}, {"name": "block-job-pause"}, {"name": "block-job-cancel"}, {"name": "block-job-set-speed"}, {"name": "drive-backup"}, {"name": "block-commit"}, {"name": "block-stream"}, {"name": "block_resize"}, {"name": "object-del"}, {"name": "object-add"}, {"name": "netdev_del"}, {"name": "netdev_add"}, {"name": "query-dump-guest-memory-capability"}, {"name": "dump-guest-memory"}, {"name": "client_migrate_info"}, {"name": "migrate_set_downtime"}, {"name": "migrate_set_speed"}, {"name": "query-migrate-cache-size"}, {"name": "migrate-set-cache-size"}, {"name": "migrate_cancel"}, {"name": "migrate"}, {"name": "xen-set-global-dirty-log"}, {"name": "xen-save-devices-state"}, {"name": "ringbuf-read"}, {"name": "ringbuf-write"}, {"name": "inject-nmi"}, {"name": "pmemsave"}, {"name": "memsave"}, {"name": "cpu-add"}, {"name": "cpu"}, {"name": "send-key"}, {"name": "device_del"}, {"name": "device_add"}, {"name": "system_powerdown"}, {"name": "system_reset"}, {"name": "system_wakeup"}, {"name": "cont"}, {"name": "stop"}, {"name": "__com.redhat_qxl_screendump"}, {"name": "screendump"}, {"name": "change"}, {"name": "__com.redhat_drive_del"}, {"name": "__com.redhat_drive_add"}, {"name": "eject"}, {"name": "quit"}]}


There is {"name": "change-backing-file"} command

Comment 41 errata-xmlrpc 2015-03-05 09:43:51 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/RHSA-2015-0624.html


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