On Wed, Feb 19, 2025 at 22:27:16 +0530, Harikumar Rajkumar wrote: > From: Chun Feng Wu <danielw...@163.com> > > Refactor iotune verification, and verify some rules > > * Disk iotune validation can be reused for throttle group validation, > refactor it into common method "virDomainDiskIoTuneValidate" > * Add "virDomainDefValidateThrottleGroups" to validate throttle groups, > which in turn calls "virDomainDiskIoTuneValidate" > * Make sure referenced throttle group exists > * Use "iotune" and "throttlefilters" exclusively for specific disk > * Throttle filters cannot be used together with CDROM > > Signed-off-by: Chun Feng Wu <danielw...@163.com> > > * Update of code documentation comments. > > Signed-off-by: Harikumar Rajkumar <harirajkumar...@gmail.com> > --- > src/conf/domain_conf.c | 8 +++ > src/conf/domain_validate.c | 118 ++++++++++++++++++++++++++----------- > src/qemu/qemu_driver.c | 13 ++++ > src/qemu/qemu_hotplug.c | 8 +++ > 4 files changed, 113 insertions(+), 34 deletions(-) > > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index 303aa7d1ae..0cc318d1f9 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -8008,6 +8008,14 @@ virDomainDiskDefThrottleFiltersParse(virDomainDiskDef > *def, > if ((n = virXPathNodeSet("./throttlefilters/throttlefilter", ctxt, > &nodes)) < 0) > return -1; > > + if (def->device == VIR_DOMAIN_DISK_DEVICE_CDROM) { > + if (n > 0) { > + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", > + _("cdrom device with throttle filters isn't > supported")); > + return -1; > + } > + }
Normally adding any form of validation into the parser is not allowed because it makes VMs vanish. as this is happening in hthe same series it's technically allowable, but ... > + > if (n) > def->throttlefilters = g_new0(virDomainThrottleFilterDef *, n); > > diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c > index 563558d920..d51682d155 100644 > --- a/src/conf/domain_validate.c > +++ b/src/conf/domain_validate.c > @@ -685,11 +685,55 @@ virDomainDiskDefValidateStartupPolicy(const > virDomainDiskDef *disk) > } > > > +static int > +virDomainDiskIoTuneValidate(const virDomainBlockIoTuneInfo blkdeviotune) > +{ > + if ((blkdeviotune.total_bytes_sec && > + blkdeviotune.read_bytes_sec) || > + (blkdeviotune.total_bytes_sec && > + blkdeviotune.write_bytes_sec)) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("total and read/write bytes_sec cannot be set at > the same time")); > + return -1; > + } > + > + if ((blkdeviotune.total_iops_sec && > + blkdeviotune.read_iops_sec) || > + (blkdeviotune.total_iops_sec && > + blkdeviotune.write_iops_sec)) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("total and read/write iops_sec cannot be set at the > same time")); > + return -1; > + } > + > + if ((blkdeviotune.total_bytes_sec_max && > + blkdeviotune.read_bytes_sec_max) || > + (blkdeviotune.total_bytes_sec_max && > + blkdeviotune.write_bytes_sec_max)) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("total and read/write bytes_sec_max cannot be set > at the same time")); > + return -1; > + } > + > + if ((blkdeviotune.total_iops_sec_max && > + blkdeviotune.read_iops_sec_max) || > + (blkdeviotune.total_iops_sec_max && > + blkdeviotune.write_iops_sec_max)) { > + virReportError(VIR_ERR_XML_ERROR, "%s", > + _("total and read/write iops_sec_max cannot be set at > the same time")); > + return -1; > + } > + > + return 0; > +} > + > + > static int > virDomainDiskDefValidate(const virDomainDef *def, > const virDomainDiskDef *disk) > { > virStorageSource *next; > + size_t i; > > /* disk target is used widely in other code so it must be validated > first */ > if (!disk->dst) { > @@ -739,41 +783,8 @@ virDomainDiskDefValidate(const virDomainDef *def, > } > > /* Validate IotuneParse */ > - if ((disk->blkdeviotune.total_bytes_sec && > - disk->blkdeviotune.read_bytes_sec) || > - (disk->blkdeviotune.total_bytes_sec && > - disk->blkdeviotune.write_bytes_sec)) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("total and read/write bytes_sec cannot be set at > the same time")); > + if (virDomainDiskIoTuneValidate(disk->blkdeviotune) < 0) > return -1; > - } > - > - if ((disk->blkdeviotune.total_iops_sec && > - disk->blkdeviotune.read_iops_sec) || > - (disk->blkdeviotune.total_iops_sec && > - disk->blkdeviotune.write_iops_sec)) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("total and read/write iops_sec cannot be set at the > same time")); > - return -1; > - } > - > - if ((disk->blkdeviotune.total_bytes_sec_max && > - disk->blkdeviotune.read_bytes_sec_max) || > - (disk->blkdeviotune.total_bytes_sec_max && > - disk->blkdeviotune.write_bytes_sec_max)) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("total and read/write bytes_sec_max cannot be set > at the same time")); > - return -1; > - } > - > - if ((disk->blkdeviotune.total_iops_sec_max && > - disk->blkdeviotune.read_iops_sec_max) || > - (disk->blkdeviotune.total_iops_sec_max && > - disk->blkdeviotune.write_iops_sec_max)) { > - virReportError(VIR_ERR_XML_ERROR, "%s", > - _("total and read/write iops_sec_max cannot be set at > the same time")); > - return -1; > - } > > /* Reject disks with a bus type that is not compatible with the > * given address type. The function considers only buses that are > @@ -974,6 +985,26 @@ virDomainDiskDefValidate(const virDomainDef *def, > return -1; > } > > + /* referenced group should be defined */ > + for (i = 0; i < disk->nthrottlefilters; i++) { > + virDomainThrottleFilterDef *filter = disk->throttlefilters[i]; > + if (!virDomainThrottleGroupByName(def, filter->group_name)) { > + virReportError(VIR_ERR_XML_ERROR, > + _("throttle group '%1$s' not found"), > + filter->group_name); > + return -1; > + } > + } > + > + if (disk->throttlefilters && > + (disk->blkdeviotune.group_name || > + virDomainBlockIoTuneInfoHasAny(&disk->blkdeviotune))) { > + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, > + _("block 'throttlefilters' can't be used together > with 'iotune' for disk '%1$s'"), > + disk->dst); > + return -1; ... really belongs here into the validation code. > + } > + > return 0; > } > > @@ -1874,6 +1905,22 @@ virDomainDefLaunchSecurityValidate(const virDomainDef > *def) > > #undef CHECK_BASE64_LEN > > +static int > +virDomainDefValidateThrottleGroups(const virDomainDef *def) > +{ > + size_t i; > + > + for (i = 0; i < def->nthrottlegroups; i++) { > + virDomainThrottleGroupDef *throttleGroup = def->throttlegroups[i]; > + > + if (virDomainDiskIoTuneValidate(*throttleGroup) < 0) > + return -1; > + } > + > + return 0; > +} > + > + > static int > virDomainDefValidateInternal(const virDomainDef *def, > virDomainXMLOption *xmlopt) > @@ -1932,6 +1979,9 @@ virDomainDefValidateInternal(const virDomainDef *def, > if (virDomainDefLaunchSecurityValidate(def) < 0) > return -1; > > + if (virDomainDefValidateThrottleGroups(def) < 0) > + return -1; > + > return 0; > } > > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index afb41a4c89..6b1e8d01e0 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -6703,6 +6703,13 @@ qemuDomainAttachDeviceConfig(virDomainDef *vmdef, > _("target %1$s already exists"), disk->dst); > return -1; > } > + if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) { > + if (disk->nthrottlefilters > 0) { > + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", > + _("cdrom device with throttle filters isn't > supported")); > + return -1; This is dead code, the validation refuses this. > + } > + } > if (virDomainDiskTranslateSourcePool(disk) < 0) > return -1; > if (qemuCheckDiskConfigAgainstDomain(vmdef, disk) < 0) > @@ -14861,6 +14868,12 @@ > qemuDomainDiskBlockIoTuneIsSupported(virDomainDiskDef *disk) > return false; > } > > + if (disk->throttlefilters) { > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, > + _("block 'iotune' can't be used together with > 'throttlefilters' for disk '%1$s'"), disk->dst); > + return false; > + } > + > return true; > } > > diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c > index 75437164ca..ff29cd55f4 100644 > --- a/src/qemu/qemu_hotplug.c > +++ b/src/qemu/qemu_hotplug.c > @@ -985,6 +985,14 @@ qemuDomainAttachDeviceDiskLiveInternal(virQEMUDriver > *driver, > bool releaseSeclabel = false; > int ret = -1; > > + if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) { > + if (disk->nthrottlefilters > 0) { > + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", > + _("cdrom device with throttle filters isn't > supported")); > + return -1; > + } > + } Dead code. > + > if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) { > virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", > _("floppy device hotplug isn't supported")); > -- > 2.39.5 (Apple Git-154) >