Fix vmdef usage while in monitor in BlockStat* APIs

Make a local copy of the disk alias instead of pointing
to the domain definition, which might get freed if
the domain dies while we're in monitor.

Also exit early if that happens.
This commit is contained in:
Ján Tomko 2015-01-07 14:35:49 +01:00
parent 051add2ff9
commit 3f21398437

View File

@ -10123,6 +10123,7 @@ qemuDomainBlockStats(virDomainPtr dom,
virDomainObjPtr vm; virDomainObjPtr vm;
virDomainDiskDefPtr disk = NULL; virDomainDiskDefPtr disk = NULL;
qemuDomainObjPrivatePtr priv; qemuDomainObjPrivatePtr priv;
char *diskAlias = NULL;
if (!*path) { if (!*path) {
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
@ -10158,11 +10159,14 @@ qemuDomainBlockStats(virDomainPtr dom,
goto endjob; goto endjob;
} }
if (VIR_STRDUP(diskAlias, disk->info.alias) < 0)
goto endjob;
priv = vm->privateData; priv = vm->privateData;
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorGetBlockStatsInfo(priv->mon, ret = qemuMonitorGetBlockStatsInfo(priv->mon,
disk->info.alias, diskAlias,
&stats->rd_req, &stats->rd_req,
&stats->rd_bytes, &stats->rd_bytes,
NULL, NULL,
@ -10172,13 +10176,15 @@ qemuDomainBlockStats(virDomainPtr dom,
NULL, NULL,
NULL, NULL,
&stats->errs); &stats->errs);
qemuDomainObjExitMonitor(driver, vm); if (qemuDomainObjExitMonitor(driver, vm) < 0)
ret = -1;
endjob: endjob:
qemuDomainObjEndJob(driver, vm); qemuDomainObjEndJob(driver, vm);
cleanup: cleanup:
qemuDomObjEndAPI(&vm); qemuDomObjEndAPI(&vm);
VIR_FREE(diskAlias);
return ret; return ret;
} }
@ -10194,11 +10200,11 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,
int idx; int idx;
int tmp, ret = -1; int tmp, ret = -1;
virDomainObjPtr vm; virDomainObjPtr vm;
virDomainDiskDefPtr disk = NULL;
qemuDomainObjPrivatePtr priv; qemuDomainObjPrivatePtr priv;
long long rd_req, rd_bytes, wr_req, wr_bytes, rd_total_times; long long rd_req, rd_bytes, wr_req, wr_bytes, rd_total_times;
long long wr_total_times, flush_req, flush_total_times, errs; long long wr_total_times, flush_req, flush_total_times, errs;
virTypedParameterPtr param; virTypedParameterPtr param;
char *diskAlias = NULL;
virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1); virCheckFlags(VIR_TYPED_PARAM_STRING_OKAY, -1);
@ -10227,6 +10233,7 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,
} }
if (*nparams != 0) { if (*nparams != 0) {
virDomainDiskDefPtr disk = NULL;
if ((idx = virDomainDiskIndexByName(vm->def, path, false)) < 0) { if ((idx = virDomainDiskIndexByName(vm->def, path, false)) < 0) {
virReportError(VIR_ERR_INVALID_ARG, virReportError(VIR_ERR_INVALID_ARG,
_("invalid path: %s"), path); _("invalid path: %s"), path);
@ -10240,6 +10247,8 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,
disk->dst); disk->dst);
goto endjob; goto endjob;
} }
if (VIR_STRDUP(diskAlias, disk->info.alias) < 0)
goto endjob;
} }
priv = vm->privateData; priv = vm->privateData;
@ -10250,12 +10259,12 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,
ret = qemuMonitorGetBlockStatsParamsNumber(priv->mon, nparams); ret = qemuMonitorGetBlockStatsParamsNumber(priv->mon, nparams);
if (tmp == 0 || ret < 0) { if (tmp == 0 || ret < 0) {
qemuDomainObjExitMonitor(driver, vm); ignore_value(qemuDomainObjExitMonitor(driver, vm));
goto endjob; goto endjob;
} }
ret = qemuMonitorGetBlockStatsInfo(priv->mon, ret = qemuMonitorGetBlockStatsInfo(priv->mon,
disk->info.alias, diskAlias,
&rd_req, &rd_req,
&rd_bytes, &rd_bytes,
&rd_total_times, &rd_total_times,
@ -10266,7 +10275,8 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,
&flush_total_times, &flush_total_times,
&errs); &errs);
qemuDomainObjExitMonitor(driver, vm); if (qemuDomainObjExitMonitor(driver, vm) < 0)
ret = -1;
if (ret < 0) if (ret < 0)
goto endjob; goto endjob;
@ -10351,6 +10361,7 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,
qemuDomainObjEndJob(driver, vm); qemuDomainObjEndJob(driver, vm);
cleanup: cleanup:
VIR_FREE(diskAlias);
qemuDomObjEndAPI(&vm); qemuDomObjEndAPI(&vm);
return ret; return ret;
} }
@ -16867,7 +16878,8 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
qemuDomainObjEnterMonitor(driver, vm); qemuDomainObjEnterMonitor(driver, vm);
ret = qemuMonitorSetBlockIoThrottle(priv->mon, device, ret = qemuMonitorSetBlockIoThrottle(priv->mon, device,
&info, supportMaxOptions); &info, supportMaxOptions);
qemuDomainObjExitMonitor(driver, vm); if (qemuDomainObjExitMonitor(driver, vm) < 0)
ret = -1;
if (ret < 0) if (ret < 0)
goto endjob; goto endjob;
vm->def->disks[idx]->blkdeviotune = info; vm->def->disks[idx]->blkdeviotune = info;