提交 22cf6d46 编写于 作者: E Eric Blake

qemu: amend existing table of device weights

Prior to this patch, for a running dom, the commands:

$ virsh blkiotune dom --device-weights /dev/sda,502,/dev/sdb,498
$ virsh blkiotune dom --device-weights /dev/sda,503
$ virsh blkiotune dom
weight         : 500
device_weight  : /dev/sda,503

claim that /dev/sdb no longer has a non-default weight, but
directly querying cgroups says otherwise:

$ cat /cgroup/blkio/libvirt/qemu/dom/blkio.weight_device
8:0     503
8:16    498

After this patch, an explicit 0 is required to remove a device path
from the XML, and omitting a device path that was previously
specified leaves that device path untouched in the XML, to match
cgroups behavior.

* src/qemu/qemu_driver.c (parseBlkioWeightDeviceStr): Rename...
(qemuDomainParseDeviceWeightStr): ...and use correct type.
(qemuDomainSetBlkioParameters): After parsing string, modify
rather than replacing existing table.
* tools/virsh.pod (blkiotune): Tweak wording.
上级 9b524ff0
......@@ -5890,8 +5890,8 @@ cleanup:
* for example, /dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0,800
*/
static int
parseBlkioWeightDeviceStr(char *deviceWeightStr,
virBlkioDeviceWeightPtr *dw, int *size)
qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
virBlkioDeviceWeightPtr *dw, size_t *size)
{
char *temp;
int ndevices = 0;
......@@ -5968,6 +5968,41 @@ cleanup:
return -1;
}
/* Modify def to reflect all device weight changes described in tmp. */
static int
qemuDomainMergeDeviceWeights(virBlkioDeviceWeightPtr *def, size_t *def_size,
virBlkioDeviceWeightPtr tmp, size_t tmp_size)
{
int i, j;
virBlkioDeviceWeightPtr dw;
for (i = 0; i < tmp_size; i++) {
bool found = false;
dw = &tmp[i];
for (j = 0; j < *def_size; j++) {
if (STREQ(dw->path, (*def)[j].path)) {
found = true;
(*def)[j].weight = dw->weight;
break;
}
}
if (!found) {
if (!dw->weight)
continue;
if (VIR_EXPAND_N(*def, *def_size, 1) < 0) {
virReportOOMError();
return -1;
}
(*def)[*def_size - 1].path = dw->path;
(*def)[*def_size - 1].weight = dw->weight;
dw->path = NULL;
}
}
return 0;
}
static int qemuDomainSetBlkioParameters(virDomainPtr dom,
virTypedParameterPtr params,
int nparams,
......@@ -6059,7 +6094,7 @@ static int qemuDomainSetBlkioParameters(virDomainPtr dom,
ret = -1;
}
} else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
int ndevices;
size_t ndevices;
virBlkioDeviceWeightPtr devices = NULL;
if (param->type != VIR_TYPED_PARAM_STRING) {
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
......@@ -6069,9 +6104,9 @@ static int qemuDomainSetBlkioParameters(virDomainPtr dom,
continue;
}
if (parseBlkioWeightDeviceStr(params[i].value.s,
&devices,
&ndevices) < 0) {
if (qemuDomainParseDeviceWeightStr(params[i].value.s,
&devices,
&ndevices) < 0) {
ret = -1;
continue;
}
......@@ -6091,14 +6126,16 @@ static int qemuDomainSetBlkioParameters(virDomainPtr dom,
ret = -1;
continue;
}
virBlkioDeviceWeightArrayClear(vm->def->blkio.devices,
vm->def->blkio.ndevices);
VIR_FREE(vm->def->blkio.devices);
vm->def->blkio.devices = devices;
vm->def->blkio.ndevices = ndevices;
if (qemuDomainMergeDeviceWeights(&vm->def->blkio.devices,
&vm->def->blkio.ndevices,
devices, ndevices) < 0)
ret = -1;
virBlkioDeviceWeightArrayClear(devices, ndevices);
VIR_FREE(devices);
} else {
qemuReportError(VIR_ERR_INVALID_ARG,
_("Parameter `%s' not supported"), param->field);
_("Parameter `%s' not supported"),
param->field);
ret = -1;
}
}
......@@ -6130,7 +6167,7 @@ static int qemuDomainSetBlkioParameters(virDomainPtr dom,
persistentDef->blkio.weight = params[i].value.ui;
} else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
virBlkioDeviceWeightPtr devices = NULL;
int ndevices;
size_t ndevices;
if (param->type != VIR_TYPED_PARAM_STRING) {
qemuReportError(VIR_ERR_INVALID_ARG, "%s",
_("invalid type for device_weight tunable, "
......@@ -6138,17 +6175,18 @@ static int qemuDomainSetBlkioParameters(virDomainPtr dom,
ret = -1;
continue;
}
if (parseBlkioWeightDeviceStr(params[i].value.s,
&devices,
&ndevices) < 0) {
if (qemuDomainParseDeviceWeightStr(params[i].value.s,
&devices,
&ndevices) < 0) {
ret = -1;
continue;
}
virBlkioDeviceWeightArrayClear(persistentDef->blkio.devices,
persistentDef->blkio.ndevices);
VIR_FREE(persistentDef->blkio.devices);
persistentDef->blkio.devices = devices;
persistentDef->blkio.ndevices = ndevices;
if (qemuDomainMergeDeviceWeights(&vm->def->blkio.devices,
&vm->def->blkio.ndevices,
devices, ndevices) < 0)
ret = -1;
virBlkioDeviceWeightArrayClear(devices, ndevices);
VIR_FREE(devices);
} else {
qemuReportError(VIR_ERR_INVALID_ARG,
_("Parameter `%s' not supported"),
......
......@@ -1085,7 +1085,9 @@ I<--weight> is in range [100, 1000].
B<device-weights> is a single string listing one or more device/weight
pairs, in the format of /path/to/device,weight,/path/to/device,weight.
Each weight is in the range [100, 1000], or the value 0 to remove that
device from per-device listings.
device from per-device listings. Only the devices listed in the string
are modified; any existing per-device weights for other devices remain
unchanged.
If I<--live> is specified, affect a running guest.
If I<--config> is specified, affect the next boot of a persistent guest.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册