|
@@ -55,11 +55,15 @@
|
|
|
#define ALUA_FAILOVER_TIMEOUT (60 * HZ)
|
|
|
#define ALUA_FAILOVER_RETRIES 5
|
|
|
|
|
|
+/* flags passed from user level */
|
|
|
+#define ALUA_OPTIMIZE_STPG 1
|
|
|
+
|
|
|
struct alua_dh_data {
|
|
|
int group_id;
|
|
|
int rel_port;
|
|
|
int tpgs;
|
|
|
int state;
|
|
|
+ unsigned flags; /* used for optimizing STPG */
|
|
|
unsigned char inq[ALUA_INQUIRY_SIZE];
|
|
|
unsigned char *buff;
|
|
|
int bufflen;
|
|
@@ -621,6 +625,37 @@ static int alua_initialize(struct scsi_device *sdev, struct alua_dh_data *h)
|
|
|
out:
|
|
|
return err;
|
|
|
}
|
|
|
+/*
|
|
|
+ * alua_set_params - set/unset the optimize flag
|
|
|
+ * @sdev: device on the path to be activated
|
|
|
+ * params - parameters in the following format
|
|
|
+ * "no_of_params\0param1\0param2\0param3\0...\0"
|
|
|
+ * For example, to set the flag pass the following parameters
|
|
|
+ * from multipath.conf
|
|
|
+ * hardware_handler "2 alua 1"
|
|
|
+ */
|
|
|
+static int alua_set_params(struct scsi_device *sdev, const char *params)
|
|
|
+{
|
|
|
+ struct alua_dh_data *h = get_alua_data(sdev);
|
|
|
+ unsigned int optimize = 0, argc;
|
|
|
+ const char *p = params;
|
|
|
+ int result = SCSI_DH_OK;
|
|
|
+
|
|
|
+ if ((sscanf(params, "%u", &argc) != 1) || (argc != 1))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ while (*p++)
|
|
|
+ ;
|
|
|
+ if ((sscanf(p, "%u", &optimize) != 1) || (optimize > 1))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (optimize)
|
|
|
+ h->flags |= ALUA_OPTIMIZE_STPG;
|
|
|
+ else
|
|
|
+ h->flags &= ~ALUA_OPTIMIZE_STPG;
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
|
|
|
/*
|
|
|
* alua_activate - activate a path
|
|
@@ -698,6 +733,7 @@ static struct scsi_device_handler alua_dh = {
|
|
|
.prep_fn = alua_prep_fn,
|
|
|
.check_sense = alua_check_sense,
|
|
|
.activate = alua_activate,
|
|
|
+ .set_params = alua_set_params,
|
|
|
.match = alua_match,
|
|
|
};
|
|
|
|