qemu: avoid memory leaks

Quite a few leaks detected by coverity.  For chr, the leaks were
close enough to the allocations to plug in place; for disk, the
leaks were separated from the allocation by enough other lines with
intermediate failure cases that I refactored the cleanup instead.

* src/qemu/qemu_command.c (qemuParseCommandLine): Plug leaks.
This commit is contained in:
Eric Blake 2011-08-02 14:07:25 -06:00
parent 0c1813f4c9
commit 2ea9409a88

View File

@ -5938,6 +5938,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
int video = VIR_DOMAIN_VIDEO_TYPE_CIRRUS; int video = VIR_DOMAIN_VIDEO_TYPE_CIRRUS;
int nvirtiodisk = 0; int nvirtiodisk = 0;
qemuDomainCmdlineDefPtr cmd = NULL; qemuDomainCmdlineDefPtr cmd = NULL;
virDomainDiskDefPtr disk = NULL;
if (pidfile) if (pidfile)
*pidfile = NULL; *pidfile = NULL;
@ -6124,7 +6125,6 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
STRPREFIX(arg, "-fd") || STRPREFIX(arg, "-fd") ||
STREQ(arg, "-cdrom")) { STREQ(arg, "-cdrom")) {
WANT_VALUE(); WANT_VALUE();
virDomainDiskDefPtr disk;
if (VIR_ALLOC(disk) < 0) if (VIR_ALLOC(disk) < 0)
goto no_memory; goto no_memory;
@ -6226,19 +6226,16 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
} }
if (!(disk->src || disk->nhosts > 0) || if (!(disk->src || disk->nhosts > 0) ||
!disk->dst) { !disk->dst)
virDomainDiskDefFree(disk);
goto no_memory; goto no_memory;
}
if (virDomainDiskDefAssignAddress(caps, disk) < 0) if (virDomainDiskDefAssignAddress(caps, disk) < 0)
goto error; goto error;
if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) { if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
virDomainDiskDefFree(disk);
goto no_memory; goto no_memory;
}
def->disks[def->ndisks++] = disk; def->disks[def->ndisks++] = disk;
disk = NULL;
} else if (STREQ(arg, "-no-acpi")) { } else if (STREQ(arg, "-no-acpi")) {
def->features &= ~(1 << VIR_DOMAIN_FEATURE_ACPI); def->features &= ~(1 << VIR_DOMAIN_FEATURE_ACPI);
} else if (STREQ(arg, "-no-reboot")) { } else if (STREQ(arg, "-no-reboot")) {
@ -6307,8 +6304,10 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
if (!(chr = virDomainChrDefNew())) if (!(chr = virDomainChrDefNew()))
goto error; goto error;
if (qemuParseCommandLineChr(&chr->source, val) < 0) if (qemuParseCommandLineChr(&chr->source, val) < 0) {
virDomainChrDefFree(chr);
goto error; goto error;
}
if (VIR_REALLOC_N(def->serials, def->nserials+1) < 0) { if (VIR_REALLOC_N(def->serials, def->nserials+1) < 0) {
virDomainChrDefFree(chr); virDomainChrDefFree(chr);
goto no_memory; goto no_memory;
@ -6325,8 +6324,10 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
if (!(chr = virDomainChrDefNew())) if (!(chr = virDomainChrDefNew()))
goto error; goto error;
if (qemuParseCommandLineChr(&chr->source, val) < 0) if (qemuParseCommandLineChr(&chr->source, val) < 0) {
virDomainChrDefFree(chr);
goto error; goto error;
}
if (VIR_REALLOC_N(def->parallels, def->nparallels+1) < 0) { if (VIR_REALLOC_N(def->parallels, def->nparallels+1) < 0) {
virDomainChrDefFree(chr); virDomainChrDefFree(chr);
goto no_memory; goto no_memory;
@ -6353,29 +6354,22 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
} }
def->inputs[def->ninputs++] = input; def->inputs[def->ninputs++] = input;
} else if (STRPREFIX(val, "disk:")) { } else if (STRPREFIX(val, "disk:")) {
virDomainDiskDefPtr disk;
if (VIR_ALLOC(disk) < 0) if (VIR_ALLOC(disk) < 0)
goto no_memory; goto no_memory;
disk->src = strdup(val + strlen("disk:")); disk->src = strdup(val + strlen("disk:"));
if (!disk->src) { if (!disk->src)
virDomainDiskDefFree(disk);
goto no_memory; goto no_memory;
}
if (STRPREFIX(disk->src, "/dev/")) if (STRPREFIX(disk->src, "/dev/"))
disk->type = VIR_DOMAIN_DISK_TYPE_BLOCK; disk->type = VIR_DOMAIN_DISK_TYPE_BLOCK;
else else
disk->type = VIR_DOMAIN_DISK_TYPE_FILE; disk->type = VIR_DOMAIN_DISK_TYPE_FILE;
disk->device = VIR_DOMAIN_DISK_DEVICE_DISK; disk->device = VIR_DOMAIN_DISK_DEVICE_DISK;
disk->bus = VIR_DOMAIN_DISK_BUS_USB; disk->bus = VIR_DOMAIN_DISK_BUS_USB;
if (!(disk->dst = strdup("sda"))) { if (!(disk->dst = strdup("sda")) ||
virDomainDiskDefFree(disk); VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
goto no_memory; goto no_memory;
}
if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) {
virDomainDiskDefFree(disk);
goto no_memory;
}
def->disks[def->ndisks++] = disk; def->disks[def->ndisks++] = disk;
disk = NULL;
} else { } else {
virDomainHostdevDefPtr hostdev; virDomainHostdevDefPtr hostdev;
if (!(hostdev = qemuParseCommandLineUSB(val))) if (!(hostdev = qemuParseCommandLineUSB(val)))
@ -6399,18 +6393,16 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
def->nets[def->nnets++] = net; def->nets[def->nnets++] = net;
} }
} else if (STREQ(arg, "-drive")) { } else if (STREQ(arg, "-drive")) {
virDomainDiskDefPtr disk;
WANT_VALUE(); WANT_VALUE();
if (!(disk = qemuParseCommandLineDisk(caps, val, nvirtiodisk))) if (!(disk = qemuParseCommandLineDisk(caps, val, nvirtiodisk)))
goto error; goto error;
if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0) { if (VIR_REALLOC_N(def->disks, def->ndisks+1) < 0)
virDomainDiskDefFree(disk);
goto no_memory; goto no_memory;
}
def->disks[def->ndisks++] = disk;
if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) if (disk->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
nvirtiodisk++; nvirtiodisk++;
def->disks[def->ndisks++] = disk;
disk = NULL;
} else if (STREQ(arg, "-pcidevice")) { } else if (STREQ(arg, "-pcidevice")) {
virDomainHostdevDefPtr hostdev; virDomainHostdevDefPtr hostdev;
WANT_VALUE(); WANT_VALUE();
@ -6516,8 +6508,10 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
if (VIR_ALLOC(chr) < 0) if (VIR_ALLOC(chr) < 0)
goto no_memory; goto no_memory;
if (qemuParseCommandLineChr(chr, val) < 0) if (qemuParseCommandLineChr(chr, val) < 0) {
virDomainChrSourceDefFree(chr);
goto error; goto error;
}
*monConfig = chr; *monConfig = chr;
} }
@ -6545,10 +6539,9 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
char *hosts, *port, *saveptr = NULL, *token; char *hosts, *port, *saveptr = NULL, *token;
virDomainDiskDefPtr first_rbd_disk = NULL; virDomainDiskDefPtr first_rbd_disk = NULL;
for (i = 0 ; i < def->ndisks ; i++) { for (i = 0 ; i < def->ndisks ; i++) {
virDomainDiskDefPtr disk = def->disks[i]; if (def->disks[i]->type == VIR_DOMAIN_DISK_TYPE_NETWORK &&
if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK && def->disks[i]->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD) {
disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_RBD) { first_rbd_disk = def->disks[i];
first_rbd_disk = disk;
break; break;
} }
} }
@ -6676,6 +6669,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
no_memory: no_memory:
virReportOOMError(); virReportOOMError();
error: error:
virDomainDiskDefFree(disk);
VIR_FREE(cmd); VIR_FREE(cmd);
virDomainDefFree(def); virDomainDefFree(def);
VIR_FREE(nics); VIR_FREE(nics);