Daniel pointed out that the way we build up the QEMU argv strnig is becoming
rather unscalable / error prone. This patch refactors it into to use a short
macro to do memory allocation/reallocation, which clears it up quite nicely
qemu_conf.c | 293 +++++++++++++++++++++++-------------------------------------
1 file changed, 116 insertions(+), 177 deletions(-)
Regards,
Daniel
diff -r 7c1231eebae9 src/qemu_conf.c
--- a/src/qemu_conf.c Thu May 22 12:31:13 2008 -0400
+++ b/src/qemu_conf.c Thu May 22 12:31:46 2008 -0400
@@ -2411,8 +2419,8 @@
int qemudBuildCommandLine(virConnectPtr conn,
struct qemud_driver *driver,
struct qemud_vm *vm,
- char ***argv) {
- int len, n = -1, i;
+ char ***retargv) {
+ int i;
char memory[50];
char vcpus[50];
char boot[QEMUD_MAX_BOOT_DEVS+1];
@@ -2424,6 +2432,8 @@
struct qemud_vm_chr_def *parallel = vm->def->parallels;
struct utsname ut;
int disableKQEMU = 0;
+ int qargc = 0, qarga = 0;
+ char **qargv = NULL;
if (vm->qemuVersion == 0) {
if (qemudExtractVersionInfo(vm->def->os.binary,
@@ -2451,65 +2461,46 @@
vm->def->virtType == QEMUD_VIRT_QEMU)
disableKQEMU = 1;
- len = 1 + /* qemu */
- 1 + /* Stopped */
- 2 + /* machine type */
- disableKQEMU + /* Disable kqemu */
- (vm->qemuCmdFlags & QEMUD_CMD_FLAG_NAME ? 2 : 0) + /* -name XXX */
- 2 * vm->def->ndisks + /* disks*/
- (vm->def->nnets > 0 ? (4 * vm->def->nnets) : 2) + /* networks */
- 1 + /* usb */
- 2 * vm->def->ninputs + /* input devices */
- ((vm->def->nsounds > 0) ? 2 : 0) + /* sound */
- (vm->def->nserials > 0 ? (2 * vm->def->nserials) : 2) + /*
character devices */
- (vm->def->nparallels > 0 ? (2 * vm->def->nparallels) : 2) + /*
character devices */
- 2 + /* memory*/
- 2 + /* cpus */
- 2 + /* boot device */
- 2 + /* monitor */
- (vm->def->localtime ? 1 : 0) + /* localtime */
- (vm->qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT &&
- vm->def->noReboot ? 1 : 0) + /* no-reboot */
- (vm->def->features & QEMUD_FEATURE_ACPI ? 0 : 1) + /* acpi */
- (vm->def->os.kernel[0] ? 2 : 0) + /* kernel */
- (vm->def->os.initrd[0] ? 2 : 0) + /* initrd */
- (vm->def->os.cmdline[0] ? 2 : 0) + /* cmdline */
- (vm->def->os.bootloader[0] ? 2 : 0) + /* bootloader */
- (vm->def->graphicsType == QEMUD_GRAPHICS_VNC ? 2 :
- (vm->def->graphicsType == QEMUD_GRAPHICS_SDL ? 0 : 1)) + /* graphics */
- (vm->migrateFrom[0] ? 2 : 0); /* migrateFrom */
+#define ADD_ARG_SPACE \
+ do { \
+ if (qargc == qarga) { \
+ qarga += 10; \
+ if (VIR_REALLOC_N(qargv, qarga) < 0) \
+ goto no_memory; \
+ } \
+ } while (0)
+
+#define ADD_ARG(thisarg) \
+ do { \
+ ADD_ARG_SPACE; \
+ qargv[qargc++] = thisarg; \
+ } while (0)
+
+#define ADD_ARG_LIT(thisarg) \
+ do { \
+ ADD_ARG_SPACE; \
+ if ((qargv[qargc++] = strdup(thisarg)) == NULL) \
+ goto no_memory; \
+ } while (0)
snprintf(memory, sizeof(memory), "%lu", vm->def->memory/1024);
snprintf(vcpus, sizeof(vcpus), "%d", vm->def->vcpus);
- if (!(*argv = calloc(len+1, sizeof(**argv))))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vm->def->os.binary)))
- goto no_memory;
- if (!((*argv)[++n] = strdup("-S")))
- goto no_memory;
- if (!((*argv)[++n] = strdup("-M")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vm->def->os.machine)))
- goto no_memory;
- if (disableKQEMU) {
- if (!((*argv)[++n] = strdup("-no-kqemu")))
- goto no_memory;
- }
- if (!((*argv)[++n] = strdup("-m")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(memory)))
- goto no_memory;
- if (!((*argv)[++n] = strdup("-smp")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vcpus)))
- goto no_memory;
+
+ ADD_ARG_LIT(vm->def->os.binary);
+ ADD_ARG_LIT("-S");
+ ADD_ARG_LIT("-M");
+ ADD_ARG_LIT(vm->def->os.machine);
+ if (disableKQEMU)
+ ADD_ARG_LIT("-no-kqemu");
+ ADD_ARG_LIT("-m");
+ ADD_ARG_LIT(memory);
+ ADD_ARG_LIT("-smp");
+ ADD_ARG_LIT(vcpus);
if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_NAME) {
- if (!((*argv)[++n] = strdup("-name")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vm->def->name)))
- goto no_memory;
+ ADD_ARG_LIT("-name");
+ ADD_ARG_LIT(vm->def->name);
}
/*
* NB, -nographic *MUST* come before any serial, or monitor
@@ -2518,31 +2509,21 @@
* if you ask for nographic. So we have to make sure we override
* these defaults ourselves...
*/
- if (vm->def->graphicsType == QEMUD_GRAPHICS_NONE) {
- if (!((*argv)[++n] = strdup("-nographic")))
- goto no_memory;
- }
-
- if (!((*argv)[++n] = strdup("-monitor")))
- goto no_memory;
- if (!((*argv)[++n] = strdup("pty")))
- goto no_memory;
-
- if (vm->def->localtime) {
- if (!((*argv)[++n] = strdup("-localtime")))
- goto no_memory;
- }
-
- if (vm->qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT &&
- vm->def->noReboot) {
- if (!((*argv)[++n] = strdup("-no-reboot")))
- goto no_memory;
- }
-
- if (!(vm->def->features & QEMUD_FEATURE_ACPI)) {
- if (!((*argv)[++n] = strdup("-no-acpi")))
- goto no_memory;
- }
+ if (vm->def->graphicsType == QEMUD_GRAPHICS_NONE)
+ ADD_ARG_LIT("-nographic");
+
+ ADD_ARG_LIT("-monitor");
+ ADD_ARG_LIT("pty");
+
+ if (vm->def->localtime)
+ ADD_ARG_LIT("-localtime");
+
+ if ((vm->qemuCmdFlags & QEMUD_CMD_FLAG_NO_REBOOT) &&
+ vm->def->noReboot)
+ ADD_ARG_LIT("-no-reboot");
+
+ if (!(vm->def->features & QEMUD_FEATURE_ACPI))
+ ADD_ARG_LIT("-no-acpi");
if (!vm->def->os.bootloader[0]) {
for (i = 0 ; i < vm->def->os.nBootDevs ; i++) {
@@ -2565,34 +2546,24 @@
}
}
boot[vm->def->os.nBootDevs] = '\0';
- if (!((*argv)[++n] = strdup("-boot")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(boot)))
- goto no_memory;
+ ADD_ARG_LIT("-boot");
+ ADD_ARG_LIT(boot);
if (vm->def->os.kernel[0]) {
- if (!((*argv)[++n] = strdup("-kernel")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vm->def->os.kernel)))
- goto no_memory;
+ ADD_ARG_LIT("-kernel");
+ ADD_ARG_LIT(vm->def->os.kernel);
}
if (vm->def->os.initrd[0]) {
- if (!((*argv)[++n] = strdup("-initrd")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vm->def->os.initrd)))
- goto no_memory;
+ ADD_ARG_LIT("-initrd");
+ ADD_ARG_LIT(vm->def->os.initrd);
}
if (vm->def->os.cmdline[0]) {
- if (!((*argv)[++n] = strdup("-append")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vm->def->os.cmdline)))
- goto no_memory;
- }
- } else {
- if (!((*argv)[++n] = strdup("-bootloader")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vm->def->os.bootloader)))
- goto no_memory;
+ ADD_ARG_LIT("-append");
+ ADD_ARG_LIT(vm->def->os.cmdline);
+ }
+ } else {
+ ADD_ARG_LIT("-bootloader");
+ ADD_ARG_LIT(vm->def->os.bootloader);
}
/* If QEMU supports -drive param instead of old -hda, -hdb, -cdrom .. */
@@ -2621,8 +2592,6 @@
const char *media = NULL;
int bootable = 0;
int idx = virDiskNameToIndex(disk->dst);
- if (!((*argv)[++n] = strdup("-drive")))
- goto no_memory;
if (idx < 0) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
@@ -2654,8 +2623,8 @@
idx,
bootable ? ",boot=on" : "");
- if (!((*argv)[++n] = strdup(opt)))
- goto no_memory;
+ ADD_ARG_LIT("-drive");
+ ADD_ARG_LIT(opt);
disk = disk->next;
}
} else {
@@ -2684,20 +2653,16 @@
snprintf(file, PATH_MAX, "%s", disk->src);
- if (!((*argv)[++n] = strdup(dev)))
- goto no_memory;
- if (!((*argv)[++n] = strdup(file)))
- goto no_memory;
+ ADD_ARG_LIT(dev);
+ ADD_ARG_LIT(file);
disk = disk->next;
}
}
if (!net) {
- if (!((*argv)[++n] = strdup("-net")))
- goto no_memory;
- if (!((*argv)[++n] = strdup("none")))
- goto no_memory;
+ ADD_ARG_LIT("-net");
+ ADD_ARG_LIT("none");
} else {
int vlan = 0;
while (net) {
@@ -2712,19 +2677,14 @@
(net->model[0] ? ",model=" : ""),
net->model) >= sizeof(nic))
goto error;
- if (!((*argv)[++n] = strdup("-net")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(nic)))
- goto no_memory;
-
- if (!((*argv)[++n] = strdup("-net")))
- goto no_memory;
+ ADD_ARG_LIT("-net");
+ ADD_ARG_LIT(nic);
+ ADD_ARG_LIT("-net");
switch (net->type) {
case QEMUD_NET_NETWORK:
case QEMUD_NET_BRIDGE:
- if (!((*argv)[++n] = qemudNetworkIfaceConnect(conn, driver, vm, net,
vlan)))
- goto error;
+ ADD_ARG(qemudNetworkIfaceConnect(conn, driver, vm, net, vlan));
break;
case QEMUD_NET_ETHERNET:
@@ -2736,8 +2696,7 @@
vlan) >= (PATH_MAX-1))
goto error;
- if (!((*argv)[++n] = strdup(arg)))
- goto no_memory;
+ ADD_ARG_LIT(arg);
}
break;
@@ -2765,8 +2724,7 @@
vlan) >= (PATH_MAX-1))
goto error;
- if (!((*argv)[++n] = strdup(arg)))
- goto no_memory;
+ ADD_ARG_LIT(arg);
}
break;
@@ -2777,8 +2735,7 @@
if (snprintf(arg, PATH_MAX-1, "user,vlan=%d", vlan) >=
(PATH_MAX-1))
goto error;
- if (!((*argv)[++n] = strdup(arg)))
- goto no_memory;
+ ADD_ARG_LIT(arg);
}
}
@@ -2788,10 +2745,8 @@
}
if (!serial) {
- if (!((*argv)[++n] = strdup("-serial")))
- goto no_memory;
- if (!((*argv)[++n] = strdup("none")))
- goto no_memory;
+ ADD_ARG_LIT("-serial");
+ ADD_ARG_LIT("none");
} else {
while (serial) {
char buf[4096];
@@ -2799,20 +2754,16 @@
if (qemudBuildCommandLineChrDevStr(serial, buf, sizeof(buf)) < 0)
goto error;
- if (!((*argv)[++n] = strdup("-serial")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(buf)))
- goto no_memory;
+ ADD_ARG_LIT("-serial");
+ ADD_ARG_LIT(buf);
serial = serial->next;
}
}
if (!parallel) {
- if (!((*argv)[++n] = strdup("-parallel")))
- goto no_memory;
- if (!((*argv)[++n] = strdup("none")))
- goto no_memory;
+ ADD_ARG_LIT("-parallel");
+ ADD_ARG_LIT("none");
} else {
while (parallel) {
char buf[4096];
@@ -2820,23 +2771,18 @@
if (qemudBuildCommandLineChrDevStr(parallel, buf, sizeof(buf)) < 0)
goto error;
- if (!((*argv)[++n] = strdup("-parallel")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(buf)))
- goto no_memory;
+ ADD_ARG_LIT("-parallel");
+ ADD_ARG_LIT(buf);
parallel = parallel->next;
}
}
- if (!((*argv)[++n] = strdup("-usb")))
- goto no_memory;
+ ADD_ARG_LIT("-usb");
while (input) {
if (input->bus == QEMU_INPUT_BUS_USB) {
- if (!((*argv)[++n] = strdup("-usbdevice")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(input->type == QEMU_INPUT_TYPE_MOUSE ?
"mouse" : "tablet")))
- goto no_memory;
+ ADD_ARG_LIT("-usbdevice");
+ ADD_ARG_LIT(input->type == QEMU_INPUT_TYPE_MOUSE ? "mouse" :
"tablet");
}
input = input->next;
@@ -2870,15 +2816,11 @@
if (ret < 0 || ret >= (int)sizeof(vncdisplay))
goto error;
- if (!((*argv)[++n] = strdup("-vnc")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vncdisplay)))
- goto no_memory;
+ ADD_ARG_LIT("-vnc");
+ ADD_ARG_LIT(vncdisplay);
if (vm->def->keymap) {
- if (!((*argv)[++n] = strdup("-k")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vm->def->keymap)))
- goto no_memory;
+ ADD_ARG_LIT("-k");
+ ADD_ARG_LIT(vm->def->keymap);
}
} else if (vm->def->graphicsType == QEMUD_GRAPHICS_NONE) {
/* Nada - we added -nographic earlier in this function */
@@ -2892,12 +2834,11 @@
char *modstr = calloc(1, size+1);
if (!modstr)
goto no_memory;
- if (!((*argv)[++n] = strdup("-soundhw")))
- goto no_memory;
while(sound && size > 0) {
const char *model = qemudSoundModelToString(sound->model);
if (!model) {
+ free(modstr);
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
"%s", _("invalid sound model"));
goto error;
@@ -2908,19 +2849,18 @@
if (sound)
strncat(modstr, ",", size--);
}
- if (!((*argv)[++n] = modstr))
- goto no_memory;
+ ADD_ARG_LIT("-soundhw");
+ ADD_ARG(modstr);
}
if (vm->migrateFrom[0]) {
- if (!((*argv)[++n] = strdup("-incoming")))
- goto no_memory;
- if (!((*argv)[++n] = strdup(vm->migrateFrom)))
- goto no_memory;
- }
-
- (*argv)[++n] = NULL;
-
+ ADD_ARG_LIT("-incoming");
+ ADD_ARG_LIT(vm->migrateFrom);
+ }
+
+ ADD_ARG(NULL);
+
+ *retargv = qargv;
return 0;
no_memory:
@@ -2934,11 +2874,10 @@
vm->tapfds = NULL;
vm->ntapfds = 0;
}
- if (argv) {
- for (i = 0 ; i < n ; i++)
- free((*argv)[i]);
- free(*argv);
- *argv = NULL;
+ if (qargv) {
+ for (i = 0 ; i < qargc ; i++)
+ free((qargv)[i]);
+ free(qargv);
}
return -1;
}
--
|: Red Hat, Engineering, Boston -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|