qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH V16 5/7] Use QemuOpts support in block layer


From: Eric Blake
Subject: Re: [Qemu-devel] [PATCH V16 5/7] Use QemuOpts support in block layer
Date: Wed, 10 Jul 2013 13:47:49 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130625 Thunderbird/17.0.7

On 06/18/2013 03:31 AM, Dong Xu Wang wrote:
> This patch uses QemuOpts related functions in block layer, add
> a member bdrv_create_opts to BlockDriver struct, it returns
> a QemuOptsList pointer, which includes the image format's create
> options.
> 

> +++ b/block/cow.c

Concluding my review...

> @@ -315,21 +309,27 @@ static int cow_create(const char *filename, 
> QEMUOptionParameter *options)
>  
>  exit:
>      bdrv_delete(cow_bs);
> +finish:
> +    g_free((/* !const */ char*)image_filename);

Yuck - the only reason you have to cast away const here is because patch
4/7 returned const in the first place.  It would be a lot easier to just
declare 'char *image_filename', after fixing qemu_opt_get_del to not
force const on something the caller must free.  And since doing that
means spinning a v17, I really would like to see this patch split into
manageable pieces (incremental conversion of one file at a time, rather
than everything in one blow).

> +++ b/block/gluster.c
> @@ -365,8 +365,7 @@ out:
>      return ret;
>  }
>  
> -static int qemu_gluster_create(const char *filename,
> -        QEMUOptionParameter *options)
> +static int qemu_gluster_create(const char *filename, QemuOpts *opts)

Kudos on fixing bad indentation in the process.indentation

> +++ b/block/iscsi.c
> @@ -1213,7 +1213,7 @@ static int iscsi_has_zero_init(BlockDriverState *bs)
>      return 0;
>  }
>  
> -static int iscsi_create(const char *filename, QEMUOptionParameter *options)
> +static int iscsi_create(const char *filename,  QemuOpts *opts)

Spacing is off.

> +++ b/block/qcow.c

> @@ -662,26 +662,21 @@ static int qcow_create(const char *filename, 
> QEMUOptionParameter *options)
>      int ret;
>      BlockDriverState *qcow_bs;
>  
> -    /* Read out options */
> -    while (options && options->name) {
> -        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
> -            total_size = options->value.n / 512;
> -        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
> -            backing_file = options->value.s;
> -        } else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
> -            flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
> -        }
> -        options++;
> +    /* Read out opts */
> +    total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
> +    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
> +    if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, 0)) {

s/0/false/ - you're passing a bool parameter

> @@ -752,6 +747,8 @@ static int qcow_create(const char *filename, 
> QEMUOptionParameter *options)
>      ret = 0;
>  exit:
>      bdrv_delete(qcow_bs);
> +finish:
> +    g_free((/* !const */ char*)backing_file);

Again, this just feels like patch 4/7 declared the wrong signature.
(I'll quit pointing it out, but there are other instances)

> +++ b/block/qcow2.c

> @@ -1243,7 +1244,8 @@ static int qcow2_create2(const char *filename, int64_t 
> total_size,
>          error_report(
>              "Cluster size must be a power of two between %d and %dk",
>              1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10));
> -        return -EINVAL;
> +        ret =  -EINVAL;

Spacing looks odd.

> @@ -1375,61 +1379,67 @@ static int qcow2_create(const char *filename, 
> QEMUOptionParameter *options)
>      size_t cluster_size = DEFAULT_CLUSTER_SIZE;
>      int prealloc = 0;
>      int version = 2;
> +    const char *buf;
> +    int ret = 0;
>  

> +    sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
> +    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
> +    backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
> +    if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, 0)) {

s/0/false/ (I'll quit pointing it out, but probably other instances)

> @@ -1704,49 +1714,55 @@ static int qcow2_load_vmstate(BlockDriverState *bs, 
> uint8_t *buf,
>  
>      .bdrv_invalidate_cache      = qcow2_invalidate_cache,
>  
> -    .create_options = qcow2_create_options,
>      .bdrv_check = qcow2_check,
> +
> +    .bdrv_create_opts     = &qcow2_create_opts,

In other files, you were aligning the '='.  Here, it looks especially
odd that you are using more than one ' ' but still didn't align things -
it looks more consistent if you either go for full alignment or use
exactly one ' ' everywhere (I don't care which, so long as the results
don't look odd).

> +++ b/block/qed.c
> @@ -555,12 +555,12 @@ static int qed_create(const char *filename, uint32_t 
> cluster_size,
>  
>      ret = bdrv_create_file(filename, NULL);
>      if (ret < 0) {
> -        return ret;
> +        goto finish;
>      }
>  
>      ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR | BDRV_O_CACHE_WB);
>      if (ret < 0) {
> -        return ret;
> +        goto finish;
>      }
>  
>      /* File must start empty and grow, check truncate is supported */
> @@ -600,55 +600,57 @@ static int qed_create(const char *filename, uint32_t 
> cluster_size,
>  out:
>      g_free(l1_table);
>      bdrv_delete(bs);
> +finish:
> +    g_free((/* !const */ char*)backing_file);
> +    g_free((/* !const */ char*)backing_fmt);

Eww - you are freeing something in the client that was allocated in the
parent, but passed via 'const char *'.  That makes it hard to trace
allocation ownership.  I'd rather see the frees moved into the function
that gets the data allocated (and _this_ function keeps 'const char *'
arguments), rather than passing the buck to the helper function...

>      return ret;
>  }
>  
> -static int bdrv_qed_create(const char *filename, QEMUOptionParameter 
> *options)
> +static int bdrv_qed_create(const char *filename, QemuOpts *opts)
>  {
>      uint64_t image_size = 0;
>      uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE;
>      uint32_t table_size = QED_DEFAULT_TABLE_SIZE;
>      const char *backing_file = NULL;
>      const char *backing_fmt = NULL;

> +    image_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
> +    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
> +    backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);

>  
>      return qed_create(filename, cluster_size, image_size, table_size,
>                        backing_file, backing_fmt);

...better would have been 'ret = qed_create(...);' with fallthrough...

> +
> +finish:
> +    g_free((/* !const */ char*)backing_file);
> +    g_free((/* !const */ char*)backing_fmt);
> +    return ret;

...and let finish do the cleanup on both success and error.

> +++ b/block/qed.h
> @@ -43,6 +43,7 @@
>   *
>   * All fields are little-endian on disk.
>   */
> +#define  QED_DEFAULT_CLUSTER_SIZE  65536
>  
>  enum {
>      QED_MAGIC = 'Q' | 'E' << 8 | 'D' << 16 | '\0' << 24,
> @@ -69,7 +70,6 @@ enum {
>       */
>      QED_MIN_CLUSTER_SIZE = 4 * 1024, /* in bytes */
>      QED_MAX_CLUSTER_SIZE = 64 * 1024 * 1024,
> -    QED_DEFAULT_CLUSTER_SIZE = 64 * 1024,

Why are you converting an enum into a define?  I personally find enums
slightly easier to debug while under gdb.  I don't think this hunk is
necessary.

> +++ b/block/raw-posix.c
> @@ -123,6 +123,19 @@
>  
>  #define MAX_BLOCKSIZE        4096
>  
> +static QemuOptsList file_proto_create_opts = {
> +    .name = "file-proto-create-opts",
> +    .head = QTAILQ_HEAD_INITIALIZER(file_proto_create_opts.head),
> +    .desc = {
> +        {
> +            .name = BLOCK_OPT_SIZE,
> +            .type = QEMU_OPT_SIZE,
> +            .help = "Virtual disk size"
> +        },
> +        { /* end of list */ }
> +    }
> +};
> +

In other files, you did the conversion...

> @@ -1179,15 +1187,6 @@ static coroutine_fn BlockDriverAIOCB 
> *raw_aio_discard(BlockDriverState *bs,
>                         cb, opaque, QEMU_AIO_DISCARD);
>  }
>  
> -static QEMUOptionParameter raw_create_options[] = {
> -    {
> -        .name = BLOCK_OPT_SIZE,
> -        .type = OPT_SIZE,
> -        .help = "Virtual disk size"
> -    },
> -    { NULL }
> -};

...next to the place you were replacing.  Why the difference in this file?

> +++ b/block/rbd.c

> @@ -997,7 +995,7 @@ static BlockDriver bdrv_rbd = {
>      .bdrv_close         = qemu_rbd_close,
>      .bdrv_create        = qemu_rbd_create,
>      .bdrv_get_info      = qemu_rbd_getinfo,
> -    .create_options     = qemu_rbd_create_options,
> +    .bdrv_create_opts   = &rbd_create_opts,

Why the lost qemu_ prefix?

> +++ b/block/sheepdog.c

> @@ -2259,7 +2253,6 @@ static int sd_load_vmstate(BlockDriverState *bs, 
> uint8_t *data,
>      return do_load_save_vmstate(s, data, pos, size, 1);
>  }
>  
> -
>  static coroutine_fn int sd_co_discard(BlockDriverState *bs, int64_t 
> sector_num,

Spurious whitespace change.

> @@ -2364,7 +2361,7 @@ static BlockDriver bdrv_sheepdog = {
>      .bdrv_save_vmstate  = sd_save_vmstate,
>      .bdrv_load_vmstate  = sd_load_vmstate,
>  
> -    .create_options = sd_create_options,
> +    .bdrv_create_opts   = &sd_create_opts,
>  };
>  
>  static BlockDriver bdrv_sheepdog_tcp = {
> @@ -2391,7 +2388,7 @@ static BlockDriver bdrv_sheepdog_tcp = {
>      .bdrv_save_vmstate  = sd_save_vmstate,
>      .bdrv_load_vmstate  = sd_load_vmstate,
>  
> -    .create_options = sd_create_options,
> +    .bdrv_create_opts = &sd_create_opts,

Inconsistent alignment.

>  };
>  
>  static BlockDriver bdrv_sheepdog_unix = {
> @@ -2418,7 +2415,7 @@ static BlockDriver bdrv_sheepdog_unix = {
>      .bdrv_save_vmstate  = sd_save_vmstate,
>      .bdrv_load_vmstate  = sd_load_vmstate,
>  
> -    .create_options = sd_create_options,
> +    .bdrv_create_opts = &sd_create_opts,

and again.

> +++ b/block/vdi.c

> @@ -648,25 +648,18 @@ static int vdi_create(const char *filename, 
> QEMUOptionParameter *options)
>      logout("\n");
>  
>      /* Read out options. */
> -    while (options && options->name) {
> -        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
> -            bytes = options->value.n;
> +    bytes = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
>  #if defined(CONFIG_VDI_BLOCK_SIZE)
> -        } else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
> -            if (options->value.n) {
> -                /* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */
> -                block_size = options->value.n;
> -            }
> +        /* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */
> +    block_size = qemu_opt_get_size_del(opts,

New comment alignment looks odd.

> +++ b/block/vpc.c
> @@ -827,7 +832,7 @@ static BlockDriver bdrv_vpc = {
>      .bdrv_read              = vpc_co_read,
>      .bdrv_write             = vpc_co_write,
>  
> -    .create_options = vpc_create_options,
> +    .bdrv_create_opts = &vpc_create_opts,

Alignment.

> +++ b/include/block/block.h
> @@ -115,9 +115,8 @@ BlockDriver *bdrv_find_protocol(const char *filename);
>  BlockDriver *bdrv_find_format(const char *format_name);
>  BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
>                                            bool readonly);
> -int bdrv_create(BlockDriver *drv, const char* filename,
> -    QEMUOptionParameter *options);
> -int bdrv_create_file(const char* filename, QEMUOptionParameter *options);
> +int bdrv_create(BlockDriver *drv, const char* filename, QemuOpts *opts);
> +int bdrv_create_file(const char *filename, QemuOpts *opts);

I see why you did things all in one patch - you changed the signature,
so all the callbacks had to pick up the new signature.  But I still
think it will be easier to review if you created the new signature with
a new name, did conversion of one file at a time, then delete the old
signature and rename the new name back to the old name.

>  BlockDriverState *bdrv_new(const char *device_name);
>  void bdrv_make_anon(BlockDriverState *bs);
>  void bdrv_swap(BlockDriverState *bs_new, BlockDriverState *bs_old);
> diff --git a/include/block/block_int.h b/include/block/block_int.h
> index ba52247..41311e2 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -95,7 +95,7 @@ struct BlockDriver {
>                        const uint8_t *buf, int nb_sectors);
>      void (*bdrv_close)(BlockDriverState *bs);
>      void (*bdrv_rebind)(BlockDriverState *bs);
> -    int (*bdrv_create)(const char *filename, QEMUOptionParameter *options);
> +    int (*bdrv_create)(const char *filename, QemuOpts *opts);

Likewise, by temporarily having two different callback names, where
clients provide one of the two callbacks during the transition over
multiple patches, makes it possible to split into reviewable portions.

> +++ b/qemu-img.c
> @@ -1531,8 +1526,10 @@ static int img_convert(int argc, char **argv)
>      }
>  out:
>      qemu_progress_end();
> -    free_option_parameters(create_options);
> -    free_option_parameters(param);
> +    qemu_opts_free(create_opts);
> +    if (opts) {
> +        qemu_opts_del(opts);

Should qemu_opts_del() be made more free-like, by having it be a no-op
if opts is NULL?  That would be an independent cleanup, though.

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

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