X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=qemu-io.c;h=475a8bd0347a1c037d8b7c33b7beb672ce520dc7;hb=9b5751ec09702ddf043bdd1f611880113d212c1a;hp=8f3b94b838c75d0fb206ac1e3a5e5d3093c05d2d;hpb=9e559533bd825a3e371497875576137a8586c831;p=qemu.git diff --git a/qemu-io.c b/qemu-io.c index 8f3b94b83..475a8bd03 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -15,8 +15,8 @@ #include #include "qemu-common.h" -#include "main-loop.h" -#include "block_int.h" +#include "qemu/main-loop.h" +#include "block/block_int.h" #include "cmd.h" #include "trace/control.h" @@ -265,6 +265,18 @@ static int do_co_write_zeroes(int64_t offset, int count, int *total) } } +static int do_write_compressed(char *buf, int64_t offset, int count, int *total) +{ + int ret; + + ret = bdrv_write_compressed(bs, offset >> 9, (uint8_t *)buf, count >> 9); + if (ret < 0) { + return ret; + } + *total = count; + return 1; +} + static int do_load_vmstate(char *buf, int64_t offset, int count, int *total) { *total = bdrv_load_vmstate(bs, (uint8_t *)buf, offset, count); @@ -687,6 +699,7 @@ static void write_help(void) " Writes into a segment of the currently open file, using a buffer\n" " filled with a set pattern (0xcdcdcdcd).\n" " -b, -- write to the VM state rather than the virtual disk\n" +" -c, -- write compressed data with bdrv_write_compressed\n" " -p, -- use bdrv_pwrite to write the file\n" " -P, -- use different pattern to fill file\n" " -C, -- report statistics in a machine parsable format\n" @@ -703,7 +716,7 @@ static const cmdinfo_t write_cmd = { .cfunc = write_f, .argmin = 2, .argmax = -1, - .args = "[-bCpqz] [-P pattern ] off len", + .args = "[-bcCpqz] [-P pattern ] off len", .oneline = "writes a number of bytes at a specified offset", .help = write_help, }; @@ -712,6 +725,7 @@ static int write_f(int argc, char **argv) { struct timeval t1, t2; int Cflag = 0, pflag = 0, qflag = 0, bflag = 0, Pflag = 0, zflag = 0; + int cflag = 0; int c, cnt; char *buf = NULL; int64_t offset; @@ -720,11 +734,14 @@ static int write_f(int argc, char **argv) int total = 0; int pattern = 0xcd; - while ((c = getopt(argc, argv, "bCpP:qz")) != EOF) { + while ((c = getopt(argc, argv, "bcCpP:qz")) != EOF) { switch (c) { case 'b': bflag = 1; break; + case 'c': + cflag = 1; + break; case 'C': Cflag = 1; break; @@ -801,6 +818,8 @@ static int write_f(int argc, char **argv) cnt = do_save_vmstate(buf, offset, count, &total); } else if (zflag) { cnt = do_co_write_zeroes(offset, count, &total); + } else if (cflag) { + cnt = do_write_compressed(buf, offset, count, &total); } else { cnt = do_write(buf, offset, count, &total); } @@ -1362,7 +1381,7 @@ static int aio_write_f(int argc, char **argv) static int aio_flush_f(int argc, char **argv) { - qemu_aio_flush(); + bdrv_drain_all(); return 0; } @@ -1652,6 +1671,78 @@ static const cmdinfo_t map_cmd = { .oneline = "prints the allocated areas of a file", }; +static int break_f(int argc, char **argv) +{ + int ret; + + ret = bdrv_debug_breakpoint(bs, argv[1], argv[2]); + if (ret < 0) { + printf("Could not set breakpoint: %s\n", strerror(-ret)); + } + + return 0; +} + +static const cmdinfo_t break_cmd = { + .name = "break", + .argmin = 2, + .argmax = 2, + .cfunc = break_f, + .args = "event tag", + .oneline = "sets a breakpoint on event and tags the stopped " + "request as tag", +}; + +static int resume_f(int argc, char **argv) +{ + int ret; + + ret = bdrv_debug_resume(bs, argv[1]); + if (ret < 0) { + printf("Could not resume request: %s\n", strerror(-ret)); + } + + return 0; +} + +static const cmdinfo_t resume_cmd = { + .name = "resume", + .argmin = 1, + .argmax = 1, + .cfunc = resume_f, + .args = "tag", + .oneline = "resumes the request tagged as tag", +}; + +static int wait_break_f(int argc, char **argv) +{ + while (!bdrv_debug_is_suspended(bs, argv[1])) { + qemu_aio_wait(); + } + + return 0; +} + +static const cmdinfo_t wait_break_cmd = { + .name = "wait_break", + .argmin = 1, + .argmax = 1, + .cfunc = wait_break_f, + .args = "tag", + .oneline = "waits for the suspension of a request", +}; + +static int abort_f(int argc, char **argv) +{ + abort(); +} + +static const cmdinfo_t abort_cmd = { + .name = "abort", + .cfunc = abort_f, + .flags = CMD_NOFILE_OK, + .oneline = "simulate a program crash using abort(3)", +}; static int close_f(int argc, char **argv) { @@ -1675,14 +1766,14 @@ static int openfile(char *name, int flags, int growable) } if (growable) { - if (bdrv_file_open(&bs, name, flags)) { + if (bdrv_file_open(&bs, name, NULL, flags)) { fprintf(stderr, "%s: can't open device %s\n", progname, name); return 1; } } else { bs = bdrv_new("hda"); - if (bdrv_open(bs, name, flags, NULL) < 0) { + if (bdrv_open(bs, name, NULL, flags, NULL) < 0) { fprintf(stderr, "%s: can't open device %s\n", progname, name); bdrv_delete(bs); bs = NULL; @@ -1808,7 +1899,7 @@ int main(int argc, char **argv) { int readonly = 0; int growable = 0; - const char *sopt = "hVc:rsnmgkt:T:"; + const char *sopt = "hVc:d:rsnmgkt:T:"; const struct option lopt[] = { { "help", 0, NULL, 'h' }, { "version", 0, NULL, 'V' }, @@ -1820,13 +1911,14 @@ int main(int argc, char **argv) { "misalign", 0, NULL, 'm' }, { "growable", 0, NULL, 'g' }, { "native-aio", 0, NULL, 'k' }, + { "discard", 1, NULL, 'd' }, { "cache", 1, NULL, 't' }, { "trace", 1, NULL, 'T' }, { NULL, 0, NULL, 0 } }; int c; int opt_index = 0; - int flags = 0; + int flags = BDRV_O_UNMAP; progname = basename(argv[0]); @@ -1838,6 +1930,12 @@ int main(int argc, char **argv) case 'n': flags |= BDRV_O_NOCACHE | BDRV_O_CACHE_WB; break; + case 'd': + if (bdrv_parse_discard_flags(optarg, &flags) < 0) { + error_report("Invalid discard option: %s", optarg); + exit(1); + } + break; case 'c': add_user_command(optarg); break; @@ -1881,9 +1979,8 @@ int main(int argc, char **argv) exit(1); } - bdrv_init(); - qemu_init_main_loop(); + bdrv_init(); /* initialize commands */ quit_init(); @@ -1905,6 +2002,10 @@ int main(int argc, char **argv) add_command(&discard_cmd); add_command(&alloc_cmd); add_command(&map_cmd); + add_command(&break_cmd); + add_command(&resume_cmd); + add_command(&wait_break_cmd); + add_command(&abort_cmd); add_args_command(init_args_command); add_check_command(init_check_command);