mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-30 18:50:18 +03:00
qemu: block: Support block disk along with throttle filters
For hot attaching/detaching * Leverage qemuBlockThrottleFiltersData to prepare attaching/detaching throttle filter data for qemuMonitorBlockdevAdd and qemuMonitorBlockdevDel * For hot attaching, within qemuDomainAttachDiskGeneric,prepare throttle filters json data, and create corresponding blockdev for QMP request ("blockdev-add" with "driver":"throttle") * Each filter has a nodename, and those filters are chained up, create them in sequence, and delete them reversely * Delete filters by "qemuBlockThrottleFiltersDetach"("blockdev-del") when detaching device For throttle group commandline * Add qemuBuildThrottleGroupCommandLine in qemuBuildCommandLine to add "object" of throttle-group * Verify throttle group definition when lauching vm * Check QEMU_CAPS_OBJECT_JSON before "qemuBuildObjectCommandlineFromJSON", which is to build "-object" option For throttle filter commandline * Add qemuBuildDiskThrottleFiltersCommandLine in qemuBuildDiskCommandLine to add "blockdev" Signed-off-by: Chun Feng Wu <danielwuwy@163.com> * Apply suggested coding style changes. * Update of code documentation comments. Signed-off-by: Harikumar Rajkumar <harirajkumar230@gmail.com> * Removed QEMU_CAPS_OBJECT_JSON_CHECK Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
80307f4823
commit
9a6560f066
@ -2033,6 +2033,90 @@ qemuBuildBlockStorageSourceAttachDataCommandline(virCommand *cmd,
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
qemuDiskConfigThrottleGroupEnabled(const virDomainThrottleGroupDef *group)
|
||||
{
|
||||
return !!group->group_name &&
|
||||
virDomainBlockIoTuneInfoHasAny(group);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* qemuBuildThrottleGroupCommandLine:
|
||||
* @cmd: the command to modify
|
||||
* @def: domain definition
|
||||
*
|
||||
* build throttle group object in json format
|
||||
*/
|
||||
static int
|
||||
qemuBuildThrottleGroupCommandLine(virCommand *cmd,
|
||||
const virDomainDef *def)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < def->nthrottlegroups; i++) {
|
||||
g_autoptr(virJSONValue) props = NULL;
|
||||
g_autoptr(virJSONValue) limits = virJSONValueNewObject();
|
||||
virDomainThrottleGroupDef *group = def->throttlegroups[i];
|
||||
/* prefix group name with "throttle-" in QOM */
|
||||
g_autofree char *prefixed_group_name = g_strdup_printf("throttle-%s", group->group_name);
|
||||
|
||||
if (!qemuDiskConfigThrottleGroupEnabled(group))
|
||||
continue;
|
||||
|
||||
if (qemuMonitorThrottleGroupLimits(limits, group) < 0)
|
||||
return -1;
|
||||
|
||||
if (qemuMonitorCreateObjectProps(&props, "throttle-group", prefixed_group_name,
|
||||
"a:limits", &limits,
|
||||
NULL) < 0)
|
||||
return -1;
|
||||
|
||||
if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuBuildBlockThrottleFilterCommandline(virCommand *cmd,
|
||||
qemuBlockThrottleFilterAttachData *data)
|
||||
{
|
||||
if (data->filterProps) {
|
||||
g_autofree char *tmp = NULL;
|
||||
if (!(tmp = virJSONValueToString(data->filterProps, false)))
|
||||
return -1;
|
||||
|
||||
virCommandAddArgList(cmd, "-blockdev", tmp, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuBuildDiskThrottleFiltersCommandLine(virCommand *cmd,
|
||||
virDomainDiskDef *disk)
|
||||
{
|
||||
g_autoptr(qemuBlockThrottleFiltersData) data = NULL;
|
||||
size_t i;
|
||||
|
||||
data = qemuBuildThrottleFiltersAttachPrepareBlockdev(disk);
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < data->nfilterdata; i++) {
|
||||
if (qemuBuildBlockThrottleFilterCommandline(cmd,
|
||||
data->filterdata[i]) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
qemuBuildDiskSourceCommandLine(virCommand *cmd,
|
||||
virDomainDiskDef *disk,
|
||||
@ -2090,6 +2174,9 @@ qemuBuildDiskCommandLine(virCommand *cmd,
|
||||
if (qemuBuildDiskSourceCommandLine(cmd, disk, qemuCaps) < 0)
|
||||
return -1;
|
||||
|
||||
if (qemuBuildDiskThrottleFiltersCommandLine(cmd, disk) < 0)
|
||||
return -1;
|
||||
|
||||
/* SD cards are currently instantiated via -drive if=sd, so the -device
|
||||
* part must be skipped */
|
||||
if (qemuDiskBusIsSD(disk->bus))
|
||||
@ -10463,6 +10550,9 @@ qemuBuildCommandLine(virDomainObj *vm,
|
||||
if (qemuBuildIOThreadCommandLine(cmd, def) < 0)
|
||||
return NULL;
|
||||
|
||||
if (qemuBuildThrottleGroupCommandLine(cmd, def) < 0)
|
||||
return NULL;
|
||||
|
||||
if (virDomainNumaGetNodeCount(def->numa) &&
|
||||
qemuBuildNumaCommandLine(cfg, def, cmd, priv) < 0)
|
||||
return NULL;
|
||||
|
@ -701,6 +701,7 @@ qemuDomainAttachDiskGeneric(virDomainObj *vm,
|
||||
virDomainAsyncJob asyncJob)
|
||||
{
|
||||
g_autoptr(qemuBlockStorageSourceChainData) data = NULL;
|
||||
g_autoptr(qemuBlockThrottleFiltersData) filterData = NULL;
|
||||
qemuDomainObjPrivate *priv = vm->privateData;
|
||||
g_autoptr(virJSONValue) devprops = NULL;
|
||||
bool extensionDeviceAttached = false;
|
||||
@ -739,6 +740,15 @@ qemuDomainAttachDiskGeneric(virDomainObj *vm,
|
||||
if (rc < 0)
|
||||
goto rollback;
|
||||
|
||||
if ((filterData = qemuBuildThrottleFiltersAttachPrepareBlockdev(disk))) {
|
||||
if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0)
|
||||
return -1;
|
||||
rc = qemuBlockThrottleFiltersAttach(priv->mon, filterData);
|
||||
qemuDomainObjExitMonitor(vm);
|
||||
if (rc < 0)
|
||||
goto rollback;
|
||||
}
|
||||
|
||||
if (disk->transient) {
|
||||
g_autoptr(qemuBlockStorageSourceAttachData) backend = NULL;
|
||||
g_autoptr(GHashTable) blockNamedNodeData = NULL;
|
||||
@ -810,6 +820,8 @@ qemuDomainAttachDiskGeneric(virDomainObj *vm,
|
||||
if (extensionDeviceAttached)
|
||||
ignore_value(qemuDomainDetachExtensionDevice(priv->mon, &disk->info));
|
||||
|
||||
qemuBlockThrottleFiltersDetach(priv->mon, filterData);
|
||||
|
||||
qemuBlockStorageSourceChainDetach(priv->mon, data);
|
||||
|
||||
qemuDomainObjExitMonitor(vm);
|
||||
@ -4727,6 +4739,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriver *driver,
|
||||
{
|
||||
qemuDomainDiskPrivate *diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
|
||||
g_autoptr(qemuBlockStorageSourceChainData) diskBackend = NULL;
|
||||
g_autoptr(qemuBlockThrottleFiltersData) filterData = NULL;
|
||||
size_t i;
|
||||
qemuDomainObjPrivate *priv = vm->privateData;
|
||||
int ret = -1;
|
||||
@ -4767,6 +4780,9 @@ qemuDomainRemoveDiskDevice(virQEMUDriver *driver,
|
||||
|
||||
qemuDomainObjEnterMonitor(vm);
|
||||
|
||||
if ((filterData = qemuBuildThrottleFiltersDetachPrepareBlockdev(disk)))
|
||||
qemuBlockThrottleFiltersDetach(priv->mon, filterData);
|
||||
|
||||
if (diskBackend)
|
||||
qemuBlockStorageSourceChainDetach(priv->mon, diskBackend);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user