Message ID | 1276624421-23999-3-git-send-email-morita.kazutaka@lab.ntt.co.jp |
---|---|
State | New |
Headers | show |
Am 15.06.2010 19:53, schrieb MORITA Kazutaka: > Some block drivers use an aio handler and do I/O completion routines > in it. However, the handler is not invoked if we only do > aio_read/write, because registered fds are not checked at all. > > This patch registers a command processing function as a fd handler to > STDIO, and calls qemu_aio_wait() in command_loop(). Any other > handlers can be invoked when user input is idle. > > Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp> This patch is much nicer than I would have expected it to be! Thanks, applied to the block branch. Kevin
Am 15.06.2010 19:53, schrieb MORITA Kazutaka: > Some block drivers use an aio handler and do I/O completion routines > in it. However, the handler is not invoked if we only do > aio_read/write, because registered fds are not checked at all. > > This patch registers a command processing function as a fd handler to > STDIO, and calls qemu_aio_wait() in command_loop(). Any other > handlers can be invoked when user input is idle. > > Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp> This breaks qemu-iotests. The reason is that synchronous requests get out of order. Previously, do_aio_readv/writev waited until the request was completed, and only afterwards the next command was read from stdio. Now the next command can start during the qemu_aio_wait() that do_aio_readv/writev uses internally to wait. So we either need to deregister the fd handler while a command is running, or (more cleanly) have an async_context_push/pop for any command except aio_*. Kevin
diff --git a/cmd.c b/cmd.c index 460df92..2b66e24 100644 --- a/cmd.c +++ b/cmd.c @@ -24,6 +24,7 @@ #include <getopt.h> #include "cmd.h" +#include "qemu-aio.h" #define _(x) x /* not gettext support yet */ @@ -149,6 +150,37 @@ add_args_command( args_func = af; } +static char *get_prompt(void); + +static void do_command(void *opaque) +{ + int c; + int *done = opaque; + char *input; + char **v; + const cmdinfo_t *ct; + + if ((input = fetchline()) == NULL) { + *done = 1; + return; + } + v = breakline(input, &c); + if (c) { + ct = find_command(v[0]); + if (ct) + *done = command(ct, c, v); + else + fprintf(stderr, _("command \"%s\" not found\n"), + v[0]); + } + doneline(input, v); + + if (*done == 0) { + printf("%s", get_prompt()); + fflush(stdout); + } +} + void command_loop(void) { @@ -186,20 +218,15 @@ command_loop(void) free(cmdline); return; } + + printf("%s", get_prompt()); + fflush(stdout); + + qemu_aio_set_fd_handler(STDIN_FILENO, do_command, NULL, NULL, NULL, &done); while (!done) { - if ((input = fetchline()) == NULL) - break; - v = breakline(input, &c); - if (c) { - ct = find_command(v[0]); - if (ct) - done = command(ct, c, v); - else - fprintf(stderr, _("command \"%s\" not found\n"), - v[0]); - } - doneline(input, v); + qemu_aio_wait(); } + qemu_aio_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL); } /* from libxcmd/input.c */ @@ -270,8 +297,6 @@ fetchline(void) if (!line) return NULL; - printf("%s", get_prompt()); - fflush(stdout); again: if (!fgets(line, MAXREADLINESZ, stdin)) { if (errno == EINTR)
Some block drivers use an aio handler and do I/O completion routines in it. However, the handler is not invoked if we only do aio_read/write, because registered fds are not checked at all. This patch registers a command processing function as a fd handler to STDIO, and calls qemu_aio_wait() in command_loop(). Any other handlers can be invoked when user input is idle. Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp> --- cmd.c | 53 +++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 39 insertions(+), 14 deletions(-)