Bug 1414049 - [RFE] Add support to qemu-img for resizing with preallocation
Summary: [RFE] Add support to qemu-img for resizing with preallocation
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: qemu-kvm-rhev
Version: 7.3
Hardware: Unspecified
OS: Unspecified
high
medium
Target Milestone: rc
: ---
Assignee: Max Reitz
QA Contact: Ping Li
URL:
Whiteboard:
Keywords: FutureFeature
: 1415820 (view as bug list)
Depends On:
Blocks: 1475978 1415820 1475979
TreeView+ depends on / blocked
 
Reported: 2017-01-17 15:46 UTC by Denis Chaplygin
Modified: 2018-04-11 00:15 UTC (History)
20 users (show)

(edit)
Clone Of:
: 1415820 1475978 1475979 (view as bug list)
(edit)
Last Closed: 2018-04-11 00:12:33 UTC


Attachments (Terms of Use)


External Trackers
Tracker ID Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2018:1104 None None None 2018-04-11 00:15 UTC

Description Denis Chaplygin 2017-01-17 15:46:23 UTC
Description of problem:
At the moment qemu-img allows you to specify how image file should be allocated during creation, using 'preallocation' option. Onr of possible choices is using 'falloc' option to fully allocate image file using fallocate(2) call.

Unfortunately, resize operation only supports sparse resizing and there is no way to preallocate new disk space during resize operation. 

It would be nice, if qemu-img will support preallocation during resize with fallocate(2) and, possibly, some fallback preallocation method.

Comment 2 Nir Soffer 2017-02-06 16:25:59 UTC
Supporting the same preallocation=(off|falloc|full) option as in create would be
nice.

Comment 3 Max Reitz 2017-02-07 22:32:33 UTC
(In reply to Nir Soffer from comment #2)
> Supporting the same preallocation=(off|falloc|full) option as in create
> would be nice.

Indeed. I had some ideas when someone asked for the same feature upstream just a day before this BZ was opened:

http://lists.nongnu.org/archive/html/qemu-block/2017-01/msg00193.html

The thing is that for qemu-img it would probably be rather simple since we could probably just manually do the necessary work after the file has been resized.

But I'm also thinking about the online use case (QMP's block_resize). This will be more difficult considering that fallocate() is hardly instant and would thus, strictly speaking, require a block job. Writing zeroes for preallocation=full isn't instant at all, of course, so this would require a block job anyway.

It's also complicated by the fact that the guest might want to write something to the newly added space, so it would be bad to blindly overwrite it with zeroes.

Max

Comment 4 Nir Soffer 2017-02-08 09:44:59 UTC
(In reply to Max Reitz from comment #3)
> (In reply to Nir Soffer from comment #2)
> > Supporting the same preallocation=(off|falloc|full) option as in create
> > would be nice.
> 
> Indeed. I had some ideas when someone asked for the same feature upstream
> just a day before this BZ was opened:
> 
> http://lists.nongnu.org/archive/html/qemu-block/2017-01/msg00193.html
> 
> The thing is that for qemu-img it would probably be rather simple since we
> could probably just manually do the necessary work after the file has been
> resized.

It will not be a good idea to preallocate *after* resizing, better resize by
preallocating; may be much faster when using file system that does not support
fallocate (e.g. NFS < 4.2).

See http://lists.nongnu.org/archive/html/qemu-block/2017-02/msg00172.html

> But I'm also thinking about the online use case (QMP's block_resize). This
> will be more difficult considering that fallocate() is hardly instant and
> would thus, strictly speaking, require a block job. Writing zeroes for
> preallocation=full isn't instant at all, of course, so this would require a
> block job anyway.
> 
> It's also complicated by the fact that the guest might want to write
> something to the newly added space, so it would be bad to blindly overwrite
> it with zeroes.

This use case is less interesting for us (ovirt) now, but resizing by
preallocating also avoid any race.

Comment 5 Ping Li 2017-03-14 10:03:36 UTC
Hi Max,

As the flag rhel-7.4.0? is set, qe wonder to know whether the issue will be fixed in rhel 7.4? Then qe can add it to RHEL 7.4 test plan for disk format. Thanks.

Comment 6 Ademar Reis 2017-03-14 15:04:02 UTC
(In reply to pingl from comment #5)
> Hi Max,
> 
> As the flag rhel-7.4.0? is set, qe wonder to know whether the issue will be
> fixed in rhel 7.4? Then qe can add it to RHEL 7.4 test plan for disk format.
> Thanks.

The patches have just been pushed upstream: https://www.mail-archive.com/qemu-devel@nongnu.org/msg436979.html and are pending review.

I've devel_ack+ it, it's worth backporting to RHEL-7.5.

Comment 8 Max Reitz 2017-03-15 22:44:39 UTC
Hi,

As for BZ 1415820, I think it will be difficult to get this into 7.4 (even more so than for BZ 1415820 because this BZ here is for RHEL instead of RHV). I can't rule it out but I think the probability that we are going to make it is very low.


Max

Comment 9 Nir Soffer 2017-03-16 08:50:49 UTC
This bug is not urgent for RHEV.

Currently we are allocating using dd, and we have this pending patch to preallocate
with posix_fallocate in a more efficient way:
https://gerrit.ovirt.org/70884

We like to use qemu-img instead, but we can wait for this.

Comment 12 Ademar Reis 2017-05-22 21:24:15 UTC
*** Bug 1415820 has been marked as a duplicate of this bug. ***

Comment 14 Ping Li 2017-10-09 16:18:16 UTC
Verified the issue with below packages:
kernel-3.10.0-727.el7.x86_64
qemu-kvm-rhev-2.10.0-1.el7

Test steps:
1. Create image with qcow2 format
# qemu-img create -f qcow2 test.qcow2 1G
Formatting 'test.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16
# qemu-img info test.qcow2 
image: test.qcow2
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 196K
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

2. Resize image with preallocation mode: "off", "metadata", "falloc", "full".
2.1 "off" mode
# qemu-img resize --preallocation=off test.qcow2 +1G
Image resized.
# qemu-img info test.qcow2 
image: test.qcow2
file format: qcow2
virtual size: 2.0G (2147483648 bytes)
disk size: 260K
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

2.2 "metadata" mode
# qemu-img resize --preallocation=metadata test.qcow2 +1G
Image resized.
# qemu-img info test.qcow2 
image: test.qcow2
file format: qcow2
virtual size: 2.0G (2147483648 bytes)
disk size: 388K
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

2.3 "falloc" mode        --------> Failed
# qemu-img resize --preallocation=falloc test.qcow2 +1G
qemu-img: block/qcow2-refcount.c:529: qcow2_refcount_area: Assertion `!(start_offset % s->cluster_size)' failed.
Aborted
# echo $?
134

2.4 "full" mode          --------> Failed
# qemu-img resize --preallocation=full test.qcow2 +1G
qemu-img: block/qcow2-refcount.c:529: qcow2_refcount_area: Assertion `!(start_offset % s->cluster_size)' failed.
Aborted
# echo $?
134

3. Create image with raw format
# qemu-img create -f raw test.img 1G
Formatting 'test.img', fmt=raw size=1073741824
# qemu-img info test.img 
image: test.img
file format: raw
virtual size: 1.0G (1073741824 bytes)
disk size: 0

4. Resize image with preallocation mode: "off", "falloc", "full".
4.1 "off" mode
# qemu-img resize --preallocation=off test.img +1G
WARNING: Image format was not specified for 'test.img' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
Image resized.
# qemu-img info test.img 
image: test.img
file format: raw
virtual size: 2.0G (2147483648 bytes)
disk size: 0

4.2 "falloc" mode
# qemu-img resize --preallocation=falloc test.img +1G
WARNING: Image format was not specified for 'test.img' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
Image resized.
# qemu-img info test.img 
image: test.img
file format: raw
virtual size: 2.0G (2147483648 bytes)
disk size: 1.0G

4.3 "full" mode
# qemu-img resize --preallocation=full test.img +1G
WARNING: Image format was not specified for 'test.img' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
Image resized.
# qemu-img info test.img 
image: test.img
file format: raw
virtual size: 2.0G (2147483648 bytes)
disk size: 1.0G

Comment 15 Max Reitz 2017-10-09 20:19:01 UTC
Oops. Thanks for spotting that bug and that the test I wrote is apparently severely lacking...

I'll write a patch.

Max

Comment 17 Miroslav Rezanina 2017-11-30 16:53:43 UTC
Fix included in qemu-kvm-rhev-2.10.0-10.el7

Comment 19 Ping Li 2017-12-01 08:21:53 UTC
Passed the test as below, set the bug as verified.

Verified the issue with below packages:
kernel3.10.0-800.el7.x86_64
qemu-kvm-rhev-2.10.0-10.el7

Test steps:
1. Create image with qcow2 format
# qemu-img create -f qcow2 test.qcow2 1G
Formatting 'test.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16
# qemu-img info test.qcow2 
image: test.qcow2
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 196K
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

2. Resize image with preallocation mode: "off", "metadata", "falloc", "full".
2.1 "off" mode
# qemu-img resize --preallocation=off test.qcow2 +1G
Image resized.
# qemu-img map --output=json test.qcow2
[{ "start": 0, "length": 2147483648, "depth": 0, "zero": true, "data": false}]
# qemu-img info test.qcow2 
image: test.qcow2
file format: qcow2
virtual size: 2.0G (2147483648 bytes)
disk size: 260K
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

2.2 "metadata" mode
# qemu-img resize --preallocation=metadata test.qcow2 +1G
Image resized.
# qemu-img map --output=json test.qcow2 ---> "data" becomes true once image size  is over 1GB
[{ "start": 0, "length": 1073741824, "depth": 0, "zero": true, "data": false},
{ "start": 1073741824, "length": 536870912, "depth": 0, "zero": true, "data": true, "offset": 327680},
{ "start": 1610612736, "length": 536866816, "depth": 0, "zero": true, "data": true, "offset": 537264128},
{ "start": 2147479552, "length": 4096, "depth": 0, "zero": false, "data": true, "offset": 1074130944}]
# qemu-img info test.qcow2
image: test.qcow2
file format: qcow2
virtual size: 2.0G (2147483648 bytes)
disk size: 388K
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

2.3 "falloc" mode
# qemu-img resize --preallocation=falloc test.qcow2 +1G
Image resized.
# qemu-img map --output=json test.qcow2 ---> "data" becomes true once image size  is over 1GB
[{ "start": 0, "length": 1073741824, "depth": 0, "zero": true, "data": false},
{ "start": 1073741824, "length": 65536, "depth": 0, "zero": false, "data": true, "offset": 393216},
{ "start": 1073807360, "length": 1073676288, "depth": 0, "zero": true, "data": true, "offset": 458752}]
# qemu-img info test.qcow2
image: test.qcow2
file format: qcow2
virtual size: 2.0G (2147483648 bytes)
disk size: 1.0G
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

2.4 "full" mode
# qemu-img resize --preallocation=full test.qcow2 +1G
Image resized.
# qemu-img map --output=json test.qcow2 ---> "data" becomes true once image size  is over 1GB
[{ "start": 0, "length": 1073741824, "depth": 0, "zero": true, "data": false},
{ "start": 1073741824, "length": 1073741824, "depth": 0, "zero": false, "data": true, "offset": 393216}]
# qemu-img info test.qcow2
image: test.qcow2
file format: qcow2
virtual size: 2.0G (2147483648 bytes)
disk size: 1.0G
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false
    refcount bits: 16
    corrupt: false

3. Create image with raw format
# qemu-img create -f raw test.img 1G
Formatting 'test.img', fmt=raw size=1073741824
# qemu-img info test.img 
image: test.img
file format: raw
virtual size: 1.0G (1073741824 bytes)
disk size: 0

4. Resize image with preallocation mode: "off", "falloc", "full".
4.1 "off" mode
# qemu-img resize --preallocation=off test.img +1G
WARNING: Image format was not specified for 'test.img' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
Image resized.
# qemu-img map --output=json test.img 
[{ "start": 0, "length": 2147483648, "depth": 0, "zero": true, "data": false, "offset": 0}]
# qemu-img info test.img 
image: test.img
file format: raw
virtual size: 2.0G (2147483648 bytes)
disk size: 0

4.2 "falloc" mode
# qemu-img resize --preallocation=falloc test.img +1G
WARNING: Image format was not specified for 'test.img' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
Image resized.
# qemu-img map --output=json test.img 
[{ "start": 0, "length": 2147483648, "depth": 0, "zero": true, "data": false, "offset": 0}]
# qemu-img info test.img 
image: test.img
file format: raw
virtual size: 2.0G (2147483648 bytes)
disk size: 1.0G

4.3 "full" mode
# qemu-img resize --preallocation=full test.img +1G
WARNING: Image format was not specified for 'test.img' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
Image resized.
# qemu-img map --output=json test.img ---> "data" becomes true once image size  is over 1GB
[{ "start": 0, "length": 1073741824, "depth": 0, "zero": true, "data": false, "offset": 0},
{ "start": 1073741824, "length": 1073741824, "depth": 0, "zero": false, "data": true, "offset": 1073741824}]
# qemu-img info test.img 
image: test.img
file format: raw
virtual size: 2.0G (2147483648 bytes)
disk size: 1.0G

Comment 22 errata-xmlrpc 2018-04-11 00:12:33 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://access.redhat.com/errata/RHSA-2018:1104


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