Allow qemu binary to be overridden at runtime.
[libguestfs.git] / src / guestfs.c
index 1b7d61c..1642019 100644 (file)
@@ -156,6 +156,7 @@ struct guestfs_h
   int autosync;
 
   const char *path;
+  const char *qemu;
 
   char *last_error;
 
@@ -217,7 +218,9 @@ guestfs_create (void)
 
   str = getenv ("LIBGUESTFS_PATH");
   g->path = str != NULL ? str : GUESTFS_DEFAULT_PATH;
-  /* XXX We should probably make QEMU configurable as well. */
+
+  str = getenv ("LIBGUESTFS_QEMU");
+  g->qemu = str != NULL ? str : QEMU;
 
   g->main_loop = guestfs_get_default_main_loop ();
 
@@ -511,6 +514,22 @@ guestfs_get_path (guestfs_h *g)
   return g->path;
 }
 
+int
+guestfs_set_qemu (guestfs_h *g, const char *qemu)
+{
+  if (qemu == NULL)
+    g->qemu = QEMU;
+  else
+    g->qemu = qemu;
+  return 0;
+}
+
+const char *
+guestfs_get_qemu (guestfs_h *g)
+{
+  return g->qemu;
+}
+
 /* Add a string to the current command line. */
 static void
 incr_cmdline_size (guestfs_h *g)
@@ -715,7 +734,7 @@ guestfs_launch (guestfs_h *g)
     /* Set up the full command line.  Do this in the subprocess so we
      * don't need to worry about cleaning up.
      */
-    g->cmdline[0] = (char *) QEMU;
+    g->cmdline[0] = (char *) g->qemu;
 
     /* Construct the -net channel parameter for qemu. */
     snprintf (vmchannel, sizeof vmchannel,
@@ -730,7 +749,9 @@ guestfs_launch (guestfs_h *g)
 
     add_cmdline (g, "-m");
     add_cmdline (g, "384");      /* XXX Choose best size. */
+#if 0
     add_cmdline (g, "-no-kqemu"); /* Avoids a warning. */
+#endif
     add_cmdline (g, "-kernel");
     add_cmdline (g, (char *) kernel);
     add_cmdline (g, "-initrd");
@@ -750,7 +771,7 @@ guestfs_launch (guestfs_h *g)
     g->cmdline[g->cmdline_size-1] = NULL;
 
     if (g->verbose) {
-      fprintf (stderr, "%s", QEMU);
+      fprintf (stderr, "%s", g->qemu);
       for (i = 0; g->cmdline[i]; ++i)
        fprintf (stderr, " %s", g->cmdline[i]);
       fprintf (stderr, "\n");
@@ -773,8 +794,8 @@ guestfs_launch (guestfs_h *g)
     setpgid (0, 0);
 #endif
 
-    execv (QEMU, g->cmdline);  /* Run qemu. */
-    perror (QEMU);
+    execv (g->qemu, g->cmdline); /* Run qemu. */
+    perror (g->qemu);
     _exit (1);
   }
 
@@ -1534,11 +1555,14 @@ guestfs__send_file_sync (guestfs_h *g, const char *filename)
   /* Send file in chunked encoding. */
   while (!cancel && (r = read (fd, buf, sizeof buf)) > 0) {
     err = send_file_data_sync (g, buf, r);
-    if (err < 0)
+    if (err < 0) {
+      if (err == -2)           /* daemon sent cancellation */
+       send_file_cancellation_sync (g);
       return err;
+    }
   }
 
-  if (cancel) {
+  if (cancel) {                        /* cancel from either end */
     send_file_cancellation_sync (g);
     return -1;
   }
@@ -1604,14 +1628,22 @@ send_file_chunk_sync (guestfs_h *g, int cancel, const char *buf, size_t len)
   }
 
   /* Did the daemon send a cancellation message? */
-  if (check_for_daemon_cancellation (g))
+  if (check_for_daemon_cancellation (g)) {
+    if (g->verbose)
+      fprintf (stderr, "got daemon cancellation\n");
     return -2;
+  }
 
   /* Serialize the chunk. */
   chunk.cancel = cancel;
   chunk.data.data_len = len;
   chunk.data.data_val = (char *) buf;
 
+  if (g->verbose)
+    fprintf (stderr,
+            "library sending chunk cancel = %d, len = %zu, buf = %p\n",
+            cancel, len, buf);
+
   xdrmem_create (&xdr, data, sizeof data, XDR_ENCODE);
   if (!xdr_guestfs_chunk (&xdr, &chunk)) {
     error (g, "xdr_guestfs_chunk failed (buf = %p, len = %zu)", buf, len);