From c45717fa823682a04814ca49669116b2f5917671 Mon Sep 17 00:00:00 2001 From: Jiahui Cen Date: Thu, 25 Feb 2021 18:55:30 +0800 Subject: [PATCH] libvirt: Add 'retry' support for error policy Introduce error_policy=/rerror_policy='retry' to support werror=/rerror=retry mechanism in qemu. Add retry_interval parameter to control the interval between retries. Add retry_timeout parameter to control the total retry times. Signed-off-by: Jiahui Cen Signed-off-by: Ying Fang --- src/conf/domain_conf.c | 26 ++++++++++++++++++++++++++ src/conf/domain_conf.h | 3 +++ src/qemu/qemu_command.c | 13 +++++++++++++ src/qemu/qemu_domain.c | 2 ++ 4 files changed, 44 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 22ad43e1d7..f31f06b428 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -385,6 +385,7 @@ VIR_ENUM_IMPL(virDomainDiskErrorPolicy, "report", "ignore", "enospace", + "retry", ); VIR_ENUM_IMPL(virDomainDiskIo, @@ -7773,6 +7774,8 @@ static int virDomainDiskDefDriverParseXML(virDomainDiskDef *def, xmlNodePtr cur) { + g_autofree char *tmp = NULL; + def->driverName = virXMLPropString(cur, "name"); if (virXMLPropEnum(cur, "cache", virDomainDiskCacheTypeFromString, @@ -7796,6 +7799,29 @@ virDomainDiskDefDriverParseXML(virDomainDiskDef *def, return -1; } + def->retry_interval = -1; + if ((tmp = virXMLPropString(cur, "retry_interval")) && + ((def->error_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY && + def->rerror_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) || + (virStrToLong_ll(tmp, NULL, 10, &def->retry_interval) < 0) || + (def->retry_interval < 0))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown disk retry interval '%s'"), tmp); + return -1; + } + VIR_FREE(tmp); + + def->retry_timeout = -1; + if ((tmp = virXMLPropString(cur, "retry_timeout")) && + ((def->error_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY && + def->rerror_policy != VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) || + (virStrToLong_ll(tmp, NULL, 10, &def->retry_timeout) < 0) || + (def->retry_timeout < 0))) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown disk retry interval '%s'"), tmp); + return -1; + } + if (virXMLPropEnum(cur, "io", virDomainDiskIoTypeFromString, VIR_XML_PROP_NONZERO, &def->iomode) < 0) return -1; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index ed07859bc5..021623cce7 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -419,6 +419,7 @@ typedef enum { VIR_DOMAIN_DISK_ERROR_POLICY_REPORT, VIR_DOMAIN_DISK_ERROR_POLICY_IGNORE, VIR_DOMAIN_DISK_ERROR_POLICY_ENOSPACE, + VIR_DOMAIN_DISK_ERROR_POLICY_RETRY, VIR_DOMAIN_DISK_ERROR_POLICY_LAST } virDomainDiskErrorPolicy; @@ -556,6 +557,8 @@ struct _virDomainDiskDef { virDomainDiskCache cachemode; virDomainDiskErrorPolicy error_policy; virDomainDiskErrorPolicy rerror_policy; + long long retry_interval; + long long retry_timeout; virDomainDiskIo iomode; virTristateSwitch ioeventfd; virTristateSwitch event_idx; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index d54149ed2d..678b84b332 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1753,6 +1753,8 @@ qemuBuildDiskDeviceProps(const virDomainDef *def, const char *biosCHSTrans = NULL; const char *wpolicy = NULL; const char *rpolicy = NULL; + g_autoptr(virJSONValue) retry_interval = NULL; + g_autoptr(virJSONValue) retry_timeout = NULL; switch (disk->bus) { case VIR_DOMAIN_DISK_BUS_IDE: @@ -1912,6 +1914,15 @@ qemuBuildDiskDeviceProps(const virDomainDef *def, } qemuBuildDiskGetErrorPolicy(disk, &wpolicy, &rpolicy); + if ((disk->error_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY || + disk->rerror_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) && + disk->retry_interval >= 0) + retry_interval = virJSONValueNewNumberUlong(disk->retry_interval); + if ((disk->error_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY || + disk->rerror_policy == VIR_DOMAIN_DISK_ERROR_POLICY_RETRY) && + disk->retry_timeout >= 0) + retry_timeout = virJSONValueNewNumberUlong(disk->retry_timeout); + if (virJSONValueObjectAdd(&props, "S:device_id", scsiVPDDeviceId, @@ -1936,6 +1947,8 @@ qemuBuildDiskDeviceProps(const virDomainDef *def, "S:serial", serial, "S:werror", wpolicy, "S:rerror", rpolicy, + "A:retry_interval", &retry_interval, + "A:retry_timeout", &retry_timeout, NULL) < 0) return NULL; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 953808fcfe..fa6a7fd1c9 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -8325,6 +8325,8 @@ qemuDomainDiskChangeSupported(virDomainDiskDef *disk, CHECK_EQ(cachemode, "cache", true); CHECK_EQ(error_policy, "error_policy", true); CHECK_EQ(rerror_policy, "rerror_policy", true); + CHECK_EQ(retry_interval, "retry_interval", true); + CHECK_EQ(retry_timeout, "retry_timeout", true); CHECK_EQ(iomode, "io", true); CHECK_EQ(ioeventfd, "ioeventfd", true); CHECK_EQ(event_idx, "event_idx", true); -- 2.27.0