1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

qemu_command: Resolve resource leaks found by Valgrind

The qemuParseGlusterString() replaced dst->src without a VIR_FREE() of
what was in there before.

The qemuBuildCommandLine() did not properly free the boot_buf depending
on various usages.

The qemuParseCommandLineDisk() had numerous paths that didn't clean up
the virDomainDiskDefPtr def properly. Adjust the logic to go through an
error: label before cleanup in order to free the resource.
This commit is contained in:
John Ferlan 2013-02-04 11:15:12 -05:00
parent 7af7c42d05
commit 890b6b351f

View File

@ -2147,6 +2147,7 @@ qemuParseGlusterString(virDomainDiskDefPtr def)
} }
} }
volimg = uri->path + 1; /* skip the prefix slash */ volimg = uri->path + 1; /* skip the prefix slash */
VIR_FREE(def->src);
def->src = strdup(volimg); def->src = strdup(volimg);
if (!def->src) if (!def->src)
goto no_memory; goto no_memory;
@ -5629,6 +5630,7 @@ qemuBuildCommandLine(virConnectPtr conn,
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("reboot timeout is not supported " _("reboot timeout is not supported "
"by this QEMU binary")); "by this QEMU binary"));
virBufferFreeAndReset(&boot_buf);
goto error; goto error;
} }
@ -5645,10 +5647,13 @@ qemuBuildCommandLine(virConnectPtr conn,
if (boot_nparams < 2 || emitBootindex) { if (boot_nparams < 2 || emitBootindex) {
virCommandAddArgBuffer(cmd, &boot_buf); virCommandAddArgBuffer(cmd, &boot_buf);
virBufferFreeAndReset(&boot_buf);
} else { } else {
char *str = virBufferContentAndReset(&boot_buf);
virCommandAddArgFormat(cmd, virCommandAddArgFormat(cmd,
"order=%s", "order=%s",
virBufferContentAndReset(&boot_buf)); str);
VIR_FREE(str);
} }
} }
@ -7425,24 +7430,23 @@ qemuParseCommandLineDisk(virCapsPtr caps,
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot parse nbd filename '%s'"), _("cannot parse nbd filename '%s'"),
def->src); def->src);
def = NULL; goto error;
goto cleanup;
} }
*port++ = '\0'; *port++ = '\0';
if (VIR_ALLOC(def->hosts) < 0) { if (VIR_ALLOC(def->hosts) < 0) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto error;
} }
def->nhosts = 1; def->nhosts = 1;
def->hosts->name = strdup(host); def->hosts->name = strdup(host);
if (!def->hosts->name) { if (!def->hosts->name) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto error;
} }
def->hosts->port = strdup(port); def->hosts->port = strdup(port);
if (!def->hosts->port) { if (!def->hosts->port) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto error;
} }
def->hosts->transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP; def->hosts->transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP;
def->hosts->socket = NULL; def->hosts->socket = NULL;
@ -7457,7 +7461,7 @@ qemuParseCommandLineDisk(virCapsPtr caps,
def->src = strdup(p + strlen("rbd:")); def->src = strdup(p + strlen("rbd:"));
if (!def->src) { if (!def->src) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto error;
} }
/* old-style CEPH_ARGS env variable is parsed later */ /* old-style CEPH_ARGS env variable is parsed later */
if (!old_style_ceph_args && qemuParseRBDString(def) < 0) if (!old_style_ceph_args && qemuParseRBDString(def) < 0)
@ -7469,7 +7473,7 @@ qemuParseCommandLineDisk(virCapsPtr caps,
def->protocol = VIR_DOMAIN_DISK_PROTOCOL_GLUSTER; def->protocol = VIR_DOMAIN_DISK_PROTOCOL_GLUSTER;
if (qemuParseGlusterString(def) < 0) if (qemuParseGlusterString(def) < 0)
goto cleanup; goto error;
} else if (STRPREFIX(def->src, "sheepdog:")) { } else if (STRPREFIX(def->src, "sheepdog:")) {
char *p = def->src; char *p = def->src;
char *port, *vdi; char *port, *vdi;
@ -7479,7 +7483,7 @@ qemuParseCommandLineDisk(virCapsPtr caps,
def->src = strdup(p + strlen("sheepdog:")); def->src = strdup(p + strlen("sheepdog:"));
if (!def->src) { if (!def->src) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto error;
} }
/* def->src must be [vdiname] or [host]:[port]:[vdiname] */ /* def->src must be [vdiname] or [host]:[port]:[vdiname] */
@ -7488,29 +7492,28 @@ qemuParseCommandLineDisk(virCapsPtr caps,
*port++ = '\0'; *port++ = '\0';
vdi = strchr(port, ':'); vdi = strchr(port, ':');
if (!vdi) { if (!vdi) {
def = NULL;
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot parse sheepdog filename '%s'"), p); _("cannot parse sheepdog filename '%s'"), p);
goto cleanup; goto error;
} }
*vdi++ = '\0'; *vdi++ = '\0';
if (VIR_ALLOC(def->hosts) < 0) { if (VIR_ALLOC(def->hosts) < 0) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto error;
} }
def->nhosts = 1; def->nhosts = 1;
def->hosts->name = def->src; def->hosts->name = def->src;
def->hosts->port = strdup(port); def->hosts->port = strdup(port);
if (!def->hosts->port) { if (!def->hosts->port) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto error;
} }
def->hosts->transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP; def->hosts->transport = VIR_DOMAIN_DISK_PROTO_TRANS_TCP;
def->hosts->socket = NULL; def->hosts->socket = NULL;
def->src = strdup(vdi); def->src = strdup(vdi);
if (!def->src) { if (!def->src) {
virReportOOMError(); virReportOOMError();
goto cleanup; goto error;
} }
} }
@ -7538,13 +7541,10 @@ qemuParseCommandLineDisk(virCapsPtr caps,
} else if (STREQ(keywords[i], "format")) { } else if (STREQ(keywords[i], "format")) {
def->driverName = strdup("qemu"); def->driverName = strdup("qemu");
if (!def->driverName) { if (!def->driverName) {
virDomainDiskDefFree(def);
def = NULL;
virReportOOMError(); virReportOOMError();
goto cleanup; goto error;
} }
def->format = virStorageFileFormatTypeFromString(values[i]); def->format = virStorageFileFormatTypeFromString(values[i]);
values[i] = NULL;
} else if (STREQ(keywords[i], "cache")) { } else if (STREQ(keywords[i], "cache")) {
if (STREQ(values[i], "off") || if (STREQ(values[i], "off") ||
STREQ(values[i], "none")) STREQ(values[i], "none"))
@ -7576,27 +7576,21 @@ qemuParseCommandLineDisk(virCapsPtr caps,
def->rerror_policy = VIR_DOMAIN_DISK_ERROR_POLICY_IGNORE; def->rerror_policy = VIR_DOMAIN_DISK_ERROR_POLICY_IGNORE;
} else if (STREQ(keywords[i], "index")) { } else if (STREQ(keywords[i], "index")) {
if (virStrToLong_i(values[i], NULL, 10, &idx) < 0) { if (virStrToLong_i(values[i], NULL, 10, &idx) < 0) {
virDomainDiskDefFree(def);
def = NULL;
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot parse drive index '%s'"), val); _("cannot parse drive index '%s'"), val);
goto cleanup; goto error;
} }
} else if (STREQ(keywords[i], "bus")) { } else if (STREQ(keywords[i], "bus")) {
if (virStrToLong_i(values[i], NULL, 10, &busid) < 0) { if (virStrToLong_i(values[i], NULL, 10, &busid) < 0) {
virDomainDiskDefFree(def);
def = NULL;
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot parse drive bus '%s'"), val); _("cannot parse drive bus '%s'"), val);
goto cleanup; goto error;
} }
} else if (STREQ(keywords[i], "unit")) { } else if (STREQ(keywords[i], "unit")) {
if (virStrToLong_i(values[i], NULL, 10, &unitid) < 0) { if (virStrToLong_i(values[i], NULL, 10, &unitid) < 0) {
virDomainDiskDefFree(def);
def = NULL;
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot parse drive unit '%s'"), val); _("cannot parse drive unit '%s'"), val);
goto cleanup; goto error;
} }
} else if (STREQ(keywords[i], "readonly")) { } else if (STREQ(keywords[i], "readonly")) {
if ((values[i] == NULL) || STREQ(values[i], "on")) if ((values[i] == NULL) || STREQ(values[i], "on"))
@ -7655,9 +7649,7 @@ qemuParseCommandLineDisk(virCapsPtr caps,
def->type != VIR_DOMAIN_DISK_TYPE_NETWORK) { def->type != VIR_DOMAIN_DISK_TYPE_NETWORK) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("missing file parameter in drive '%s'"), val); _("missing file parameter in drive '%s'"), val);
virDomainDiskDefFree(def); goto error;
def = NULL;
goto cleanup;
} }
if (idx == -1 && if (idx == -1 &&
def->bus == VIR_DOMAIN_DISK_BUS_VIRTIO) def->bus == VIR_DOMAIN_DISK_BUS_VIRTIO)
@ -7667,10 +7659,9 @@ qemuParseCommandLineDisk(virCapsPtr caps,
unitid == -1 && unitid == -1 &&
busid == -1) { busid == -1) {
virReportError(VIR_ERR_INTERNAL_ERROR, virReportError(VIR_ERR_INTERNAL_ERROR,
_("missing index/unit/bus parameter in drive '%s'"), val); _("missing index/unit/bus parameter in drive '%s'"),
virDomainDiskDefFree(def); val);
def = NULL; goto error;
goto cleanup;
} }
if (idx == -1) { if (idx == -1) {
@ -7704,10 +7695,8 @@ qemuParseCommandLineDisk(virCapsPtr caps,
} }
if (!def->dst) { if (!def->dst) {
virDomainDiskDefFree(def);
def = NULL;
virReportOOMError(); virReportOOMError();
goto cleanup; goto error;
} }
if (STREQ(def->dst, "xvda")) if (STREQ(def->dst, "xvda"))
def->dst[3] = 'a' + idx; def->dst[3] = 'a' + idx;
@ -7730,6 +7719,11 @@ cleanup:
VIR_FREE(keywords); VIR_FREE(keywords);
VIR_FREE(values); VIR_FREE(values);
return def; return def;
error:
virDomainDiskDefFree(def);
def = NULL;
goto cleanup;
} }
/* /*