[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 05/14] add support for protocol driver create_option
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PATCH 05/14] add support for protocol driver create_options |
Date: |
Fri, 28 May 2010 18:46:04 +0200 |
From: MORITA Kazutaka <address@hidden>
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 <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
block.c | 7 +++----
block.h | 1 +
qemu-img.c | 49 ++++++++++++++++++++++++++++++++++---------------
qemu-option.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++-------
qemu-option.h | 2 ++
5 files changed, 86 insertions(+), 26 deletions(-)
diff --git a/block.c b/block.c
index 47be5ba..24c63f6 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];
@@ -478,7 +477,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 cb007b7..ea091f0 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..acd74f9 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -346,6 +346,51 @@ 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;
+ dest[num_dest_options].name = NULL;
+ }
+ list++;
+ }
+
+ return dest;
+}
+
+/*
* Parses a parameter string (param) into an option list (dest).
*
* list is the templace is. If dest is NULL, a new copy of list is created for
@@ -365,7 +410,6 @@ void free_option_parameters(QEMUOptionParameter *list)
QEMUOptionParameter *parse_option_parameters(const char *param,
QEMUOptionParameter *list, QEMUOptionParameter *dest)
{
- QEMUOptionParameter *cur;
QEMUOptionParameter *allocated = NULL;
char name[256];
char value[256];
@@ -379,12 +423,7 @@ QEMUOptionParameter *parse_option_parameters(const char
*param,
if (dest == NULL) {
// Count valid options
- num_options = 0;
- cur = list;
- while (cur->name) {
- num_options++;
- cur++;
- }
+ num_options = count_option_parameters(list);
// Create a copy of the option list to fill in values
dest = qemu_mallocz((num_options + 1) * sizeof(QEMUOptionParameter));
diff --git a/qemu-option.h b/qemu-option.h
index 58136f3..4823219 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -70,6 +70,8 @@ int set_option_parameter(QEMUOptionParameter *list, const
char *name,
const char *value);
int set_option_parameter_int(QEMUOptionParameter *list, const char *name,
uint64_t value);
+QEMUOptionParameter *append_option_parameters(QEMUOptionParameter *dest,
+ QEMUOptionParameter *list);
QEMUOptionParameter *parse_option_parameters(const char *param,
QEMUOptionParameter *list, QEMUOptionParameter *dest);
void free_option_parameters(QEMUOptionParameter *list);
--
1.6.6.1
- [Qemu-devel] [PULL 00/14] Block patches, Kevin Wolf, 2010/05/28
- [Qemu-devel] [PATCH 01/14] qcow2: Clear L2 table cache after write error, Kevin Wolf, 2010/05/28
- [Qemu-devel] [PATCH 02/14] qcow2: Fix error handling in l2_allocate, Kevin Wolf, 2010/05/28
- [Qemu-devel] [PATCH 03/14] block: Fix multiwrite with overlapping requests, Kevin Wolf, 2010/05/28
- [Qemu-devel] [PATCH 04/14] qemu-io: Add multiwrite command, Kevin Wolf, 2010/05/28
- [Qemu-devel] [PATCH 05/14] add support for protocol driver create_options,
Kevin Wolf <=
- [Qemu-devel] [PATCH 06/14] drive: allow rerror, werror and readonly for if=none, Kevin Wolf, 2010/05/28
- [Qemu-devel] [PATCH 07/14] posix-aio-compat: Expand tabs that have crept in, Kevin Wolf, 2010/05/28
- [Qemu-devel] [PATCH 08/14] block.h: Make BDRV_SECTOR_SIZE 64 bit safe, Kevin Wolf, 2010/05/28
- [Qemu-devel] [PATCH 09/14] qcow2: Allow qcow2_get_cluster_offset to return errors, Kevin Wolf, 2010/05/28
- [Qemu-devel] [PATCH 10/14] qcow2: Change l2_load to return 0/-errno, Kevin Wolf, 2010/05/28
- [Qemu-devel] [PATCH 11/14] qcow2: Return right error code in write_refcount_block_entries, Kevin Wolf, 2010/05/28
- [Qemu-devel] [PATCH 12/14] qcow2: Fix corruption after refblock allocation, Kevin Wolf, 2010/05/28
- [Qemu-devel] [PATCH 13/14] qcow2: Fix corruption after error in update_refcount, Kevin Wolf, 2010/05/28
- [Qemu-devel] [PATCH 14/14] block: Add missing bdrv_delete() for SG_IO BlockDriver in find_image_format(), Kevin Wolf, 2010/05/28
- [Qemu-devel] Re: [PULL 00/14] Block patches, Anthony Liguori, 2010/05/28