[dm-devel] [PATCH 10/57] libmultipath: finally fix dev_loss_tmo setting
Hannes Reinecke
hare at suse.de
Wed Apr 27 11:10:11 UTC 2016
We need to take the current value when comparing
'dev_loss_tmo' and 'fast_io_fail', otherwise we still
might be getting an error as we might comparing wrong
values.
Signed-off-by: Hannes Reinecke <hare at suse.com>
---
libmultipath/defaults.h | 1 +
libmultipath/discovery.c | 72 ++++++++++++++++++++++++----------------------
multipath/multipath.conf.5 | 2 +-
3 files changed, 39 insertions(+), 36 deletions(-)
diff --git a/libmultipath/defaults.h b/libmultipath/defaults.h
index bce8bcc..96f5a2c 100644
--- a/libmultipath/defaults.h
+++ b/libmultipath/defaults.h
@@ -15,6 +15,7 @@
#define DEFAULT_REASSIGN_MAPS 0
#define DEFAULT_FIND_MULTIPATHS 0
#define DEFAULT_FAST_IO_FAIL 5
+#define DEFAULT_DEV_LOSS_TMO 600
#define DEFAULT_RETAIN_HWHANDLER RETAIN_HWHANDLER_OFF
#define DEFAULT_DETECT_PRIO DETECT_PRIO_OFF
#define DEFAULT_DEFERRED_REMOVE DEFERRED_REMOVE_OFF
diff --git a/libmultipath/discovery.c b/libmultipath/discovery.c
index 324e217..83cc4f7 100644
--- a/libmultipath/discovery.c
+++ b/libmultipath/discovery.c
@@ -504,6 +504,22 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
pp->sg_id.channel, pp->sg_id.scsi_id, rport_id);
/*
+ * read the current dev_loss_tmo value from sysfs
+ */
+ ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo", value, 16);
+ if (ret <= 0) {
+ condlog(0, "%s: failed to read dev_loss_tmo value, "
+ "error %d", rport_id, -ret);
+ goto out;
+ }
+ tmo = strtoull(value, &eptr, 0);
+ if (value == eptr || tmo == ULLONG_MAX) {
+ condlog(0, "%s: Cannot parse dev_loss_tmo "
+ "attribute '%s'", rport_id, value);
+ goto out;
+ }
+
+ /*
* This is tricky.
* dev_loss_tmo will be limited to 600 if fast_io_fail
* is _not_ set.
@@ -514,45 +530,31 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
* then set fast_io_fail, and _then_ set dev_loss_tmo
* to the correct value.
*/
- memset(value, 0, 16);
if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET &&
mpp->fast_io_fail != MP_FAST_IO_FAIL_ZERO &&
mpp->fast_io_fail != MP_FAST_IO_FAIL_OFF) {
/* Check if we need to temporarily increase dev_loss_tmo */
- ret = sysfs_attr_get_value(rport_dev, "dev_loss_tmo",
- value, 16);
- if (ret <= 0) {
- condlog(0, "%s: failed to read dev_loss_tmo value, "
- "error %d", rport_id, -ret);
- goto out;
- }
- tmo = strtoull(value, &eptr, 0);
- if (value == eptr || tmo == ULLONG_MAX) {
- condlog(0, "%s: Cannot parse dev_loss_tmo "
- "attribute '%s'", rport_id, value);
- goto out;
- }
if (mpp->fast_io_fail >= tmo) {
+ /* Increase dev_loss_tmo temporarily */
snprintf(value, 16, "%u", mpp->fast_io_fail + 1);
+ ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
+ value, strlen(value));
+ if (ret <= 0) {
+ if (ret == -EBUSY)
+ condlog(3, "%s: rport blocked",
+ rport_id);
+ else
+ condlog(0, "%s: failed to set "
+ "dev_loss_tmo to %s, error %d",
+ rport_id, value, -ret);
+ goto out;
+ }
}
- } else if (mpp->dev_loss > 600) {
- condlog(3, "%s: limiting dev_loss_tmo to 600, since "
- "fast_io_fail is not set", rport_id);
- snprintf(value, 16, "%u", 600);
- } else {
- snprintf(value, 16, "%u", mpp->dev_loss);
- }
- if (strlen(value)) {
- ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
- value, strlen(value));
- if (ret <= 0) {
- if (ret == -EBUSY)
- condlog(3, "%s: rport blocked", rport_id);
- else
- condlog(0, "%s: failed to set dev_loss_tmo to %s, error %d",
- rport_id, value, -ret);
- goto out;
- }
+ } else if (mpp->dev_loss > DEFAULT_DEV_LOSS_TMO) {
+ condlog(3, "%s: limiting dev_loss_tmo to %d, since "
+ "fast_io_fail is not set",
+ rport_id, DEFAULT_DEV_LOSS_TMO);
+ mpp->dev_loss = DEFAULT_DEV_LOSS_TMO;
}
if (mpp->fast_io_fail != MP_FAST_IO_FAIL_UNSET) {
if (mpp->fast_io_fail == MP_FAST_IO_FAIL_OFF)
@@ -571,7 +573,7 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
rport_id, value, -ret);
}
}
- if (tmo > 0) {
+ if (mpp->dev_loss > 0) {
snprintf(value, 16, "%u", mpp->dev_loss);
ret = sysfs_attr_set_value(rport_dev, "dev_loss_tmo",
value, strlen(value));
@@ -673,11 +675,11 @@ sysfs_set_scsi_tmo (struct multipath *mpp)
no_path_retry_tmo = MAX_DEV_LOSS_TMO;
if (no_path_retry_tmo > dev_loss_tmo)
dev_loss_tmo = no_path_retry_tmo;
- condlog(3, "%s: update dev_loss_tmo to %d",
+ condlog(3, "%s: update dev_loss_tmo to %u",
mpp->alias, dev_loss_tmo);
} else if (mpp->no_path_retry == NO_PATH_RETRY_QUEUE) {
dev_loss_tmo = MAX_DEV_LOSS_TMO;
- condlog(3, "%s: update dev_loss_tmo to %d",
+ condlog(3, "%s: update dev_loss_tmo to %u",
mpp->alias, dev_loss_tmo);
}
mpp->dev_loss = dev_loss_tmo;
diff --git a/multipath/multipath.conf.5 b/multipath/multipath.conf.5
index 0d4df0f..b21279e 100644
--- a/multipath/multipath.conf.5
+++ b/multipath/multipath.conf.5
@@ -394,7 +394,7 @@ retry interval
if a number of retries is given with \fIno_path_retry\fR and the
overall retry interval is longer than the specified \fIdev_loss_tmo\fR value.
The linux kernel will cap this value to \fI300\fR if \fBfast_io_fail_tmo\fR
-is not set.
+is not set. Default is 600.
.TP
.B queue_without_daemon
If set to
--
2.6.6
More information about the dm-devel
mailing list