add transport scan callout to fix sysfs layout when scanning from userspace
Subsystems (2)
RFC PATCH 1/2 add transport scan callout to fix sysfs layout when scanning from userspace
When scanning hosts that implement FC rport support and open-iscsi/linux-iscsi-5 hosts from userspace the sysfs layout will end up placing the target's parent as the host instead of some transport specific object. For FC the target's parent should be the rport and for open-iscsi the parent should be a session (that is if for open-iscsi our using struct devices and our sysfs layout is correct).
The problem is due to the scsi host scan attribute calling scsi_scan_host_selected, but the transports calling scsi_scan_target. To further complicate matters iscsi does not use a work queue for scanning since it initiates the scanning from usersapce and it manages its channel and target numbers from userspace. And, FC rport support is the opposite.
To fix this the inlined patch just adds a scan callout onto the scsi_transport_template so scsi_sysfs can call it if set.
drivers/scsi/scsi_sysfs.c +5 -1
@@ -80,7 +80,11 @@ static int scsi_scan(struct Scsi_Host *sreturn -EINVAL ;if (check_set (&lun, s3))return -EINVAL ; - res =scsi_scan_host_selected (shost, channel, id, lun,1 ); + +if (shost->transportt->scan) + res = shost->transportt->scan (shost, channel, id, lun,1 ); +else + res =scsi_scan_host_selected (shost, channel, id, lun,1 );return res; }
include/scsi/scsi_transport.h +6 -0
@@ -39,6 +39,12 @@ struct scsi_transport_template {* True if the transport wants to use a host-based work-queue */ unsigned int create_work_queue : 1; + +/* +* optional transport specific scanning function +*/ +int (* scan)(struct Scsi_Host *,unsigned int ,unsigned int , +unsigned int ,int ); };#define transport_class_to_shost (tc) \
[dropped iscsi list ...]
Quoted 7 lines · Mike Christie
When scanning hosts that implement FC rport support and open-iscsi/linux-iscsi-5 hosts from userspace the sysfs layout will end up placing the target's parent as the host instead of some transport specific object. For FC the target's parent should be the rport and for open-iscsi the parent should be a session (that is if for open-iscsi our using struct devices and our sysfs layout is correct).
I was trying FC to see if it caused problems, instead of a different layout, no devices are found at all :-(
Getting more info from Mike C, and looking at the code, I expected the scan to work OK, but for the targets to to show up directly under the host, rather than under the rport.
modprobe qla2300 finds sd's as expected (sdg -> sdz), then I remove them all via delete attribute, and then scan via /sys/class/scsi_host/host2/scan, and nothing shows up.
With scsi command and scan logging on (0x2400 | 0x01c0), there were no commands sent, just:
elm3b79:~# scsi_scan_host_selected: <2:4294967295:4294967295:4294967295>
Reloading the qla2300, the devices show up fine again.
I am running plain linux-2.6.12-rc4.
Others with FC storage might want to try this out ...
elm3b79:/sys/bus/scsi/devices# ls 0:0:0:0 0:0:4:0 2:0:12:0 2:0:16:0 2:0:1:0 2:0:5:0 2:0:9:0 0:0:1:0 0:0:5:0 2:0:13:0 2:0:17:0 2:0:2:0 2:0:6:0 0:0:2:0 2:0:10:0 2:0:14:0 2:0:18:0 2:0:3:0 2:0:7:0 0:0:3:0 2:0:11:0 2:0:15:0 2:0:19:0 2:0:4:0 2:0:8:0 elm3b79:/sys/bus/scsi/devices# for x in 2\:0\:*/delete
Quoted 3 lines
do
echo x > ${x}
done
elm3b79:/sys/bus/scsi/devices# echo "- - -" > /sys/class/scsi_host/host2/scan
elm3b79:~# modprobe -r qla2300 elm3b79:~# modprobe qla2300 elm3b79:~# ls /sys/bus/scsi/devices 0:0:0:0 0:0:4:0 3:0:11:0 3:0:15:0 3:0:19:0 3:0:4:0 3:0:8:0 0:0:1:0 0:0:5:0 3:0:12:0 3:0:16:0 3:0:1:0 3:0:5:0 3:0:9:0 0:0:2:0 3:0:0:0 3:0:13:0 3:0:17:0 3:0:2:0 3:0:6:0 0:0:3:0 3:0:10:0 3:0:14:0 3:0:18:0 3:0:3:0 3:0:7:0
-- Patrick Mansfield
Quoted 2 lines · Patrick Mansfield
I was trying FC to see if it caused problems, instead of a different layout, no devices are found at all :-(
The qla2xxx_slave_alloc() is returning -ENXIO, and we don't output any printks in that case for qla2xxx. I added a couple qla_printk's and got lots of:
qla2300 0000:01:0c.0: no rport for <7:0:0:0>
For:
echo "- - -" > /sys/class/scsi_host/hostX/scan
A change similar change what Mike C. did for iSCSI is needed for FC transport, or any transport that has a "device" between the host and target. For qla, we need to eventually call its slave_alloc() with a target under an rport (so starget_to_rport() gets the rport).
Having a transportt->scan seems a bit high level, I have no better suggestion, there should be a way to make this generic for all transports.
It is easy for iSCSI since it has a one-to-one mapping of scsi_host toscsi_target: AFAICT you just call scsi_scan_target() once. FC has to iterate over all rports, and call scsi_scan_target() for all targets, or find the rport that matches the id.
Where is iscsi_register_transport? A current git tree? I should probably be using that tree, still trying to get up to speed on git.
qla2xxx debug patch, but we should always print something when returning -ENXIO:
drivers/scsi/qla2xxx/qla_os.c renamed from drivers/scsi/qla2xxx/orig-qla_os.c +10 -2
@@ -992,8 +992,12 @@ qla2xxx_slave_alloc(struct scsi_device *fc_port_t *fcport;int found; -if (!rport) +if (!rport) { +qla_printk (KERN_WARNING , ha, +"no rport for <%d:%d:%d:%d>\n" , + sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);return -ENXIO ; + } found =0 ;list_for_each_entry (fcport, &ha->fcports, list) {
@@ -1003,8 +1007,12 @@ qla2xxx_slave_alloc(struct scsi_device *break ; } } -if (!found) +if (!found) { +qla_printk (KERN_WARNING , ha, +"no device at <%d:%d:%d:%d>\n" , + sdev->host->host_no, sdev->channel, sdev->id, sdev->lun);return -ENXIO ; + } sdev->hostdata = fcport;
Quoted 2 lines · Patrick Mansfield
Where is
iscsi_register_transport? A current git tree? I should probably
subversion tree
svn checkout svn://svn.berlios.de/open-iscsi
Look in kernel/scsi_transport_iscsi.c
http://svn.berlios.de/viewcvs/open-iscsi/kernel/scsi_transport_iscsi.c?rev=338&view=markup