From 5688fa63f6fea61f5dced94878f94cff66e1d056 Mon Sep 17 00:00:00 2001 From: Vladislav Bolkhovitin Date: Sat, 16 Apr 2011 16:06:17 +0000 Subject: [PATCH] Stable 2.1 branch added git-svn-id: http://svn.code.sf.net/p/scst/svn/branches/2.1.0.x@3390 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/ChangeLog | 2 + scst/src/dev_handlers/scst_vdisk.c | 21 ++++++--- scst/src/scst_lib.c | 7 +++ scst/src/scst_main.c | 6 +++ srpt/README | 68 ++++++++++++++++++++++++++++++ srpt/src/ib_srpt.c | 29 ++++++++++++- 6 files changed, 125 insertions(+), 8 deletions(-) diff --git a/scst/ChangeLog b/scst/ChangeLog index 5bb1c4ad3..8d24f9a1a 100644 --- a/scst/ChangeLog +++ b/scst/ChangeLog @@ -20,6 +20,8 @@ Summary of changes between versions 2.0.0 and 2.1.0 to prevent possible starvation under heavy load and in some cases improve performance + - Autogenerated SCST target names made deprecated + - Custom parse improvements - Logging improvements diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index eebc25e62..3276610e6 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -1412,8 +1412,6 @@ static void vdisk_exec_inquiry(struct scst_cmd *cmd) } buf[0] = cmd->dev->type; /* type dev */ - if (virt_dev->removable) - buf[1] = 0x80; /* removable */ /* Vital Product */ if (cmd->cdb[1] & EVPD) { if (0 == cmd->cdb[2]) { @@ -1577,6 +1575,8 @@ static void vdisk_exec_inquiry(struct scst_cmd *cmd) goto out_put; } + if (virt_dev->removable) + buf[1] = 0x80; /* removable */ buf[2] = 5; /* Device complies to SPC-3 */ buf[3] = 0x12; /* HiSup + data in format specified in SPC */ if (cmd->tgtt->fake_aca) @@ -2041,15 +2041,22 @@ out: } static void vdisk_ctrl_m_pg_select(unsigned char *p, - struct scst_vdisk_dev *virt_dev) + struct scst_vdisk_dev *virt_dev, struct scst_cmd *cmd) { struct scst_device *dev = virt_dev->dev; int old_swp = dev->swp, old_tas = dev->tas, old_dsense = dev->d_sense; -#if 0 - /* Not implemented yet, see comment in vdisk_ctrl_m_pg() */ - dev->tst = p[2] >> 5; +#if 0 /* Not implemented yet, see comment in vdisk_ctrl_m_pg() */ + dev->tst = (p[2] >> 5) & 1; dev->queue_alg = p[3] >> 4; +#else + if ((dev->tst != ((p[2] >> 5) & 1)) || (dev->queue_alg != (p[3] >> 4))) { + TRACE(TRACE_MINOR|TRACE_SCSI, "%s", "MODE SELECT: Changing of " + "TST and QUEUE ALGORITHM not supported"); + scst_set_cmd_error(cmd, + SCST_LOAD_SENSE(scst_sense_invalid_field_in_cdb)); + return; + } #endif dev->swp = (p[4] & 0x8) >> 3; dev->tas = (p[5] & 0x40) >> 6; @@ -2140,7 +2147,7 @@ static void vdisk_exec_mode_select(struct scst_cmd *cmd) scst_sense_invalid_field_in_parm_list)); goto out_put; } - vdisk_ctrl_m_pg_select(&address[offset], virt_dev); + vdisk_ctrl_m_pg_select(&address[offset], virt_dev, cmd); } else { PRINT_ERROR("MODE SELECT: Invalid request %x", address[offset] & 0x3f); diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 3f1b11ec3..0c614f781 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -796,6 +796,13 @@ int scst_set_cmd_error_status(struct scst_cmd *cmd, int status) TRACE_ENTRY(); + if (status == SAM_STAT_RESERVATION_CONFLICT) { + TRACE(TRACE_SCSI|TRACE_MINOR, "Reservation conflict (dev %s, " + "initiator %s, tgt_id %d)", + cmd->dev ? cmd->dev->virt_name : NULL, + cmd->sess->initiator_name, cmd->tgt->rel_tgt_id); + } + if (cmd->status != 0) { TRACE_MGMT_DBG("cmd %p already has status %x set", cmd, cmd->status); diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index d4cf5a99f..c0f9121a3 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -506,6 +506,12 @@ struct scst_tgt *scst_register_target(struct scst_tgt_template *vtt, } else { static int tgt_num; /* protected by scst_mutex */ + PRINT_WARNING("Usage of autogenerated SCST target names " + "is deprecated and will be removed in one of the next " + "versions. It is strongly recommended to update target " + "driver %s to use hardware related persistent target " + "names instead", vtt->name); + tgt->tgt_name = kasprintf(GFP_KERNEL, "%s%s%d", vtt->name, SCST_DEFAULT_TGT_NAME_SUFFIX, tgt_num); if (tgt->tgt_name == NULL) { diff --git a/srpt/README b/srpt/README index 9b5888385..c63404af4 100644 --- a/srpt/README +++ b/srpt/README @@ -184,6 +184,74 @@ the disk names assigned on the SCST target ("disk01" in the example below): [8:0:0:0] disk SCST_FIO disk01 102 /dev/sdb +Target names +------------ + +The name assigned by the ib_srpt target driver to an SCST target is the node +GUID of a HCA in hexadecimal form with a colon after every fourth digit. The +HCA node GUIDs can be obtained via the ibv_devices command, the ibv_devinfo +command or via sysfs. An example: + +# ibv_devices + device node GUID + ------ ---------------- + mlx4_1 0002c9030003cca2 + mlx4_0 0002c9030005f34e + +# head /sys/devices/*/*/*/infiniband/*/node_guid +==> /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/infiniband/mlx4_0/node_guid <== +0002:c903:0005:f34e + +==> /sys/devices/pci0000:00/0000:00:1c.0/0000:05:00.0/infiniband/mlx4_1/node_guid <== +0002:c903:0003:cca2 + +Once the ib_srpt driver has been loaded there will be SCST targets available +with the HCA node GUID as name: + +# ls /sys/bus/scst_target/drivers/ib_srpt/0* +0002:c903:0003:cca2 0002:c903:0005:f34e + +If you need deprecated target names in form ib_srpt_target_X, you should +set use_node_guid_in_target_name parameter of module ib_srpt to 0. + + +Session names +------------- + +The ib_srpt target driver uses the 128-bit SRP initiator port identifier for +the session name. This identifier is sent by the SRP initiator to the SRP +target via the SRP_LOGIN_REQ information unit. The Linux SRP initiator +(ib_srp) generates the initiator port identifier as follows: +- The first eight bytes are the identifier extension ('initiator_ext' parameter + specified in the login string echoed into the sysfs file 'add_target'). +- The last eight bytes are the GUID of the initiator HCA port used to + communicate with the target. + +An example: + +[ INITIATOR ] + +$ for f in /sys/devices/*/*/*/infiniband/*/ports/*/gids/0; do echo +f; cat $f | cut -c21-; done +/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/infiniband/mlx4_0/ports/1/gids/0 +0002:c903:0005:f34b +/sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0/infiniband/mlx4_0/ports/2/gids/0 +0002:c903:0005:f34c +/sys/devices/pci0000:00/0000:00:1c.0/0000:05:00.0/infiniband/mlx4_1/ports/1/gids/0 +0002:c903:0003:cca7 +/sys/devices/pci0000:00/0000:00:1c.0/0000:05:00.0/infiniband/mlx4_1/ports/2/gids/0 +0002:c903:0003:cca8 + +[ TARGET, after login ] + +$ ls /sys/bus/scst_target/drivers/ib_srpt/*/sessions +/sys/bus/scst_target/drivers/ib_srpt/0002:c903:0003:cca2/sessions: +0x00000000000000000002c9030003cca7 + +/sys/bus/scst_target/drivers/ib_srpt/0002:c903:0005:f34e/sessions: +0x00000000000000000002c9030005f34b + + High availability ----------------- diff --git a/srpt/src/ib_srpt.c b/srpt/src/ib_srpt.c index 61194c35a..7872e7cf8 100644 --- a/srpt/src/ib_srpt.c +++ b/srpt/src/ib_srpt.c @@ -144,6 +144,16 @@ MODULE_PARM_DESC(use_port_guid_in_session_name, "Use target port ID in the SCST session name such that" " redundant paths between multiport systems can be masked."); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) \ + || defined(RHEL_MAJOR) && RHEL_MAJOR -0 <= 5 +static int use_node_guid_in_target_name; +#else +static bool use_node_guid_in_target_name; +#endif +module_param(use_node_guid_in_target_name, bool, 0444); +MODULE_PARM_DESC(use_node_guid_in_target_name, + "Use target node GUIDs of HCAs as SCST target names."); + static int srpt_get_u64_x(char *buffer, struct kernel_param *kp) { return sprintf(buffer, "0x%016llx", *(u64 *)kp->arg); @@ -3524,6 +3534,7 @@ static void srpt_add_one(struct ib_device *device) struct srpt_device *sdev; struct srpt_port *sport; struct ib_srq_init_attr srq_attr; + char tgt_name[24]; int i; TRACE_ENTRY(); @@ -3538,7 +3549,15 @@ static void srpt_add_one(struct ib_device *device) INIT_LIST_HEAD(&sdev->rch_list); spin_lock_init(&sdev->spinlock); - sdev->scst_tgt = scst_register_target(&srpt_template, NULL); + if (use_node_guid_in_target_name) { + snprintf(tgt_name, sizeof(tgt_name), "%04x:%04x:%04x:%04x", + be16_to_cpu(((__be16 *)&device->node_guid)[0]), + be16_to_cpu(((__be16 *)&device->node_guid)[1]), + be16_to_cpu(((__be16 *)&device->node_guid)[2]), + be16_to_cpu(((__be16 *)&device->node_guid)[3])); + sdev->scst_tgt = scst_register_target(&srpt_template, tgt_name); + } else + sdev->scst_tgt = scst_register_target(&srpt_template, NULL); if (!sdev->scst_tgt) { PRINT_ERROR("SCST registration failed for %s.", sdev->device->name); @@ -3861,6 +3880,14 @@ static int __init srpt_init_module(void) goto out; } + if (!use_node_guid_in_target_name) + PRINT_WARNING("%s", "Usage of HCA numbers as SCST target names " + "is deprecated and will be removed in one of the next " + "versions. It is strongly recommended to set " + "use_node_guid_in_target_name parameter in 1 and " + "update your SCST config file accordingly to use HCAs " + "GUIDs."); + #ifdef CONFIG_SCST_PROC ret = class_register(&srpt_class); if (ret) {