1
0
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:
Chun Feng Wu 2025-02-19 22:27:15 +05:30 committed by Peter Krempa
parent 80307f4823
commit 9a6560f066
2 changed files with 106 additions and 0 deletions

View File

@ -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;

View File

@ -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);