tools/libxl: Extra management APIs for the save helper
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 9 Jun 2015 11:41:06 +0000 (12:41 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Wed, 15 Jul 2015 10:22:53 +0000 (11:22 +0100)
With migration v2, there are several moving parts needing to be
juggled at once.  This requires the error handling logic to be able to
query the state of each moving part, possibly before they have been
started, and be able to cancel them.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Ian Campbell <Ian.Campbell@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
v4: Don't force _init() to be mandatory
v3: Adjust helper_{stop,failed,done} to use libxl__save_helper_inuse()
v2: Add an _init() function which allows _inuse() to be safe to call even
    before the save helper has started.

tools/libxl/libxl_internal.h
tools/libxl/libxl_save_callout.c

index e5599a3901027f16837393afa01485f7631dad2a..8ce3d491da4bf563cf3a8d8a7050975a7ae299a3 100644 (file)
@@ -3272,6 +3272,15 @@ _hidden void libxl__xc_domain_restore(libxl__egc *egc,
 _hidden void libxl__xc_domain_restore_done(libxl__egc *egc, void *dcs_void,
                                            int rc, int retval, int errnoval);
 
+_hidden void libxl__save_helper_init(libxl__save_helper_state *shs);
+_hidden void libxl__save_helper_abort(libxl__egc *egc,
+                                      libxl__save_helper_state *shs);
+
+static inline bool libxl__save_helper_inuse(const libxl__save_helper_state *shs)
+{
+    return libxl__ev_child_inuse(&shs->child);
+}
+
 /* Each time the dm needs to be saved, we must call suspend and then save */
 _hidden int libxl__domain_suspend_device_model(libxl__gc *gc,
                                            libxl__domain_suspend_state *dss);
index 1136b79289af1b699429ff409df660b30aa9c877..c56b68ca1ad657eda4ee315639a494416d9eb1bb 100644 (file)
@@ -146,6 +146,13 @@ void libxl__xc_domain_saverestore_async_callback_done(libxl__egc *egc,
     shs->egc = 0;
 }
 
+void libxl__save_helper_init(libxl__save_helper_state *shs)
+{
+    libxl__ao_abortable_init(&shs->abrt);
+    libxl__ev_fd_init(&shs->readable);
+    libxl__ev_child_init(&shs->child);
+}
+
 /*----- helper execution -----*/
 
 static void run_helper(libxl__egc *egc, libxl__save_helper_state *shs,
@@ -167,9 +174,7 @@ static void run_helper(libxl__egc *egc, libxl__save_helper_state *shs,
     shs->rc = 0;
     shs->completed = 0;
     shs->pipes[0] = shs->pipes[1] = 0;
-    libxl__ao_abortable_init(&shs->abrt);
-    libxl__ev_fd_init(&shs->readable);
-    libxl__ev_child_init(&shs->child);
+    libxl__save_helper_init(shs);
 
     shs->abrt.ao = shs->ao;
     shs->abrt.callback = helper_stop;
@@ -255,7 +260,7 @@ static void helper_failed(libxl__egc *egc, libxl__save_helper_state *shs,
 
     libxl__ev_fd_deregister(gc, &shs->readable);
 
-    if (!libxl__ev_child_inuse(&shs->child)) {
+    if (!libxl__save_helper_inuse(shs)) {
         helper_done(egc, shs);
         return;
     }
@@ -268,7 +273,7 @@ static void helper_stop(libxl__egc *egc, libxl__ao_abortable *abrt, int rc)
     libxl__save_helper_state *shs = CONTAINER_OF(abrt, *shs, abrt);
     STATE_AO_GC(shs->ao);
 
-    if (!libxl__ev_child_inuse(&shs->child)) {
+    if (!libxl__save_helper_inuse(shs)) {
         helper_failed(egc, shs, rc);
         return;
     }
@@ -279,6 +284,12 @@ static void helper_stop(libxl__egc *egc, libxl__ao_abortable *abrt, int rc)
     libxl__kill(gc, shs->child.pid, SIGTERM, "save/restore helper");
 }
 
+void libxl__save_helper_abort(libxl__egc *egc,
+                              libxl__save_helper_state *shs)
+{
+    helper_stop(egc, &shs->abrt, ERROR_FAIL);
+}
+
 static void helper_stdout_readable(libxl__egc *egc, libxl__ev_fd *ev,
                                    int fd, short events, short revents)
 {
@@ -356,7 +367,7 @@ static void helper_done(libxl__egc *egc, libxl__save_helper_state *shs)
     libxl__ev_fd_deregister(gc, &shs->readable);
     libxl__carefd_close(shs->pipes[0]);  shs->pipes[0] = 0;
     libxl__carefd_close(shs->pipes[1]);  shs->pipes[1] = 0;
-    assert(!libxl__ev_child_inuse(&shs->child));
+    assert(!libxl__save_helper_inuse(shs));
     if (shs->toolstack_data_file) fclose(shs->toolstack_data_file);
 
     shs->egc = egc;