X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=qemu-io.c;h=ed0e2dceaa7f641e5ad513fa97615e2a332d0838;hb=f3676379cc9f2c803e5e35e1fb7e0ae2041f6f1a;hp=8c31257ac4a917f8876a976dd42f3daa54125cc9;hpb=8eb779e4223a18db9838a49ece1bc72cfdfb7761;p=mirror_qemu.git diff --git a/qemu-io.c b/qemu-io.c index 8c31257ac4..ed0e2dceaa 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -11,17 +11,20 @@ #include #include +#include "qapi/error.h" #include "qemu-io.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "qemu/option.h" #include "qemu/config-file.h" #include "qemu/readline.h" +#include "qemu/log.h" #include "qapi/qmp/qstring.h" #include "qom/object_interfaces.h" #include "sysemu/block-backend.h" #include "block/block_int.h" #include "trace/control.h" +#include "crypto/init.h" #define CMD_NOFILE_OK 0x01 @@ -50,7 +53,7 @@ static const cmdinfo_t close_cmd = { .oneline = "close the current open file", }; -static int openfile(char *name, int flags, QDict *opts) +static int openfile(char *name, int flags, bool writethrough, QDict *opts) { Error *local_err = NULL; BlockDriverState *bs; @@ -61,7 +64,7 @@ static int openfile(char *name, int flags, QDict *opts) return 1; } - qemuio_blk = blk_new_open("hda", name, NULL, opts, flags, &local_err); + qemuio_blk = blk_new_open(name, NULL, opts, flags, &local_err); if (!qemuio_blk) { error_reportf_err(local_err, "can't open%s%s: ", name ? " device " : "", name ?: ""); @@ -69,7 +72,7 @@ static int openfile(char *name, int flags, QDict *opts) } bs = blk_bs(qemuio_blk); - if (bdrv_is_encrypted(bs)) { + if (bdrv_is_encrypted(bs) && bdrv_key_required(bs)) { char password[256]; printf("Disk image '%s' is encrypted.\n", name); if (qemu_read_password(password, sizeof(password)) < 0) { @@ -82,6 +85,7 @@ static int openfile(char *name, int flags, QDict *opts) } } + blk_set_enable_write_cache(qemuio_blk, !writethrough); return 0; @@ -98,12 +102,15 @@ static void open_help(void) " opens a new file in the requested mode\n" "\n" " Example:\n" -" 'open -Cn /tmp/data' - creates/opens data file read-write and uncached\n" +" 'open -n -o driver=raw /tmp/data' - opens raw data file read-write, uncached\n" "\n" " Opens a file for subsequent use by all of the other qemu-io commands.\n" " -r, -- open file read-only\n" " -s, -- use snapshot file\n" -" -n, -- disable host cache\n" +" -n, -- disable host cache, short for -t none\n" +" -k, -- use kernel AIO implementation (on Linux only)\n" +" -t, -- use the given cache mode for the image\n" +" -d, -- use the given discard mode for the image\n" " -o, -- options to be given to the block driver" "\n"); } @@ -117,7 +124,7 @@ static const cmdinfo_t open_cmd = { .argmin = 1, .argmax = -1, .flags = CMD_NOFILE_OK, - .args = "[-Crsn] [-o options] [path]", + .args = "[-rsnk] [-t cache] [-d discard] [-o options] [path]", .oneline = "open the file specified by path", .help = open_help, }; @@ -134,26 +141,46 @@ static QemuOptsList empty_opts = { static int open_f(BlockBackend *blk, int argc, char **argv) { - int flags = 0; + int flags = BDRV_O_UNMAP; int readonly = 0; + bool writethrough = true; int c; QemuOpts *qopts; QDict *opts; - while ((c = getopt(argc, argv, "snrgo:")) != -1) { + while ((c = getopt(argc, argv, "snro:kt:d:")) != -1) { switch (c) { case 's': flags |= BDRV_O_SNAPSHOT; break; case 'n': - flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB; + flags |= BDRV_O_NOCACHE; + writethrough = false; break; case 'r': readonly = 1; break; + case 'k': + flags |= BDRV_O_NATIVE_AIO; + break; + case 't': + if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) { + error_report("Invalid cache option: %s", optarg); + qemu_opts_reset(&empty_opts); + return 0; + } + break; + case 'd': + if (bdrv_parse_discard_flags(optarg, &flags) < 0) { + error_report("Invalid discard option: %s", optarg); + qemu_opts_reset(&empty_opts); + return 0; + } + break; case 'o': if (imageOpts) { printf("--image-opts and 'open -o' are mutually exclusive\n"); + qemu_opts_reset(&empty_opts); return 0; } if (!qemu_opts_parse_noisily(&empty_opts, optarg, false)) { @@ -184,9 +211,9 @@ static int open_f(BlockBackend *blk, int argc, char **argv) qemu_opts_reset(&empty_opts); if (optind == argc - 1) { - return openfile(argv[optind], flags, opts); + return openfile(argv[optind], flags, writethrough, opts); } else if (optind == argc) { - return openfile(NULL, flags, opts); + return openfile(NULL, flags, writethrough, opts); } else { QDECREF(opts); return qemuio_command_usage(&open_cmd); @@ -211,21 +238,25 @@ static const cmdinfo_t quit_cmd = { static void usage(const char *name) { printf( -"Usage: %s [-h] [-V] [-rsnm] [-f FMT] [-c STRING] ... [file]\n" +"Usage: %s [OPTIONS]... [-c STRING]... [file]\n" "QEMU Disk exerciser\n" "\n" " --object OBJECTDEF define an object such as 'secret' for\n" " passwords and/or encryption keys\n" +" --image-opts treat file as option string\n" " -c, --cmd STRING execute command with its arguments\n" " from the given string\n" " -f, --format FMT specifies the block driver to use\n" " -r, --read-only export read-only\n" " -s, --snapshot use snapshot file\n" -" -n, --nocache disable host cache\n" +" -n, --nocache disable host cache, short for -t none\n" " -m, --misalign misalign allocations for O_DIRECT\n" " -k, --native-aio use kernel AIO implementation (on Linux only)\n" " -t, --cache=MODE use the given cache mode for the image\n" -" -T, --trace FILE enable trace events listed in the given file\n" +" -d, --discard=MODE use the given discard mode for the image\n" +" -T, --trace [[enable=]][,events=][,file=]\n" +" specify tracing options\n" +" see qemu-img(1) man page for full description\n" " -h, --help display this help and exit\n" " -V, --version output version information and exit\n" "\n" @@ -405,11 +436,10 @@ static QemuOptsList file_opts = { int main(int argc, char **argv) { int readonly = 0; - const char *sopt = "hVc:d:f:rsnmgkt:T:"; + const char *sopt = "hVc:d:f:rsnmkt:T:"; const struct option lopt[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, - { "offset", required_argument, NULL, 'o' }, { "cmd", required_argument, NULL, 'c' }, { "format", required_argument, NULL, 'f' }, { "read-only", no_argument, NULL, 'r' }, @@ -427,19 +457,25 @@ int main(int argc, char **argv) int c; int opt_index = 0; int flags = BDRV_O_UNMAP; + bool writethrough = true; Error *local_error = NULL; QDict *opts = NULL; const char *format = NULL; + char *trace_file = NULL; #ifdef CONFIG_POSIX signal(SIGPIPE, SIG_IGN); #endif + module_call_init(MODULE_INIT_TRACE); progname = basename(argv[0]); qemu_init_exec_dir(argv[0]); + qcrypto_init(&error_fatal); + module_call_init(MODULE_INIT_QOM); qemu_add_opts(&qemu_object_opts); + qemu_add_opts(&qemu_trace_opts); bdrv_init(); while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) { @@ -448,7 +484,8 @@ int main(int argc, char **argv) flags |= BDRV_O_SNAPSHOT; break; case 'n': - flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB; + flags |= BDRV_O_NOCACHE; + writethrough = false; break; case 'd': if (bdrv_parse_discard_flags(optarg, &flags) < 0) { @@ -472,15 +509,14 @@ int main(int argc, char **argv) flags |= BDRV_O_NATIVE_AIO; break; case 't': - if (bdrv_parse_cache_flags(optarg, &flags) < 0) { + if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) { error_report("Invalid cache option: %s", optarg); exit(1); } break; case 'T': - if (!trace_init_backends()) { - exit(1); /* error message will have been printed */ - } + g_free(trace_file); + trace_file = trace_opt_parse(optarg); break; case 'V': printf("%s version %s\n", progname, QEMU_VERSION); @@ -522,11 +558,16 @@ int main(int argc, char **argv) if (qemu_opts_foreach(&qemu_object_opts, user_creatable_add_opts_foreach, - NULL, &local_error)) { - error_report_err(local_error); + NULL, NULL)) { exit(1); } + if (!trace_init_backends()) { + exit(1); + } + trace_init_file(trace_file); + qemu_set_log(LOG_TRACE); + /* initialize commands */ qemuio_add_command(&quit_cmd); qemuio_add_command(&open_cmd); @@ -554,13 +595,17 @@ int main(int argc, char **argv) exit(1); } opts = qemu_opts_to_qdict(qopts, NULL); - openfile(NULL, flags, opts); + if (openfile(NULL, flags, writethrough, opts)) { + exit(1); + } } else { if (format) { opts = qdict_new(); - qdict_put(opts, "driver", qstring_from_str(format)); + qdict_put_str(opts, "driver", format); + } + if (openfile(argv[optind], flags, writethrough, opts)) { + exit(1); } - openfile(argv[optind], flags, opts); } } command_loop();