libxl: Expose functions for helping with subprocesses.
authorKeir Fraser <keir.fraser@citrix.com>
Mon, 12 Apr 2010 16:41:05 +0000 (17:41 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Mon, 12 Apr 2010 16:41:05 +0000 (17:41 +0100)
 * Expose libxl_fork in libxl_utils.h
 * Expose libxl_pipe in libxl_utils.h
 * Make libxl_exec put SIGPIPE back (so that libxl callers may
    have SIGPIPE ignored)

xl would like to use libxl_fork (which is like fork(2) except that it
logs errors) and also a similar function libxl_pipe.  So put these in
libxl_utils.[ch] and use them in libxl.c as appropriate, to avoid
having to duplicate code between xl and libxl.

Also, make sure that subprocesses spawned by libxl have SIGPIPE set
back to SIG_DFL as they are entitled to expect.  This means that a
libxl caller which sets SIGPIPE to SIG_IGN is no longer buggy.  (This
is relevant for xl migration, because xl would like to be such a
caller.)

Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
tools/libxl/libxl.c
tools/libxl/libxl_exec.c
tools/libxl/libxl_utils.c
tools/libxl/libxl_utils.h

index 4d80be5935cd87343a9447fc481dd7feb4a8e924..2cc9602d47930c85bf2ed5fcef870b20e20a78ce 100644 (file)
@@ -1238,15 +1238,9 @@ int libxl_device_disk_add(struct libxl_ctx *ctx, uint32_t domid, libxl_device_di
                 char buf[1024], *dev;
                 dev = get_blktap2_device(ctx, disk->physpath, device_disk_string_of_phystype(disk->phystype));
                 if (dev == NULL) {
-                    if (pipe(p) < 0) {
-                        XL_LOG(ctx, XL_LOG_ERROR, "Failed to create a pipe");
-                        return -1;
-                    }
-                    rc = fork();
-                    if (rc < 0) {
-                        XL_LOG(ctx, XL_LOG_ERROR, "Failed to fork a new process");
-                        return -1;
-                    } else if (!rc) { /* child */
+                    rc= libxl_pipe(ctx, p);  if (rc==-1) return -1;
+                    rc= libxl_fork(ctx);  if (rc==-1) return -1;
+                    if (!rc) { /* child */
                         int null_r, null_w;
                         char *args[4];
                         args[0] = "tapdisk2";
index e8cc74c7dac3c1ea1c0d28aeb775042234ccc65e..6d4a5c511552011961b8be595a5042fc006d95a1 100644 (file)
 #include "libxl.h"
 #include "libxl_internal.h"
 
-static pid_t libxl_fork(struct libxl_ctx *ctx)
-{
-    pid_t pid;
-
-    pid = fork();
-    if (pid == -1) {
-        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "fork failed");
-        return -1;
-    }
-
-    return pid;
-}
-
 static int call_waitpid(pid_t (*waitpid_cb)(pid_t, int *, int), pid_t pid, int *status, int options)
 {
     return (waitpid_cb) ? waitpid_cb(pid, status, options) : waitpid(pid, status, options);
@@ -61,6 +48,11 @@ void libxl_exec(int stdinfd, int stdoutfd, int stderrfd, char *arg0, char **args
         dup2(stderrfd, STDERR_FILENO);
     for (i = 4; i < 256; i++)
         close(i);
+
+    signal(SIGPIPE, SIG_DFL);
+    /* in case our caller set it to IGN.  subprocesses are entitled
+     * to assume they got DFL. */
+
     execv(arg0, args);
     _exit(-1);
 }
index 3a1f095cc22fc623aa11ca1a855a16ed4628f2c8..c6989cef54bc3079fbb15ced2a33ae2e3428213c 100644 (file)
@@ -280,3 +280,26 @@ int libxl_read_file_contents(struct libxl_ctx *ctx, const char *filename,
 
 READ_WRITE_EXACTLY(read, 1, /* */)
 READ_WRITE_EXACTLY(write, 0, const)
+
+
+pid_t libxl_fork(struct libxl_ctx *ctx)
+{
+    pid_t pid;
+
+    pid = fork();
+    if (pid == -1) {
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "fork failed");
+        return -1;
+    }
+
+    return pid;
+}
+
+int libxl_pipe(struct libxl_ctx *ctx, int pipes[2])
+{
+    if (pipe(pipes) < 0) {
+        XL_LOG(ctx, XL_LOG_ERROR, "Failed to create a pipe");
+        return -1;
+    }
+    return 0;
+}
index 65e7e31d238b6799ccfc77f263adc36dc61f2437..fe8b975fcd0e3f502522e3b3c850465cf35c52a9 100644 (file)
@@ -44,5 +44,9 @@ int libxl_write_exactly(struct libxl_ctx *ctx, int fd, const void *data,
    * logged using filename (which is only used for logging) and what
    * (which may be 0). */
     
+pid_t libxl_fork(struct libxl_ctx *ctx);
+int libxl_pipe(struct libxl_ctx *ctx, int pipes[2]);
+  /* Just like fork(2), pipe(2), but log errors. */
+
 #endif