diff options
author | Olaf Hering <olaf@aepfle.de> | 2011-10-27 11:23:24 +0200 |
---|---|---|
committer | Olaf Hering <olaf@aepfle.de> | 2011-10-27 11:23:24 +0200 |
commit | 05a3635760240a0b92014a6c77d35ac8b5231b52 (patch) | |
tree | 30cffa1cd7b2b64ac066d248402a40cd30067d1f /tools/libxl/libxl_exec.c | |
parent | b46dfd222ea6262b9e5f25cdbe433cb63562ecb8 (diff) | |
download | xen-05a3635760240a0b92014a6c77d35ac8b5231b52.tar.gz xen-05a3635760240a0b92014a6c77d35ac8b5231b52.tar.bz2 xen-05a3635760240a0b92014a6c77d35ac8b5231b52.zip |
libxl: add libxl__wait_for_offspring function
libxl__wait_for_offspring() is a generic version of
libxl__wait_for_device_model().
Use libxl__wait_for_offspring for device model.
Signed-off-by: Olaf Hering <olaf@aepfle.de>
Acked-by: Ian Jackson <ian.jackson.citrix.com>
Committed-by: Ian Jackson <ian.jackson.citrix.com>
Diffstat (limited to 'tools/libxl/libxl_exec.c')
-rw-r--r-- | tools/libxl/libxl_exec.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/tools/libxl/libxl_exec.c b/tools/libxl/libxl_exec.c index 5021d28c27..6113f9ed0e 100644 --- a/tools/libxl/libxl_exec.c +++ b/tools/libxl/libxl_exec.c @@ -169,6 +169,99 @@ out: free(pid); } +int libxl__wait_for_offspring(libxl__gc *gc, + uint32_t domid, + uint32_t timeout, char *what, + char *path, char *state, + libxl__spawn_starting *spawning, + int (*check_callback)(libxl__gc *gc, + uint32_t domid, + const char *state, + void *userdata), + void *check_callback_userdata) +{ + libxl_ctx *ctx = libxl__gc_owner(gc); + char *p; + unsigned int len; + int rc = 0; + struct xs_handle *xsh; + int nfds; + fd_set rfds; + struct timeval tv; + unsigned int num; + char **l = NULL; + + xsh = xs_daemon_open(); + if (xsh == NULL) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to open xenstore connection"); + goto err; + } + + xs_watch(xsh, path, path); + tv.tv_sec = timeout; + tv.tv_usec = 0; + nfds = xs_fileno(xsh) + 1; + if (spawning && spawning->fd > xs_fileno(xsh)) + nfds = spawning->fd + 1; + + while (rc > 0 || (!rc && tv.tv_sec > 0)) { + if ( spawning ) { + rc = libxl__spawn_check(gc, spawning); + if ( rc ) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "%s died during startup", what); + rc = -1; + goto err_died; + } + } + p = xs_read(xsh, XBT_NULL, path, &len); + if ( NULL == p ) + goto again; + + if ( NULL != state && strcmp(p, state) ) + goto again; + + if ( NULL != check_callback ) { + rc = (*check_callback)(gc, domid, p, check_callback_userdata); + if ( rc > 0 ) + goto again; + } + + free(p); + xs_unwatch(xsh, path, path); + xs_daemon_close(xsh); + return rc; +again: + free(p); + FD_ZERO(&rfds); + FD_SET(xs_fileno(xsh), &rfds); + if (spawning) + FD_SET(spawning->fd, &rfds); + rc = select(nfds, &rfds, NULL, NULL, &tv); + if (rc > 0) { + if (FD_ISSET(xs_fileno(xsh), &rfds)) { + l = xs_read_watch(xsh, &num); + if (l != NULL) + free(l); + else + goto again; + } + if (spawning && FD_ISSET(spawning->fd, &rfds)) { + unsigned char dummy; + if (read(spawning->fd, &dummy, sizeof(dummy)) != 1) + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_DEBUG, + "failed to read spawn status pipe"); + } + } + } + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "%s not ready", what); +err_died: + xs_unwatch(xsh, path, path); + xs_daemon_close(xsh); +err: + return -1; +} + static int libxl__set_fd_flag(libxl__gc *gc, int fd, int flag) { int flags; |