Patchwork [v2] qemu-io: check registered fds in command_loop()

login
register
mail settings
Submitter MORITA Kazutaka
Date June 20, 2010, 7:03 p.m.
Message ID <1277060632-7768-1-git-send-email-morita.kazutaka@lab.ntt.co.jp>
Download mbox | patch
Permalink /patch/56269/
State New
Headers show

Comments

MORITA Kazutaka - June 20, 2010, 7:03 p.m.
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 an aio handler of STDIO to checks whether we can
read a command without blocking, 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>
---

It seems that the QEMU aio implementation doesn't allow to call
qemu_aio_wait() in the aio handler, so the previous patch is broken.

This patch only checks that STDIO is ready to read a line in the aio
handler, and invokes a command in command_loop().

I think this also fixes the problem which occurs in qemu-iotests.

 cmd.c |   33 ++++++++++++++++++++++++++++++---
 1 files changed, 30 insertions(+), 3 deletions(-)
Kevin Wolf - June 21, 2010, 10:39 a.m.
Am 20.06.2010 21:03, 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 an aio handler of STDIO to checks whether we can
> read a command without blocking, 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>
> ---
> 
> It seems that the QEMU aio implementation doesn't allow to call
> qemu_aio_wait() in the aio handler, so the previous patch is broken.
> 
> This patch only checks that STDIO is ready to read a line in the aio
> handler, and invokes a command in command_loop().
> 
> I think this also fixes the problem which occurs in qemu-iotests.

It does, indeed. Thanks, applied to the block branch.

Kevin

Patch

diff --git a/cmd.c b/cmd.c
index 2336334..db2c9c4 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,10 +150,20 @@  add_args_command(
 	args_func = af;
 }
 
+static void prep_fetchline(void *opaque)
+{
+    int *fetchable = opaque;
+
+    qemu_aio_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL);
+    *fetchable= 1;
+}
+
+static char *get_prompt(void);
+
 void
 command_loop(void)
 {
-	int		c, i, j = 0, done = 0;
+	int		c, i, j = 0, done = 0, fetchable = 0, prompted = 0;
 	char		*input;
 	char		**v;
 	const cmdinfo_t	*ct;
@@ -186,7 +197,21 @@  command_loop(void)
 		free(cmdline);
 		return;
 	}
+
 	while (!done) {
+        if (!prompted) {
+            printf("%s", get_prompt());
+            fflush(stdout);
+            qemu_aio_set_fd_handler(STDIN_FILENO, prep_fetchline, NULL, NULL,
+                                    NULL, &fetchable);
+            prompted = 1;
+        }
+
+        qemu_aio_wait();
+
+        if (!fetchable) {
+            continue;
+        }
 		if ((input = fetchline()) == NULL)
 			break;
 		v = breakline(input, &c);
@@ -199,7 +224,11 @@  command_loop(void)
 					v[0]);
 		}
 		doneline(input, v);
+
+        prompted = 0;
+        fetchable = 0;
 	}
+    qemu_aio_set_fd_handler(STDIN_FILENO, NULL, NULL, NULL, NULL, NULL);
 }
 
 /* from libxcmd/input.c */
@@ -270,8 +299,6 @@  fetchline(void)
 
 	if (!line)
 		return NULL;
-	printf("%s", get_prompt());
-	fflush(stdout);
 	if (!fgets(line, MAXREADLINESZ, stdin)) {
 		free(line);
 		return NULL;