]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Allow non-blocking/daemon mode to be specified via virExec flags
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 20 Aug 2008 09:24:14 +0000 (09:24 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Wed, 20 Aug 2008 09:24:14 +0000 (09:24 +0000)
ChangeLog
src/openvz_driver.c
src/qemu_driver.c
src/storage_backend.c
src/util.c
src/util.h

index a4e52d7af68bbb81c1414e0d766ca12abe742151..7dad3cf2eb236985318efbf253338ca58b6c438c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Wed Aug 20 10:16:54 BST 2008 Daniel P. Berrange <berrange@redhat.com>
+
+       * src/util.c, src/util.h: Allow flags to be passed to specify
+       non-blocking, or daemon mode
+       * src/qemu_driver.c, src/openvz_driver.c, src/storage_backend.c:
+       Switch to virExec() with VIR_EXEC_NONBLOCK flag
+
 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
index 886a42af595ea32d813d93308252d18b96186b61..d117480b67805db408ce35eedb5d10e436f9a9c1 100644 (file)
@@ -744,7 +744,7 @@ static int openvzListDomains(virConnectPtr conn, int *ids, int nids) {
     char *endptr;
     const char *cmd[] = {VZLIST, "-ovpsid", "-H" , NULL};
 
-    ret = virExec(conn, cmd, &pid, -1, &outfd, &errfd);
+    ret = virExec(conn, cmd, NULL, &pid, -1, &outfd, &errfd, VIR_EXEC_NONE);
     if(ret == -1) {
         openvzError(conn, VIR_ERR_INTERNAL_ERROR,
                _("Could not exec %s"), VZLIST);
@@ -781,7 +781,7 @@ static int openvzListDefinedDomains(virConnectPtr conn,
     const char *cmd[] = {VZLIST, "-ovpsid", "-H", "-S", NULL};
 
     /* the -S options lists only stopped domains */
-    ret = virExec(conn, cmd, &pid, -1, &outfd, &errfd);
+    ret = virExec(conn, cmd, NULL, &pid, -1, &outfd, &errfd, VIR_EXEC_NONE);
     if(ret == -1) {
         openvzError(conn, VIR_ERR_INTERNAL_ERROR,
                _("Could not exec %s"), VZLIST);
index 6d5171f254798799a356c6a3d60ccfc962355358..6533f6b83d455a40c537fff6bcd734745a29c74b 100644 (file)
@@ -952,8 +952,9 @@ static int qemudStartVMDaemon(virConnectPtr conn,
     vm->stdout_fd = -1;
     vm->stderr_fd = -1;
 
-    ret = virExecNonBlock(conn, argv, &vm->pid,
-                          vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd);
+    ret = virExec(conn, argv, NULL, &vm->pid,
+                  vm->stdin_fd, &vm->stdout_fd, &vm->stderr_fd,
+                  VIR_EXEC_NONBLOCK);
     if (ret == 0) {
         vm->def->id = driver->nextvmid++;
         vm->state = migrateFrom ? VIR_DOMAIN_PAUSED : VIR_DOMAIN_RUNNING;
@@ -1200,7 +1201,7 @@ dhcpStartDhcpDaemon(virConnectPtr conn,
     if (qemudBuildDnsmasqArgv(conn, network, &argv) < 0)
         return -1;
 
-    ret = virExecNonBlock(conn, argv, &network->dnsmasqPid, -1, NULL, NULL);
+    ret = virExec(conn, argv, NULL, &network->dnsmasqPid, -1, NULL, NULL, VIR_EXEC_NONBLOCK);
 
     for (i = 0; argv[i]; i++)
         VIR_FREE(argv[i]);
index 23b846c63e86ddfadd3d98257565c8e4c8913331..72af05cea36b03fe56f085b4d5b389a9b48cbdbe 100644 (file)
@@ -403,7 +403,7 @@ virStorageBackendRunProgRegex(virConnectPtr conn,
 
 
     /* Run the program and capture its output */
-    if (virExec(conn, prog, &child, -1, &fd, NULL) < 0) {
+    if (virExec(conn, prog, NULL, &child, -1, &fd, NULL, VIR_EXEC_NONE) < 0) {
         goto cleanup;
     }
 
@@ -537,7 +537,7 @@ virStorageBackendRunProgNul(virConnectPtr conn,
         v[i] = NULL;
 
     /* Run the program and capture its output */
-    if (virExec(conn, prog, &child, -1, &fd, NULL) < 0) {
+    if (virExec(conn, prog, NULL, &child, -1, &fd, NULL, VIR_EXEC_NONE) < 0) {
         goto cleanup;
     }
 
index 483da5d7406bdc5ec0937db6ce2e2188ebb6e1b8..25a9f0555ed40cfb16fe27deebbe47198569f9cc 100644 (file)
@@ -111,11 +111,14 @@ static int virSetNonBlock(int fd) {
     return 0;
 }
 
-static int
-_virExec(virConnectPtr conn,
-         const char *const*argv,
-         int *retpid, int infd, int *outfd, int *errfd, int non_block) {
-    int pid, null, i;
+int
+virExec(virConnectPtr conn,
+        const char *const*argv,
+        const char *const*envp,
+        int *retpid,
+        int infd, int *outfd, int *errfd,
+        int flags) {
+    int pid, null, i, openmax;
     int pipeout[2] = {-1,-1};
     int pipeerr[2] = {-1,-1};
     int childout = -1;
@@ -150,7 +153,7 @@ _virExec(virConnectPtr conn,
                 goto cleanup;
             }
 
-            if (non_block &&
+            if ((flags & VIR_EXEC_NONBLOCK) &&
                 virSetNonBlock(pipeout[0]) == -1) {
                 ReportError(conn, VIR_ERR_INTERNAL_ERROR,
                             _("Failed to set non-blocking file descriptor flag"));
@@ -181,7 +184,7 @@ _virExec(virConnectPtr conn,
                 goto cleanup;
             }
 
-            if (non_block &&
+            if ((flags & VIR_EXEC_NONBLOCK) &&
                 virSetNonBlock(pipeerr[0]) == -1) {
                 ReportError(conn, VIR_ERR_INTERNAL_ERROR,
                             _("Failed to set non-blocking file descriptor flag"));
@@ -268,10 +271,40 @@ _virExec(virConnectPtr conn,
         return -1;
     }
 
-    if (pipeout[0] > 0)
-        close(pipeout[0]);
-    if (pipeerr[0] > 0)
-        close(pipeerr[0]);
+    openmax = sysconf (_SC_OPEN_MAX);
+    for (i = 3; i < openmax; i++)
+        if (i != infd &&
+            i != null &&
+            i != childout &&
+            i != childerr)
+            close(i);
+
+    if (flags & VIR_EXEC_DAEMON) {
+        if (setsid() < 0) {
+            ReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                        _("cannot become session leader: %s"),
+                        strerror(errno));
+            _exit(1);
+        }
+
+        if (chdir("/") < 0) {
+            ReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                        _("cannot change to root directory: %s"),
+                        strerror(errno));
+            _exit(1);
+        }
+
+        pid = fork();
+        if (pid < 0) {
+            ReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                        _("cannot fork child process: %s"),
+                        strerror(errno));
+            _exit(1);
+        }
+
+        if (pid > 0)
+            _exit(0);
+    }
 
 
     if (dup2(infd >= 0 ? infd : null, STDIN_FILENO) < 0) {
@@ -299,7 +332,10 @@ _virExec(virConnectPtr conn,
         childerr != childout)
         close(childerr);
 
-    execvp(argv[0], (char **) argv);
+    if (envp)
+        execve(argv[0], (char **) argv, (char**)envp);
+    else
+        execvp(argv[0], (char **) argv);
 
     ReportError(conn, VIR_ERR_INTERNAL_ERROR,
                 _("cannot execute binary '%s': %s"),
@@ -329,22 +365,6 @@ _virExec(virConnectPtr conn,
     return -1;
 }
 
-int
-virExec(virConnectPtr conn,
-        const char *const*argv,
-        int *retpid, int infd, int *outfd, int *errfd) {
-
-    return(_virExec(conn, argv, retpid, infd, outfd, errfd, 0));
-}
-
-int
-virExecNonBlock(virConnectPtr conn,
-                const char *const*argv,
-                int *retpid, int infd, int *outfd, int *errfd) {
-
-    return(_virExec(conn, argv, retpid, infd, outfd, errfd, 1));
-}
-
 /**
  * @conn connection to report errors against
  * @argv NULL terminated argv to run
@@ -366,7 +386,7 @@ virRun(virConnectPtr conn,
        int *status) {
     int childpid, exitstatus, ret;
 
-    if ((ret = virExec(conn, argv, &childpid, -1, NULL, NULL)) < 0)
+    if ((ret = virExec(conn, argv, NULL, &childpid, -1, NULL, NULL, VIR_EXEC_NONE)) < 0)
         return ret;
 
     while ((ret = waitpid(childpid, &exitstatus, 0) == -1) && errno == EINTR);
index 4452a297d2853bdcb21298057cd7f89a40293533..123d08aa3d2e4470678899f24171c62c4a5a5ced 100644 (file)
 #include "util-lib.h"
 #include "verify.h"
 
-int virExec(virConnectPtr conn, const char *const*argv, int *retpid,
-            int infd, int *outfd, int *errfd);
-int virExecNonBlock(virConnectPtr conn, const char *const*argv, int *retpid,
-                    int infd, int *outfd, int *errfd);
+enum {
+    VIR_EXEC_NONE   = 0,
+    VIR_EXEC_NONBLOCK = (1 << 0),
+    VIR_EXEC_DAEMON = (1 << 1),
+};
+
+int virExec(virConnectPtr conn,
+            const char *const*argv,
+            const char *const*envp,
+            int *retpid,
+            int infd,
+            int *outfd,
+            int *errfd,
+            int flags);
 int virRun(virConnectPtr conn, const char *const*argv, int *status);
 
 int __virFileReadAll(const char *path,