diff mbox

[v5,11/22] block: Allow block devices without files

Message ID 1386954633-28905-12-git-send-email-mreitz@redhat.com
State New
Headers show

Commit Message

Max Reitz Dec. 13, 2013, 5:10 p.m. UTC
blkdebug and blkverify will, in order to retain compatibility, not
support the field "file" implicitly through bdrv_open(). In order to be
able to use those drivers without giving a filename anyway, it is
necessary to be able to have block devices without files implicitly
opened by bdrv_open(). This is the case, if there was neither a file
name, a reference to an existing block device to use as a file nor
options specific to the file.

Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

Comments

Kevin Wolf Dec. 13, 2013, 8:06 p.m. UTC | #1
Am 13.12.2013 um 18:10 hat Max Reitz geschrieben:
> blkdebug and blkverify will, in order to retain compatibility, not
> support the field "file" implicitly through bdrv_open(). In order to be
> able to use those drivers without giving a filename anyway, it is
> necessary to be able to have block devices without files implicitly
> opened by bdrv_open(). This is the case, if there was neither a file
> name, a reference to an existing block device to use as a file nor
> options specific to the file.
> 
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
>  block.c | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/block.c b/block.c
> index bef4f82..9659eb5 100644
> --- a/block.c
> +++ b/block.c
> @@ -1145,11 +1145,14 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
>      qdict_extract_subqdict(options, &file_options, "file.");
>      file_reference = qdict_get_try_str(options, "file");
>  
> -    ret = bdrv_file_open(&file, filename, file_reference, file_options,
> -                         bdrv_open_flags(bs, flags | BDRV_O_UNMAP), &local_err);
> -    qdict_del(options, "file");
> -    if (ret < 0) {
> -        goto fail;
> +    if (filename || file_reference || qdict_size(file_options)) {
> +        ret = bdrv_file_open(&file, filename, file_reference, file_options,
> +                             bdrv_open_flags(bs, flags | BDRV_O_UNMAP),
> +                             &local_err);
> +        qdict_del(options, "file");
> +        if (ret < 0) {
> +            goto fail;
> +        }
>      }
>  
>      /* Find the right image format driver */
> @@ -1178,7 +1181,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,

Manually adding more context before the next hunk:

>     if (!drv) {
>         ret = find_image_format(file, filename, &drv, &local_err);
>     }

We can get file == NULL now, which will cause a segfault in
find_image_format. (For a reproducer of the segfault, try
'x86_64-softmmu/qemu-system-x86_64 -drive foo=bar')

Kevin
Max Reitz Dec. 14, 2013, 12:10 a.m. UTC | #2
On 13.12.2013 21:06, Kevin Wolf wrote:
> Am 13.12.2013 um 18:10 hat Max Reitz geschrieben:
>> blkdebug and blkverify will, in order to retain compatibility, not
>> support the field "file" implicitly through bdrv_open(). In order to be
>> able to use those drivers without giving a filename anyway, it is
>> necessary to be able to have block devices without files implicitly
>> opened by bdrv_open(). This is the case, if there was neither a file
>> name, a reference to an existing block device to use as a file nor
>> options specific to the file.
>>
>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>> ---
>>   block.c | 15 +++++++++------
>>   1 file changed, 9 insertions(+), 6 deletions(-)
>>
>> diff --git a/block.c b/block.c
>> index bef4f82..9659eb5 100644
>> --- a/block.c
>> +++ b/block.c
>> @@ -1145,11 +1145,14 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
>>       qdict_extract_subqdict(options, &file_options, "file.");
>>       file_reference = qdict_get_try_str(options, "file");
>>   
>> -    ret = bdrv_file_open(&file, filename, file_reference, file_options,
>> -                         bdrv_open_flags(bs, flags | BDRV_O_UNMAP), &local_err);
>> -    qdict_del(options, "file");
>> -    if (ret < 0) {
>> -        goto fail;
>> +    if (filename || file_reference || qdict_size(file_options)) {
>> +        ret = bdrv_file_open(&file, filename, file_reference, file_options,
>> +                             bdrv_open_flags(bs, flags | BDRV_O_UNMAP),
>> +                             &local_err);
>> +        qdict_del(options, "file");
>> +        if (ret < 0) {
>> +            goto fail;
>> +        }
>>       }
>>   
>>       /* Find the right image format driver */
>> @@ -1178,7 +1181,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
> Manually adding more context before the next hunk:
>
>>      if (!drv) {
>>          ret = find_image_format(file, filename, &drv, &local_err);
>>      }
> We can get file == NULL now, which will cause a segfault in
> find_image_format. (For a reproducer of the segfault, try
> 'x86_64-softmmu/qemu-system-x86_64 -drive foo=bar')

Right, thanks.

Max
diff mbox

Patch

diff --git a/block.c b/block.c
index bef4f82..9659eb5 100644
--- a/block.c
+++ b/block.c
@@ -1145,11 +1145,14 @@  int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
     qdict_extract_subqdict(options, &file_options, "file.");
     file_reference = qdict_get_try_str(options, "file");
 
-    ret = bdrv_file_open(&file, filename, file_reference, file_options,
-                         bdrv_open_flags(bs, flags | BDRV_O_UNMAP), &local_err);
-    qdict_del(options, "file");
-    if (ret < 0) {
-        goto fail;
+    if (filename || file_reference || qdict_size(file_options)) {
+        ret = bdrv_file_open(&file, filename, file_reference, file_options,
+                             bdrv_open_flags(bs, flags | BDRV_O_UNMAP),
+                             &local_err);
+        qdict_del(options, "file");
+        if (ret < 0) {
+            goto fail;
+        }
     }
 
     /* Find the right image format driver */
@@ -1178,7 +1181,7 @@  int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
         goto unlink_and_fail;
     }
 
-    if (bs->file != file) {
+    if (file && (bs->file != file)) {
         bdrv_unref(file);
         file = NULL;
     }