This patch adds a SysFS hook for systemd service to kick off autoconnect command at the boot time. Output of the SysFS hook will provide host-traddr/traddr which will be used by NVMe CLI to kick off discovery at boot time. Signed-off-by: Himanshu Madhani <himanshu.madhani@xxxxxxxxxx> --- Hi Martin, This patch provides mechanism for qla2xxx driver's boot time scripts for autodiscovery and autoconnection of NVMe LUNs. Please apply this to 4.21/scsi-queue at your earliest convenience. Thanks, Himanshu --- drivers/scsi/qla2xxx/qla_attr.c | 122 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 678aff5ca947..323a4aa35f16 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1665,6 +1665,125 @@ qla2x00_max_speed_sup_show(struct device *dev, struct device_attribute *attr, ha->max_speed_sup ? "32Gps" : "16Gps"); } +static ssize_t +qla27xx_nvme_connect_str_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); + struct nvme_fc_remote_port *rport; + struct nvme_fc_local_port *lport; + struct qla_hw_data *ha = vha->hw; + struct qla_nvme_rport *qla_rport, *trport; + fc_port_t *fcport; + char temp[150] = {0}; + char *rportstate = ""; + + if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + return scnprintf(buf, PAGE_SIZE, "\n"); + + if (!vha->flags.nvme_enabled) + return scnprintf(buf, PAGE_SIZE, "%s\n", + "FC-NVMe is not enabled"); + + list_for_each_entry(fcport, &vha->vp_fcports, list) { + if (!fcport) { + scnprintf(buf, PAGE_SIZE, "No FC host\n"); + return strlen(buf); + } + + if (!vha->nvme_local_port) { + scnprintf(buf, PAGE_SIZE, + "FC-NVMe Initiator on 0x%16llx not registered.\n", + wwn_to_u64(fcport->port_name)); + return strlen(buf); + } + + list_for_each_entry_safe(qla_rport, trport, + &vha->nvme_rport_list, list) { + if (qla_rport->fcport == fcport) { + rport = fcport->nvme_remote_port; + + lport = vha->nvme_local_port; + + scnprintf(temp, sizeof(temp), + "FC-NVMe LPORT: host%ld nn-0x%16llx:pn-0x%16llx port_id %06x %s\n", + vha->host_no, lport->node_name, + lport->port_name, lport->port_id, "ONLINE"); + + if (strlcat(buf, temp, PAGE_SIZE) >= PAGE_SIZE) + goto done; + + scnprintf(temp, sizeof(temp), + "FC-NVMe RPORT: host%ld nn-0x%llx:pn-0x%llx port_id %06x ", + vha->host_no, rport->node_name, + rport->port_name, rport->port_id); + + /* Find out Rport State */ + if (rport->port_state & FC_OBJSTATE_ONLINE) + rportstate = "ONLINE"; + + if (rport->port_state & FC_OBJSTATE_UNKNOWN) + rportstate = "UNKNOWN"; + + if (rport->port_state & ~(FC_OBJSTATE_ONLINE | + FC_OBJSTATE_UNKNOWN)) + rportstate = "UNSUPPORTED"; + + if (strlcat(buf, temp, PAGE_SIZE) >= + PAGE_SIZE) + goto done; + + if (rport->port_role & + (FC_PORT_ROLE_NVME_INITIATOR | + FC_PORT_ROLE_NVME_TARGET | + FC_PORT_ROLE_NVME_DISCOVERY)) { + if (rport->port_role & + FC_PORT_ROLE_NVME_INITIATOR) + if (strlcat(buf, "INITIATOR ", + PAGE_SIZE) >= PAGE_SIZE) + goto done; + + if (rport->port_role & + FC_PORT_ROLE_NVME_TARGET) + if (strlcat(buf, "TARGET ", + PAGE_SIZE) >= PAGE_SIZE) + goto done; + + if (rport->port_role & + FC_PORT_ROLE_NVME_DISCOVERY) + if (strlcat(buf, "DISCOVERY ", + PAGE_SIZE) >= PAGE_SIZE) + goto done; + } else { + if (strlcat(buf, "UNKNOWN_ROLE ", + PAGE_SIZE) >= PAGE_SIZE) + goto done; + } + scnprintf(temp, sizeof(temp), "%s\n", rportstate); + + if (strlcat(buf, temp, PAGE_SIZE) >= PAGE_SIZE) + goto done; + + scnprintf(temp, sizeof(temp), + "NVMECLI: host-traddr=nn-0x%16llx:pn-0x%16llx traddr=nn-0x%16llx:pn-0x%16llx\n", + lport->node_name, lport->port_name, + rport->node_name, rport->port_name); + + if (strlcat(buf, temp, PAGE_SIZE) >= PAGE_SIZE) + goto done; + } + } + } + + return strlen(buf); + +done: + ql_log(ql_log_warn, vha, 0xffff, + "NVME connect string buffer size 0x%lx exceeds 0x%lx\n", + sizeof(*buf), PAGE_SIZE); + return strlen(buf); +} + /* ----- */ static ssize_t @@ -2145,7 +2264,7 @@ static DEVICE_ATTR(zio_threshold, 0644, static DEVICE_ATTR_RW(qlini_mode); static DEVICE_ATTR_RW(ql2xexchoffld); static DEVICE_ATTR_RW(ql2xiniexchg); - +static DEVICE_ATTR(nvme_connect_str, 0444, qla27xx_nvme_connect_str_show, NULL); struct device_attribute *qla2x00_host_attrs[] = { &dev_attr_driver_version, @@ -2183,6 +2302,7 @@ struct device_attribute *qla2x00_host_attrs[] = { &dev_attr_min_link_speed, &dev_attr_max_speed_sup, &dev_attr_zio_threshold, + &dev_attr_nvme_connect_str, NULL, /* reserve for qlini_mode */ NULL, /* reserve for ql2xiniexchg */ NULL, /* reserve for ql2xexchoffld */ -- 2.12.0