diff mbox

[01/12] block: qcow2 driver may not be found

Message ID 1416924485-13304-2-git-send-email-mreitz@redhat.com
State New
Headers show

Commit Message

Max Reitz Nov. 25, 2014, 2:07 p.m. UTC
Albeit absolutely impossible right now, bdrv_find_format("qcow2") may
fail. bdrv_append_temp_snapshot() should heed that case.

Cc: qemu-stable@nongnu.org
Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block.c | 6 ++++++
 1 file changed, 6 insertions(+)

Comments

Markus Armbruster Nov. 26, 2014, 7:23 a.m. UTC | #1
Max Reitz <mreitz@redhat.com> writes:

> Albeit absolutely impossible right now, bdrv_find_format("qcow2") may
> fail. bdrv_append_temp_snapshot() should heed that case.

Impossible because we always compile in bdrv_qcow2.

> Cc: qemu-stable@nongnu.org
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
>  block.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/block.c b/block.c
> index 866c8b4..b31fb67 100644
> --- a/block.c
> +++ b/block.c
> @@ -1320,6 +1320,12 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
>      }
>  
>      bdrv_qcow2 = bdrv_find_format("qcow2");
> +    if (!bdrv_qcow2) {
> +        error_setg(errp, "Failed to locate qcow2 driver");
> +        ret = -ENOENT;
> +        goto out;
> +    }
> +
>      opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0,
>                              &error_abort);
>      qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);

This dynamic qcow2 driver lookup business is silly.  Compiling without
qcow2 would be a massive loss of functionality, and I wouldn't bet a
nickel on the error paths it would pring to live.

Even sillier lookups: "file" in bdrv_find_protocol(), and "raw" in
find_image_format().

Statically linking to them would be simpler and more honest.

Aside: similar silliness exists around QemuOpts.

Patch looks correct.
Max Reitz Nov. 26, 2014, 9:13 a.m. UTC | #2
On 2014-11-26 at 08:23, Markus Armbruster wrote:
> Max Reitz <mreitz@redhat.com> writes:
>
>> Albeit absolutely impossible right now, bdrv_find_format("qcow2") may
>> fail. bdrv_append_temp_snapshot() should heed that case.
> Impossible because we always compile in bdrv_qcow2.

Right now we do, right.

>> Cc: qemu-stable@nongnu.org
>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>> ---
>>   block.c | 6 ++++++
>>   1 file changed, 6 insertions(+)
>>
>> diff --git a/block.c b/block.c
>> index 866c8b4..b31fb67 100644
>> --- a/block.c
>> +++ b/block.c
>> @@ -1320,6 +1320,12 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
>>       }
>>   
>>       bdrv_qcow2 = bdrv_find_format("qcow2");
>> +    if (!bdrv_qcow2) {
>> +        error_setg(errp, "Failed to locate qcow2 driver");
>> +        ret = -ENOENT;
>> +        goto out;
>> +    }
>> +
>>       opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0,
>>                               &error_abort);
>>       qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
> This dynamic qcow2 driver lookup business is silly.  Compiling without
> qcow2 would be a massive loss of functionality, and I wouldn't bet a
> nickel on the error paths it would pring to live.

True.

> Even sillier lookups: "file" in bdrv_find_protocol(), and "raw" in
> find_image_format().
>
> Statically linking to them would be simpler and more honest.
>
> Aside: similar silliness exists around QemuOpts.
>
> Patch looks correct.

Well, at least it will silence Coverity...

Max
Eric Blake Nov. 26, 2014, 3:19 p.m. UTC | #3
On 11/26/2014 02:13 AM, Max Reitz wrote:
> On 2014-11-26 at 08:23, Markus Armbruster wrote:
>> Max Reitz <mreitz@redhat.com> writes:
>>
>>> Albeit absolutely impossible right now, bdrv_find_format("qcow2") may
>>> fail. bdrv_append_temp_snapshot() should heed that case.
>> Impossible because we always compile in bdrv_qcow2.
> 

>>> +++ b/block.c
>>> @@ -1320,6 +1320,12 @@ int bdrv_append_temp_snapshot(BlockDriverState
>>> *bs, int flags, Error **errp)
>>>       }
>>>         bdrv_qcow2 = bdrv_find_format("qcow2");
>>> +    if (!bdrv_qcow2) {

Would it be shorter to 'assert(bdrv_qcow2);' to still silence Coverity?
Max Reitz Nov. 26, 2014, 3:20 p.m. UTC | #4
On 2014-11-26 at 16:19, Eric Blake wrote:
> On 11/26/2014 02:13 AM, Max Reitz wrote:
>> On 2014-11-26 at 08:23, Markus Armbruster wrote:
>>> Max Reitz <mreitz@redhat.com> writes:
>>>
>>>> Albeit absolutely impossible right now, bdrv_find_format("qcow2") may
>>>> fail. bdrv_append_temp_snapshot() should heed that case.
>>> Impossible because we always compile in bdrv_qcow2.
>>>> +++ b/block.c
>>>> @@ -1320,6 +1320,12 @@ int bdrv_append_temp_snapshot(BlockDriverState
>>>> *bs, int flags, Error **errp)
>>>>        }
>>>>          bdrv_qcow2 = bdrv_find_format("qcow2");
>>>> +    if (!bdrv_qcow2) {
> Would it be shorter to 'assert(bdrv_qcow2);' to still silence Coverity?

Sounds like a good compromise. Will do.

Max
Kevin Wolf Nov. 26, 2014, 3:24 p.m. UTC | #5
Am 26.11.2014 um 16:20 hat Max Reitz geschrieben:
> On 2014-11-26 at 16:19, Eric Blake wrote:
> >On 11/26/2014 02:13 AM, Max Reitz wrote:
> >>On 2014-11-26 at 08:23, Markus Armbruster wrote:
> >>>Max Reitz <mreitz@redhat.com> writes:
> >>>
> >>>>Albeit absolutely impossible right now, bdrv_find_format("qcow2") may
> >>>>fail. bdrv_append_temp_snapshot() should heed that case.
> >>>Impossible because we always compile in bdrv_qcow2.
> >>>>+++ b/block.c
> >>>>@@ -1320,6 +1320,12 @@ int bdrv_append_temp_snapshot(BlockDriverState
> >>>>*bs, int flags, Error **errp)
> >>>>       }
> >>>>         bdrv_qcow2 = bdrv_find_format("qcow2");
> >>>>+    if (!bdrv_qcow2) {
> >Would it be shorter to 'assert(bdrv_qcow2);' to still silence Coverity?
> 
> Sounds like a good compromise. Will do.

I think it's better to have either proper error handling for the case
that someone compiles it out, like implemented by this patch, or to
reference the symbol so that compiling it out already breaks the build.
The assert() would potentially be a crash of a running VM, which is not
as nice.

Kevin
Markus Armbruster Nov. 27, 2014, 9:02 a.m. UTC | #6
Kevin Wolf <kwolf@redhat.com> writes:

> Am 26.11.2014 um 16:20 hat Max Reitz geschrieben:
>> On 2014-11-26 at 16:19, Eric Blake wrote:
>> >On 11/26/2014 02:13 AM, Max Reitz wrote:
>> >>On 2014-11-26 at 08:23, Markus Armbruster wrote:
>> >>>Max Reitz <mreitz@redhat.com> writes:
>> >>>
>> >>>>Albeit absolutely impossible right now, bdrv_find_format("qcow2") may
>> >>>>fail. bdrv_append_temp_snapshot() should heed that case.
>> >>>Impossible because we always compile in bdrv_qcow2.
>> >>>>+++ b/block.c
>> >>>>@@ -1320,6 +1320,12 @@ int bdrv_append_temp_snapshot(BlockDriverState
>> >>>>*bs, int flags, Error **errp)
>> >>>>       }
>> >>>>         bdrv_qcow2 = bdrv_find_format("qcow2");
>> >>>>+    if (!bdrv_qcow2) {
>> >Would it be shorter to 'assert(bdrv_qcow2);' to still silence Coverity?
>> 
>> Sounds like a good compromise. Will do.
>
> I think it's better to have either proper error handling for the case
> that someone compiles it out, like implemented by this patch, or to
> reference the symbol so that compiling it out already breaks the build.
> The assert() would potentially be a crash of a running VM, which is not
> as nice.

Ways to bind to a well-known block driver, and how the binding fails
when the driver isn't around, in decreasing order of preference:

1. Static binding

   Fails at compile time.  Me like.

2. Dynamic binding, assert the required code is there

   Fails at run time in a catastrophic, but locally obvious way.

3. Dynamic binding without error checking

   Fails at run time in a catastrophic way, when the pointer gets
   dereferenced.  Less predictable than 2.

4. Dynamic binding, error out if the required code is there

   Fails at run time in a way that could be recoverable, but probably
   isn't, not least because nobody ever tests it.  Moreover, code
   clutter.

Use of dynamic binding to reference a well-known block driver feels like
"Look ma, dynamic binding in C!" to me.
diff mbox

Patch

diff --git a/block.c b/block.c
index 866c8b4..b31fb67 100644
--- a/block.c
+++ b/block.c
@@ -1320,6 +1320,12 @@  int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
     }
 
     bdrv_qcow2 = bdrv_find_format("qcow2");
+    if (!bdrv_qcow2) {
+        error_setg(errp, "Failed to locate qcow2 driver");
+        ret = -ENOENT;
+        goto out;
+    }
+
     opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0,
                             &error_abort);
     qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);