From: Kevin Wolf <kwolf-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: MORITA Kazutaka
<morita.kazutaka-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
Cc: sheepdog-CJ+3F33aHDCwRfvgX43A7Q@public.gmane.org,
hch-jcswGhMUV9g@public.gmane.org,
kvm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
qemu-devel-qX2TKyscuCcdnm+yROfE0A@public.gmane.org
Subject: Re: [PATCH] add support for protocol driver create_options
Date: Fri, 21 May 2010 18:57:36 +0200 [thread overview]
Message-ID: <4BF6BB80.1060504@redhat.com> (raw)
In-Reply-To: <1274333777-15415-1-git-send-email-morita.kazutaka-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
Am 20.05.2010 07:36, schrieb MORITA Kazutaka:
> This patch enables protocol drivers to use their create options which
> are not supported by the format. For example, protcol drivers can use
> a backing_file option with raw format.
>
> Signed-off-by: MORITA Kazutaka <morita.kazutaka-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
> ---
> block.c | 7 +++----
> block.h | 1 +
> qemu-img.c | 49 ++++++++++++++++++++++++++++++++++---------------
> qemu-option.c | 52 +++++++++++++++++++++++++++++++++++++++++++++-------
> qemu-option.h | 2 ++
> 5 files changed, 85 insertions(+), 26 deletions(-)
>
> diff --git a/block.c b/block.c
> index 48d8468..0ab9424 100644
> --- a/block.c
> +++ b/block.c
> @@ -56,7 +56,6 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
> uint8_t *buf, int nb_sectors);
> static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
> const uint8_t *buf, int nb_sectors);
> -static BlockDriver *find_protocol(const char *filename);
>
> static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
> QTAILQ_HEAD_INITIALIZER(bdrv_states);
> @@ -210,7 +209,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
> {
> BlockDriver *drv;
>
> - drv = find_protocol(filename);
> + drv = bdrv_find_protocol(filename);
> if (drv == NULL) {
> drv = bdrv_find_format("file");
> }
> @@ -283,7 +282,7 @@ static BlockDriver *find_hdev_driver(const char *filename)
> return drv;
> }
>
> -static BlockDriver *find_protocol(const char *filename)
> +BlockDriver *bdrv_find_protocol(const char *filename)
> {
> BlockDriver *drv1;
> char protocol[128];
> @@ -469,7 +468,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
> BlockDriver *drv;
> int ret;
>
> - drv = find_protocol(filename);
> + drv = bdrv_find_protocol(filename);
> if (!drv) {
> return -ENOENT;
> }
> diff --git a/block.h b/block.h
> index 24efeb6..9034ebb 100644
> --- a/block.h
> +++ b/block.h
> @@ -54,6 +54,7 @@ void bdrv_info_stats(Monitor *mon, QObject **ret_data);
>
> void bdrv_init(void);
> void bdrv_init_with_whitelist(void);
> +BlockDriver *bdrv_find_protocol(const char *filename);
> BlockDriver *bdrv_find_format(const char *format_name);
> BlockDriver *bdrv_find_whitelisted_format(const char *format_name);
> int bdrv_create(BlockDriver *drv, const char* filename,
> diff --git a/qemu-img.c b/qemu-img.c
> index d3c30a7..8ae7184 100644
> --- a/qemu-img.c
> +++ b/qemu-img.c
> @@ -252,8 +252,8 @@ static int img_create(int argc, char **argv)
> const char *base_fmt = NULL;
> const char *filename;
> const char *base_filename = NULL;
> - BlockDriver *drv;
> - QEMUOptionParameter *param = NULL;
> + BlockDriver *drv, *proto_drv;
> + QEMUOptionParameter *param = NULL, *create_options = NULL;
> char *options = NULL;
>
> flags = 0;
> @@ -286,33 +286,42 @@ static int img_create(int argc, char **argv)
> }
> }
>
> + /* Get the filename */
> + if (optind >= argc)
> + help();
> + filename = argv[optind++];
> +
> /* Find driver and parse its options */
> drv = bdrv_find_format(fmt);
> if (!drv)
> error("Unknown file format '%s'", fmt);
>
> + proto_drv = bdrv_find_protocol(filename);
> + if (!proto_drv)
> + error("Unknown protocol '%s'", filename);
> +
> + create_options = append_option_parameters(create_options,
> + drv->create_options);
> + create_options = append_option_parameters(create_options,
> + proto_drv->create_options);
> +
> if (options && !strcmp(options, "?")) {
> - print_option_help(drv->create_options);
> + print_option_help(create_options);
> return 0;
> }
>
> /* Create parameter list with default values */
> - param = parse_option_parameters("", drv->create_options, param);
> + param = parse_option_parameters("", create_options, param);
> set_option_parameter_int(param, BLOCK_OPT_SIZE, -1);
>
> /* Parse -o options */
> if (options) {
> - param = parse_option_parameters(options, drv->create_options, param);
> + param = parse_option_parameters(options, create_options, param);
> if (param == NULL) {
> error("Invalid options for file format '%s'.", fmt);
> }
> }
>
> - /* Get the filename */
> - if (optind >= argc)
> - help();
> - filename = argv[optind++];
> -
> /* Add size to parameters */
> if (optind < argc) {
> set_option_parameter(param, BLOCK_OPT_SIZE, argv[optind++]);
> @@ -362,6 +371,7 @@ static int img_create(int argc, char **argv)
> puts("");
>
> ret = bdrv_create(drv, filename, param);
> + free_option_parameters(create_options);
> free_option_parameters(param);
>
> if (ret < 0) {
> @@ -543,14 +553,14 @@ static int img_convert(int argc, char **argv)
> {
> int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
> const char *fmt, *out_fmt, *out_baseimg, *out_filename;
> - BlockDriver *drv;
> + BlockDriver *drv, *proto_drv;
> BlockDriverState **bs, *out_bs;
> int64_t total_sectors, nb_sectors, sector_num, bs_offset;
> uint64_t bs_sectors;
> uint8_t * buf;
> const uint8_t *buf1;
> BlockDriverInfo bdi;
> - QEMUOptionParameter *param = NULL;
> + QEMUOptionParameter *param = NULL, *create_options = NULL;
> char *options = NULL;
>
> fmt = NULL;
> @@ -615,19 +625,27 @@ static int img_convert(int argc, char **argv)
> if (!drv)
> error("Unknown file format '%s'", out_fmt);
>
> + proto_drv = bdrv_find_protocol(out_filename);
> + if (!proto_drv)
> + error("Unknown protocol '%s'", out_filename);
> +
> + create_options = append_option_parameters(create_options,
> + drv->create_options);
> + create_options = append_option_parameters(create_options,
> + proto_drv->create_options);
> if (options && !strcmp(options, "?")) {
> - print_option_help(drv->create_options);
> + print_option_help(create_options);
> free(bs);
> return 0;
> }
>
> if (options) {
> - param = parse_option_parameters(options, drv->create_options, param);
> + param = parse_option_parameters(options, create_options, param);
> if (param == NULL) {
> error("Invalid options for file format '%s'.", out_fmt);
> }
> } else {
> - param = parse_option_parameters("", drv->create_options, param);
> + param = parse_option_parameters("", create_options, param);
> }
>
> set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
> @@ -649,6 +667,7 @@ static int img_convert(int argc, char **argv)
>
> /* Create the new image */
> ret = bdrv_create(drv, out_filename, param);
> + free_option_parameters(create_options);
> free_option_parameters(param);
>
> if (ret < 0) {
> diff --git a/qemu-option.c b/qemu-option.c
> index 076dddf..3ef4abc 100644
> --- a/qemu-option.c
> +++ b/qemu-option.c
> @@ -346,6 +346,50 @@ void free_option_parameters(QEMUOptionParameter *list)
> }
>
> /*
> + * Count valid options in list
> + */
> +static size_t count_option_parameters(QEMUOptionParameter *list)
> +{
> + size_t num_options = 0;
> +
> + while (list && list->name) {
> + num_options++;
> + list++;
> + }
> +
> + return num_options;
> +}
> +
> +/*
> + * Append an option list (list) to an option list (dest).
> + *
> + * If dest is NULL, a new copy of list is created.
> + *
> + * Returns a pointer to the first element of dest (or the newly allocated copy)
> + */
> +QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest,
> + QEMUOptionParameter *list)
> +{
> + size_t num_options, num_dest_options;
> +
> + num_options = count_option_parameters(dest);
> + num_dest_options = num_options;
> +
> + num_options += count_option_parameters(list);
> +
> + dest = qemu_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter));
> +
> + while (list && list->name) {
> + if (get_option_parameter(dest, list->name) == NULL) {
> + dest[num_dest_options++] = *list;
You need to add a dest[num_dest_options].name = NULL; here. Otherwise
the next loop iteration works on uninitialized memory and possibly an
unterminated list. I got a segfault for that reason.
Kevin
WARNING: multiple messages have this Message-ID (diff)
From: Kevin Wolf <kwolf@redhat.com>
To: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Cc: sheepdog@lists.wpkg.org, hch@lst.de, kvm@vger.kernel.org,
qemu-devel@nongnu.org
Subject: [Qemu-devel] Re: [PATCH] add support for protocol driver create_options
Date: Fri, 21 May 2010 18:57:36 +0200 [thread overview]
Message-ID: <4BF6BB80.1060504@redhat.com> (raw)
In-Reply-To: <1274333777-15415-1-git-send-email-morita.kazutaka@lab.ntt.co.jp>
Am 20.05.2010 07:36, schrieb MORITA Kazutaka:
> This patch enables protocol drivers to use their create options which
> are not supported by the format. For example, protcol drivers can use
> a backing_file option with raw format.
>
> Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
> ---
> block.c | 7 +++----
> block.h | 1 +
> qemu-img.c | 49 ++++++++++++++++++++++++++++++++++---------------
> qemu-option.c | 52 +++++++++++++++++++++++++++++++++++++++++++++-------
> qemu-option.h | 2 ++
> 5 files changed, 85 insertions(+), 26 deletions(-)
>
> diff --git a/block.c b/block.c
> index 48d8468..0ab9424 100644
> --- a/block.c
> +++ b/block.c
> @@ -56,7 +56,6 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
> uint8_t *buf, int nb_sectors);
> static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
> const uint8_t *buf, int nb_sectors);
> -static BlockDriver *find_protocol(const char *filename);
>
> static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
> QTAILQ_HEAD_INITIALIZER(bdrv_states);
> @@ -210,7 +209,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options)
> {
> BlockDriver *drv;
>
> - drv = find_protocol(filename);
> + drv = bdrv_find_protocol(filename);
> if (drv == NULL) {
> drv = bdrv_find_format("file");
> }
> @@ -283,7 +282,7 @@ static BlockDriver *find_hdev_driver(const char *filename)
> return drv;
> }
>
> -static BlockDriver *find_protocol(const char *filename)
> +BlockDriver *bdrv_find_protocol(const char *filename)
> {
> BlockDriver *drv1;
> char protocol[128];
> @@ -469,7 +468,7 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
> BlockDriver *drv;
> int ret;
>
> - drv = find_protocol(filename);
> + drv = bdrv_find_protocol(filename);
> if (!drv) {
> return -ENOENT;
> }
> diff --git a/block.h b/block.h
> index 24efeb6..9034ebb 100644
> --- a/block.h
> +++ b/block.h
> @@ -54,6 +54,7 @@ void bdrv_info_stats(Monitor *mon, QObject **ret_data);
>
> void bdrv_init(void);
> void bdrv_init_with_whitelist(void);
> +BlockDriver *bdrv_find_protocol(const char *filename);
> BlockDriver *bdrv_find_format(const char *format_name);
> BlockDriver *bdrv_find_whitelisted_format(const char *format_name);
> int bdrv_create(BlockDriver *drv, const char* filename,
> diff --git a/qemu-img.c b/qemu-img.c
> index d3c30a7..8ae7184 100644
> --- a/qemu-img.c
> +++ b/qemu-img.c
> @@ -252,8 +252,8 @@ static int img_create(int argc, char **argv)
> const char *base_fmt = NULL;
> const char *filename;
> const char *base_filename = NULL;
> - BlockDriver *drv;
> - QEMUOptionParameter *param = NULL;
> + BlockDriver *drv, *proto_drv;
> + QEMUOptionParameter *param = NULL, *create_options = NULL;
> char *options = NULL;
>
> flags = 0;
> @@ -286,33 +286,42 @@ static int img_create(int argc, char **argv)
> }
> }
>
> + /* Get the filename */
> + if (optind >= argc)
> + help();
> + filename = argv[optind++];
> +
> /* Find driver and parse its options */
> drv = bdrv_find_format(fmt);
> if (!drv)
> error("Unknown file format '%s'", fmt);
>
> + proto_drv = bdrv_find_protocol(filename);
> + if (!proto_drv)
> + error("Unknown protocol '%s'", filename);
> +
> + create_options = append_option_parameters(create_options,
> + drv->create_options);
> + create_options = append_option_parameters(create_options,
> + proto_drv->create_options);
> +
> if (options && !strcmp(options, "?")) {
> - print_option_help(drv->create_options);
> + print_option_help(create_options);
> return 0;
> }
>
> /* Create parameter list with default values */
> - param = parse_option_parameters("", drv->create_options, param);
> + param = parse_option_parameters("", create_options, param);
> set_option_parameter_int(param, BLOCK_OPT_SIZE, -1);
>
> /* Parse -o options */
> if (options) {
> - param = parse_option_parameters(options, drv->create_options, param);
> + param = parse_option_parameters(options, create_options, param);
> if (param == NULL) {
> error("Invalid options for file format '%s'.", fmt);
> }
> }
>
> - /* Get the filename */
> - if (optind >= argc)
> - help();
> - filename = argv[optind++];
> -
> /* Add size to parameters */
> if (optind < argc) {
> set_option_parameter(param, BLOCK_OPT_SIZE, argv[optind++]);
> @@ -362,6 +371,7 @@ static int img_create(int argc, char **argv)
> puts("");
>
> ret = bdrv_create(drv, filename, param);
> + free_option_parameters(create_options);
> free_option_parameters(param);
>
> if (ret < 0) {
> @@ -543,14 +553,14 @@ static int img_convert(int argc, char **argv)
> {
> int c, ret, n, n1, bs_n, bs_i, flags, cluster_size, cluster_sectors;
> const char *fmt, *out_fmt, *out_baseimg, *out_filename;
> - BlockDriver *drv;
> + BlockDriver *drv, *proto_drv;
> BlockDriverState **bs, *out_bs;
> int64_t total_sectors, nb_sectors, sector_num, bs_offset;
> uint64_t bs_sectors;
> uint8_t * buf;
> const uint8_t *buf1;
> BlockDriverInfo bdi;
> - QEMUOptionParameter *param = NULL;
> + QEMUOptionParameter *param = NULL, *create_options = NULL;
> char *options = NULL;
>
> fmt = NULL;
> @@ -615,19 +625,27 @@ static int img_convert(int argc, char **argv)
> if (!drv)
> error("Unknown file format '%s'", out_fmt);
>
> + proto_drv = bdrv_find_protocol(out_filename);
> + if (!proto_drv)
> + error("Unknown protocol '%s'", out_filename);
> +
> + create_options = append_option_parameters(create_options,
> + drv->create_options);
> + create_options = append_option_parameters(create_options,
> + proto_drv->create_options);
> if (options && !strcmp(options, "?")) {
> - print_option_help(drv->create_options);
> + print_option_help(create_options);
> free(bs);
> return 0;
> }
>
> if (options) {
> - param = parse_option_parameters(options, drv->create_options, param);
> + param = parse_option_parameters(options, create_options, param);
> if (param == NULL) {
> error("Invalid options for file format '%s'.", out_fmt);
> }
> } else {
> - param = parse_option_parameters("", drv->create_options, param);
> + param = parse_option_parameters("", create_options, param);
> }
>
> set_option_parameter_int(param, BLOCK_OPT_SIZE, total_sectors * 512);
> @@ -649,6 +667,7 @@ static int img_convert(int argc, char **argv)
>
> /* Create the new image */
> ret = bdrv_create(drv, out_filename, param);
> + free_option_parameters(create_options);
> free_option_parameters(param);
>
> if (ret < 0) {
> diff --git a/qemu-option.c b/qemu-option.c
> index 076dddf..3ef4abc 100644
> --- a/qemu-option.c
> +++ b/qemu-option.c
> @@ -346,6 +346,50 @@ void free_option_parameters(QEMUOptionParameter *list)
> }
>
> /*
> + * Count valid options in list
> + */
> +static size_t count_option_parameters(QEMUOptionParameter *list)
> +{
> + size_t num_options = 0;
> +
> + while (list && list->name) {
> + num_options++;
> + list++;
> + }
> +
> + return num_options;
> +}
> +
> +/*
> + * Append an option list (list) to an option list (dest).
> + *
> + * If dest is NULL, a new copy of list is created.
> + *
> + * Returns a pointer to the first element of dest (or the newly allocated copy)
> + */
> +QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest,
> + QEMUOptionParameter *list)
> +{
> + size_t num_options, num_dest_options;
> +
> + num_options = count_option_parameters(dest);
> + num_dest_options = num_options;
> +
> + num_options += count_option_parameters(list);
> +
> + dest = qemu_realloc(dest, (num_options + 1) * sizeof(QEMUOptionParameter));
> +
> + while (list && list->name) {
> + if (get_option_parameter(dest, list->name) == NULL) {
> + dest[num_dest_options++] = *list;
You need to add a dest[num_dest_options].name = NULL; here. Otherwise
the next loop iteration works on uninitialized memory and possibly an
unterminated list. I got a segfault for that reason.
Kevin
next prev parent reply other threads:[~2010-05-21 16:57 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-20 5:36 [PATCH] add support for protocol driver create_options MORITA Kazutaka
2010-05-20 5:36 ` [Qemu-devel] " MORITA Kazutaka
2010-05-20 5:40 ` Kvm device passthrough Mu Lin
2010-05-20 5:40 ` [Qemu-devel] " Mu Lin
2010-05-21 11:40 ` [PATCH] add support for protocol driver create_options Kevin Wolf
2010-05-21 11:40 ` [Qemu-devel] " Kevin Wolf
[not found] ` <4BF6712F.5060300-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-05-24 6:21 ` MORITA Kazutaka
2010-05-24 6:21 ` [Qemu-devel] " MORITA Kazutaka
[not found] ` <1274333777-15415-1-git-send-email-morita.kazutaka-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org>
2010-05-21 16:57 ` Kevin Wolf [this message]
2010-05-21 16:57 ` Kevin Wolf
[not found] ` <4BF6BB80.1060504-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-05-24 6:34 ` MORITA Kazutaka
2010-05-24 6:34 ` [Qemu-devel] " MORITA Kazutaka
2010-05-25 13:43 ` Kevin Wolf
2010-05-25 13:43 ` [Qemu-devel] " Kevin Wolf
[not found] ` <4BFBD3F5.5020805-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2010-05-26 2:35 ` MORITA Kazutaka
2010-05-26 2:35 ` [Qemu-devel] " MORITA Kazutaka
2010-05-26 9:02 ` Kevin Wolf
2010-05-26 9:02 ` [Qemu-devel] " Kevin Wolf
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=4BF6BB80.1060504@redhat.com \
--to=kwolf-h+wxahxf7alqt0dzr+alfa@public.gmane.org \
--cc=hch-jcswGhMUV9g@public.gmane.org \
--cc=kvm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=morita.kazutaka-Zyj7fXuS5i5L9jVzuh4AOg@public.gmane.org \
--cc=qemu-devel-qX2TKyscuCcdnm+yROfE0A@public.gmane.org \
--cc=sheepdog-CJ+3F33aHDCwRfvgX43A7Q@public.gmane.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.