专职 iSCSI target 开发已经是四五年前的事情了,最近发现有些命令都有些生疏了。简单总结一下 Linux 下 iSCSI 的使用和 iSCSI initiator 内核态代码流程。
环境为 CentOS 7.x,需要注意的是,Ubuntu 下的 targetcli 与 CentOS 下的 targetcli 使用的是不同的 fork。
target 配置
$ fallocate -l $((1024 * 1024 * 1024)) dat
$ ll -h dat
-rw-r--r--. 1 runsisi runsisi 1.0G Oct 28 14:01 dat
$ sudo targetcli
/> cd /backstores/fileio
/backstores/fileio> create file_or_dev=dat name=xxx
Created fileio xxx with size 1073741824
/backstores/fileio> cd /iscsi/
/iscsi> create
Created target iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1.
Created TPG 1.
Global pref auto_add_default_portal=true
Created default portal listening on all IPs (0.0.0.0), port 3260.
/iscsi> cd iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1/tpg1/luns/
/iscsi/iqn.20...cd1/tpg1/luns> create /backstores/fileio/xxx
Created LUN 0.
/iscsi/iqn.20...cd1/tpg1/luns> cd /iscsi/
/iscsi> set discovery_auth enable=0
Parameter enable is now 'False'.
/iscsi> cd iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1/tpg1/
/iscsi/iqn.20...795b3cd1/tpg1> set attribute authentication=0
Parameter authentication is now '0'.
/iscsi/iqn.20...795b3cd1/tpg1> set parameter AuthMethod=None
Parameter AuthMethod is now 'None'.
/iscsi/iqn.20...795b3cd1/tpg1> cd acls/
/iscsi/iqn.20...cd1/tpg1/acls> create iqn.1994-05.com.redhat:6eff34aa8f8
Created Node ACL for iqn.1994-05.com.redhat:6eff34aa8f8
Created mapped LUN 0.
/iscsi/iqn.20...cd1/tpg1/acls> ls /
o- / ......................................................................................................................... [...]
o- backstores .............................................................................................................. [...]
| o- block .................................................................................................. [Storage Objects: 0]
| o- fileio ................................................................................................. [Storage Objects: 1]
| | o- xxx ................................................................................... [dat (1.0GiB) write-back activated]
| | o- alua ................................................................................................... [ALUA Groups: 1]
| | o- default_tg_pt_gp ....................................................................... [ALUA state: Active/optimized]
| o- pscsi .................................................................................................. [Storage Objects: 0]
| o- ramdisk ................................................................................................ [Storage Objects: 0]
o- iscsi ............................................................................................................ [Targets: 1]
| o- iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1 .......................................................... [TPGs: 1]
| o- tpg1 ............................................................................................... [no-gen-acls, no-auth]
| o- acls .......................................................................................................... [ACLs: 1]
| | o- iqn.1994-05.com.redhat:6eff34aa8f8 ................................................................... [Mapped LUNs: 1]
| | o- mapped_lun0 .................................................................................. [lun0 fileio/xxx (rw)]
| o- luns .......................................................................................................... [LUNs: 1]
| | o- lun0 ............................................................................ [fileio/xxx (dat) (default_tg_pt_gp)]
| o- portals .................................................................................................... [Portals: 1]
| o- 0.0.0.0:3260 ..................................................................................................... [OK]
o- loopback ......................................................................................................... [Targets: 0]
o- qla2xxx .......................................................................................................... [Targets: 0]
/iscsi/iqn.20...cd1/tpg1/acls> cd /
/> saveconfig
Configuration saved to /etc/target/saveconfig.json
/> exit
Global pref auto_save_on_exit=true
Configuration saved to /etc/target/saveconfig.json
ISCSI-SPECIFIC
discovery_auth
/iscsi configuration node. Set the normal and mutual authentication userid and password
for discovery sessions, as well as enabling or disabling it. By default it is disabled --
no authentication is required for discovery.
parameter
/iscsi/<target_iqn>/tpgX configuration node. ISCSI-specific parameters such as AuthMethod,
MaxBurstLength, IFMarker, DataDigest, and similar.
attribute
/iscsi/<target_iqn>/tpgX configuration node. Contains implementation-specific settings for
the TPG, such as authentication, to enforce or disable authentication for the full-feature
phase (i.e. non-discovery).
auth
/iscsi/<target_iqn>/tpgX/acls/<initiator_iqn> configuration node. Set the userid and
password for full-feature phase for this ACL.
$ ss -ntpl | grep 3260
LISTEN 0 256 *:3260 *:*
# lsmod | grep iscsi
iscsi_target_mod 287476 7
target_core_mod 342807 15 target_core_iblock,target_core_pscsi,iscsi_target_mod,target_core_file,target_core_user
initiator 配置
$ cat /etc/iscsi/initiatorname.iscsi
InitiatorName=iqn.1994-05.com.redhat:6eff34aa8f8
$ sudo vi /etc/iscsi/iscsid.conf
# *************
# CHAP Settings
# *************
# To enable CHAP authentication set node.session.auth.authmethod
# to CHAP. The default is None.
#node.session.auth.authmethod = CHAP
# To set a CHAP username and password for initiator
# authentication by the target(s), uncomment the following lines:
#node.session.auth.username = username
#node.session.auth.password = password
# To set a CHAP username and password for target(s)
# authentication by the initiator, uncomment the following lines:
#node.session.auth.username_in = username_in
#node.session.auth.password_in = password_in
# To enable CHAP authentication for a discovery session to the target
# set discovery.sendtargets.auth.authmethod to CHAP. The default is None.
#discovery.sendtargets.auth.authmethod = CHAP
# To set a discovery session CHAP username and password for the initiator
# authentication by the target(s), uncomment the following lines:
#discovery.sendtargets.auth.username = username
#discovery.sendtargets.auth.password = password
# To set a discovery session CHAP username and password for target(s)
# authentication by the initiator, uncomment the following lines:
#discovery.sendtargets.auth.username_in = username_in
#discovery.sendtargets.auth.password_in = password_in
$ sudo iscsiadm -m discovery -t st -p 192.168.5.3
192.168.5.3:3260,1 iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1
$ sudo iscsiadm -m discovery -P 1
SENDTARGETS:
DiscoveryAddress: 192.168.5.3,3260
Target: iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1
Portal: 192.168.5.3:3260,1
Iface Name: default
$ sudo iscsiadm -m node -l
Logging in to [iface: default, target: iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1, portal: 192.168.5.3,3260] (multiple)
Login to [iface: default, target: iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1, portal: 192.168.5.3,3260] successful.
$ sudo iscsiadm -m session -P 3
iSCSI Transport Class version 2.0-870
version 6.2.0.874-7
Target: iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1 (non-flash)
Current Portal: 192.168.5.3:3260,1
Persistent Portal: 192.168.5.3:3260,1
**********
Interface:
**********
Iface Name: default
Iface Transport: tcp
Iface Initiatorname: iqn.1994-05.com.redhat:6eff34aa8f8
Iface IPaddress: 192.168.5.2
Iface HWaddress: <empty>
Iface Netdev: <empty>
SID: 2
iSCSI Connection State: LOGGED IN
iSCSI Session State: LOGGED_IN
Internal iscsid Session State: NO CHANGE
*********
Timeouts:
*********
Recovery Timeout: 120
Target Reset Timeout: 30
LUN Reset Timeout: 30
Abort Timeout: 15
*****
CHAP:
*****
username: <empty>
password: ********
username_in: <empty>
password_in: ********
************************
Negotiated iSCSI params:
************************
HeaderDigest: None
DataDigest: None
MaxRecvDataSegmentLength: 262144
MaxXmitDataSegmentLength: 262144
FirstBurstLength: 65536
MaxBurstLength: 262144
ImmediateData: Yes
InitialR2T: Yes
MaxOutstandingR2T: 1
************************
Attached SCSI devices:
************************
Host Number: 8 State: running
scsi8 Channel 00 Id 0 Lun: 0
Attached scsi disk sdh State: running
$ lsmod | grep iscsi | grep -v target
iscsi_tcp 18333 1
libiscsi_tcp 25146 1 iscsi_tcp
libiscsi 57233 2 libiscsi_tcp,iscsi_tcp
scsi_transport_iscsi 99909 3 iscsi_tcp,libiscsi
$ ll /sys/block/sdh
lrwxrwxrwx. 1 root root 0 Oct 28 15:59 /sys/block/sdh -> ../devices/platform/host8/session2/target8:0:0/8:0:0:0/block/sdh
$ cd /sys/devices/platform/host8
$ ls
iscsi_host power scsi_host session2 subsystem uevent
增加 LUN 并 rescan
$ fallocate -l $((1024*1024*1024)) dat2
$ sudo targetcli
/> cd backstores/fileio/
/backstores/fileio> create file_or_dev=dat2 name=xxx2
Created fileio xxx2 with size 1073741824
/backstores/fileio> cd /iscsi/iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1/tpg1/luns/
/iscsi/iqn.20...cd1/tpg1/luns> create /backstores/fileio/xxx2
Created LUN 1.
Created LUN 1->1 mapping in node ACL iqn.1994-05.com.redhat:6eff34aa8f8
/iscsi/iqn.20...cd1/tpg1/luns> ls /
o- / ......................................................................................................................... [...]
o- backstores .............................................................................................................. [...]
| o- block .................................................................................................. [Storage Objects: 0]
| o- fileio ................................................................................................. [Storage Objects: 2]
| | o- xxx ................................................................................... [dat (1.0GiB) write-back activated]
| | | o- alua ................................................................................................... [ALUA Groups: 1]
| | | o- default_tg_pt_gp ....................................................................... [ALUA state: Active/optimized]
| | o- xxx2 ................................................................................. [dat2 (1.0GiB) write-back activated]
| | o- alua ................................................................................................... [ALUA Groups: 1]
| | o- default_tg_pt_gp ....................................................................... [ALUA state: Active/optimized]
| o- pscsi .................................................................................................. [Storage Objects: 0]
| o- ramdisk ................................................................................................ [Storage Objects: 0]
o- iscsi ............................................................................................................ [Targets: 1]
| o- iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1 .......................................................... [TPGs: 1]
| o- tpg1 ............................................................................................... [no-gen-acls, no-auth]
| o- acls .......................................................................................................... [ACLs: 1]
| | o- iqn.1994-05.com.redhat:6eff34aa8f8 ................................................................... [Mapped LUNs: 2]
| | o- mapped_lun0 .................................................................................. [lun0 fileio/xxx (rw)]
| | o- mapped_lun1 ................................................................................. [lun1 fileio/xxx2 (rw)]
| o- luns .......................................................................................................... [LUNs: 2]
| | o- lun0 ............................................................................ [fileio/xxx (dat) (default_tg_pt_gp)]
| | o- lun1 .......................................................................... [fileio/xxx2 (dat2) (default_tg_pt_gp)]
| o- portals .................................................................................................... [Portals: 1]
| o- 0.0.0.0:3260 ..................................................................................................... [OK]
o- loopback ......................................................................................................... [Targets: 0]
o- qla2xxx .......................................................................................................... [Targets: 0]
/iscsi/iqn.20...cd1/tpg1/luns> cd /
/> saveconfig
Configuration saved to /etc/target/saveconfig.json
/> exit
Global pref auto_save_on_exit=true
Last 10 configs saved in /etc/target/backup/.
Configuration saved to /etc/target/saveconfig.json
$ sudo iscsiadm -m session -R
Rescanning session [sid: 2, target: iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1, portal: 192.168.5.3,3260]
$ sudo iscsiadm -m session -P 3
iSCSI Transport Class version 2.0-870
version 6.2.0.874-7
Target: iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1 (non-flash)
Current Portal: 192.168.5.3:3260,1
Persistent Portal: 192.168.5.3:3260,1
**********
Interface:
**********
Iface Name: default
Iface Transport: tcp
Iface Initiatorname: iqn.1994-05.com.redhat:6eff34aa8f8
Iface IPaddress: 192.168.5.2
Iface HWaddress: <empty>
Iface Netdev: <empty>
SID: 2
iSCSI Connection State: LOGGED IN
iSCSI Session State: LOGGED_IN
Internal iscsid Session State: NO CHANGE
*********
Timeouts:
*********
Recovery Timeout: 120
Target Reset Timeout: 30
LUN Reset Timeout: 30
Abort Timeout: 15
*****
CHAP:
*****
username: <empty>
password: ********
username_in: <empty>
password_in: ********
************************
Negotiated iSCSI params:
************************
HeaderDigest: None
DataDigest: None
MaxRecvDataSegmentLength: 262144
MaxXmitDataSegmentLength: 262144
FirstBurstLength: 65536
MaxBurstLength: 262144
ImmediateData: Yes
InitialR2T: Yes
MaxOutstandingR2T: 1
************************
Attached SCSI devices:
************************
Host Number: 8 State: running
scsi8 Channel 00 Id 0 Lun: 0
Attached scsi disk sdh State: running
scsi8 Channel 00 Id 0 Lun: 1
Attached scsi disk sdi State: running
$ ll /sys/block/sdh
lrwxrwxrwx. 1 root root 0 Oct 28 15:59 /sys/block/sdh -> ../devices/platform/host8/session2/target8:0:0/8:0:0:0/block/sdh
$ ll /sys/block/sdi
lrwxrwxrwx. 1 root root 0 Oct 28 16:32 /sys/block/sdi -> ../devices/platform/host8/session2/target8:0:0/8:0:0:1/block/sdi
增加 LUN 并手工 scan
$ sudo iscsiadm -m node -u
Logging out of session [sid: 2, target: iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1, portal: 192.168.5.3,3260]
Logout of [sid: 2, target: iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1, portal: 192.168.5.3,3260] successful.
$ sudo iscsiadm -m node -l
Logging in to [iface: default, target: iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1, portal: 192.168.5.3,3260] (multiple)
Login to [iface: default, target: iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1, portal: 192.168.5.3,3260] successful.
$ sudo iscsiadm -m session -P 3
iSCSI Transport Class version 2.0-870
version 6.2.0.874-7
Target: iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1 (non-flash)
Current Portal: 192.168.5.3:3260,1
Persistent Portal: 192.168.5.3:3260,1
**********
Interface:
**********
Iface Name: default
Iface Transport: tcp
Iface Initiatorname: iqn.1994-05.com.redhat:6eff34aa8f8
Iface IPaddress: 192.168.5.2
Iface HWaddress: <empty>
Iface Netdev: <empty>
SID: 3
iSCSI Connection State: LOGGED IN
iSCSI Session State: LOGGED_IN
Internal iscsid Session State: NO CHANGE
*********
Timeouts:
*********
Recovery Timeout: 120
Target Reset Timeout: 30
LUN Reset Timeout: 30
Abort Timeout: 15
*****
CHAP:
*****
username: <empty>
password: ********
username_in: <empty>
password_in: ********
************************
Negotiated iSCSI params:
************************
HeaderDigest: None
DataDigest: None
MaxRecvDataSegmentLength: 262144
MaxXmitDataSegmentLength: 262144
FirstBurstLength: 65536
MaxBurstLength: 262144
ImmediateData: Yes
InitialR2T: Yes
MaxOutstandingR2T: 1
************************
Attached SCSI devices:
************************
Host Number: 9 State: running
scsi9 Channel 00 Id 0 Lun: 0
Attached scsi disk sdh State: running
scsi9 Channel 00 Id 0 Lun: 1
Attached scsi disk sdi State: running
$ ll /sys/block/sdh
lrwxrwxrwx. 1 root root 0 Oct 28 16:35 /sys/block/sdh -> ../devices/platform/host9/session3/target9:0:0/9:0:0:0/block/sdh
$ ll /sys/block/sdi
lrwxrwxrwx. 1 root root 0 Oct 28 16:36 /sys/block/sdi -> ../devices/platform/host9/session3/target9:0:0/9:0:0:1/block/sdi
$ cd /sys/devices/platform/host9/scsi_host/host9/
$ sudo su
// channel id / target id / lun, scsi_sysfs.c/scsi_scan -> scsi_transport_iscsi.c/iscsi_user_scan
# echo '0 0 2' > scan
# iscsiadm -m session -P 3
iSCSI Transport Class version 2.0-870
version 6.2.0.874-7
Target: iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1 (non-flash)
Current Portal: 192.168.5.3:3260,1
Persistent Portal: 192.168.5.3:3260,1
**********
Interface:
**********
Iface Name: default
Iface Transport: tcp
Iface Initiatorname: iqn.1994-05.com.redhat:6eff34aa8f8
Iface IPaddress: 192.168.5.2
Iface HWaddress: <empty>
Iface Netdev: <empty>
SID: 3
iSCSI Connection State: LOGGED IN
iSCSI Session State: LOGGED_IN
Internal iscsid Session State: NO CHANGE
*********
Timeouts:
*********
Recovery Timeout: 120
Target Reset Timeout: 30
LUN Reset Timeout: 30
Abort Timeout: 15
*****
CHAP:
*****
username: <empty>
password: ********
username_in: <empty>
password_in: ********
************************
Negotiated iSCSI params:
************************
HeaderDigest: None
DataDigest: None
MaxRecvDataSegmentLength: 262144
MaxXmitDataSegmentLength: 262144
FirstBurstLength: 65536
MaxBurstLength: 262144
ImmediateData: Yes
InitialR2T: Yes
MaxOutstandingR2T: 1
************************
Attached SCSI devices:
************************
Host Number: 9 State: running
scsi9 Channel 00 Id 0 Lun: 0
Attached scsi disk sdh State: running
scsi9 Channel 00 Id 0 Lun: 1
Attached scsi disk sdi State: running
scsi9 Channel 00 Id 0 Lun: 2
Attached scsi disk sdj State: running
$ tree /var/lib/iscsi/
/var/lib/iscsi/
├── ifaces
├── isns
├── nodes
│ ├── iqn.2003-01.org.linux-iscsi.ceph11.x8664:sn.43626b03664a
│ │ └── 192.168.5.2,3260,1
│ │ └── default
│ └── iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1
│ └── 192.168.5.3,3260,1
│ └── default
├── send_targets
│ ├── 192.168.5.2,3260
│ │ ├── iqn.2003-01.org.linux-iscsi.ceph11.x8664:sn.43626b03664a,192.168.5.2,3260,1,default -> /var/lib/iscsi/nodes/iqn.2003-01.org.linux-iscsi.ceph11.x8664:sn.43626b03664a/192.168.5.2,3260,1
│ │ └── st_config
│ └── 192.168.5.3,3260
│ ├── iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1,192.168.5.3,3260,1,default -> /var/lib/iscsi/nodes/iqn.2003-01.org.linux-iscsi.hust17.x8664:sn.6760795b3cd1/192.168.5.3,3260,1
│ └── st_config
├── slp
└── static
sysfs & procfs
$ ls /sys/class/ | grep ^iscsi
iscsi_connection
iscsi_endpoint
iscsi_host
iscsi_iface
iscsi_session
iscsi_transport
$ cat /proc/scsi/scsi
...
Host: scsi9 Channel: 00 Id: 00 Lun: 00
Vendor: LIO-ORG Model: xxx Rev: 4.0
Type: Direct-Access ANSI SCSI revision: 05
Host: scsi9 Channel: 00 Id: 00 Lun: 01
Vendor: LIO-ORG Model: xxx2 Rev: 4.0
Type: Direct-Access ANSI SCSI revision: 05
Host: scsi9 Channel: 00 Id: 00 Lun: 02
Vendor: LIO-ORG Model: xxx3 Rev: 4.0
Type: Direct-Access ANSI SCSI revision: 05
$ ls /sys/class/ | grep ^scsi
scsi_device
scsi_disk
scsi_generic
scsi_host
initiator (kernel) 代码实现
scsi_transport_iscsi
iscsi_tcp
libiscsi
libiscsi_tcp
scsi_transport_iscsi.c
iscsi_transport_init
struct netlink_kernel_cfg cfg = {
.groups = 1,
.input = iscsi_if_rx,
};
netlink_kernel_create(&init_net, NETLINK_ISCSI, &cfg)
iscsi_if_rx
iscsi_if_recv_msg(skb)
struct iscsi_internal *priv = iscsi_if_transport_lookup(iscsi_ptr(ev->transport_handle))
transport = priv->iscsi_transport // iscsi_transport
switch (nlh->nlmsg_type) {
case ISCSI_UEVENT_CREATE_SESSION:
iscsi_if_create_session(priv)
session = transport->create_session
case ISCSI_UEVENT_CREATE_CONN:
iscsi_if_create_conn(transport)
session = iscsi_session_lookup(ev->u.c_conn.sid)
conn = transport->create_conn(session, ev->u.c_conn.cid)
case ISCSI_UEVENT_BIND_CONN:
session = iscsi_session_lookup(ev->u.b_conn.sid)
conn = iscsi_conn_lookup(ev->u.b_conn.sid, ev->u.b_conn.cid)
transport->bind_conn(session, conn)
iscsi_register_transport(struct iscsi_transport *tt)
struct iscsi_internal *priv = kzalloc(sizeof(*priv), GFP_KERNEL)
priv->iscsi_transport = tt // iscsi_transport, &iscsi_sw_tcp_transport
priv->t.user_scan = iscsi_user_scan // /sys/devices/platform/hostX/scsi_host/hostX/scan
priv->dev.class = &iscsi_transport_class // /sys/class/iscsi_transport
dev_set_name(&priv->dev, "%s", tt->name)
device_register(&priv->dev) // /sys/class/iscsi_transport/tcp
transport_container_register(&priv->t.host_attrs) // /sys/class/iscsi_host
transport_container_register(&priv->conn_cont) // /sys/class/iscsi_connection
transport_container_register(&priv->session_cont) // /sys/class/iscsi_session
iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *iscsit, int dd_size)
session = kzalloc(sizeof(*session) + dd_size, GFP_KERNEL)
session->transport = iscsit // iscsi_transport
device_initialize(&session->dev)
iscsi_add_session(struct iscsi_cls_session *session, unsigned int target_id)
session->sid = atomic_add_return(1, &iscsi_session_nr)
dev_set_name(&session->dev, "session%u", session->sid);
device_add(&session->dev)
iscsi_create_conn(struct iscsi_cls_session *session, int dd_size, uint32_t cid)
iscsi_transport *transport = session->transport
iscsi_cls_conn *conn = kzalloc(sizeof(*conn) + dd_size, GFP_KERNEL)
conn->transport = transport;
conn->cid = cid;
dev_set_name(&conn->dev, "connection%d:%u", session->sid, cid)
device_register(&conn->dev)
device_initialize(dev)
device_add(dev)
transport_register_device(&conn->dev)
hosts.c
scsi_host_alloc(struct scsi_host_template *sht, int privsize)
shost = kzalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask)
shost->host_no = atomic_inc_return(&scsi_host_next_hn) - 1
shost->hostt = sht
device_initialize(&shost->shost_gendev)
dev_set_name(&shost->shost_gendev, "host%d", shost->host_no)
device_initialize(&shost->shost_dev)
dev_set_name(&shost->shost_dev, "host%d", shost->host_no)
shost->ehandler = kthread_run(scsi_error_handler, shost)
scsi_proc_hostdir_add(shost->hostt)
iscsi_tcp.c
iscsi_sw_tcp_init
iscsi_sw_tcp_scsi_transport = iscsi_register_transport(iscsi_sw_tcp_transport)
iscsi_sw_tcp_session_create
shost = iscsi_host_alloc(&iscsi_sw_tcp_sht)
shost->transportt = iscsi_sw_tcp_scsi_transport // scsi_transport_template
iscsi_host_add(shost, NULL)
iscsi_session_setup(&iscsi_sw_tcp_transport, shost)
iscsi_sw_tcp_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)
struct iscsi_cls_conn *cls_conn = iscsi_tcp_conn_setup(cls_session, sizeof(*tcp_sw_conn), conn_idx)
static struct scsi_host_template iscsi_sw_tcp_sht = {
.module = THIS_MODULE,
.name = "iSCSI Initiator over TCP/IP",
.queuecommand = iscsi_queuecommand,
.change_queue_depth = iscsi_change_queue_depth,
.can_queue = ISCSI_DEF_XMIT_CMDS_MAX - 1,
.sg_tablesize = 4096,
.max_sectors = 0xFFFF,
.cmd_per_lun = ISCSI_DEF_CMD_PER_LUN,
.eh_abort_handler = iscsi_eh_abort,
.eh_device_reset_handler= iscsi_eh_device_reset,
.eh_target_reset_handler = iscsi_eh_recover_target,
.use_clustering = DISABLE_CLUSTERING,
.slave_alloc = iscsi_sw_tcp_slave_alloc,
.slave_configure = iscsi_sw_tcp_slave_configure,
.target_alloc = iscsi_target_alloc,
.proc_name = "iscsi_tcp",
.this_id = -1,
};
static struct iscsi_transport iscsi_sw_tcp_transport = {
.owner = THIS_MODULE,
.name = "tcp",
.caps = CAP_RECOVERY_L0 | CAP_MULTI_R2T | CAP_HDRDGST | CAP_DATADGST,
/* session management */
.create_session = iscsi_sw_tcp_session_create,
.destroy_session = iscsi_sw_tcp_session_destroy,
/* connection management */
.create_conn = iscsi_sw_tcp_conn_create,
.bind_conn = iscsi_sw_tcp_conn_bind,
.destroy_conn = iscsi_sw_tcp_conn_destroy,
.attr_is_visible = iscsi_sw_tcp_attr_is_visible,
.set_param = iscsi_sw_tcp_conn_set_param,
.get_conn_param = iscsi_sw_tcp_conn_get_param,
.get_session_param = iscsi_session_get_param,
.start_conn = iscsi_conn_start,
.stop_conn = iscsi_sw_tcp_conn_stop,
/* iscsi host params */
.get_host_param = iscsi_sw_tcp_host_get_param,
.set_host_param = iscsi_host_set_param,
/* IO */
.send_pdu = iscsi_conn_send_pdu,
.get_stats = iscsi_sw_tcp_conn_get_stats,
/* iscsi task/cmd helpers */
.init_task = iscsi_tcp_task_init,
.xmit_task = iscsi_tcp_task_xmit,
.cleanup_task = iscsi_tcp_cleanup_task,
/* low level pdu helpers */
.xmit_pdu = iscsi_sw_tcp_pdu_xmit,
.init_pdu = iscsi_sw_tcp_pdu_init,
.alloc_pdu = iscsi_sw_tcp_pdu_alloc,
/* recovery */
.session_recovery_timedout = iscsi_session_recovery_timedout,
};
libiscsi.c
iscsi_host_alloc(struct scsi_host_template *sht)
shost = scsi_host_alloc(sht)
iscsi_host_add(struct Scsi_Host *shost, struct device *pdev)
scsi_add_host(shost, pdev)
scsi_add_host_with_dma(host, dev, dev)
device_add(&shost->shost_gendev)
device_add(&shost->shost_dev)
scsi_sysfs_add_host(shost)
scsi_proc_host_add(shost)
iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost)
cls_session = iscsi_alloc_session(shost, iscsit)
iscsi_add_session(cls_session, 0)
iscsi_conn_setup(struct iscsi_cls_session *cls_session, int dd_size, uint32_t conn_idx)
iscsi_session *session = cls_session->dd_data
cls_conn = iscsi_create_conn(cls_session, sizeof(*conn) + dd_size, conn_idx)
conn = cls_conn->dd_data;
conn->session = session;
conn->cls_conn = cls_conn;
libiscsi_tcp.c
iscsi_tcp_conn_setup(struct iscsi_cls_session *cls_session, int dd_data_size, uint32_t conn_idx)
cls_conn = iscsi_conn_setup(cls_session, sizeof(*tcp_conn) + dd_data_size, conn_idx)
参考资料
targetcli - administration shell for storage targets
http://manpages.ubuntu.com/manpages/bionic/man8/targetcli.8.html
Tour the Linux generic SCSI driver
https://developer.ibm.com/technologies/linux/tutorials/l-scsi-api/
An introduction to SCSI drivers
Advanced Programmable Interrupt Controller
https://en.wikipedia.org/wiki/Advanced_Programmable_Interrupt_Controller
Message Signaled Interrupts
https://en.wikipedia.org/wiki/Message_Signaled_Interrupts
A block layer introduction part 1: the bio layer
https://lwn.net/Articles/736534/
Block layer introduction part 2: the request layer
https://lwn.net/Articles/738449/
最后修改于 2019-10-30