From e880fc334edb8d07593679cf0c6a9af810c51d0d Mon Sep 17 00:00:00 2001 From: Jiahui Cen <cenjiahui@huawei.com> Date: Thu, 18 Mar 2021 19:45:11 +0800 Subject: [PATCH] block: Add sanity check when setting retry parameters Add sanity check when setting retry parameters to avoid invalid retry configuration. Signed-off-by: Jiahui Cen <cenjiahui@huawei.com> Signed-off-by: Alex Chen <alex.chen@huawei.com> --- hw/core/qdev-prop-internal.h | 2 ++ hw/core/qdev-properties-system.c | 45 +++++++++++++++++++++++++++++ hw/core/qdev-properties.c | 4 +-- include/hw/block/block.h | 7 +++-- include/hw/qdev-properties-system.h | 8 +++++ 5 files changed, 61 insertions(+), 5 deletions(-) diff --git a/hw/core/qdev-prop-internal.h b/hw/core/qdev-prop-internal.h index d7b77844fe..68b1b9d10c 100644 --- a/hw/core/qdev-prop-internal.h +++ b/hw/core/qdev-prop-internal.h @@ -22,6 +22,8 @@ void qdev_propinfo_set_default_value_uint(ObjectProperty *op, void qdev_propinfo_get_int32(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp); +void qdev_propinfo_get_int64(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp); void qdev_propinfo_get_size32(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp); diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index 1473ab3d5e..f2e2718c74 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -635,6 +635,51 @@ const PropertyInfo qdev_prop_blockdev_on_error = { .set_default_value = qdev_propinfo_set_default_value_enum, }; +static void set_retry_time(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + int64_t value, *ptr = object_field_prop_ptr(obj, prop); + Error *local_err = NULL; + + if (dev->realized) { + qdev_prop_set_after_realize(dev, name, errp); + return; + } + + visit_type_int64(v, name, &value, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + /* value should not be negative */ + if (value < 0) { + error_setg(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, + dev->id ? : "", name, (int64_t)value, 0L, LONG_MAX); + return; + } + + *ptr = value; +} + +const PropertyInfo qdev_prop_blockdev_retry_interval = { + .name = "BlockdevRetryInterval", + .description = "Interval for retry error handling policy", + .get = qdev_propinfo_get_int64, + .set = set_retry_time, + .set_default_value = qdev_propinfo_set_default_value_int, +}; + +const PropertyInfo qdev_prop_blockdev_retry_timeout = { + .name = "BlockdevRetryTimeout", + .description = "Timeout for retry error handling policy", + .get = qdev_propinfo_get_int64, + .set = set_retry_time, + .set_default_value = qdev_propinfo_set_default_value_int, +}; + /* --- BIOS CHS translation */ QEMU_BUILD_BUG_ON(sizeof(BiosAtaTranslation) != sizeof(int)); diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index 840006e953..19b7450b4d 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -398,7 +398,7 @@ static void set_uint64(Object *obj, Visitor *v, const char *name, visit_type_uint64(v, name, ptr, errp); } -static void get_int64(Object *obj, Visitor *v, const char *name, +void qdev_propinfo_get_int64(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { Property *prop = opaque; @@ -425,7 +425,7 @@ const PropertyInfo qdev_prop_uint64 = { const PropertyInfo qdev_prop_int64 = { .name = "int64", - .get = get_int64, + .get = qdev_propinfo_get_int64, .set = set_int64, .set_default_value = qdev_propinfo_set_default_value_int, }; diff --git a/include/hw/block/block.h b/include/hw/block/block.h index fb8c0df4a5..844e87495a 100644 --- a/include/hw/block/block.h +++ b/include/hw/block/block.h @@ -87,9 +87,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf) BLOCKDEV_ON_ERROR_AUTO), \ DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror, \ BLOCKDEV_ON_ERROR_AUTO), \ - DEFINE_PROP_INT64("retry_interval", _state, _conf.retry_interval, \ - -1), \ - DEFINE_PROP_INT64("retry_timeout", _state, _conf.retry_timeout, -1) + DEFINE_PROP_BLOCKDEV_RETRY_INTERVAL("retry_interval", _state, \ + _conf.retry_interval, 1000), \ + DEFINE_PROP_BLOCKDEV_RETRY_TIMEOUT("retry_timeout", _state, \ + _conf.retry_timeout, 0) /* Backend access helpers */ diff --git a/include/hw/qdev-properties-system.h b/include/hw/qdev-properties-system.h index 91f7a2452d..7cf27e51b9 100644 --- a/include/hw/qdev-properties-system.h +++ b/include/hw/qdev-properties-system.h @@ -10,6 +10,8 @@ extern const PropertyInfo qdev_prop_multifd_compression; extern const PropertyInfo qdev_prop_mig_mode; extern const PropertyInfo qdev_prop_losttickpolicy; extern const PropertyInfo qdev_prop_blockdev_on_error; +extern const PropertyInfo qdev_prop_blockdev_retry_interval; +extern const PropertyInfo qdev_prop_blockdev_retry_timeout; extern const PropertyInfo qdev_prop_bios_chs_trans; extern const PropertyInfo qdev_prop_fdc_drive_type; extern const PropertyInfo qdev_prop_drive; @@ -52,6 +54,12 @@ extern const PropertyInfo qdev_prop_cpus390entitlement; #define DEFINE_PROP_BLOCKDEV_ON_ERROR(_n, _s, _f, _d) \ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_on_error, \ BlockdevOnError) +#define DEFINE_PROP_BLOCKDEV_RETRY_INTERVAL(_n, _s, _f, _d) \ + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_retry_interval, \ + int64_t) +#define DEFINE_PROP_BLOCKDEV_RETRY_TIMEOUT(_n, _s, _f, _d) \ + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_blockdev_retry_timeout, \ + int64_t) #define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int) #define DEFINE_PROP_BLOCKSIZE(_n, _s, _f) \ -- 2.27.0