Re: [Qemu-devel] [PATCH 2/3] qtest: make QEMU our direct child process

2014-02-18 Thread Stefan Hajnoczi
On Mon, Feb 17, 2014 at 05:44:55PM +0100, Markus Armbruster wrote:
 Stefan Hajnoczi stefa...@redhat.com writes:
 
  qtest_init() cannot use exec*p() to launch QEMU since the exec*p()
  functions take an argument array while qtest_init() takes char
  *extra_args.  Therefore we execute /bin/sh -c command-line and let the
  shell parse the argument string.
 
  This left /bin/sh as our child process and our child's child was QEMU.
  We still want QEMU's pid so the -pidfile option was used to let QEMU
  report its pid.
 
  The pidfile needs to be unlinked when the test case exits or fails.  In
  other words, the pidfile creates a new problem for us!
 
  Simplify all this using the shell 'exec' command.  It allows us to
  replace the /bin/sh process with QEMU.  Then we no longer need to use
  -pidfile because we already know our fork child's pid.
 
  Note: Yes, it seems silly to exec /bin/sh when we could just exec QEMU
  directly.  But remember qtest_init() takes a single char *extra_args
  command-line fragment instead of a real argv[] array, so we need
  /bin/sh's argument parsing behavior.
 
 Sounds like a design mistake to me.

I wouldn't call char *extra_args a mistake because strings are still
simpler to manipulate in C than char *argv[] arrays.  So we write less
code in test cases and libqtest.c at the expense of a roundabout way to
spawn the process.

Stefan



Re: [Qemu-devel] [PATCH 2/3] qtest: make QEMU our direct child process

2014-02-18 Thread Markus Armbruster
Stefan Hajnoczi stefa...@gmail.com writes:

 On Mon, Feb 17, 2014 at 05:44:55PM +0100, Markus Armbruster wrote:
 Stefan Hajnoczi stefa...@redhat.com writes:
 
  qtest_init() cannot use exec*p() to launch QEMU since the exec*p()
  functions take an argument array while qtest_init() takes char
  *extra_args.  Therefore we execute /bin/sh -c command-line and let the
  shell parse the argument string.
 
  This left /bin/sh as our child process and our child's child was QEMU.
  We still want QEMU's pid so the -pidfile option was used to let QEMU
  report its pid.
 
  The pidfile needs to be unlinked when the test case exits or fails.  In
  other words, the pidfile creates a new problem for us!
 
  Simplify all this using the shell 'exec' command.  It allows us to
  replace the /bin/sh process with QEMU.  Then we no longer need to use
  -pidfile because we already know our fork child's pid.
 
  Note: Yes, it seems silly to exec /bin/sh when we could just exec QEMU
  directly.  But remember qtest_init() takes a single char *extra_args
  command-line fragment instead of a real argv[] array, so we need
  /bin/sh's argument parsing behavior.
 
 Sounds like a design mistake to me.

 I wouldn't call char *extra_args a mistake because strings are still
 simpler to manipulate in C than char *argv[] arrays.  So we write less
 code in test cases and libqtest.c at the expense of a roundabout way to
 spawn the process.

Building command arguments in a string is deceptively simple.  The
deception collapses once you add funny characters that make the shell do
funny and unexpected things.

Our extra_args string manipulations are typically of the form format a
bunch of options and option arguments into a string.  I suspect using a
function to collect a bunch of options and option arguments into an
array would be about the same amount of code in most cases.

Just sayin'; I'm not objecting to your patch.



[Qemu-devel] [PATCH 2/3] qtest: make QEMU our direct child process

2014-02-17 Thread Stefan Hajnoczi
qtest_init() cannot use exec*p() to launch QEMU since the exec*p()
functions take an argument array while qtest_init() takes char
*extra_args.  Therefore we execute /bin/sh -c command-line and let the
shell parse the argument string.

This left /bin/sh as our child process and our child's child was QEMU.
We still want QEMU's pid so the -pidfile option was used to let QEMU
report its pid.

The pidfile needs to be unlinked when the test case exits or fails.  In
other words, the pidfile creates a new problem for us!

Simplify all this using the shell 'exec' command.  It allows us to
replace the /bin/sh process with QEMU.  Then we no longer need to use
-pidfile because we already know our fork child's pid.

Note: Yes, it seems silly to exec /bin/sh when we could just exec QEMU
directly.  But remember qtest_init() takes a single char *extra_args
command-line fragment instead of a real argv[] array, so we need
/bin/sh's argument parsing behavior.

Signed-off-by: Stefan Hajnoczi stefa...@redhat.com
---
 tests/libqtest.c | 34 +-
 1 file changed, 5 insertions(+), 29 deletions(-)

diff --git a/tests/libqtest.c b/tests/libqtest.c
index 2876ce4..8b2b2d7 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -43,7 +43,7 @@ struct QTestState
 int qmp_fd;
 bool irq_level[MAX_IRQ];
 GString *rx;
-pid_t qemu_pid;  /* QEMU process spawned by our child */
+pid_t qemu_pid;  /* our child QEMU process */
 };
 
 #define g_assert_no_errno(ret) do { \
@@ -88,32 +88,14 @@ static int socket_accept(int sock)
 return ret;
 }
 
-static pid_t read_pid_file(const char *pid_file)
-{
-FILE *f;
-char buffer[1024];
-pid_t pid = -1;
-
-f = fopen(pid_file, r);
-if (f) {
-if (fgets(buffer, sizeof(buffer), f)) {
-pid = atoi(buffer);
-}
-fclose(f);
-}
-return pid;
-}
-
 QTestState *qtest_init(const char *extra_args)
 {
 QTestState *s;
 int sock, qmpsock, i;
 gchar *socket_path;
 gchar *qmp_socket_path;
-gchar *pid_file;
 gchar *command;
 const char *qemu_binary;
-pid_t pid;
 
 qemu_binary = getenv(QTEST_QEMU_BINARY);
 g_assert(qemu_binary != NULL);
@@ -122,22 +104,20 @@ QTestState *qtest_init(const char *extra_args)
 
 socket_path = g_strdup_printf(/tmp/qtest-%d.sock, getpid());
 qmp_socket_path = g_strdup_printf(/tmp/qtest-%d.qmp, getpid());
-pid_file = g_strdup_printf(/tmp/qtest-%d.pid, getpid());
 
 sock = init_socket(socket_path);
 qmpsock = init_socket(qmp_socket_path);
 
-pid = fork();
-if (pid == 0) {
-command = g_strdup_printf(%s 
+s-qemu_pid = fork();
+if (s-qemu_pid == 0) {
+command = g_strdup_printf(exec %s 
   -qtest unix:%s,nowait 
   -qtest-log /dev/null 
   -qmp unix:%s,nowait 
-  -pidfile %s 
   -machine accel=qtest 
   -display none 
   %s, qemu_binary, socket_path,
-  qmp_socket_path, pid_file,
+  qmp_socket_path,
   extra_args ?: );
 execlp(/bin/sh, sh, -c, command, NULL);
 exit(1);
@@ -159,10 +139,6 @@ QTestState *qtest_init(const char *extra_args)
 qtest_qmp_discard_response(s, );
 qtest_qmp_discard_response(s, { 'execute': 'qmp_capabilities' });
 
-s-qemu_pid = read_pid_file(pid_file);
-unlink(pid_file);
-g_free(pid_file);
-
 if (getenv(QTEST_STOP)) {
 kill(s-qemu_pid, SIGSTOP);
 }
-- 
1.8.5.3




Re: [Qemu-devel] [PATCH 2/3] qtest: make QEMU our direct child process

2014-02-17 Thread Markus Armbruster
Stefan Hajnoczi stefa...@redhat.com writes:

 qtest_init() cannot use exec*p() to launch QEMU since the exec*p()
 functions take an argument array while qtest_init() takes char
 *extra_args.  Therefore we execute /bin/sh -c command-line and let the
 shell parse the argument string.

 This left /bin/sh as our child process and our child's child was QEMU.
 We still want QEMU's pid so the -pidfile option was used to let QEMU
 report its pid.

 The pidfile needs to be unlinked when the test case exits or fails.  In
 other words, the pidfile creates a new problem for us!

 Simplify all this using the shell 'exec' command.  It allows us to
 replace the /bin/sh process with QEMU.  Then we no longer need to use
 -pidfile because we already know our fork child's pid.

 Note: Yes, it seems silly to exec /bin/sh when we could just exec QEMU
 directly.  But remember qtest_init() takes a single char *extra_args
 command-line fragment instead of a real argv[] array, so we need
 /bin/sh's argument parsing behavior.

Sounds like a design mistake to me.

 Signed-off-by: Stefan Hajnoczi stefa...@redhat.com

Patch looks good.