diff options
author | Kevin Wolf <kwolf@redhat.com> | 2013-03-15 18:47:22 +0100 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2013-03-22 17:51:32 +0100 |
commit | 6963a30d82413bea36c7545137b090b284cc2b18 (patch) | |
tree | f4258be2af81298342b01f359790ea10ba5f856c | |
parent | f53a1febcd9d887149ac1429880a3f2fdb2c117f (diff) |
block: Introduce .bdrv_parse_filename callback
If a driver needs structured data and not just a string, it can provide
a .bdrv_parse_filename callback now that parses the command line string
into separate options. Keeping this separate from .bdrv_open_filename
ensures that the preferred way of directly specifying the options always
works as well if parsing the string works.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
-rw-r--r-- | block.c | 11 | ||||
-rw-r--r-- | block/nbd.c | 29 | ||||
-rw-r--r-- | include/block/block_int.h | 1 |
3 files changed, 25 insertions, 16 deletions
@@ -770,6 +770,17 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, bs->options = options; options = qdict_clone_shallow(options); + if (drv->bdrv_parse_filename) { + Error *local_err = NULL; + drv->bdrv_parse_filename(filename, options, &local_err); + if (error_is_set(&local_err)) { + qerror_report_err(local_err); + error_free(local_err); + ret = -EINVAL; + goto fail; + } + } + ret = bdrv_open_common(bs, NULL, filename, options, flags, drv); if (ret < 0) { goto fail; diff --git a/block/nbd.c b/block/nbd.c index 5ed8502071..9858f060ca 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -143,17 +143,20 @@ out: return ret; } -static int nbd_parse_filename(const char *filename, QDict *options) +static void nbd_parse_filename(const char *filename, QDict *options, + Error **errp) { char *file; char *export_name; const char *host_spec; const char *unixpath; - int ret = -EINVAL; - Error *local_err = NULL; if (strstr(filename, "://")) { - return nbd_parse_uri(filename, options); + int ret = nbd_parse_uri(filename, options); + if (ret < 0) { + error_setg(errp, "No valid URL specified"); + } + return; } file = g_strdup(filename); @@ -171,11 +174,11 @@ static int nbd_parse_filename(const char *filename, QDict *options) /* extract the host_spec - fail if it's not nbd:... */ if (!strstart(file, "nbd:", &host_spec)) { + error_setg(errp, "File name string for NBD must start with 'nbd:'"); goto out; } if (!*host_spec) { - ret = 1; goto out; } @@ -185,10 +188,8 @@ static int nbd_parse_filename(const char *filename, QDict *options) } else { InetSocketAddress *addr = NULL; - addr = inet_parse(host_spec, &local_err); - if (local_err != NULL) { - qerror_report_err(local_err); - error_free(local_err); + addr = inet_parse(host_spec, errp); + if (error_is_set(errp)) { goto out; } @@ -197,10 +198,8 @@ static int nbd_parse_filename(const char *filename, QDict *options) qapi_free_InetSocketAddress(addr); } - ret = 1; out: g_free(file); - return ret; } static int nbd_config(BDRVNBDState *s, QDict *options) @@ -437,11 +436,6 @@ static int nbd_open(BlockDriverState *bs, const char* filename, qemu_co_mutex_init(&s->free_sema); /* Pop the config into our state object. Exit if invalid. */ - result = nbd_parse_filename(filename, options); - if (result < 0) { - return result; - } - result = nbd_config(s, options); if (result != 0) { return result; @@ -622,6 +616,7 @@ static BlockDriver bdrv_nbd = { .format_name = "nbd", .protocol_name = "nbd", .instance_size = sizeof(BDRVNBDState), + .bdrv_parse_filename = nbd_parse_filename, .bdrv_file_open = nbd_open, .bdrv_co_readv = nbd_co_readv, .bdrv_co_writev = nbd_co_writev, @@ -635,6 +630,7 @@ static BlockDriver bdrv_nbd_tcp = { .format_name = "nbd", .protocol_name = "nbd+tcp", .instance_size = sizeof(BDRVNBDState), + .bdrv_parse_filename = nbd_parse_filename, .bdrv_file_open = nbd_open, .bdrv_co_readv = nbd_co_readv, .bdrv_co_writev = nbd_co_writev, @@ -648,6 +644,7 @@ static BlockDriver bdrv_nbd_unix = { .format_name = "nbd", .protocol_name = "nbd+unix", .instance_size = sizeof(BDRVNBDState), + .bdrv_parse_filename = nbd_parse_filename, .bdrv_file_open = nbd_open, .bdrv_co_readv = nbd_co_readv, .bdrv_co_writev = nbd_co_writev, diff --git a/include/block/block_int.h b/include/block/block_int.h index fb2a136774..1b06a11590 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -75,6 +75,7 @@ struct BlockDriver { int instance_size; int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename); int (*bdrv_probe_device)(const char *filename); + void (*bdrv_parse_filename)(const char *filename, QDict *options, Error **errp); /* For handling image reopen for split or non-split files */ int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state, |