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

[Libvir] [patch 6/9] Re-factor qemudExec()



Re-factor out qemudExec() so that it can be used to
launch dnsmasq.

Note, exec() doesn't take an argc argument, just a
null-terminated argv, so there's no need for
qemudBuildCommandLine() to return argc.

Note, Dan originally folded this into his qemu patches, but
it looks to have since been lost.

Signed-off-by: Mark McLoughlin <markmc redhat com>

Index: libvirt/qemud/conf.c
===================================================================
--- libvirt.orig/qemud/conf.c
+++ libvirt/qemud/conf.c
@@ -775,16 +775,15 @@ static int qemudParseXML(struct qemud_se
  */
 int qemudBuildCommandLine(struct qemud_server *server,
                           struct qemud_vm *vm,
-                          char ***argv,
-                          int *argc) {
-    int n = -1, i;
+                          char ***argv) {
+    int len, n = -1, i;
     char memory[50];
     char vcpus[50];
     char boot[QEMUD_MAX_BOOT_DEVS+1];
     struct qemud_vm_disk_def *disk = vm->def.disks;
     struct qemud_vm_net_def *net = vm->def.nets;
 
-    *argc = 1 + /* qemu */
+    len = 1 + /* qemu */
         2 + /* machine type */
         (vm->def.virtType == QEMUD_VIRT_QEMU ? 1 : 0) + /* Disable kqemu */
         2 * vm->def.ndisks + /* disks*/
@@ -803,7 +802,7 @@ int qemudBuildCommandLine(struct qemud_s
     sprintf(memory, "%d", vm->def.memory/1024);
     sprintf(vcpus, "%d", vm->def.vcpus);
 
-    if (!(*argv = malloc(sizeof(char *) * (*argc +1))))
+    if (!(*argv = malloc(sizeof(char *) * (len+1))))
         goto no_memory;
     if (!((*argv)[++n] = strdup(vm->def.os.binary)))
         goto no_memory;
Index: libvirt/qemud/qemud.c
===================================================================
--- libvirt.orig/qemud/qemud.c
+++ libvirt/qemud/qemud.c
@@ -324,103 +324,110 @@ static int qemudDispatchServer(struct qe
 }
 
 
-int qemudStartVMDaemon(struct qemud_server *server,
-                       struct qemud_vm *vm) {
-    char **argv = NULL;
-    int argc = 0;
-    int pid;
-    int i, ret = -1;
-    int stdinfd = -1;
+static int
+qemudExec(struct qemud_server *server, char **argv,
+          int *retpid, int *outfd, int *errfd) {
+    int pid, null;
     int pipeout[2] = {-1,-1};
     int pipeerr[2] = {-1,-1};
 
-    if (vm->def.vncPort < 0)
-        vm->def.vncActivePort = 5900 + server->nextvmid;
-    else
-        vm->def.vncActivePort = vm->def.vncPort;
-
-    if (qemudBuildCommandLine(server, vm, &argv, &argc) < 0)
-        return -1;
-
-    if (1) { /* XXX debug stuff */
-        QEMUD_DEBUG("Spawn QEMU '");
-        for (i = 0 ; i < argc; i++) {
-            QEMUD_DEBUG("%s", argv[i]);
-            if (i == (argc-1)) {
-                QEMUD_DEBUG("'\n");
-            } else {
-                QEMUD_DEBUG(" ");
-            }
-        }
-    }
-
-    if ((stdinfd = open(_PATH_DEVNULL, O_RDONLY)) < 0) {
-        qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot open %s", _PATH_DEVNULL);
+    if ((null = open(_PATH_DEVNULL, O_RDONLY)) < 0) {
+        qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot open %s : %s",
+                         _PATH_DEVNULL, strerror(errno));
         goto cleanup;
     }
 
-    if (pipe(pipeout) < 0) {
-        qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot create pipe");
-        goto cleanup;
-    }
-
-    if (pipe(pipeerr) < 0) {
-        qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot create pipe");
+    if ((outfd != NULL && pipe(pipeout) < 0) ||
+        (errfd != NULL && pipe(pipeerr) < 0)) {
+        qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot create pipe : %s",
+                         strerror(errno));
         goto cleanup;
     }
 
     if ((pid = fork()) < 0) {
-        qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot fork child process");
+        qemudReportError(server, VIR_ERR_INTERNAL_ERROR, "cannot fork child process : %s",
+                         strerror(errno));
         goto cleanup;
     }
 
     if (pid) { /* parent */
-        close(stdinfd);
-        close(pipeout[1]);
-        close(pipeerr[1]);
-        qemudSetNonBlock(pipeout[0]);
-        qemudSetNonBlock(pipeerr[0]);
-        vm->def.id = server->nextvmid++;
-        vm->pid = pid;
-        vm->stdout = pipeout[0];
-        vm->stderr = pipeerr[0];
-
-    } else { /* child */
-        int null;
-        if ((null = open(_PATH_DEVNULL, O_RDONLY)) < 0)
-            _exit(1);
-
-        if (close(pipeout[0]) < 0)
-            _exit(1);
-        if (close(pipeerr[0]) < 0)
-            _exit(1);
-
-        if (dup2(stdinfd, STDIN_FILENO) < 0)
-            _exit(1);
-        if (dup2(pipeout[1], STDOUT_FILENO) < 0)
-            _exit(1);
-        if (dup2(pipeerr[1], STDERR_FILENO) < 0)
-            _exit(1);
-
-        int open_max = sysconf (_SC_OPEN_MAX);
-        for (i = 0; i < open_max; i++)
-            if (i != STDOUT_FILENO &&
-                i != STDERR_FILENO &&
-                i != STDIN_FILENO)
-                close(i);
+        close(null);
+        if (outfd) {
+            close(pipeout[1]);
+            qemudSetNonBlock(pipeout[0]);
+            *outfd = pipeout[0];
+        }
+        if (errfd) {
+            close(pipeerr[1]);
+            qemudSetNonBlock(pipeerr[0]);
+            *errfd = pipeerr[0];
+        }
+        *retpid = pid;
+        return 0;
+    }
 
-        execvp(argv[0], argv);
+    /* child */
 
+    if (pipeout[0] > 0 && close(pipeout[0]) < 0)
+        _exit(1);
+    if (pipeerr[0] > 0 && close(pipeerr[0]) < 0)
         _exit(1);
-    }
 
-    ret = 0;
+    if (dup2(null, STDIN_FILENO) < 0)
+        _exit(1);
+    if (dup2(pipeout[1] > 0 ? pipeout[1] : null, STDOUT_FILENO) < 0)
+        _exit(1);
+    if (dup2(pipeerr[1] > 0 ? pipeerr[1] : null, STDERR_FILENO) < 0)
+        _exit(1);
+
+    int i, open_max = sysconf (_SC_OPEN_MAX);
+    for (i = 0; i < open_max; i++)
+        if (i != STDOUT_FILENO &&
+            i != STDERR_FILENO &&
+            i != STDIN_FILENO)
+            close(i);
+
+    execvp(argv[0], argv);
+
+    _exit(1);
+
+    return 0;
 
  cleanup:
+    if (pipeerr[0] > 0)
+        close(pipeerr[0] > 0);
+    if (pipeerr[1])
+        close(pipeerr[1] > 0);
+    if (pipeout[0])
+        close(pipeout[0] > 0);
+    if (pipeout[1])
+        close(pipeout[1] > 0);
+    if (null > 0)
+        close(null);
+    return -1;
+}
+
+
+int qemudStartVMDaemon(struct qemud_server *server,
+                       struct qemud_vm *vm) {
+    char **argv = NULL;
+    int i, ret = -1;
+
+    if (vm->def.vncPort < 0)
+        vm->def.vncActivePort = 5900 + server->nextvmid;
+    else
+        vm->def.vncActivePort = vm->def.vncPort;
+
+    if (qemudBuildCommandLine(server, vm, &argv) < 0)
+        return -1;
+
+    if (qemudExec(server, argv, &vm->pid, &vm->stdout, &vm->stderr) == 0) {
+        vm->def.id = server->nextvmid++;
+        ret = 0;
+    }
   
-    for (i = 0 ; i < argc ; i++) {
+    for (i = 0 ; argv[i] ; i++)
         free(argv[i]);
-    }
     free(argv);
 
     return ret;

-- 


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