computing-offload/generic_vdpa/qemu/block-Add-error-retry-param-setting.patch
jiangdongxu 79c4324644 add generic_vdpa basecode
Change-Id: I2d302dda68298877c65c99147f5bf22186a59aac
2024-09-19 17:19:46 +08:00

228 lines
8.5 KiB
Diff

From a58fda7b158441c645e143bf658d12914ffbc7b8 Mon Sep 17 00:00:00 2001
From: Jiahui Cen <cenjiahui@huawei.com>
Date: Thu, 21 Jan 2021 15:46:50 +0800
Subject: [PATCH 6/7] block: Add error retry param setting
Add "retry_interval" and "retry_timeout" parameter for drive and device
option. These parameter are valid only when werror/rerror=retry.
eg. --drive file=image,rerror=retry,retry_interval=1000,retry_timeout=5000
Signed-off-by: Jiahui Cen <cenjiahui(a)huawei.com>
Signed-off-by: Ying Fang <fangying1(a)huawei.com>
Signed-off-by: Alex Chen <alex.chen@huawei.com>
---
block/block-backend.c | 13 +++++++--
blockdev.c | 50 ++++++++++++++++++++++++++++++++++
hw/block/block.c | 10 +++++++
include/hw/block/block.h | 7 ++++-
include/sysemu/block-backend.h | 5 ++++
5 files changed, 81 insertions(+), 4 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 37e21c473e..d3d90a95a5 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -35,9 +35,6 @@
static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb);
-/* block backend default retry interval */
-#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000
-
typedef struct BlockBackendAioNotifier {
void (*attached_aio_context)(AioContext *new_context, void *opaque);
void (*detach_aio_context)(void *opaque);
@@ -1766,6 +1763,16 @@ void blk_drain_all(void)
bdrv_drain_all_end();
}
+void blk_set_on_error_retry_interval(BlockBackend *blk, int64_t interval)
+{
+ blk->retry_interval = interval;
+}
+
+void blk_set_on_error_retry_timeout(BlockBackend *blk, int64_t timeout)
+{
+ blk->retry_timeout = timeout;
+}
+
static bool blk_error_retry_timeout(BlockBackend *blk)
{
/* No timeout set, infinite retries. */
diff --git a/blockdev.c b/blockdev.c
index 6f1981635b..10a73fa423 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -480,6 +480,7 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
const char *buf;
int bdrv_flags = 0;
int on_read_error, on_write_error;
+ int64_t retry_interval, retry_timeout;
bool account_invalid, account_failed;
bool writethrough, read_only;
BlockBackend *blk;
@@ -572,6 +573,10 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
}
}
+ retry_interval = qemu_opt_get_number(opts, "retry_interval",
+ BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL);
+ retry_timeout = qemu_opt_get_number(opts, "retry_timeout", 0);
+
if (snapshot) {
bdrv_flags |= BDRV_O_SNAPSHOT;
}
@@ -635,6 +640,11 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
blk_set_enable_write_cache(blk, !writethrough);
blk_set_on_error(blk, on_read_error, on_write_error);
+ if (on_read_error == BLOCKDEV_ON_ERROR_RETRY ||
+ on_write_error == BLOCKDEV_ON_ERROR_RETRY) {
+ blk_set_on_error_retry_interval(blk, retry_interval);
+ blk_set_on_error_retry_timeout(blk, retry_timeout);
+ }
if (!monitor_add_blk(blk, id, errp)) {
blk_unref(blk);
@@ -761,6 +771,14 @@ QemuOptsList qemu_legacy_drive_opts = {
.name = "werror",
.type = QEMU_OPT_STRING,
.help = "write error action",
+ },{
+ .name = "retry_interval",
+ .type = QEMU_OPT_NUMBER,
+ .help = "interval for retry action in millisecond",
+ },{
+ .name = "retry_timeout",
+ .type = QEMU_OPT_NUMBER,
+ .help = "timeout for retry action in millisecond",
},{
.name = "copy-on-read",
.type = QEMU_OPT_BOOL,
@@ -783,6 +801,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type,
BlockInterfaceType type;
int max_devs, bus_id, unit_id, index;
const char *werror, *rerror;
+ int64_t retry_interval, retry_timeout;
bool read_only = false;
bool copy_on_read;
const char *filename;
@@ -990,6 +1009,29 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type,
qdict_put_str(bs_opts, "rerror", rerror);
}
+ if (qemu_opt_find(legacy_opts, "retry_interval")) {
+ if ((werror == NULL || strcmp(werror, "retry")) &&
+ (rerror == NULL || strcmp(rerror, "retry"))) {
+ error_setg(errp, "retry_interval is only supported "
+ "by werror/rerror=retry");
+ goto fail;
+ }
+ retry_interval = qemu_opt_get_number(legacy_opts, "retry_interval",
+ BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL);
+ qdict_put_int(bs_opts, "retry_interval", retry_interval);
+ }
+
+ if (qemu_opt_find(legacy_opts, "retry_timeout")) {
+ if ((werror == NULL || strcmp(werror, "retry")) &&
+ (rerror == NULL || strcmp(rerror, "retry"))) {
+ error_setg(errp, "retry_timeout is only supported "
+ "by werror/rerror=retry");
+ goto fail;
+ }
+ retry_timeout = qemu_opt_get_number(legacy_opts, "retry_timeout", 0);
+ qdict_put_int(bs_opts, "retry_timeout", retry_timeout);
+ }
+
/* Actual block device init: Functionality shared with blockdev-add */
blk = blockdev_init(filename, bs_opts, errp);
bs_opts = NULL;
@@ -3806,6 +3848,14 @@ QemuOptsList qemu_common_drive_opts = {
.name = "werror",
.type = QEMU_OPT_STRING,
.help = "write error action",
+ },{
+ .name = "retry_interval",
+ .type = QEMU_OPT_NUMBER,
+ .help = "interval for retry action in millisecond",
+ },{
+ .name = "retry_timeout",
+ .type = QEMU_OPT_NUMBER,
+ .help = "timeout for retry action in millisecond",
},{
.name = BDRV_OPT_READ_ONLY,
.type = QEMU_OPT_BOOL,
diff --git a/hw/block/block.c b/hw/block/block.c
index d47ebf005a..26c0767552 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -206,6 +206,16 @@ bool blkconf_apply_backend_options(BlockConf *conf, bool readonly,
blk_set_enable_write_cache(blk, wce);
blk_set_on_error(blk, rerror, werror);
+ if (rerror == BLOCKDEV_ON_ERROR_RETRY ||
+ werror == BLOCKDEV_ON_ERROR_RETRY) {
+ if (conf->retry_interval >= 0) {
+ blk_set_on_error_retry_interval(blk, conf->retry_interval);
+ }
+ if (conf->retry_timeout >= 0) {
+ blk_set_on_error_retry_timeout(blk, conf->retry_timeout);
+ }
+ }
+
return true;
}
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index 5902c0440a..24fb7d77af 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -33,6 +33,8 @@ typedef struct BlockConf {
bool share_rw;
BlockdevOnError rerror;
BlockdevOnError werror;
+ int64_t retry_interval;
+ int64_t retry_timeout;
} BlockConf;
static inline unsigned int get_physical_block_exp(BlockConf *conf)
@@ -79,7 +81,10 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
DEFINE_PROP_BLOCKDEV_ON_ERROR("rerror", _state, _conf.rerror, \
BLOCKDEV_ON_ERROR_AUTO), \
DEFINE_PROP_BLOCKDEV_ON_ERROR("werror", _state, _conf.werror, \
- BLOCKDEV_ON_ERROR_AUTO)
+ BLOCKDEV_ON_ERROR_AUTO), \
+ DEFINE_PROP_INT64("retry_interval", _state, _conf.retry_interval, \
+ -1), \
+ DEFINE_PROP_INT64("retry_timeout", _state, _conf.retry_timeout, -1)
/* Backend access helpers */
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 56a403883d..887c19ff5d 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -25,6 +25,9 @@
*/
#include "block/block.h"
+/* block backend default retry interval */
+#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000
+
/* Callbacks for block device models */
typedef struct BlockDevOps {
/*
@@ -198,6 +201,8 @@ void blk_inc_in_flight(BlockBackend *blk);
void blk_dec_in_flight(BlockBackend *blk);
void blk_drain(BlockBackend *blk);
void blk_drain_all(void);
+void blk_set_on_error_retry_interval(BlockBackend *blk, int64_t interval);
+void blk_set_on_error_retry_timeout(BlockBackend *blk, int64_t timeout);
void blk_error_retry_reset_timeout(BlockBackend *blk);
void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error,
BlockdevOnError on_write_error);
--
2.27.0