mrc0mmand / rpms / libguestfs

Forked from rpms/libguestfs 3 years ago
Clone
Blob Blame History Raw
From 547504706ea62956201d40c230d2ab85bd99fbc4 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Thu, 30 Jun 2016 14:13:24 +0100
Subject: [PATCH] p2v: Send ^C to remote end to cancel the conversion.

We are now able to cancel the conversion instantly by sending ^C to
the remote virt-v2v process.

Also, this reverts:
"p2v: Poll to make Cancel Conversion button more responsive."
(commit 6da4941db7f8a85997d6281b9b4c5165768e6489)

(cherry picked from commit 87131d8681b6e72dac4d8c952f3b3fb7ade02eed)
---
 p2v/conversion.c | 60 +++++++++++++++++++++++++++-----------------------------
 1 file changed, 29 insertions(+), 31 deletions(-)

diff --git a/p2v/conversion.c b/p2v/conversion.c
index f9b8350..484c0e4 100644
--- a/p2v/conversion.c
+++ b/p2v/conversion.c
@@ -25,7 +25,6 @@
 #include <fcntl.h>
 #include <inttypes.h>
 #include <unistd.h>
-#include <poll.h>
 #include <time.h>
 #include <errno.h>
 #include <error.h>
@@ -127,6 +126,7 @@ static pthread_mutex_t running_mutex = PTHREAD_MUTEX_INITIALIZER;
 static int running = 0;
 static pthread_mutex_t cancel_requested_mutex = PTHREAD_MUTEX_INITIALIZER;
 static int cancel_requested = 0;
+static mexp_h *control_h = NULL;
 
 static int
 is_running (void)
@@ -161,6 +161,21 @@ set_cancel_requested (int r)
 {
   pthread_mutex_lock (&cancel_requested_mutex);
   cancel_requested = r;
+
+  /* Send ^C to the remote so that virt-v2v "knows" the connection has
+   * been cancelled.  mexp_send_interrupt is a single write(2) call.
+   */
+  if (r && control_h)
+    ignore_value (mexp_send_interrupt (control_h));
+
+  pthread_mutex_unlock (&cancel_requested_mutex);
+}
+
+static void
+set_control_h (mexp_h *new_h)
+{
+  pthread_mutex_lock (&cancel_requested_mutex);
+  control_h = new_h;
   pthread_mutex_unlock (&cancel_requested_mutex);
 }
 
@@ -175,7 +190,6 @@ start_conversion (struct config *config,
   const size_t nr_disks = guestfs_int_count_strings (config->disks);
   time_t now;
   struct tm tm;
-  mexp_h *control_h = NULL;
   struct data_conn data_conns[nr_disks];
   CLEANUP_FREE char *remote_dir = NULL;
   char tmpdir[]           = "/tmp/p2v.XXXXXX";
@@ -189,6 +203,7 @@ start_conversion (struct config *config,
   fprintf (stderr, "\n");
 #endif
 
+  set_control_h (NULL);
   set_running (1);
   set_cancel_requested (0);
 
@@ -299,7 +314,7 @@ start_conversion (struct config *config,
   if (notify_ui)
     notify_ui (NOTIFY_STATUS, _("Setting up the control connection ..."));
 
-  control_h = start_remote_connection (config, remote_dir);
+  set_control_h (start_remote_connection (config, remote_dir));
   if (control_h == NULL) {
     set_conversion_error ("could not open control connection over SSH to the conversion server: %s",
                           get_ssh_error ());
@@ -346,35 +361,13 @@ start_conversion (struct config *config,
   }
 
   /* Read output from the virt-v2v process and echo it through the
-   * notify function, until virt-v2v closes the connection.  We
-   * actually poll in this loop (albeit it only every 2 seconds) so
-   * that the user won't have to wait too long between pressing the
-   * cancel button and having the conversion cancelled.
+   * notify function, until virt-v2v closes the connection.
    */
   while (!is_cancel_requested ()) {
-    int fd = mexp_get_fd (control_h);
-    struct pollfd fds[1];
-    int rp;
     char buf[257];
     ssize_t r;
 
-    fds[0].fd = fd;
-    fds[0].events = POLLIN;
-    fds[0].revents = 0;
-    rp = poll (fds, 1, 2000 /* ms */);
-    if (rp == -1) {
-      /* See comment about this in miniexpect.c. */
-      if (errno == EIO)
-        break;
-      set_conversion_error ("poll: %m");
-      goto out;
-    }
-    else if (rp == 0)
-      /* Timeout. */
-      continue;
-    /* ... else rp == 1, ignore revents and just do the read. */
-
-    r = read (fd, buf, sizeof buf - 1);
+    r = read (mexp_get_fd (control_h), buf, sizeof buf - 1);
     if (r == -1) {
       /* See comment about this in miniexpect.c. */
       if (errno == EIO)
@@ -402,12 +395,17 @@ start_conversion (struct config *config,
   ret = 0;
  out:
   if (control_h) {
-    if ((status = mexp_close (control_h)) == -1) {
+    mexp_h *h = control_h;
+    set_control_h (NULL);
+    status = mexp_close (h);
+
+    if (status == -1) {
       set_conversion_error ("mexp_close: %m");
       ret = -1;
-    } else if (ret == 0 &&
-               WIFEXITED (status) &&
-               WEXITSTATUS (status) != 0) {
+    }
+    else if (ret == 0 &&
+             WIFEXITED (status) &&
+             WEXITSTATUS (status) != 0) {
       set_conversion_error ("virt-v2v exited with status %d",
                             WEXITSTATUS (status));
       ret = -1;
-- 
1.8.3.1