From: Eric Blake <eblake@redhat.com>
To: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Cc: kwolf@redhat.com, wdongxu@cn.ibm.com, qemu-devel@nongnu.org,
stefanha@redhat.com, armbru@redhat.com
Subject: Re: [Qemu-devel] [PATCH V16 5/7] Use QemuOpts support in block layer
Date: Wed, 10 Jul 2013 13:47:49 -0600 [thread overview]
Message-ID: <51DDBA65.2010401@redhat.com> (raw)
In-Reply-To: <1371547919-15654-6-git-send-email-wdongxu@linux.vnet.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 13369 bytes --]
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 #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]
next prev parent reply other threads:[~2013-07-10 19:48 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-18 9:31 [Qemu-devel] [PATCH V16 0/7] replace QEMUOptionParameter with QemuOpts parser Dong Xu Wang
2013-06-18 9:31 ` [Qemu-devel] [PATCH V16 1/7] add def_value_str in QemuOptDesc struct and rewrite qemu_opts_print Dong Xu Wang
2013-06-18 9:31 ` [Qemu-devel] [PATCH V16 2/7] avoid duplication of default value in QemuOpts Dong Xu Wang
2013-06-18 9:31 ` [Qemu-devel] [PATCH V16 3/7] Create four QemuOptsList related functions Dong Xu Wang
2013-07-10 16:07 ` Eric Blake
2013-06-18 9:31 ` [Qemu-devel] [PATCH V16 4/7] Create some QemuOpts functons Dong Xu Wang
2013-07-10 16:51 ` Eric Blake
2013-07-10 19:06 ` Eric Blake
2013-06-18 9:31 ` [Qemu-devel] [PATCH V16 5/7] Use QemuOpts support in block layer Dong Xu Wang
2013-07-10 17:56 ` Eric Blake
2013-07-10 19:47 ` Eric Blake [this message]
2013-06-18 9:31 ` [Qemu-devel] [PATCH V16 6/7] query-command-line-options outputs def_value_str Dong Xu Wang
2013-07-10 19:56 ` Eric Blake
2013-06-18 9:31 ` [Qemu-devel] [PATCH V16 7/7] remove QEMUOptionParameter related functions and struct Dong Xu Wang
2013-07-10 19:57 ` Eric Blake
2013-07-04 12:52 ` [Qemu-devel] [PATCH V16 0/7] replace QEMUOptionParameter with QemuOpts parser Stefan Hajnoczi
2013-07-09 20:41 ` Eric Blake
2013-07-10 19:49 ` Eric Blake
2013-07-15 7:38 ` Dong Xu Wang
2013-07-09 22:05 ` Andreas Färber
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=51DDBA65.2010401@redhat.com \
--to=eblake@redhat.com \
--cc=armbru@redhat.com \
--cc=kwolf@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
--cc=wdongxu@cn.ibm.com \
--cc=wdongxu@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).