From 547504706ea62956201d40c230d2ab85bd99fbc4 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" 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 #include #include -#include #include #include #include @@ -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