Blob Blame History Raw
From c29743cdbdd8f5b526704705de7cc2ae3d0790c7 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Tue, 22 Mar 2016 14:04:26 +0000
Subject: [PATCH] launch: direct: Don't run qemu -version.

Dr. David Gilbert pointed out to me that the first line of the
qemu -help output includes the qemu version, so we don't need
to run qemu -version at all.

This saves about 0.04s on the launch time when using the direct
backend.

(cherry picked from commit b7b34119766349522528fdfe56237bede0794b6a)
---
 src/launch-direct.c | 54 +++++++++++++++++++----------------------------------
 1 file changed, 19 insertions(+), 35 deletions(-)

diff --git a/src/launch-direct.c b/src/launch-direct.c
index cbaf4f3..646f9c6 100644
--- a/src/launch-direct.c
+++ b/src/launch-direct.c
@@ -61,7 +61,6 @@ struct backend_direct_data {
   pid_t recoverypid;          /* Recovery process PID. */
 
   char *qemu_help;            /* Output of qemu -help. */
-  char *qemu_version;         /* Output of qemu -version. */
   char *qemu_devices;         /* Output of qemu -device ? */
 
   /* qemu version (0, 0 if unable to parse). */
@@ -935,22 +934,18 @@ print_qemu_command_line (guestfs_h *g, char **argv)
 static void parse_qemu_version (guestfs_h *g, struct backend_direct_data *data);
 static void read_all (guestfs_h *g, void *retv, const char *buf, size_t len);
 
-/* Test qemu binary (or wrapper) runs, and do 'qemu -help' and
- * 'qemu -version' so we know what options this qemu supports and
- * the version.
+/* Test qemu binary (or wrapper) runs, and do 'qemu -help' so we know
+ * the version of qemu what options this qemu supports.
  */
 static int
 test_qemu (guestfs_h *g, struct backend_direct_data *data)
 {
   CLEANUP_CMD_CLOSE struct command *cmd1 = guestfs_int_new_command (g);
   CLEANUP_CMD_CLOSE struct command *cmd2 = guestfs_int_new_command (g);
-  CLEANUP_CMD_CLOSE struct command *cmd3 = guestfs_int_new_command (g);
   int r;
 
   free (data->qemu_help);
   data->qemu_help = NULL;
-  free (data->qemu_version);
-  data->qemu_version = NULL;
   free (data->qemu_devices);
   data->qemu_devices = NULL;
 
@@ -964,34 +959,24 @@ test_qemu (guestfs_h *g, struct backend_direct_data *data)
   if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0)
     goto error;
 
+  parse_qemu_version (g, data);
+
   guestfs_int_cmd_add_arg (cmd2, g->hv);
   guestfs_int_cmd_add_arg (cmd2, "-display");
   guestfs_int_cmd_add_arg (cmd2, "none");
-  guestfs_int_cmd_add_arg (cmd2, "-version");
-  guestfs_int_cmd_set_stdout_callback (cmd2, read_all, &data->qemu_version,
-				       CMD_STDOUT_FLAG_WHOLE_BUFFER);
-  r = guestfs_int_cmd_run (cmd2);
-  if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0)
-    goto error;
-
-  parse_qemu_version (g, data);
-
-  guestfs_int_cmd_add_arg (cmd3, g->hv);
-  guestfs_int_cmd_add_arg (cmd3, "-display");
-  guestfs_int_cmd_add_arg (cmd3, "none");
-  guestfs_int_cmd_add_arg (cmd3, "-machine");
-  guestfs_int_cmd_add_arg (cmd3,
+  guestfs_int_cmd_add_arg (cmd2, "-machine");
+  guestfs_int_cmd_add_arg (cmd2,
 #ifdef MACHINE_TYPE
                            MACHINE_TYPE ","
 #endif
                            "accel=kvm:tcg");
-  guestfs_int_cmd_add_arg (cmd3, "-device");
-  guestfs_int_cmd_add_arg (cmd3, "?");
-  guestfs_int_cmd_clear_capture_errors (cmd3);
-  guestfs_int_cmd_set_stderr_to_stdout (cmd3);
-  guestfs_int_cmd_set_stdout_callback (cmd3, read_all, &data->qemu_devices,
+  guestfs_int_cmd_add_arg (cmd2, "-device");
+  guestfs_int_cmd_add_arg (cmd2, "?");
+  guestfs_int_cmd_clear_capture_errors (cmd2);
+  guestfs_int_cmd_set_stderr_to_stdout (cmd2);
+  guestfs_int_cmd_set_stdout_callback (cmd2, read_all, &data->qemu_devices,
 				       CMD_STDOUT_FLAG_WHOLE_BUFFER);
-  r = guestfs_int_cmd_run (cmd3);
+  r = guestfs_int_cmd_run (cmd2);
   if (r == -1 || !WIFEXITED (r) || WEXITSTATUS (r) != 0)
     goto error;
 
@@ -1005,8 +990,9 @@ test_qemu (guestfs_h *g, struct backend_direct_data *data)
   return -1;
 }
 
-/* Parse data->qemu_version (if not NULL) into the major and minor
- * version of qemu, but don't fail if parsing is not possible.
+/* Parse the first line of data->qemu_help (if not NULL) into the
+ * major and minor version of qemu, but don't fail if parsing is not
+ * possible.
  */
 static void
 parse_qemu_version (guestfs_h *g, struct backend_direct_data *data)
@@ -1017,13 +1003,13 @@ parse_qemu_version (guestfs_h *g, struct backend_direct_data *data)
   data->qemu_version_major = 0;
   data->qemu_version_minor = 0;
 
-  if (!data->qemu_version)
+  if (!data->qemu_help)
     return;
 
-  if (!match2 (g, data->qemu_version, re_major_minor, &major_s, &minor_s)) {
+  if (!match2 (g, data->qemu_help, re_major_minor, &major_s, &minor_s)) {
   parse_failed:
-    debug (g, "%s: failed to parse qemu version string '%s'",
-           __func__, data->qemu_version);
+    debug (g, "%s: failed to parse qemu version string from the first line of the output of '%s -help'.  When reporting this bug please include the -help output.",
+           __func__, g->hv);
     return;
   }
 
@@ -1505,8 +1491,6 @@ shutdown_direct (guestfs_h *g, void *datav, int check_for_errors)
 
   free (data->qemu_help);
   data->qemu_help = NULL;
-  free (data->qemu_version);
-  data->qemu_version = NULL;
   free (data->qemu_devices);
   data->qemu_devices = NULL;
 
-- 
1.8.3.1