# HG changeset patch
# User Olaf Hering <olaf@xxxxxxxxx>
# Date 1317653613 -7200
# Node ID cfca4b1f83f9c2ebf1c1986aad51571243db4c77
# Parent 219ab93f22c0492595686a1cc34911e9d6775b07
libxl: add libxl__wait_for_offspring function
libxl__wait_for_offspring() is a generic version of
libxl__wait_for_device_model().
Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>
diff -r 219ab93f22c0 -r cfca4b1f83f9 tools/libxl/libxl_exec.c
--- 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;
diff -r 219ab93f22c0 -r cfca4b1f83f9 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -303,6 +303,16 @@ _hidden int libxl__destroy_device_model(
_hidden void libxl_spawner_record_pid(void *for_spawn, pid_t innerchild);
+_hidden 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);
/* Logs errors. A copy of "what" is taken. Return values:
* < 0 error, for_spawn need not be detached
* +1 caller is the parent, must call detach on *for_spawn eventually
@@ -318,7 +328,7 @@ _hidden int libxl__spawn_check(libxl__gc
/* Logs errors but also returns them.
* for_spawn must actually be a libxl__spawn_starting* but
* we take void* so you can pass this function directly to
- * libxl__wait_for_device_model. Caller must still call detach. */
+ * libxl__wait_for_offspring. Caller must still call detach. */
/* low-level stuff, for synchronous subprocesses etc. */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|