[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 26/32] libxl_dm: Pre-open QMP socket for QEMU
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 will be available in QEMU 3.0. Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> --- Notes: v4: separate the logic to open a socket into a function. Use libxl__prepare_sockaddr_un() to check path size tools/libxl/libxl_dm.c | 86 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 9 deletions(-) diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c index 5c28a0ced4..9e3e501457 100644 --- a/tools/libxl/libxl_dm.c +++ b/tools/libxl/libxl_dm.c @@ -24,6 +24,8 @@ #include <sys/types.h> #include <pwd.h> #include <grp.h> +#include <sys/socket.h> +#include <sys/un.h> static const char *libxl_tapif_script(libxl__gc *gc) { @@ -915,12 +917,58 @@ const char *libxl__qemu_qmp_path(libxl__gc *gc, int domid) return GCSPRINTF("%s/qmp-libxl-%d", libxl__run_dir_path(), domid); } +static int libxl__pre_open_qmp_socket(libxl__gc *gc, int domid, int *fd_r) +{ + int rc; + int fd = -1; + struct sockaddr_un un; + const char *path; + + 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; + + if (unlink(path) < 0 && errno != ENOENT) { + LOGED(ERROR, domid, "unlink('%s') failed", path); + rc = ERROR_FAIL; + goto out; + } + + if (bind(fd, (struct sockaddr*) &un, sizeof(un)) < 0) { + LOGED(ERROR, domid, "bind('%s') failed", path); + rc = ERROR_FAIL; + goto out; + } + + if (listen(fd, 1) < 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, char ***args, char ***envs, const libxl__domain_build_state *state, - int *dm_state_fd) + int *dm_state_fd, int *dm_monitor_fd) { const libxl_domain_create_info *c_info = &guest_config->c_info; const libxl_domain_build_info *b_info = &guest_config->b_info; @@ -949,10 +997,25 @@ 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 we have to use dm_restrict, QEMU need to be new enough and will have + * the new interface where we can pre-open the QMP socket. */ + if (libxl_defbool_val(b_info->dm_restrict)) + { + int rc; + + rc = libxl__pre_open_qmp_socket(gc, guest_domid, dm_monitor_fd); + if (rc) + return rc; + + flexarray_append(dm_args, + GCSPRINTF("socket,id=libxl-cmd,fd=%d,server,nowait", + *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"); @@ -1731,7 +1794,8 @@ static int libxl__build_device_model_args(libxl__gc *gc, const libxl_domain_config *guest_config, char ***args, char ***envs, const libxl__domain_build_state *state, - int *dm_state_fd) + int *dm_state_fd, + int *dm_monitor_fd) /* dm_state_fd may be NULL iff caller knows we are using old stubdom * and therefore will be passing a filename rather than a fd. */ { @@ -1744,10 +1808,11 @@ static int libxl__build_device_model_args(libxl__gc *gc, case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN: assert(dm_state_fd != NULL); assert(*dm_state_fd < 0); + assert(dm_monitor_fd != NULL); return libxl__build_device_model_args_new(gc, dm, guest_domid, guest_config, args, envs, - state, dm_state_fd); + state, dm_state_fd, dm_monitor_fd); default: LOGED(ERROR, guest_domid, "unknown device model version %d", guest_config->b_info.device_model_version); @@ -1968,7 +2033,7 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss) ret = libxl__build_device_model_args(gc, "stubdom-dm", guest_domid, guest_config, &args, NULL, - d_state, NULL); + d_state, NULL, NULL); if (ret) { ret = ERROR_FAIL; goto out; @@ -2254,6 +2319,7 @@ void libxl__spawn_local_dm(libxl__egc *egc, libxl__dm_spawn_state *dmss) char **pass_stuff; const char *dm; int dm_state_fd = -1; + int dm_monitor_fd = -1; if (libxl_defbool_val(b_info->device_model_stubdomain)) { abort(); @@ -2271,7 +2337,8 @@ void libxl__spawn_local_dm(libxl__egc *egc, libxl__dm_spawn_state *dmss) } rc = libxl__build_device_model_args(gc, dm, domid, guest_config, &args, &envs, state, - &dm_state_fd); + &dm_state_fd, + &dm_monitor_fd); if (rc) goto out; @@ -2369,6 +2436,7 @@ out_close: if (logfile_w >= 0) close(logfile_w); out: if (dm_state_fd >= 0) close(dm_state_fd); + if (dm_monitor_fd >= 0) close(dm_monitor_fd); if (rc) device_model_spawn_outcome(egc, dmss, rc); } -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |