[libvirt] [PATCH] Cancel migration/dump if user presses Ctrl-C when migration/dump is in progress

Hu Tao hutao at cn.fujitsu.com
Thu Jan 6 09:16:53 UTC 2011


While migration/dump is in progress and virsh is waiting for its
completion, user may want to terminate the progress by pressing
Ctrl-C. But virsh just exits on user's Ctrl-C leaving migration/dump
in background that user isn't even aware of. It's not reasonable.

This patch changes the behaviour for migration/dump. For other
commands Ctrl-C still terminates virsh itself.
---
Hi Daniel, Eric,

This patch is entirely different from my previous implementation so
not titled with v2. It's simpler than the previous one and introduces
less changes: not introducing threadpool in virsh;Ctrl-C remains
terminating virsh if no job in progress.

Thanks for your review of the previous patch.

 src/remote/remote_driver.c |    9 +++++++--
 tools/virsh.c              |   37 +++++++++++++++++++++++++++++++++++--
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index ee2de4a..59ec486 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -9810,7 +9810,7 @@ processCallDispatchReply(virConnectPtr conn ATTRIBUTE_UNUSED,
         remoteError(VIR_ERR_RPC,
                     _("no call waiting for reply with serial %d"),
                     hdr->serial);
-        return -1;
+        return -2;
     }
 
     if (hdr->proc != thecall->proc_nr) {
@@ -10160,7 +10160,12 @@ remoteIOEventLoop(virConnectPtr conn,
         }
 
         if (fds[0].revents & POLLIN) {
-            if (remoteIOHandleInput(conn, priv, flags) < 0)
+            int ret = remoteIOHandleInput(conn, priv, flags);
+            if (ret == -2) {
+                /* Not expected result, repoll */
+                remoteDriverUnlock(priv);
+                goto repoll;
+            } else if (ret < 0)
                 goto error;
         }
 
diff --git a/tools/virsh.c b/tools/virsh.c
index 55e2a68..e4d431e 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -492,6 +492,15 @@ out:
     last_error = NULL;
 }
 
+static bool intCatched = FALSE;
+
+static void vshCatchInt(int sig ATTRIBUTE_UNUSED,
+                        siginfo_t *siginfo ATTRIBUTE_UNUSED,
+                        void *context ATTRIBUTE_UNUSED)
+{
+    intCatched = TRUE;
+}
+
 /*
  * Detection of disconnections and automatic reconnection support
  */
@@ -1838,6 +1847,9 @@ cmdDump(vshControl *ctl, const vshCmd *cmd)
     char *to;
     int ret = TRUE;
     int flags = 0;
+    int result;
+    struct sigaction sig_action;
+    struct sigaction old_sig_action;
 
     if (!vshConnectionUsability(ctl, ctl->conn))
         return FALSE;
@@ -1848,18 +1860,27 @@ cmdDump(vshControl *ctl, const vshCmd *cmd)
     if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
         return FALSE;
 
+    sig_action.sa_sigaction = vshCatchInt;
+    sig_action.sa_flags = SA_SIGINFO;
+    sigemptyset(&sig_action.sa_mask);
+    sigaction(SIGINT, &sig_action, &old_sig_action);
+
     if (vshCommandOptBool (cmd, "live"))
         flags |= VIR_DUMP_LIVE;
     if (vshCommandOptBool (cmd, "crash"))
         flags |= VIR_DUMP_CRASH;
 
-    if (virDomainCoreDump(dom, to, flags) == 0) {
+    result = virDomainCoreDump(dom, to, flags);
+    if (result == 0) {
         vshPrint(ctl, _("Domain %s dumped to %s\n"), name, to);
+    } else if (intCatched) {
+        virDomainAbortJob(dom);
     } else {
         vshError(ctl, _("Failed to core dump domain %s to %s"), name, to);
         ret = FALSE;
     }
 
+    sigaction(SIGINT, &old_sig_action, NULL);
     virDomainFree(dom);
     return ret;
 }
@@ -3388,6 +3409,9 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
     const char *desturi;
     const char *migrateuri;
     const char *dname;
+    int result;
+    struct sigaction sig_action;
+    struct sigaction old_sig_action;
     int flags = 0, found, ret = FALSE;
 
     if (!vshConnectionUsability (ctl, ctl->conn))
@@ -3396,6 +3420,11 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
     if (!(dom = vshCommandOptDomain (ctl, cmd, NULL)))
         return FALSE;
 
+    sig_action.sa_sigaction = vshCatchInt;
+    sig_action.sa_flags = SA_SIGINFO;
+    sigemptyset(&sig_action.sa_mask);
+    sigaction(SIGINT, &sig_action, &old_sig_action);
+
     desturi = vshCommandOptString (cmd, "desturi", &found);
     if (!found)
         goto done;
@@ -3437,6 +3466,8 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
 
         if (virDomainMigrateToURI (dom, desturi, flags, dname, 0) == 0)
             ret = TRUE;
+        else if (intCatched)
+            virDomainAbortJob(dom);
     } else {
         /* For traditional live migration, connect to the destination host directly. */
         virConnectPtr dconn = NULL;
@@ -3449,11 +3480,13 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
         if (ddom) {
             virDomainFree(ddom);
             ret = TRUE;
-        }
+        } else if (intCatched)
+            virDomainAbortJob(dom);
         virConnectClose (dconn);
     }
 
  done:
+    sigaction(SIGINT, &old_sig_action, NULL);
     if (dom) virDomainFree (dom);
     return ret;
 }
-- 
1.7.3.1


-- 
Thanks,
Hu Tao




More information about the libvir-list mailing list