]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Allow a pre-opened FD to be be pass to virExec for stdout/err
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 20 Aug 2008 09:08:17 +0000 (09:08 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 20 Aug 2008 09:08:17 +0000 (09:08 +0000)
ChangeLog
src/openvz_driver.c
src/qemu_driver.c
src/util.c

index 3eba2d5e729c00ab9f4bf48d988f6aaa98b676a1..a4e52d7af68bbb81c1414e0d766ca12abe742151 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Wed Aug 20 09:59:54 BST 2008 Daniel P. Berrange <berrange@redhat.com>
+
+       * src/util.c: Allow a pre-opened FD to be passed in for childs
+       stdout/err
+       * src/openvz_driver.c, src/qemu_driver.c: Initialize FDs to
+       -1 before calling virExec()
+
 Wed Aug 20 09:35:33 BST 2008 Daniel P. Berrange <berrange@redhat.com>
 
        Avoid signal race in virExec()
index 0d0eac1af7e53aabfeec8f3da22186e1f838e0fd..886a42af595ea32d813d93308252d18b96186b61 100644 (file)
@@ -736,7 +736,9 @@ static int openvzGetNodeInfo(virConnectPtr conn,
 
 static int openvzListDomains(virConnectPtr conn, int *ids, int nids) {
     int got = 0;
-    int veid, pid, outfd, errfd;
+    int veid, pid;
+    int outfd = -1;
+    int errfd = -1;
     int ret;
     char buf[32];
     char *endptr;
@@ -772,7 +774,7 @@ static int openvzNumDomains(virConnectPtr conn ATTRIBUTE_UNUSED) {
 static int openvzListDefinedDomains(virConnectPtr conn,
                             char **const names, int nnames) {
     int got = 0;
-    int veid, pid, outfd, errfd, ret;
+    int veid, pid, outfd = -1, errfd = -1, ret;
     char vpsname[OPENVZ_NAME_MAX];
     char buf[32];
     char *endptr;
index 2398686ced80c6fcbadc89c5fa7e550ad4b725e4..6d5171f254798799a356c6a3d60ccfc962355358 100644 (file)
@@ -949,6 +949,9 @@ static int qemudStartVMDaemon(virConnectPtr conn,
         qemudLog(QEMUD_WARN, _("Unable to write argv to logfile %d: %s\n"),
                  errno, strerror(errno));
 
+    vm->stdout_fd = -1;
+    vm->stderr_fd = -1;
+
     ret = virExecNonBlock(conn, argv, &vm->pid,
                           vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd);
     if (ret == 0) {
index 731145303520460cc852dddbbc66cddee59cd411..483da5d7406bdc5ec0937db6ce2e2188ebb6e1b8 100644 (file)
@@ -118,6 +118,8 @@ _virExec(virConnectPtr conn,
     int pid, null, i;
     int pipeout[2] = {-1,-1};
     int pipeerr[2] = {-1,-1};
+    int childout = -1;
+    int childerr = -1;
     sigset_t oldmask, newmask;
     struct sigaction sig_action;
 
@@ -140,39 +142,66 @@ _virExec(virConnectPtr conn,
         goto cleanup;
     }
 
-    if ((outfd != NULL && pipe(pipeout) < 0) ||
-        (errfd != NULL && pipe(pipeerr) < 0)) {
-        ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                    _("cannot create pipe: %s"), strerror(errno));
-        goto cleanup;
-    }
+    if (outfd != NULL) {
+        if (*outfd == -1) {
+            if (pipe(pipeout) < 0) {
+                ReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                            _("cannot create pipe: %s"), strerror(errno));
+                goto cleanup;
+            }
 
-    if (outfd) {
-        if(non_block &&
-           virSetNonBlock(pipeout[0]) == -1) {
-            ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                        _("Failed to set non-blocking file descriptor flag"));
-            goto cleanup;
-        }
+            if (non_block &&
+                virSetNonBlock(pipeout[0]) == -1) {
+                ReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                            _("Failed to set non-blocking file descriptor flag"));
+                goto cleanup;
+            }
 
-        if(virSetCloseExec(pipeout[0]) == -1) {
-            ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                        _("Failed to set close-on-exec file descriptor flag"));
-            goto cleanup;
+            if (virSetCloseExec(pipeout[0]) == -1) {
+                ReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                            _("Failed to set close-on-exec file descriptor flag"));
+                goto cleanup;
+            }
+
+            childout = pipeout[1];
+        } else {
+            childout = *outfd;
         }
+#ifndef ENABLE_DEBUG
+    } else {
+        childout = null;
+#endif
     }
-    if (errfd) {
-        if(non_block &&
-           virSetNonBlock(pipeerr[0]) == -1) {
-            ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                        _("Failed to set non-blocking file descriptor flag"));
-            goto cleanup;
-        }
-        if(virSetCloseExec(pipeerr[0]) == -1) {
-            ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                        _("Failed to set close-on-exec file descriptor flag"));
-            goto cleanup;
+
+    if (errfd != NULL) {
+        if (*errfd == -1) {
+            if (pipe(pipeerr) < 0) {
+                ReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                            _("Failed to create pipe: %s"), strerror(errno));
+                goto cleanup;
+            }
+
+            if (non_block &&
+                virSetNonBlock(pipeerr[0]) == -1) {
+                ReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                            _("Failed to set non-blocking file descriptor flag"));
+                goto cleanup;
+            }
+
+            if (virSetCloseExec(pipeerr[0]) == -1) {
+                ReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                            _("Failed to set close-on-exec file descriptor flag"));
+                goto cleanup;
+            }
+
+            childerr = pipeerr[1];
+        } else {
+            childerr = *errfd;
         }
+#ifndef ENABLE_DEBUG
+    } else {
+        childerr = null;
+#endif
     }
 
     if ((pid = fork()) < 0) {
@@ -183,11 +212,11 @@ _virExec(virConnectPtr conn,
 
     if (pid) { /* parent */
         close(null);
-        if (outfd) {
+        if (outfd && *outfd == -1) {
             close(pipeout[1]);
             *outfd = pipeout[0];
         }
-        if (errfd) {
+        if (errfd && *errfd == -1) {
             close(pipeerr[1]);
             *errfd = pipeerr[0];
         }
@@ -250,35 +279,25 @@ _virExec(virConnectPtr conn,
                     _("failed to setup stdin file handle: %s"), strerror(errno));
         _exit(1);
     }
-#ifndef ENABLE_DEBUG
-    if (dup2(pipeout[1] > 0 ? pipeout[1] : null, STDOUT_FILENO) < 0) {
+    if (childout > 0 &&
+        dup2(childout, STDOUT_FILENO) < 0) {
         ReportError(conn, VIR_ERR_INTERNAL_ERROR,
                     _("failed to setup stdout file handle: %s"), strerror(errno));
         _exit(1);
     }
-    if (dup2(pipeerr[1] > 0 ? pipeerr[1] : null, STDERR_FILENO) < 0) {
+    if (childerr > 0 &&
+        dup2(childerr, STDERR_FILENO) < 0) {
         ReportError(conn, VIR_ERR_INTERNAL_ERROR,
                     _("failed to setup stderr file handle: %s"), strerror(errno));
         _exit(1);
     }
-#else /* ENABLE_DEBUG */
-    if (pipeout[1] > 0 && dup2(pipeout[1], STDOUT_FILENO) < 0) {
-        ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                    _("failed to setup stderr file handle: %s"), strerror(errno));
-        _exit(1);
-    }
-    if (pipeerr[1] > 0 && dup2(pipeerr[1], STDERR_FILENO) < 0) {
-        ReportError(conn, VIR_ERR_INTERNAL_ERROR,
-                    _("failed to setup stdout file handle: %s"), strerror(errno));
-        _exit(1);
-    }
-#endif /* ENABLE_DEBUG */
 
     close(null);
-    if (pipeout[1] > 0)
-        close(pipeout[1]);
-    if (pipeerr[1] > 0)
-        close(pipeerr[1]);
+    if (childout > 0)
+        close(childout);
+    if (childerr > 0 &&
+        childerr != childout)
+        close(childerr);
 
     execvp(argv[0], (char **) argv);