Bug 1650497 - RFE: block-commit without root node as 'device'
Summary: RFE: block-commit without root node as 'device'
Keywords:
Status: NEW
Alias: None
Product: Red Hat Enterprise Linux Advanced Virtualization
Classification: Red Hat
Component: qemu-kvm
Version: ---
Hardware: Unspecified
OS: Unspecified
high
high
Target Milestone: rc
: ---
Assignee: Kevin Wolf
QA Contact: aihua liang
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2018-11-16 10:49 UTC by Gu Nini
Modified: 2020-02-05 22:51 UTC (History)
8 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed:
Type: Feature Request
Target Upstream Version:


Attachments (Terms of Use)
query-named-block-nodes_output-11162018 (10.00 KB, text/plain)
2018-11-16 11:19 UTC, Gu Nini
no flags Details

Description Gu Nini 2018-11-16 10:49:02 UTC
Description of problem:


Version-Release number of selected component (if applicable):
Host kernel: 4.18.0-32.el8.ppc64le
qemu: upstream v3.1.0-rc1-dirty

How reproducible:
100%

Steps to Reproduce:
1.
2.
3.

Actual results:


Expected results:


Additional info:

Comment 1 Gu Nini 2018-11-16 11:17:59 UTC
Description of problem:
This is in fact the issue of https://bugzilla.redhat.com/show_bug.cgi?id=1623986#c11 , but I also met it after the application of auto-read-only in upstream qemu(i.e. after the fix of above bz), so report it out as a separate one.

Version-Release number of selected component (if applicable):
Host kernel: 4.18.0-32.el8.ppc64le
qemu: upstream v3.1.0-rc1-dirty

Steps to Reproduce:
1. Boot up a guest with its system disk:
    -blockdev node-name=disk0,file.driver=file,driver=qcow2,file.filename=/home/rhel80-ppc64le-upstream.qcow2,file.read-only=off,file.auto-read-only=on,read-only=on \
    -device scsi-hd,drive=disk0,id=image0,bootindex=0 \

# ./vm00.sh
QEMU 3.0.91 monitor - type 'help' for more information
(qemu) info block
floppy0: [not inserted]
    Removable device: not locked, tray closed

sd0: [not inserted]
    Removable device: not locked, tray closed

disk0: /home/rhel80-ppc64le-upstream.qcow2 (qcow2, read-only)
    Attached to:      image0
    Cache mode:       writeback
(qemu) 

2. Create 4 snapshots with blockdev-create/blockdev-snapshot(disk0->sn1->sn2->sn3->sn4):
#!/bin/bash

for i in {1..4}
do
echo -e "{'execute':'qmp_capabilities'} {'execute':'blockdev-create','arguments':{'options': {'driver':'file','filename':'/home/sn$i.qcow2','size':21474836480},'job-id':'job1'}}" | nc -U /var/tmp/avocado1
sleep 1
echo -e "{'execute':'qmp_capabilities'} {'execute':'blockdev-add','arguments':{'driver':'file','node-name':'driveimage$i','filename':'/home/sn$i.qcow2'}}" | nc -U /var/tmp/avocado1
sleep 1
echo -e "{'execute':'qmp_capabilities'} {'execute':'blockdev-create','arguments':{'options': {'cluster-size':131072, 'driver': 'qcow2', 'file': 'driveimage$i', 'size': 21474836480},'job-id': 'job2'}}" | nc -U /var/tmp/avocado1
sleep 5
echo -e "{'execute':'qmp_capabilities'} {'execute':'blockdev-add','arguments':{'driver':'qcow2','node-name':'disk$i','file':'driveimage$i'}}" | nc -U /var/tmp/avocado1
sleep 5
echo -e "{'execute':'qmp_capabilities'} {'execute':'job-dismiss','arguments':{'id':'job1'}}" | nc -U /var/tmp/avocado1
sleep 1
echo -e "{'execute':'qmp_capabilities'} {'execute':'job-dismiss','arguments':{'id':'job2'}}" | nc -U /var/tmp/avocado1
sleep 1
echo -e "{'execute':'qmp_capabilities'} {'execute':'blockdev-snapshot','arguments':{'node':'disk$((i-1))','overlay':'disk$i'}}" | nc -U /var/tmp/avocado1
sleep 2
done

3. Do block-commit from sn4->sn3:
{'execute': 'block-commit', 'arguments': { 'device': 'disk4', 'speed': 1000000000, 'base-node': 'disk3', 'top-node': 'disk4', 'job-id':'j1'}}
{ "execute" : "block-job-complete", "arguments" :{ "device": "j1"} }

4. Check block info:
{ "execute" : "query-block"}
{"return": [{"device": "floppy0", "locked": false, "removable": true, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "type": "unknown"}, {"io-status": "ok", "device": "", "locked": false, "removable": false, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"backing-image": {"backing-image": {"backing-image": {"virtual-size": 21474836480, "filename": "/home/rhel80-ppc64le-upstream.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": 2451247104, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "refcount-bits": 16, "corrupt": false}}, "dirty-flag": false}, "backing-filename-format": "qcow2", "virtual-size": 21474836480, "filename": "/home/sn1.qcow2", "cluster-size": 131072, "format": "qcow2", "actual-size": 589824, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "refcount-bits": 16, "corrupt": false}}, "full-backing-filename": "/home/rhel80-ppc64le-upstream.qcow2", "backing-filename": "/home/rhel80-ppc64le-upstream.qcow2", "dirty-flag": false}, "backing-filename-format": "qcow2", "virtual-size": 21474836480, "filename": "/home/sn2.qcow2", "cluster-size": 131072, "format": "qcow2", "actual-size": 589824, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "refcount-bits": 16, "corrupt": false}}, "full-backing-filename": "/home/sn1.qcow2", "backing-filename": "/home/sn1.qcow2", "dirty-flag": false}, "backing-filename-format": "qcow2", "virtual-size": 21474836480, "filename": "/home/sn3.qcow2", "cluster-size": 131072, "format": "qcow2", "actual-size": 589824, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "refcount-bits": 16, "corrupt": false}}, "full-backing-filename": "/home/sn2.qcow2", "backing-filename": "/home/sn2.qcow2", "dirty-flag": false}, "iops_wr": 0, "ro": false, "node-name": "disk3", "backing_file_depth": 3, "drv": "qcow2", "iops": 0, "bps_wr": 0, "write_threshold": 0, "backing_file": "/home/sn2.qcow2", "encrypted": false, "bps": 0, "bps_rd": 0, "cache": {"no-flush": false, "direct": false, "writeback": true}, "file": "/home/sn3.qcow2", "encryption_key_missing": false}, "qdev": "image0", "type": "unknown"}]}

{ "execute" : "query-named-block-nodes"}
Please refer to attachment 'query-named-block-nodes_output-11162018'

5. Do block-commit again from sn3->sn1:
{'execute': 'block-commit', 'arguments': { 'device': 'disk3', 'speed': 1000000000, 'base-node': 'disk1', 'top-node': 'disk3', 'job-id':'j1'}}
{"error": {"class": "GenericError", "desc": "Need a root block node"}}

{'execute': 'block-commit', 'arguments': { 'device': 'disk4', 'speed': 1000000000, 'base-node': 'disk1', 'top-node': 'disk3', 'job-id':'j1'}}
{"timestamp": {"seconds": 1542366253, "microseconds": 255860}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "j1"}}
{"timestamp": {"seconds": 1542366253, "microseconds": 256151}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "j1"}}
{"return": {}}
{"timestamp": {"seconds": 1542366253, "microseconds": 898307}, "event": "JOB_STATUS_CHANGE", "data": {"status": "waiting", "id": "j1"}}
{"timestamp": {"seconds": 1542366253, "microseconds": 898340}, "event": "JOB_STATUS_CHANGE", "data": {"status": "pending", "id": "j1"}}
{"timestamp": {"seconds": 1542366253, "microseconds": 898706}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "j1", "len": 21474836480, "offset": 21474836480, "speed": 1000000000, "type": "commit"}}
{"timestamp": {"seconds": 1542366253, "microseconds": 898747}, "event": "JOB_STATUS_CHANGE", "data": {"status": "concluded", "id": "j1"}}
{"timestamp": {"seconds": 1542366253, "microseconds": 898779}, "event": "JOB_STATUS_CHANGE", "data": {"status": "null", "id": "j1"}}


Actual results:
In step4, from 'query-block' output, only 3 snapshots(sn1/sn2/sn3) exist as showed in the steps; while from 'query-named-block-nodes' output, there are all 4 snapshots created in previous.
In step5, it's proved the root block node is not the active layer sn3, while it's the original one sn4.

Expected results:
In step4, from 'query-named-block-nodes' output, there are only 3 snapshots with correct backing file.
In step5, the root block node should be sn3, i.e., the active layer.

Additional info:

Comment 2 Gu Nini 2018-11-16 11:19:02 UTC
Created attachment 1506392 [details]
query-named-block-nodes_output-11162018

Comment 3 Kevin Wolf 2018-11-16 13:00:29 UTC
So, in summary, you start with a graph like this:

disk0 <- disk1 <- disk2 <- disk3 <- disk4 <- image0 (= scsi-hd)

Each of disk* are explicitly created with blockdev-add, so the monitor hold a reference to each node. After the commit operation you end up with:

disk0 <- disk1 <- disk2 <- disk3 <- image0 (= scsi-hd)
                               ^
                               |
                               +--- disk4

disk4 is still referenced by the monitor, so it doesn't go away automatically. You would have to call an explicit blockdev-del for this.

Now block-commit only supports committing from a root node, which means in this case a node that has only BlockBackends as its parent, not other nodes. As long as you don't blockdev-delete disk4, this condition is not fulfilled and the operation will fail.

In the short term this shouldn't be a practical problem because libvirt probably doesn't try something like this and could just blockdev-delete the node, but in the long term this is a restriction that we should get rid of. As far as I know, the reason for the restriction is the old op blocker system which works at the root node level. So in order to lifting the restriction, we need to convert the commit op blocker to a different mechanism.

Comment 4 Ademar Reis 2020-02-05 22:51:35 UTC
QEMU has been recently split into sub-components and as a one-time operation to avoid breakage of tools, we are setting the QEMU sub-component of this BZ to "General". Please review and change the sub-component if necessary the next time you review this BZ. Thanks


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