@@ -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;
@@ -846,6 +846,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. */
@@ -1151,6 +1153,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);
@@ -1705,6 +1709,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",
@@ -1728,9 +1733,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;
@@ -1739,6 +1759,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)
@@ -1747,6 +1791,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)
@@ -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);
@@ -4180,6 +4182,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,