]> xenbits.xensource.com Git - people/sstabellini/xen-unstable.git/.git/commitdiff
libxl: wait for console path before firing console_available
authorPaweł Marczewski <pawel@invisiblethingslab.com>
Tue, 3 Mar 2020 13:28:20 +0000 (14:28 +0100)
committerWei Liu <wl@xen.org>
Wed, 4 Mar 2020 10:15:45 +0000 (10:15 +0000)
If the path doesn't become available after LIBXL_INIT_TIMEOUT
seconds, fail the domain creation.

If we skip the bootloader, the TTY path will be set by xenconsoled.
However, there is no guarantee that this will happen by the time we
want to call the console_available callback, so we have to wait.

Signed-off-by: Paweł Marczewski <pawel@invisiblethingslab.com>
Reviewed-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
tools/libxl/libxl_console.c
tools/libxl/libxl_create.c
tools/libxl/libxl_internal.h

index 088a455b528f1e459f9ce3db3b46303408d2318d..047d23d7ae78adf4ce9e3990064a53d39d0fda40 100644 (file)
@@ -16,8 +16,8 @@
 
 #include "libxl_internal.h"
 
-static int libxl__console_tty_path(libxl__gc *gc, uint32_t domid, int cons_num,
-                                   libxl_console_type type, char **tty_path)
+int libxl__console_tty_path(libxl__gc *gc, uint32_t domid, int cons_num,
+                            libxl_console_type type, char **tty_path)
 {
     int rc;
     char *dom_path;
index ccc9e709902be917074e6e7d59fe754dcc7e2ab8..7891fae4263a25f9d378baf8aac23411604b47b2 100644 (file)
@@ -912,6 +912,8 @@ static void domcreate_devmodel_started(libxl__egc *egc,
 static void domcreate_attach_devices(libxl__egc *egc,
                                      libxl__multidev *multidev,
                                      int ret);
+static void console_xswait_callback(libxl__egc *egc, libxl__xswait_state *xswa,
+                                    int rc, const char *p);
 
 /* Our own function to clean up and call the user's callback.
  * The final call in the sequence. */
@@ -1217,6 +1219,8 @@ static void initiate_domain_create(libxl__egc *egc,
     if (ret)
         goto error_out;
 
+    libxl__xswait_init(&dcs->console_xswait);
+
     if (restore_fd >= 0 || dcs->soft_reset) {
         LOGD(DEBUG, domid, "restoring, not running bootloader");
         domcreate_bootloader_done(egc, &dcs->bl, 0);
@@ -1771,6 +1775,7 @@ static void domcreate_attach_devices(libxl__egc *egc,
     int domid = dcs->guest_domid;
     libxl_domain_config *const d_config = dcs->guest_config;
     const libxl__device_type *dt;
+    char *tty_path;
 
     if (ret) {
         LOGD(ERROR, domid, "unable to add %s devices",
@@ -1794,9 +1799,24 @@ static void domcreate_attach_devices(libxl__egc *egc,
         return;
     }
 
-    domcreate_console_available(egc, dcs);
+    ret = libxl__console_tty_path(gc, domid, 0, LIBXL_CONSOLE_TYPE_PV, &tty_path);
+    if (ret) {
+        LOG(ERROR, "failed to get domain %d console tty path",
+            domid);
+        goto error_out;
+    }
 
-    domcreate_complete(egc, dcs, 0);
+    dcs->console_xswait.ao = ao;
+    dcs->console_xswait.what = GCSPRINTF("domain %d console tty", domid);
+    dcs->console_xswait.path = tty_path;
+    dcs->console_xswait.timeout_ms = LIBXL_INIT_TIMEOUT * 1000;
+    dcs->console_xswait.callback = console_xswait_callback;
+    ret = libxl__xswait_start(gc, &dcs->console_xswait);
+    if (ret) {
+        LOG(ERROR, "unable to set up watch for domain %d console tty path",
+            domid);
+        goto error_out;
+    }
 
     return;
 
@@ -1805,6 +1825,30 @@ error_out:
     domcreate_complete(egc, dcs, ret);
 }
 
+static void console_xswait_callback(libxl__egc *egc, libxl__xswait_state *xswa,
+                                    int rc, const char *p)
+{
+    EGC_GC;
+    libxl__domain_create_state *dcs = CONTAINER_OF(xswa, *dcs, console_xswait);
+
+    if (rc) {
+        if (rc == ERROR_TIMEDOUT)
+            LOG(ERROR, "%s: timed out", xswa->what);
+        goto out;
+    }
+
+    if (p && p[0] != '\0') {
+        domcreate_console_available(egc, dcs);
+        goto out;
+    }
+
+    return;
+
+out:
+    libxl__xswait_stop(gc, xswa);
+    domcreate_complete(egc, dcs, rc);
+}
+
 static void domcreate_complete(libxl__egc *egc,
                                libxl__domain_create_state *dcs,
                                int rc)
@@ -1813,6 +1857,8 @@ static void domcreate_complete(libxl__egc *egc,
     libxl_domain_config *const d_config = dcs->guest_config;
     libxl_domain_config *d_config_saved = &dcs->guest_config_saved;
 
+    libxl__xswait_stop(gc, &dcs->console_xswait);
+
     libxl__domain_build_state_dispose(&dcs->build_state);
 
     if (!rc && d_config->b_info.exec_ssidref)
index 4891722a6be719a5946a9d53b824965d282c5964..5f39e44cb95c548b63942c1700bc19ddccc620ec 100644 (file)
@@ -1517,6 +1517,8 @@ _hidden char *libxl__domain_device_libxl_path(libxl__gc *gc, uint32_t domid, uin
                                               libxl__device_kind device_kind);
 _hidden int libxl__parse_backend_path(libxl__gc *gc, const char *path,
                                       libxl__device *dev);
+_hidden int libxl__console_tty_path(libxl__gc *gc, uint32_t domid, int cons_num,
+                                    libxl_console_type type, char **tty_path);
 _hidden int libxl__device_destroy(libxl__gc *gc, libxl__device *dev);
 _hidden int libxl__wait_for_backend(libxl__gc *gc, const char *be_path,
                                     const char *state);
@@ -4182,6 +4184,7 @@ struct libxl__domain_create_state {
     /* necessary if the domain creation failed and we have to destroy it */
     libxl__domain_destroy_state dds;
     libxl__multidev multidev;
+    libxl__xswait_state console_xswait;
 };
 
 _hidden int libxl__device_nic_set_devids(libxl__gc *gc,