|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XEN PATCH] libxl: Use fdset to provide migration saved state file
Since QEMU 11.0, `-incoming fd:` doesn't accept file descriptors of
plain file, only sockets and pipe are accepted. This has been
deprecated since QEMU 9.1
Instead, switch to use `-incoming file:` with an fdset.
`incoming file:` schema seems to have been only introduced in QEMU
8.2. And `-incoming` isn't present in `query-command-line-options` QMP
command output, so we'll use a check based on QEMU version instead.
QEMU keep the FD open when added as a fdset, so close it in
postconfig. And now we have two optional set QMP command to run after
starting QEMU, for VNC and for migration.
Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---
tools/libs/light/libxl_dm.c | 98 ++++++++++++++++++++++++++++---
tools/libs/light/libxl_internal.h | 1 +
2 files changed, 90 insertions(+), 9 deletions(-)
diff --git a/tools/libs/light/libxl_dm.c b/tools/libs/light/libxl_dm.c
index 511ec76a65..0fdeded92b 100644
--- a/tools/libs/light/libxl_dm.c
+++ b/tools/libs/light/libxl_dm.c
@@ -24,6 +24,8 @@
#include <pwd.h>
#include <grp.h>
+#define QEMU_FDSET_SAVED_STATE 1
+
static const char *libxl_tapif_script(libxl__gc *gc)
{
#if defined(__linux__) || defined(__FreeBSD__)
@@ -1546,8 +1548,21 @@ static int libxl__build_device_model_args_new(libxl__gc
*gc,
} 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));
+ if (qemu_opts->use_incoming_file) {
+ flexarray_append_pair(dm_args, "-add-fd",
+ GCSPRINTF("fd=%d,set="STR(QEMU_FDSET_SAVED_STATE)
+ ",opaque=\"saved_state\"",
+ *dm_state_fd));
+ flexarray_append_pair(dm_args, "-incoming",
+ "file:/dev/fdset/1");
+ } else {
+ /*
+ * Passing a file descriptor of a plain file to `fd:` has
+ * been deprecated in QEMU 9.1.
+ */
+ 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++)
@@ -2631,6 +2646,12 @@ static void device_model_launch(libxl__egc *egc,
libxl__dm_spawn_state *dmss, int rc);
static void device_model_postconfig_chardev(libxl__egc *egc,
libxl__ev_qmp *qmp, const libxl__json_object *response, int rc);
+static void device_model_postconfig_do_remove_fdset(libxl__egc *egc,
+ libxl__ev_qmp *qmp, int rc);
+static void device_model_postconfig_removed_fdset(libxl__egc *egc,
+ libxl__ev_qmp *qmp, const libxl__json_object *response, int rc);
+static void device_model_postconfig_do_vnc(libxl__egc *egc,
+ libxl__ev_qmp *qmp, int rc);
static void device_model_postconfig_vnc(libxl__egc *egc,
libxl__ev_qmp *qmp, const libxl__json_object *response, int rc);
static void device_model_postconfig_vnc_passwd(libxl__egc *egc,
@@ -2832,6 +2853,13 @@ static void device_model_probe_cmdline(libxl__egc *egc,
}
}
+ /*
+ * Other checks based on QEMU's version
+ */
+ if (libxl__qmp_ev_qemu_compare_version(qmp, 9, 1, 0) >= 0) {
+ dmss->qemu_opts.use_incoming_file = true;
+ }
+
qmp->callback = device_model_probe_quit;
rc = libxl__ev_qmp_send(egc, qmp, "quit", NULL);
if (rc) goto out;
@@ -3152,7 +3180,6 @@ static void device_model_postconfig_chardev(libxl__egc
*egc,
{
EGC_GC;
libxl__dm_spawn_state *dmss = CONTAINER_OF(qmp, *dmss, qmp);
- const libxl_vnc_info *vnc = libxl__dm_vnc(dmss->guest_config);
const libxl__json_object *item = NULL;
const libxl__json_object *o = NULL;
int i = 0;
@@ -3210,12 +3237,7 @@ static void device_model_postconfig_chardev(libxl__egc
*egc,
if (rc) goto out;
}
- if (!vnc)
- goto out;
-
- qmp->callback = device_model_postconfig_vnc;
- rc = libxl__ev_qmp_send(egc, qmp, "query-vnc", NULL);
- if (rc) goto out;
+ device_model_postconfig_do_remove_fdset(egc, qmp, rc); /* must be last */
return;
protocol_error:
@@ -3227,6 +3249,64 @@ static void device_model_postconfig_chardev(libxl__egc
*egc,
device_model_postconfig_done(egc, dmss, rc); /* must be last */
}
+static void device_model_postconfig_do_remove_fdset(libxl__egc *egc,
+ libxl__ev_qmp *qmp, int rc)
+{
+ EGC_GC;
+ libxl__dm_spawn_state *dmss = CONTAINER_OF(qmp, *dmss, qmp);
+
+ /*
+ * If we used -add-fd for the `saved_state`, ask QEMU to close it.
+ */
+ if (dmss->qemu_opts.use_incoming_file && dmss->build_state->saved_state) {
+ libxl__json_object *args = NULL;
+ qmp->callback = device_model_postconfig_removed_fdset;
+ libxl__qmp_param_add_integer(gc, &args, "fdset-id",
+ QEMU_FDSET_SAVED_STATE);
+ rc = libxl__ev_qmp_send(egc, qmp, "remove-fd", args);
+ if (rc) goto out;
+ return;
+ }
+
+ device_model_postconfig_do_vnc(egc, qmp, rc); /* must be last */
+ return;
+
+out:
+ device_model_postconfig_done(egc, dmss, rc); /* must be last */
+}
+
+static void device_model_postconfig_removed_fdset(libxl__egc *egc,
+ libxl__ev_qmp *qmp, const libxl__json_object *response, int rc)
+{
+ libxl__dm_spawn_state *dmss = CONTAINER_OF(qmp, *dmss, qmp);
+
+ if (rc) goto out;
+
+ device_model_postconfig_do_vnc(egc, qmp, rc); /* must be last */
+ return;
+
+out:
+ device_model_postconfig_done(egc, dmss, rc); /* must be last */
+}
+
+static void device_model_postconfig_do_vnc(libxl__egc *egc,
+ libxl__ev_qmp *qmp, int rc)
+{
+ EGC_GC;
+ libxl__dm_spawn_state *dmss = CONTAINER_OF(qmp, *dmss, qmp);
+ const libxl_vnc_info *vnc = libxl__dm_vnc(dmss->guest_config);
+
+ if (vnc) {
+ qmp->callback = device_model_postconfig_vnc;
+ rc = libxl__ev_qmp_send(egc, qmp, "query-vnc", NULL);
+ if (rc) goto out;
+ return;
+ }
+
+out:
+ device_model_postconfig_done(egc, dmss, rc); /* must be last */
+}
+
static void device_model_postconfig_vnc(libxl__egc *egc,
libxl__ev_qmp *qmp, const libxl__json_object *response, int rc)
{
diff --git a/tools/libs/light/libxl_internal.h
b/tools/libs/light/libxl_internal.h
index b65e0064b9..7d916ee64a 100644
--- a/tools/libs/light/libxl_internal.h
+++ b/tools/libs/light/libxl_internal.h
@@ -4094,6 +4094,7 @@ typedef struct libxl__qemu_available_opts
libxl__qemu_available_opts;
struct libxl__qemu_available_opts {
bool have_runwith_chroot;
bool have_runwith_user;
+ bool use_incoming_file;
};
typedef void libxl__dm_spawn_cb(libxl__egc *egc, libxl__dm_spawn_state*,
--
Anthony PERARD
--
| Vates
XCP-ng & Xen Orchestra - Vates solutions
web: https://vates.tech
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |