This patch move 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 usefull to findout if QEMU is ready, and pre-opening it means that libxl can connect to it without waiting for QEMU to create it. The pre-openning is conditionnal, 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> --- Notes: 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 | 3 ++ tools/libxl/libxl_dm.c | 71 ++++++++++++++++++++++++++++++++++-- tools/libxl/libxl_internal.h | 1 + 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index fa573344bc..fcbe36feba 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -539,6 +539,9 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_config *d_config, libxl_domain_create_info *info = &d_config->c_info; libxl_domain_build_info *b_info = &d_config->b_info; + /* Attempt to initialise libxl__domain_build_state */ + state->dm_monitor_fd = -1; + uuid_string = libxl__uuid2string(gc, info->uuid); if (!uuid_string) { rc = ERROR_NOMEM; diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c index 9c47060473..3bf1e37894 100644 --- a/tools/libxl/libxl_dm.c +++ b/tools/libxl/libxl_dm.c @@ -910,6 +910,53 @@ 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); + + assert(fd_r != NULL); + + 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, @@ -944,10 +991,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"); @@ -2000,6 +2053,7 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss) if (ret) goto out; + d_state->dm_monitor_fd = -1; ret = libxl__build_device_model_args(gc, "stubdom-dm", guest_domid, guest_config, &args, NULL, d_state, NULL); @@ -2303,6 +2357,14 @@ void libxl__spawn_local_dm(libxl__egc *egc, libxl__dm_spawn_state *dmss) rc = ERROR_FAIL; 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); @@ -2408,6 +2470,7 @@ out_close: if (logfile_w >= 0) close(logfile_w); out: if (dm_state_fd >= 0) close(dm_state_fd); + if (state->dm_monitor_fd >= 0) close(state->dm_monitor_fd); if (rc) device_model_spawn_outcome(egc, dmss, rc); } diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 6c118ccb3b..b768d1b09f 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1233,6 +1233,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