qemu/block-Add-error-retry-param-setting.patch
Jiabo Feng 1f0277483b QEMU update to version 8.2.0-2
- block: bugfix: Don't pause vm when NOSPACE EIO happened
- block: enable cache mode of empty cdrom
- block/mirror: fix file-system went to read-only after block-mirror
- scsi-bus: fix incorrect call for blk_error_retry_reset_timeout()
- scsi-bus: fix unmatched object_unref()
- block: Add sanity check when setting retry parameters
- block-backend: Stop retrying when draining
- scsi-disk: Add support for retry on errors
- scsi-bus: Refactor the code that retries requests
- virtio_blk: Add support for retry on errors
- block: Add error retry param setting
- block-backend: Add timeout support for retry
- block-backend: Enable retry action on errors
- block-backend: Add device specific retry callback
- block-backend: Introduce retry timer
- qapi/block-core: Add retry option for error action
- scsi: bugfix: fix division by zero
- scsi: cdrom: Fix crash after remote cdrom detached
- qemu-pr: fixed ioctl failed for multipath disk
- scsi-disk: define props in scsi_block_disk to avoid memleaks
- bugfix: fix possible memory leak
- bugfix: fix some illegal memory access and memory leak
- util/log: add CONFIG_DISABLE_QEMU_LOG macro
- log: Add some logs on VM runtime path
- bugfix: fix eventfds may double free when vm_id reused in ivshmem
- hw/display/macfb: Fix missing ERRP_GUARD() in macfb_nubus_realize()
- hw/cxl/cxl-host: Fix missing ERRP_GUARD() in cxl_fixed_memory_window_config()
- qemu-img create: 'cache' paramter only use for reg file image
- qemu-img: add qemu-img direct create
- qemu-img block: set zero flags only when discard_zeros of the block supported
- Revert "file-posix: Remove unused s->discard_zeroes"
- pcie_sriov: Validate NumVFs (CVE-2024-26327)
- hw/nvme: Use pcie_sriov_num_vfs() (CVE-2024-26328)
- hw/acpi/cpu: Use CPUState typedef
- target/i386/sev: Fix missing ERRP_GUARD() for error_prepend()
- virtio-gpu: remove needless condition
- hw/i2c/smbus_slave: Add object path on error prints
- vfio/pci: Ascend710 change to bar2 quirk
- vfio/pci: Ascend910 need 4Bytes quirk in bar0
- vfio/pci: Ascend710 need 4Bytes quirk in bar0
- vfio/pci: Ascend310 need 4Bytes quirk in bar4
- chardev/char-socket: Fix TLS io channels sending too much data to the backend
- i386/cpuid: Move leaf 7 to correct group
- i386/cpuid: Decrease cpuid_i when skipping CPUID leaf 1F
- i386/cpu: Mask with XCR0/XSS mask for FEAT_XSAVE_XCR0_HI and FEAT_XSAVE_XSS_HI leafs
- i386/cpu: Clear FEAT_XSAVE_XSS_LO/HI leafs when CPUID_EXT_XSAVE is not available
- blkio: Respect memory-alignment for bounce buffer allocations
- virtio-gpu: Correct virgl_renderer_resource_get_info() error check
- hw/usb: Style cleanup
- tests/qemu-iotests: resolved the problem that the 108 test cases in
  the container fail

Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
(cherry picked from commit 404d45bf9147058a475a8031c454a6c8e0acc123)
2024-03-26 21:11:41 +08:00

233 lines
9.1 KiB
Diff

From d777d1585603aa7599ae8bac4492fafdf1e4b109 Mon Sep 17 00:00:00 2001
From: yexiao <yexiao7@huawei.com>
Date: Thu, 21 Jan 2021 15:46:50 +0800
Subject: [PATCH] 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. -device device_name,drive=drive_id,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-common.h | 3 ++
include/sysemu/block-backend-global-state.h | 2 +
6 files changed, 81 insertions(+), 4 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index 919699bb70..85d732de7e 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -33,9 +33,6 @@
#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
-/* 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);
@@ -2149,6 +2146,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 2817f73fad..6a229e77a5 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -484,6 +484,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;
OnOffAuto account_invalid, account_failed;
bool writethrough, read_only;
BlockBackend *blk;
@@ -576,6 +577,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;
}
@@ -639,6 +644,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);
@@ -773,6 +783,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,
@@ -795,6 +813,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;
@@ -1013,6 +1032,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;
@@ -3794,6 +3836,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 9f52ee6e72..6bece87709 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -239,6 +239,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);
+ }
+ }
+
block_acct_setup(blk_get_stats(blk), conf->account_invalid,
conf->account_failed);
return true;
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index 15fff66435..fb8c0df4a5 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -34,6 +34,8 @@ typedef struct BlockConf {
OnOffAuto account_invalid, account_failed;
BlockdevOnError rerror;
BlockdevOnError werror;
+ int64_t retry_interval;
+ int64_t retry_timeout;
} BlockConf;
static inline unsigned int get_physical_block_exp(BlockConf *conf)
@@ -84,7 +86,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-common.h b/include/sysemu/block-backend-common.h
index b76df8834a..5a1cdac9c4 100644
--- a/include/sysemu/block-backend-common.h
+++ b/include/sysemu/block-backend-common.h
@@ -16,6 +16,9 @@
#include "qemu/iov.h"
#include "block/throttle-groups.h"
+/* block backend default retry interval */
+#define BLOCK_BACKEND_DEFAULT_RETRY_INTERVAL 1000
+
/*
* TODO Have to include block/block.h for a bunch of block layer
* types. Unfortunately, this pulls in the whole BlockDriverState
diff --git a/include/sysemu/block-backend-global-state.h b/include/sysemu/block-backend-global-state.h
index 7f59fd411d..d56592c22e 100644
--- a/include/sysemu/block-backend-global-state.h
+++ b/include/sysemu/block-backend-global-state.h
@@ -84,6 +84,8 @@ int blk_commit_all(void);
bool blk_in_drain(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