qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 30/31] blockdev: Convert drive_new() to Error


From: Max Reitz
Subject: Re: [Qemu-devel] [PATCH 30/31] blockdev: Convert drive_new() to Error
Date: Mon, 8 Oct 2018 23:22:19 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.0

On 08.10.18 19:31, Markus Armbruster wrote:
> Calling error_report() from within a a function that takes an Error **
> argument is suspicious.  drive_new() does that, and its caller
> drive_init_func() then exit()s.

I'm afraid I don't quite follow you here.  There is no function here
that takes an Error ** already and then calls error_report().  There is
however drive_new() that does not take an Error **, consequentially
calls error_report(), and there is its caller drive_init_func() which
does take an Error ** but does not set it.

So while I fully agree with you to make drive_new() take an Error **
(and thus effectively fix drive_init_func()), I don't quite understand
this explanation.

(Furthermore, drive_init_func() does not exit().  It's main() that
exit()s after calling drive_init_func().)

> Its caller main(), via
> qemu_opts_foreach(), is fine with it, but clean it up anyway:
> 
> * Convert drive_new() to Error
> 
> * Update add_init_drive() to report the error received from
>   drive_new().
> 
> * Make main() pass &error_fatal through qemu_opts_foreach(),
>   drive_init_func() to drive_new()
> 
> * Make default_drive() pass &error_abort through qemu_opts_foreach(),
>   drive_init_func() to drive_new()
> 
> Cc: Kevin Wolf <address@hidden>
> Cc: Max Reitz <address@hidden>
> Signed-off-by: Markus Armbruster <address@hidden>
> ---
>  blockdev.c                | 27 ++++++++++++++-------------
>  device-hotplug.c          |  5 ++++-
>  include/sysemu/blockdev.h |  3 ++-
>  vl.c                      | 11 ++++-------
>  4 files changed, 24 insertions(+), 22 deletions(-)
> 
> diff --git a/blockdev.c b/blockdev.c
> index a8755bd908..574adbcb7f 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -759,7 +759,8 @@ QemuOptsList qemu_legacy_drive_opts = {

[...]

> @@ -991,7 +992,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, 
> BlockInterfaceType block_default_type)
>      bs_opts = NULL;
>      if (!blk) {
>          if (local_err) {
> -            error_report_err(local_err);
> +            error_propagate(errp, local_err);
>          }

Wait, what would be the case where blockdev_init() returns NULL but
*errp remains unse——— oh no.

There is only one case which is someone specified "format=help".  Hm.  I
suppose you are as unhappy as me about the fact that because of this
drive_new() cannot guarantee that *errp is set in case of an error.

I think it's ""fine"" (*gnashing teeth*) to keep it this way, but it
means that callers need to continue to check the return value and not
*errp alone.

>          goto fail;
>      } else {
> diff --git a/device-hotplug.c b/device-hotplug.c
> index cd427e2c76..6090d5f1e9 100644
> --- a/device-hotplug.c
> +++ b/device-hotplug.c
> @@ -28,6 +28,7 @@
>  #include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "qapi/qmp/qdict.h"
> +#include "qapi/error.h"
>  #include "qemu/config-file.h"
>  #include "qemu/option.h"
>  #include "sysemu/sysemu.h"
> @@ -36,6 +37,7 @@
>  
>  static DriveInfo *add_init_drive(const char *optstr)
>  {
> +    Error *err = NULL;
>      DriveInfo *dinfo;
>      QemuOpts *opts;
>      MachineClass *mc;
> @@ -45,8 +47,9 @@ static DriveInfo *add_init_drive(const char *optstr)
>          return NULL;
>  
>      mc = MACHINE_GET_CLASS(current_machine);
> -    dinfo = drive_new(opts, mc->block_default_type);
> +    dinfo = drive_new(opts, mc->block_default_type, &err);
>      if (!dinfo) {
> +        error_report_err(err);
>          qemu_opts_del(opts);
>          return NULL;
>      }
> diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
> index 24954b94e0..d34c4920dc 100644
> --- a/include/sysemu/blockdev.h
> +++ b/include/sysemu/blockdev.h
> @@ -54,7 +54,8 @@ DriveInfo *drive_get_next(BlockInterfaceType type);
>  QemuOpts *drive_def(const char *optstr);
>  QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
>                      const char *optstr);
> -DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type);
> +DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type,
> +                     Error **errp);
>  
>  /* device-hotplug */
>  
> diff --git a/vl.c b/vl.c
> index 0d25956b2f..101e0123d9 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1129,7 +1129,7 @@ static int drive_init_func(void *opaque, QemuOpts 
> *opts, Error **errp)
>  {
>      BlockInterfaceType *block_default_type = opaque;
>  
> -    return drive_new(opts, *block_default_type) == NULL;
> +    return drive_new(opts, *block_default_type, errp) == NULL;
>  }
>  
>  static int drive_enable_snapshot(void *opaque, QemuOpts *opts, Error **errp)
> @@ -1155,8 +1155,7 @@ static void default_drive(int enable, int snapshot, 
> BlockInterfaceType type,
>          drive_enable_snapshot(NULL, opts, NULL);
>      }
>  
> -    dinfo = drive_new(opts, type);
> -    assert(dinfo);
> +    dinfo = drive_new(opts, type, &error_abort);

Which means the assertion is still necessary here.

>      dinfo->is_default = true;
>  
>  }
> @@ -4348,10 +4347,8 @@ int main(int argc, char **argv, char **envp)
>          qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot,
>                            NULL, NULL);
>      }
> -    if (qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func,
> -                          &machine_class->block_default_type, NULL)) {
> -        exit(1);
> -    }
> +    qemu_opts_foreach(qemu_find_opts("drive"), drive_init_func,
> +                      &machine_class->block_default_type, &error_fatal);

And we still have to keep an exit() here.

Alternative: You transform blockdev_init()'s format=help into an error
(or construct a new error in drive_new() if blockdev_init() returned
NULL but no error).

Max

>  
>      default_drive(default_cdrom, snapshot, 
> machine_class->block_default_type, 2,
>                    CDROM_OPTS);
> 


Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]