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

Reply via email to