qemu-io: Let "open" pass options to block driver

Add an option to the open command to specify runtime options for the
block driver used.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Max Reitz 2013-10-11 14:02:10 +02:00 committed by Kevin Wolf
parent 899f1ae219
commit b543c5cdcb
1 changed files with 31 additions and 8 deletions

View File

@ -16,6 +16,8 @@
#include "qemu-io.h" #include "qemu-io.h"
#include "qemu/main-loop.h" #include "qemu/main-loop.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "block/block_int.h" #include "block/block_int.h"
#include "trace/control.h" #include "trace/control.h"
@ -44,7 +46,7 @@ static const cmdinfo_t close_cmd = {
.oneline = "close the current open file", .oneline = "close the current open file",
}; };
static int openfile(char *name, int flags, int growable) static int openfile(char *name, int flags, int growable, QDict *opts)
{ {
Error *local_err = NULL; Error *local_err = NULL;
@ -54,7 +56,7 @@ static int openfile(char *name, int flags, int growable)
} }
if (growable) { if (growable) {
if (bdrv_file_open(&qemuio_bs, name, NULL, flags, &local_err)) { if (bdrv_file_open(&qemuio_bs, name, opts, flags, &local_err)) {
fprintf(stderr, "%s: can't open device %s: %s\n", progname, name, fprintf(stderr, "%s: can't open device %s: %s\n", progname, name,
error_get_pretty(local_err)); error_get_pretty(local_err));
error_free(local_err); error_free(local_err);
@ -63,7 +65,7 @@ static int openfile(char *name, int flags, int growable)
} else { } else {
qemuio_bs = bdrv_new("hda"); qemuio_bs = bdrv_new("hda");
if (bdrv_open(qemuio_bs, name, NULL, flags, NULL, &local_err) < 0) { if (bdrv_open(qemuio_bs, name, opts, flags, NULL, &local_err) < 0) {
fprintf(stderr, "%s: can't open device %s: %s\n", progname, name, fprintf(stderr, "%s: can't open device %s: %s\n", progname, name,
error_get_pretty(local_err)); error_get_pretty(local_err));
error_free(local_err); error_free(local_err);
@ -89,7 +91,8 @@ static void open_help(void)
" -r, -- open file read-only\n" " -r, -- open file read-only\n"
" -s, -- use snapshot file\n" " -s, -- use snapshot file\n"
" -n, -- disable host cache\n" " -n, -- disable host cache\n"
" -g, -- allow file to grow (only applies to protocols)" " -g, -- allow file to grow (only applies to protocols)\n"
" -o, -- options to be given to the block driver"
"\n"); "\n");
} }
@ -102,19 +105,30 @@ static const cmdinfo_t open_cmd = {
.argmin = 1, .argmin = 1,
.argmax = -1, .argmax = -1,
.flags = CMD_NOFILE_OK, .flags = CMD_NOFILE_OK,
.args = "[-Crsn] [path]", .args = "[-Crsn] [-o options] [path]",
.oneline = "open the file specified by path", .oneline = "open the file specified by path",
.help = open_help, .help = open_help,
}; };
static QemuOptsList empty_opts = {
.name = "drive",
.head = QTAILQ_HEAD_INITIALIZER(empty_opts.head),
.desc = {
/* no elements => accept any params */
{ /* end of list */ }
},
};
static int open_f(BlockDriverState *bs, int argc, char **argv) static int open_f(BlockDriverState *bs, int argc, char **argv)
{ {
int flags = 0; int flags = 0;
int readonly = 0; int readonly = 0;
int growable = 0; int growable = 0;
int c; int c;
QemuOpts *qopts;
QDict *opts = NULL;
while ((c = getopt(argc, argv, "snrg")) != EOF) { while ((c = getopt(argc, argv, "snrgo:")) != EOF) {
switch (c) { switch (c) {
case 's': case 's':
flags |= BDRV_O_SNAPSHOT; flags |= BDRV_O_SNAPSHOT;
@ -128,6 +142,15 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
case 'g': case 'g':
growable = 1; growable = 1;
break; break;
case 'o':
qopts = qemu_opts_parse(&empty_opts, optarg, 0);
if (qopts == NULL) {
printf("could not parse option list -- %s\n", optarg);
return 0;
}
opts = qemu_opts_to_qdict(qopts, opts);
qemu_opts_del(qopts);
break;
default: default:
return qemuio_command_usage(&open_cmd); return qemuio_command_usage(&open_cmd);
} }
@ -141,7 +164,7 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
return qemuio_command_usage(&open_cmd); return qemuio_command_usage(&open_cmd);
} }
return openfile(argv[optind], flags, growable); return openfile(argv[optind], flags, growable, opts);
} }
static int quit_f(BlockDriverState *bs, int argc, char **argv) static int quit_f(BlockDriverState *bs, int argc, char **argv)
@ -418,7 +441,7 @@ int main(int argc, char **argv)
} }
if ((argc - optind) == 1) { if ((argc - optind) == 1) {
openfile(argv[optind], flags, growable); openfile(argv[optind], flags, growable, NULL);
} }
command_loop(); command_loop();