This patch moves the creation of the QMP unix socket from QEMU to libxl. But libxl doesn't rely on this yet.
When starting QEMU with dm_restrict=1, pre-open the QMP socket before exec QEMU. That socket will be useful to find out if QEMU is ready, and pre-opening it means that libxl can connect to it without waiting for QEMU to create it. The pre-opening is conditional, based on the use of dm_restrict because it is using a new command line option of QEMU, and dm_restrict support in QEMU is newer. -chardev socket,fd=X is available with QEMU 2.12, since commit: > char: allow passing pre-opened socket file descriptor at startup > 0935700f8544033ebbd41e1f13cd528f8a58d24d dm_restrict is available in QEMU 3.0. Signed-off-by: Anthony PERARD <anthony.per...@citrix.com> Acked-by: Ian Jackson <ian.jack...@eu.citrix.com> --- Notes: v8: acked v7: move domain_build_state init/dispose to a different patch and close dm_monitor_fd in that new dispose function assert that dm_monitor_fd should be -1 when using old qemu v6: move dm_monitor_fd into libxl_domain_build_info (or d_state) -> move the creation of the socket into libxl__spawn_local_dm instead of libxl__build_device_model_args Use libxl_domid type instead of int for libxl__pre_open_qmp_socket() Check function calls (bind and listen) return value in a separate statement. typo and other coding style issue fixes v5: use libxl__remove_file few changes in coding style remove stale includes (sys/socket, sys/un) which are now in libxl_internal.h v4: separate the logic to open a socket into a function. Use libxl__prepare_sockaddr_un() to check path size tools/libxl/libxl_create.c | 5 +++ tools/libxl/libxl_dm.c | 71 ++++++++++++++++++++++++++++++++++-- tools/libxl/libxl_internal.h | 1 + 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index 4ca25f56a6..89f4766a27 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -763,12 +763,17 @@ static int store_libxl_entry(libxl__gc *gc, uint32_t domid, void libxl__domain_build_state_init(libxl__domain_build_state *state) { + state->dm_monitor_fd = -1; } void libxl__domain_build_state_dispose(libxl__domain_build_state *state) { libxl__file_reference_unmap(&state->pv_kernel); libxl__file_reference_unmap(&state->pv_ramdisk); + if (state->dm_monitor_fd >= 0) { + close(state->dm_monitor_fd); + state->dm_monitor_fd = -1; + } } /*----- main domain creation -----*/ diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c index 200310083f..b9921eb885 100644 --- a/tools/libxl/libxl_dm.c +++ b/tools/libxl/libxl_dm.c @@ -670,6 +670,8 @@ static int libxl__build_device_model_args_old(libxl__gc *gc, dm_args = flexarray_make(gc, 16, 1); dm_envs = flexarray_make(gc, 16, 1); + assert(state->dm_monitor_fd == -1); + libxl__set_qemu_env_for_xsa_180(gc, dm_envs); flexarray_vappend(dm_args, dm, @@ -1100,6 +1102,51 @@ static char *qemu_disk_ide_drive_string(libxl__gc *gc, const char *target_path, return drive; } +static int libxl__pre_open_qmp_socket(libxl__gc *gc, libxl_domid domid, + int *fd_r) +{ + int rc, r; + int fd; + struct sockaddr_un un; + const char *path = libxl__qemu_qmp_path(gc, domid); + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + LOGED(ERROR, domid, "socket() failed"); + return ERROR_FAIL; + } + + rc = libxl__prepare_sockaddr_un(gc, &un, path, "QEMU's QMP socket"); + if (rc) + goto out; + + rc = libxl__remove_file(gc, path); + if (rc) + goto out; + + r = bind(fd, (struct sockaddr *) &un, sizeof(un)); + if (r < 0) { + LOGED(ERROR, domid, "bind('%s') failed", path); + rc = ERROR_FAIL; + goto out; + } + + r = listen(fd, 1); + if (r < 0) { + LOGED(ERROR, domid, "listen() failed"); + rc = ERROR_FAIL; + goto out; + } + + *fd_r = fd; + rc = 0; + +out: + if (rc && fd >= 0) + close(fd); + return rc; +} + static int libxl__build_device_model_args_new(libxl__gc *gc, const char *dm, int guest_domid, const libxl_domain_config *guest_config, @@ -1132,10 +1179,16 @@ static int libxl__build_device_model_args_new(libxl__gc *gc, GCSPRINTF("%d", guest_domid), NULL); flexarray_append(dm_args, "-chardev"); - flexarray_append(dm_args, - GCSPRINTF("socket,id=libxl-cmd," - "path=%s,server,nowait", - libxl__qemu_qmp_path(gc, guest_domid))); + if (state->dm_monitor_fd >= 0) { + flexarray_append(dm_args, + GCSPRINTF("socket,id=libxl-cmd,fd=%d,server,nowait", + state->dm_monitor_fd)); + } else { + flexarray_append(dm_args, + GCSPRINTF("socket,id=libxl-cmd," + "path=%s,server,nowait", + libxl__qemu_qmp_path(gc, guest_domid))); + } flexarray_append(dm_args, "-no-shutdown"); flexarray_append(dm_args, "-mon"); @@ -2437,6 +2490,16 @@ void libxl__spawn_local_dm(libxl__egc *egc, libxl__dm_spawn_state *dmss) if (rc) goto out; + if (b_info->device_model_version + == LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN && + libxl_defbool_val(b_info->dm_restrict)) { + /* If we have to use dm_restrict, QEMU needs to be new enough + * and will have the new interface where we can pre-open the + * QMP socket. */ + rc = libxl__pre_open_qmp_socket(gc, domid, &state->dm_monitor_fd); + if (rc) goto out; + } + rc = libxl__build_device_model_args(gc, dm, domid, guest_config, &args, &envs, state, &dm_state_fd); diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 88c01ff118..83bc384d3e 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1240,6 +1240,7 @@ typedef struct { char *console_tty; char *saved_state; + int dm_monitor_fd; libxl__file_reference pv_kernel; libxl__file_reference pv_ramdisk; -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel