[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 3/7] introduce an API to async exec scripts



Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxx>
Signed-off-by: Wen Congyang <wency@xxxxxxxxxxxxxx>
---
 tools/libxl/libxl_internal.c |   79 ++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_internal.h |   17 +++++++++
 2 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/tools/libxl/libxl_internal.c b/tools/libxl/libxl_internal.c
index 6c94d3e..4c9c23b 100644
--- a/tools/libxl/libxl_internal.c
+++ b/tools/libxl/libxl_internal.c
@@ -375,6 +375,85 @@ out:
     return rc;
 }
 
+static void libxl_async_exec_timeout(libxl__egc *egc,
+                                     libxl__ev_time *ev,
+                                     const struct timeval *requested_abs)
+{
+    libxl_async_exec *async_exec = CONTAINER_OF(ev, *async_exec, time);
+
+    STATE_AO_GC(async_exec->ao);
+
+    libxl__ev_time_deregister(gc, &async_exec->time);
+    assert(libxl__ev_child_inuse(&async_exec->child));
+
+    LOG(DEBUG, "killing hotplug script %s because of timeout",
+        async_exec->args[0]);
+
+    if (kill(async_exec->child.pid, SIGKILL)) {
+        LOGEV(ERROR, errno, "unable to kill hotplug script %s [%ld]",
+              async_exec->args[0],
+              (unsigned long)async_exec->child.pid);
+    }
+
+    return;
+}
+
+static void libxl_async_exec_done(libxl__egc *egc,
+                                  libxl__ev_child *child,
+                                  pid_t pid, int status)
+{
+    libxl_async_exec *async_exec = CONTAINER_OF(child, *async_exec, child);
+
+    STATE_AO_GC(async_exec->ao);
+
+    libxl__ev_time_deregister(gc, &async_exec->time);
+
+    if (status && !async_exec->allow_fail) {
+        libxl_report_child_exitstatus(CTX, LIBXL__LOG_ERROR,
+                                      async_exec->args[0],
+                                      pid, status);
+    }
+
+    async_exec->finish_cb(async_exec->opaque, status);
+}
+
+int libxl_async_exec_script(libxl__gc *gc, libxl_async_exec *async_exec)
+{
+    pid_t pid;
+
+    /* Convenience aliases */
+    libxl__ev_child *const child = &async_exec->child;
+    char * const *args = async_exec->args;
+    char * const *env = async_exec->env;
+
+    /* Set hotplug timeout */
+    if (libxl__ev_time_register_rel(gc, &async_exec->time,
+                                    libxl_async_exec_timeout,
+                                    async_exec->timeout * 1000)) {
+        LOG(ERROR, "unable to register timeout for "
+            "script %s", args[0]);
+        return ERROR_FAIL;
+    }
+
+    LOG(DEBUG, "Calling script: %s ", args[0]);
+
+    /* Fork and exec netbuf script */
+    pid = libxl__ev_child_fork(gc, child, libxl_async_exec_done);
+    if (pid == -1) {
+        LOG(ERROR, "unable to fork for script %s", args[0]);
+        return ERROR_FAIL;
+    }
+
+    if (!pid) {
+        /* child: Launch netbuf script */
+        libxl__exec(gc, -1, -1, -1, args[0], args, env);
+        /* notreached */
+        abort();
+    }
+
+    return 0;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index dc49f16..ab82334 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -3133,6 +3133,23 @@ void libxl__numa_candidate_put_nodemap(libxl__gc *gc,
  */
 #define CTYPE(isfoo,c) (isfoo((unsigned char)(c)))
 
+typedef struct libxl_async_exec {
+    char * *env;
+    char * *args;
+    void *opaque;
+    void (*finish_cb)(void *opaque, int status);
+    /* unit: second */
+    int timeout;
+    bool allow_fail;
+
+    libxl__ev_time time;
+    libxl__ev_child child;
+    libxl__ao *ao;
+} libxl_async_exec;
+
+_hidden extern int libxl_async_exec_script(libxl__gc *gc,
+                                           libxl_async_exec *async_exec);
+
 
 #endif
 
-- 
1.7.4.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.