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:
parent
7af7c42d05
commit
890b6b351f
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user