mirror of https://github.com/xemu-project/xemu.git
vmdk: Reject excess extents in blockdev-create
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>
This commit is contained in:
parent
1c4e7b640b
commit
4a960ece17
29
block/vmdk.c
29
block/vmdk.c
|
@ -1970,6 +1970,7 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
|
||||||
{
|
{
|
||||||
int extent_idx;
|
int extent_idx;
|
||||||
BlockBackend *blk = NULL;
|
BlockBackend *blk = NULL;
|
||||||
|
BlockBackend *extent_blk;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
char *desc = NULL;
|
char *desc = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
@ -2107,7 +2108,6 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
|
||||||
}
|
}
|
||||||
extent_idx = 1;
|
extent_idx = 1;
|
||||||
while (created_size < size) {
|
while (created_size < size) {
|
||||||
BlockBackend *extent_blk;
|
|
||||||
int64_t cur_size = MIN(size - created_size, extent_size);
|
int64_t cur_size = MIN(size - created_size, extent_size);
|
||||||
extent_blk = extent_fn(cur_size, extent_idx, flat, split, compress,
|
extent_blk = extent_fn(cur_size, extent_idx, flat, split, compress,
|
||||||
zeroed_grain, opaque, errp);
|
zeroed_grain, opaque, errp);
|
||||||
|
@ -2121,6 +2121,17 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
|
||||||
extent_idx++;
|
extent_idx++;
|
||||||
blk_unref(extent_blk);
|
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 */
|
/* generate descriptor file */
|
||||||
desc = g_strdup_printf(desc_template,
|
desc = g_strdup_printf(desc_template,
|
||||||
g_random_int(),
|
g_random_int(),
|
||||||
|
@ -2181,6 +2192,12 @@ static BlockBackend *vmdk_co_create_opts_cb(int64_t size, int idx,
|
||||||
char *ext_filename = NULL;
|
char *ext_filename = NULL;
|
||||||
char *rel_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) {
|
if (idx == 0) {
|
||||||
rel_filename = g_strdup_printf("%s%s", data->prefix, data->postfix);
|
rel_filename = g_strdup_printf("%s%s", data->prefix, data->postfix);
|
||||||
} else if (split) {
|
} else if (split) {
|
||||||
|
@ -2342,10 +2359,12 @@ static BlockBackend *vmdk_co_create_cb(int64_t size, int idx,
|
||||||
blk_set_allow_write_beyond_eof(blk, true);
|
blk_set_allow_write_beyond_eof(blk, true);
|
||||||
bdrv_unref(bs);
|
bdrv_unref(bs);
|
||||||
|
|
||||||
ret = vmdk_init_extent(blk, size, flat, compress, zeroed_grain, errp);
|
if (size != -1) {
|
||||||
if (ret) {
|
ret = vmdk_init_extent(blk, size, flat, compress, zeroed_grain, errp);
|
||||||
blk_unref(blk);
|
if (ret) {
|
||||||
blk = NULL;
|
blk_unref(blk);
|
||||||
|
blk = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4184,7 +4184,8 @@
|
||||||
# twoGbMaxExtentSparse and twoGbMaxExtentFlat formats. For
|
# twoGbMaxExtentSparse and twoGbMaxExtentFlat formats. For
|
||||||
# monolithicFlat, only one entry is required; for
|
# monolithicFlat, only one entry is required; for
|
||||||
# twoGbMaxExtent* formats, the number of entries required is
|
# 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".
|
# @subformat The subformat of the VMDK image. Default: "monolithicSparse".
|
||||||
# @backing-file The path of backing file. Default: no backing file is used.
|
# @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.
|
# @adapter-type The adapter type used to fill in the descriptor. Default: ide.
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import math
|
||||||
import iotests
|
import iotests
|
||||||
from iotests import imgfmt
|
from iotests import imgfmt
|
||||||
|
|
||||||
|
@ -222,12 +223,15 @@ with iotests.FilePath('t.vmdk') as disk_path, \
|
||||||
iotests.log("= %s %d =" % (subfmt, size))
|
iotests.log("= %s %d =" % (subfmt, size))
|
||||||
iotests.log("")
|
iotests.log("")
|
||||||
|
|
||||||
|
num_extents = math.ceil(size / 2.0**31)
|
||||||
|
extents = [ "ext%d" % (i) for i in range(1, num_extents + 1) ]
|
||||||
|
|
||||||
vm.launch()
|
vm.launch()
|
||||||
blockdev_create(vm, { 'driver': imgfmt,
|
blockdev_create(vm, { 'driver': imgfmt,
|
||||||
'file': 'node0',
|
'file': 'node0',
|
||||||
'size': size,
|
'size': size,
|
||||||
'subformat': subfmt,
|
'subformat': subfmt,
|
||||||
'extents': ['ext1', 'ext2', 'ext3'] })
|
'extents': extents })
|
||||||
vm.shutdown()
|
vm.shutdown()
|
||||||
|
|
||||||
iotests.img_info_log(disk_path)
|
iotests.img_info_log(disk_path)
|
||||||
|
|
|
@ -154,6 +154,7 @@ 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"}}}
|
{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "monolithicFlat"}}}
|
||||||
{"return": {}}
|
{"return": {}}
|
||||||
|
Job failed: List of extents contains unused extents
|
||||||
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
||||||
{"return": {}}
|
{"return": {}}
|
||||||
|
|
||||||
|
@ -161,7 +162,7 @@ Job failed: Extent [0] not specified
|
||||||
|
|
||||||
= twoGbMaxExtentFlat 512 =
|
= 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": {}}
|
{"return": {}}
|
||||||
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
||||||
{"return": {}}
|
{"return": {}}
|
||||||
|
@ -181,7 +182,7 @@ Format specific information:
|
||||||
|
|
||||||
= twoGbMaxExtentSparse 512 =
|
= 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": {}}
|
{"return": {}}
|
||||||
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
||||||
{"return": {}}
|
{"return": {}}
|
||||||
|
@ -203,7 +204,7 @@ Format specific information:
|
||||||
|
|
||||||
= twoGbMaxExtentFlat 1073741824 =
|
= 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": {}}
|
{"return": {}}
|
||||||
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
||||||
{"return": {}}
|
{"return": {}}
|
||||||
|
@ -223,7 +224,7 @@ Format specific information:
|
||||||
|
|
||||||
= twoGbMaxExtentSparse 1073741824 =
|
= 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": {}}
|
{"return": {}}
|
||||||
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
||||||
{"return": {}}
|
{"return": {}}
|
||||||
|
@ -245,7 +246,7 @@ Format specific information:
|
||||||
|
|
||||||
= twoGbMaxExtentFlat 2147483648 =
|
= 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": {}}
|
{"return": {}}
|
||||||
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
||||||
{"return": {}}
|
{"return": {}}
|
||||||
|
@ -265,7 +266,7 @@ Format specific information:
|
||||||
|
|
||||||
= twoGbMaxExtentSparse 2147483648 =
|
= 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": {}}
|
{"return": {}}
|
||||||
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
|
||||||
{"return": {}}
|
{"return": {}}
|
||||||
|
|
Loading…
Reference in New Issue