@@ -1728,10 +1728,17 @@ static int libxl__build_device_model_args_new(libxl__gc *gc,
}
if (state->saved_state) {
- /* This file descriptor is meant to be used by QEMU */
- *dm_state_fd = open(state->saved_state, O_RDONLY);
- flexarray_append(dm_args, "-incoming");
- flexarray_append(dm_args, GCSPRINTF("fd:%d",*dm_state_fd));
+ if (is_stubdom) {
+ /* Linux stubdomain connects specific FD to STUBDOM_CONSOLE_RESTORE
+ */
+ flexarray_append(dm_args, "-incoming");
+ flexarray_append(dm_args, "fd:3");
+ } else {
+ /* This file descriptor is meant to be used by QEMU */
+ *dm_state_fd = open(state->saved_state, O_RDONLY);
+ flexarray_append(dm_args, "-incoming");
+ flexarray_append(dm_args, GCSPRINTF("fd:%d",*dm_state_fd));
+ }
}
for (i = 0; b_info->extra && b_info->extra[i] != NULL; i++)
flexarray_append(dm_args, b_info->extra[i]);
@@ -2202,14 +2209,6 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss)
assert(libxl_defbool_val(guest_config->b_info.device_model_stubdomain));
- if (libxl__stubdomain_is_linux(&guest_config->b_info)) {
- if (d_state->saved_state) {
- LOG(ERROR, "Save/Restore not supported yet with Linux Stubdom.");
- ret = -1;
- goto out;
- }
- }
-
sdss->pvqemu.guest_domid = 0;
libxl_domain_create_info_init(&dm_config->c_info);
@@ -962,6 +962,7 @@ static void dm_stopped(libxl__egc *egc, libxl__ev_qmp *ev,
const libxl__json_object *response, int rc);
static void dm_state_fd_ready(libxl__egc *egc, libxl__ev_qmp *ev,
const libxl__json_object *response, int rc);
+static void dm_state_save_to_fdset(libxl__egc *egc, libxl__ev_qmp *ev, int fdset);
static void dm_state_saved(libxl__egc *egc, libxl__ev_qmp *ev,
const libxl__json_object *response, int rc);
@@ -994,10 +995,17 @@ static void dm_stopped(libxl__egc *egc, libxl__ev_qmp *ev,
EGC_GC;
libxl__domain_suspend_state *dsps = CONTAINER_OF(ev, *dsps, qmp);
const char *const filename = dsps->dm_savefile;
+ uint32_t dm_domid = libxl_get_stubdom_id(CTX, dsps->domid);
if (rc)
goto error;
+ if (dm_domid) {
+ /* see Linux stubdom interface in docs/stubdom.txt */
+ dm_state_save_to_fdset(egc, ev, 1);
+ return;
+ }
+
ev->payload_fd = open(filename, O_WRONLY | O_CREAT, 0600);
if (ev->payload_fd < 0) {
LOGED(ERROR, ev->domid,
@@ -1028,7 +1036,6 @@ static void dm_state_fd_ready(libxl__egc *egc, libxl__ev_qmp *ev,
EGC_GC;
int fdset;
const libxl__json_object *o;
- libxl__json_object *args = NULL;
libxl__domain_suspend_state *dsps = CONTAINER_OF(ev, *dsps, qmp);
close(ev->payload_fd);
@@ -1043,6 +1050,21 @@ static void dm_state_fd_ready(libxl__egc *egc, libxl__ev_qmp *ev,
goto error;
}
fdset = libxl__json_object_get_integer(o);
+ dm_state_save_to_fdset(egc, ev, fdset);
+ return;
+
+error:
+ assert(rc);
+ libxl__remove_file(gc, dsps->dm_savefile);
+ dsps->callback_device_model_done(egc, dsps, rc);
+}
+
+static void dm_state_save_to_fdset(libxl__egc *egc, libxl__ev_qmp *ev, int fdset)
+{
+ EGC_GC;
+ int rc;
+ libxl__json_object *args = NULL;
+ libxl__domain_suspend_state *dsps = CONTAINER_OF(ev, *dsps, qmp);
ev->callback = dm_state_saved;
@@ -1060,6 +1082,7 @@ static void dm_state_fd_ready(libxl__egc *egc, libxl__ev_qmp *ev,
error:
assert(rc);
+ /* TODO: only in non-stubdom case */
libxl__remove_file(gc, dsps->dm_savefile);
dsps->callback_device_model_done(egc, dsps, rc);
}
Rely on a wrapper script in stubdomain to attach FD 3/4 of qemu to relevant consoles. Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> --- Changes in v3: - adjust for qmp_ev* - assume specific fdset id in qemu set in stubdomain --- tools/libxl/libxl_dm.c | 23 +++++++++++------------ tools/libxl/libxl_qmp.c | 25 ++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 13 deletions(-)