Skip to content

Commit

Permalink
vmdk: Reject excess extents in blockdev-create
Browse files Browse the repository at this point in the history
Clarify that the number of extents provided in BlockdevCreateOptionsVmdk
must match the number of extents that will actually be used. Providing
more extents will result in an error now.

This requires adapting the test case to provide the right number of
extents.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
  • Loading branch information
kevmw committed Feb 1, 2019
1 parent 1c4e7b6 commit 4a960ec
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 13 deletions.
29 changes: 24 additions & 5 deletions block/vmdk.c
Expand Up @@ -1970,6 +1970,7 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
{
int extent_idx;
BlockBackend *blk = NULL;
BlockBackend *extent_blk;
Error *local_err = NULL;
char *desc = NULL;
int ret = 0;
Expand Down Expand Up @@ -2107,7 +2108,6 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
}
extent_idx = 1;
while (created_size < size) {
BlockBackend *extent_blk;
int64_t cur_size = MIN(size - created_size, extent_size);
extent_blk = extent_fn(cur_size, extent_idx, flat, split, compress,
zeroed_grain, opaque, errp);
Expand All @@ -2121,6 +2121,17 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
extent_idx++;
blk_unref(extent_blk);
}

/* Check whether we got excess extents */
extent_blk = extent_fn(-1, extent_idx, flat, split, compress, zeroed_grain,
opaque, NULL);
if (extent_blk) {
blk_unref(extent_blk);
error_setg(errp, "List of extents contains unused extents");
ret = -EINVAL;
goto exit;
}

/* generate descriptor file */
desc = g_strdup_printf(desc_template,
g_random_int(),
Expand Down Expand Up @@ -2181,6 +2192,12 @@ static BlockBackend *vmdk_co_create_opts_cb(int64_t size, int idx,
char *ext_filename = NULL;
char *rel_filename = NULL;

/* We're done, don't create excess extents. */
if (size == -1) {
assert(errp == NULL);
return NULL;
}

if (idx == 0) {
rel_filename = g_strdup_printf("%s%s", data->prefix, data->postfix);
} else if (split) {
Expand Down Expand Up @@ -2342,10 +2359,12 @@ static BlockBackend *vmdk_co_create_cb(int64_t size, int idx,
blk_set_allow_write_beyond_eof(blk, true);
bdrv_unref(bs);

ret = vmdk_init_extent(blk, size, flat, compress, zeroed_grain, errp);
if (ret) {
blk_unref(blk);
blk = NULL;
if (size != -1) {
ret = vmdk_init_extent(blk, size, flat, compress, zeroed_grain, errp);
if (ret) {
blk_unref(blk);
blk = NULL;
}
}
return blk;
}
Expand Down
3 changes: 2 additions & 1 deletion qapi/block-core.json
Expand Up @@ -4184,7 +4184,8 @@
# twoGbMaxExtentSparse and twoGbMaxExtentFlat formats. For
# monolithicFlat, only one entry is required; for
# twoGbMaxExtent* formats, the number of entries required is
# calculated as extent_number = virtual_size / 2GB.
# calculated as extent_number = virtual_size / 2GB. Providing
# more extents than will be used is an error.
# @subformat The subformat of the VMDK image. Default: "monolithicSparse".
# @backing-file The path of backing file. Default: no backing file is used.
# @adapter-type The adapter type used to fill in the descriptor. Default: ide.
Expand Down
6 changes: 5 additions & 1 deletion tests/qemu-iotests/237
Expand Up @@ -20,6 +20,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

import math
import iotests
from iotests import imgfmt

Expand Down Expand Up @@ -222,12 +223,15 @@ with iotests.FilePath('t.vmdk') as disk_path, \
iotests.log("= %s %d =" % (subfmt, size))
iotests.log("")

num_extents = math.ceil(size / 2.0**31)
extents = [ "ext%d" % (i) for i in range(1, num_extents + 1) ]

vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': size,
'subformat': subfmt,
'extents': ['ext1', 'ext2', 'ext3'] })
'extents': extents })
vm.shutdown()

iotests.img_info_log(disk_path)
13 changes: 7 additions & 6 deletions tests/qemu-iotests/237.out
Expand Up @@ -154,14 +154,15 @@ Job failed: Extent [0] not specified

{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "monolithicFlat"}}}
{"return": {}}
Job failed: List of extents contains unused extents
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}

== Split formats ==

= twoGbMaxExtentFlat 512 =

{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentFlat"}}}
{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentFlat"}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
Expand All @@ -181,7 +182,7 @@ Format specific information:

= twoGbMaxExtentSparse 512 =

{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentSparse"}}}
{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentSparse"}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
Expand All @@ -203,7 +204,7 @@ Format specific information:

= twoGbMaxExtentFlat 1073741824 =

{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentFlat"}}}
{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentFlat"}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
Expand All @@ -223,7 +224,7 @@ Format specific information:

= twoGbMaxExtentSparse 1073741824 =

{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentSparse"}}}
{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentSparse"}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
Expand All @@ -245,7 +246,7 @@ Format specific information:

= twoGbMaxExtentFlat 2147483648 =

{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentFlat"}}}
{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentFlat"}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
Expand All @@ -265,7 +266,7 @@ Format specific information:

= twoGbMaxExtentSparse 2147483648 =

{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentSparse"}}}
{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentSparse"}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
Expand Down

0 comments on commit 4a960ec

Please sign in to comment.