339e1d
From 9c8108a4d3a837c51a29f28229a06d97654eaeb6 Mon Sep 17 00:00:00 2001
339e1d
From: Chris Leech <cleech@redhat.com>
339e1d
Date: Tue, 16 Jun 2015 16:07:13 -0700
339e1d
Subject: iSCSI: let session recovery_tmo sysfs writes persist across recovery
339e1d
339e1d
The iSCSI session recovery_tmo setting is writeable in sysfs, but it's
339e1d
also set every time a connection is established when parameters are set
339e1d
from iscsid over netlink.  That results in the timeout being reset to
339e1d
the default value after every recovery.
339e1d
339e1d
The DM multipath tools want to use the sysfs interface to lower the
339e1d
default timeout when there are multiple paths to fail over.  It has
339e1d
caused confusion that we have a writeable sysfs value that seem to keep
339e1d
resetting itself.
339e1d
339e1d
This patch adds an in-kernel flag that gets set once a sysfs write
339e1d
occurs, and then ignores netlink parameter setting once it's been
339e1d
modified via the sysfs interface.  My thinking here is that the sysfs
339e1d
interface is much simpler for external tools to influence the session
339e1d
timeout, but if we're going to allow it to be modified directly we
339e1d
should ensure that setting is maintained.
339e1d
339e1d
Signed-off-by: Chris Leech <cleech@redhat.com>
339e1d
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
339e1d
Signed-off-by: James Bottomley <JBottomley@Odin.com>
339e1d
339e1d
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
339e1d
index 55647aa..4c25539 100644
339e1d
--- a/drivers/scsi/scsi_transport_iscsi.c
339e1d
+++ b/drivers/scsi/scsi_transport_iscsi.c
339e1d
@@ -2042,6 +2042,7 @@ iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport,
339e1d
 	session->transport = transport;
339e1d
 	session->creator = -1;
339e1d
 	session->recovery_tmo = 120;
339e1d
+	session->recovery_tmo_sysfs_override = false;
339e1d
 	session->state = ISCSI_SESSION_FREE;
339e1d
 	INIT_DELAYED_WORK(&session->recovery_work, session_recovery_timedout);
339e1d
 	INIT_LIST_HEAD(&session->sess_list);
339e1d
@@ -2786,7 +2787,8 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
339e1d
 	switch (ev->u.set_param.param) {
339e1d
 	case ISCSI_PARAM_SESS_RECOVERY_TMO:
339e1d
 		sscanf(data, "%d", &value);
339e1d
-		session->recovery_tmo = value;
339e1d
+		if (!session->recovery_tmo_sysfs_override)
339e1d
+			session->recovery_tmo = value;
339e1d
 		break;
339e1d
 	default:
339e1d
 		err = transport->set_param(conn, ev->u.set_param.param,
339e1d
@@ -4049,13 +4051,15 @@ store_priv_session_##field(struct device *dev,				\
339e1d
 	if ((session->state == ISCSI_SESSION_FREE) ||			\
339e1d
 	    (session->state == ISCSI_SESSION_FAILED))			\
339e1d
 		return -EBUSY;						\
339e1d
-	if (strncmp(buf, "off", 3) == 0)				\
339e1d
+	if (strncmp(buf, "off", 3) == 0) {				\
339e1d
 		session->field = -1;					\
339e1d
-	else {								\
339e1d
+		session->field##_sysfs_override = true;			\
339e1d
+	} else {							\
339e1d
 		val = simple_strtoul(buf, &cp, 0);			\
339e1d
 		if (*cp != '\0' && *cp != '\n')				\
339e1d
 			return -EINVAL;					\
339e1d
 		session->field = val;					\
339e1d
+		session->field##_sysfs_override = true;			\
339e1d
 	}								\
339e1d
 	return count;							\
339e1d
 }
339e1d
@@ -4066,6 +4070,7 @@ store_priv_session_##field(struct device *dev,				\
339e1d
 static ISCSI_CLASS_ATTR(priv_sess, field, S_IRUGO | S_IWUSR,		\
339e1d
 			show_priv_session_##field,			\
339e1d
 			store_priv_session_##field)
339e1d
+
339e1d
 iscsi_priv_session_rw_attr(recovery_tmo, "%d");
339e1d
 
339e1d
 static struct attribute *iscsi_session_attrs[] = {
339e1d
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
339e1d
index 2555ee5..6183d20 100644
339e1d
--- a/include/scsi/scsi_transport_iscsi.h
339e1d
+++ b/include/scsi/scsi_transport_iscsi.h
339e1d
@@ -241,6 +241,7 @@ struct iscsi_cls_session {
339e1d
 
339e1d
 	/* recovery fields */
339e1d
 	int recovery_tmo;
339e1d
+	bool recovery_tmo_sysfs_override;
339e1d
 	struct delayed_work recovery_work;
339e1d
 
339e1d
 	unsigned int target_id;
339e1d
-- 
339e1d
cgit v0.10.2
339e1d