-Tue Feb 14 15:52:34 EST 2007 Mark McLoughlin <markmc@redhat.com>
-
- * qemud/protocol.h: add the protocol for virtual networks
-
- * qemud/dispatch.c: implement the protocol
-
- * qemud/driver.[ch]: add stubs for the driver
-
- * qemud/internal.h: add struct qemud_network
-
- * src/qemu_internal.c: add a virtual networks driver
-
-Tue Feb 14 15:43:28 EST 2007 Mark McLoughlin <markmc@redhat.com>
-
- * src/virsh.c: add the net-* commands.
-
-Tue Feb 14 15:37:17 EST 2007 Mark McLoughlin <markmc@redhat.com>
-
- Note: potential ABI break here, but people should
- only really be using virError structs returned from
- libvirt itself.
-
- * include/libvirt/virterror.h: add virNetwork
- to virError
-
- * src/internal.h, src/virterror.c: add network param
- to __virRaiseError()
-
- * src/conf.c, src/hash.c, src/libvirt.c, src/proxy_internal.c,
- src/qemu_internal.c, src/sexpr.c, src/test.c, src/xen_internal.c,
- src/xend_internal.c, src/xm_internal.c, src/xml.c, src/xmlrpc.c,
- src/xs_internal.c: update.
-
-Tue Feb 14 15:33:05 EST 2007 Mark McLoughlin <markmc@redhat.com>
-
- * include/libvirt/libvirt.h.in: add the networks APIs
-
- * include/libvirt/virterror.h: add some error codes
-
- * src/driver.h: add network driver vtable
-
- * src/hash.c: add networks hash
-
- * src/internal.h: add virNetwork
-
- * src/libvirt.c: hook up the APIs to the network
- driver
-
- * src/libvirt_sym.version: add the new APIs
-
- * src/virterror.c: handle the new error codes
-
-Tue Feb 14 15:07:26 EST 2007 Mark McLoughlin <markmc@redhat.com>
-
- * src/conf.h: fix merge error - remove the argc argument
- from qemudBuildCommandLine()
-
-Tue Feb 14 15:03:22 EST 2007 Mark McLoughlin <markmc@redhat.com>
-
- * src/virsh.c: Re-name some of the VSH_DOMBYFOO stuff
- to VSH_BYFOO in order to re-use it for the network stuff.
-
-Tue Feb 14 14:58:35 EST 2007 Mark McLoughlin <markmc@redhat.com>
-
- * src/hash.c, src/internal.h: Re-name virConnect->domains_mux
- to virConnect->hashes_mux since it will also be used to
- protect the networks hash.
-
-Tue Feb 14 14:57:52 EST 2007 Mark McLoughlin <markmc@redhat.com>
-
- * qemud/conf.c: qemudSaveConfig() will always report a
- more specific error, so we should avoid overwriting
- this error.
-
-Tue Feb 14 14:54:25 EST 2007 Mark McLoughlin <markmc@redhat.com>
+Tue Feb 14 14:54:25 EST 2007 Mark McLoughlin <markmc@redhat.com
* qemud/qemud.c: Re-factor out qemudExec() so that it can
be used to launch dnsmasq.
* qemud/conf.c: don't return argc from qemudBuildCommandLine()
as exec() doesn't need it.
-Tue Feb 14 14:52:12 EST 2007 Mark McLoughlin <markmc@redhat.com>
+Tue Feb 14 14:52:12 EST 2007 Mark McLoughlin <markmc@redhat.com
* qemud/conf.c: Re-factor bits of conf.c so that:
- split qemudScanConfigDir() out so that qemudScanConfigs()
can scan multiple configDirs
-Tue Feb 14 14:50:22 EST 2007 Mark McLoughlin <markmc@redhat.com>
+Tue Feb 14 14:50:22 EST 2007 Mark McLoughlin <markmc@redhat.com
* qemud/conf.c: handle an unspecified MAC address,
fix the argv freeing code in qemudBuildCommandLine()
and fix copy and paste error in qemudGenerateXML()
-Tue Feb 14 14:42:38 EST 2007 Mark McLoughlin <markmc@redhat.com>
+Tue Feb 14 14:42:38 EST 2007 Mark McLoughlin <markmc@redhat.com
* src/internal.h: add virConnect->qemud_fd so that
xen and qemu don't share the handle member.
* src/hash.c, src/qemu_internal.c: update
-Tue Feb 14 14:40:52 EST 2007 Mark McLoughlin <markmc@redhat.com>
+Tue Feb 14 14:40:52 EST 2007 Mark McLoughlin <markmc@redhat.com
* qemud/conf.c, qemud/dispatch.c, qemud/driver.c,
qemud/qemud.c: include autoconf's config.h
-Tue Feb 14 14:39:18 EST 2007 Mark McLoughlin <markmc@redhat.com>
+Tue Feb 14 14:39:18 EST 2007 Mark McLoughlin <markmc@redhat.com
* conf.[ch]: rename from config.[ch] so we can use
autoconf's config.h
* driver.c, qemud.c: upd.
-Tue Feb 14 14:33:22 EST 2007 Mark McLoughlin <markmc@redhat.com>
+Tue Feb 14 14:33:22 EST 2007 Mark McLoughlin <markmc@redhat.com
* autogen.sh: run autoheader
*/
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*/
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;
}
-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);
-
- execvp(argv[0], argv);
+ 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;
+ }
+ /* 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;