diff options
author | Hannes Reinecke <hare@suse.de> | 2013-10-16 03:12:53 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-10-16 18:41:26 -0400 |
commit | fb2b2844743bc3d84ce1033167210e5fe3963455 (patch) | |
tree | 1b201f28602ef120a018c008aa98149bedd0adc6 /drivers/target | |
parent | 1ec59fee296d798b83a11f888981531dae16bfe8 (diff) |
tcm_loop: Implement transport offline
Add attribute 'transport_status' to simulate link failure.
Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/loopback/tcm_loop.c | 53 | ||||
-rw-r--r-- | drivers/target/loopback/tcm_loop.h | 4 |
2 files changed, 56 insertions, 1 deletions
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 21b49f351723..a00ad27940b7 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c | |||
@@ -178,7 +178,10 @@ static void tcm_loop_submission_work(struct work_struct *work) | |||
178 | set_host_byte(sc, DID_NO_CONNECT); | 178 | set_host_byte(sc, DID_NO_CONNECT); |
179 | goto out_done; | 179 | goto out_done; |
180 | } | 180 | } |
181 | 181 | if (tl_tpg->tl_transport_status == TCM_TRANSPORT_OFFLINE) { | |
182 | set_host_byte(sc, DID_TRANSPORT_DISRUPTED); | ||
183 | goto out_done; | ||
184 | } | ||
182 | tl_nexus = tl_hba->tl_nexus; | 185 | tl_nexus = tl_hba->tl_nexus; |
183 | if (!tl_nexus) { | 186 | if (!tl_nexus) { |
184 | scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus" | 187 | scmd_printk(KERN_ERR, sc, "TCM_Loop I_T Nexus" |
@@ -1064,8 +1067,56 @@ check_newline: | |||
1064 | 1067 | ||
1065 | TF_TPG_BASE_ATTR(tcm_loop, nexus, S_IRUGO | S_IWUSR); | 1068 | TF_TPG_BASE_ATTR(tcm_loop, nexus, S_IRUGO | S_IWUSR); |
1066 | 1069 | ||
1070 | static ssize_t tcm_loop_tpg_show_transport_status( | ||
1071 | struct se_portal_group *se_tpg, | ||
1072 | char *page) | ||
1073 | { | ||
1074 | struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, | ||
1075 | struct tcm_loop_tpg, tl_se_tpg); | ||
1076 | const char *status = NULL; | ||
1077 | ssize_t ret = -EINVAL; | ||
1078 | |||
1079 | switch (tl_tpg->tl_transport_status) { | ||
1080 | case TCM_TRANSPORT_ONLINE: | ||
1081 | status = "online"; | ||
1082 | break; | ||
1083 | case TCM_TRANSPORT_OFFLINE: | ||
1084 | status = "offline"; | ||
1085 | break; | ||
1086 | default: | ||
1087 | break; | ||
1088 | } | ||
1089 | |||
1090 | if (status) | ||
1091 | ret = snprintf(page, PAGE_SIZE, "%s\n", status); | ||
1092 | |||
1093 | return ret; | ||
1094 | } | ||
1095 | |||
1096 | static ssize_t tcm_loop_tpg_store_transport_status( | ||
1097 | struct se_portal_group *se_tpg, | ||
1098 | const char *page, | ||
1099 | size_t count) | ||
1100 | { | ||
1101 | struct tcm_loop_tpg *tl_tpg = container_of(se_tpg, | ||
1102 | struct tcm_loop_tpg, tl_se_tpg); | ||
1103 | |||
1104 | if (!strncmp(page, "online", 6)) { | ||
1105 | tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE; | ||
1106 | return count; | ||
1107 | } | ||
1108 | if (!strncmp(page, "offline", 7)) { | ||
1109 | tl_tpg->tl_transport_status = TCM_TRANSPORT_OFFLINE; | ||
1110 | return count; | ||
1111 | } | ||
1112 | return -EINVAL; | ||
1113 | } | ||
1114 | |||
1115 | TF_TPG_BASE_ATTR(tcm_loop, transport_status, S_IRUGO | S_IWUSR); | ||
1116 | |||
1067 | static struct configfs_attribute *tcm_loop_tpg_attrs[] = { | 1117 | static struct configfs_attribute *tcm_loop_tpg_attrs[] = { |
1068 | &tcm_loop_tpg_nexus.attr, | 1118 | &tcm_loop_tpg_nexus.attr, |
1119 | &tcm_loop_tpg_transport_status.attr, | ||
1069 | NULL, | 1120 | NULL, |
1070 | }; | 1121 | }; |
1071 | 1122 | ||
diff --git a/drivers/target/loopback/tcm_loop.h b/drivers/target/loopback/tcm_loop.h index dd7a84ee78e1..56528f7dafae 100644 --- a/drivers/target/loopback/tcm_loop.h +++ b/drivers/target/loopback/tcm_loop.h | |||
@@ -40,8 +40,12 @@ struct tcm_loop_nacl { | |||
40 | struct se_node_acl se_node_acl; | 40 | struct se_node_acl se_node_acl; |
41 | }; | 41 | }; |
42 | 42 | ||
43 | #define TCM_TRANSPORT_ONLINE 0 | ||
44 | #define TCM_TRANSPORT_OFFLINE 1 | ||
45 | |||
43 | struct tcm_loop_tpg { | 46 | struct tcm_loop_tpg { |
44 | unsigned short tl_tpgt; | 47 | unsigned short tl_tpgt; |
48 | unsigned short tl_transport_status; | ||
45 | atomic_t tl_tpg_port_count; | 49 | atomic_t tl_tpg_port_count; |
46 | struct se_portal_group tl_se_tpg; | 50 | struct se_portal_group tl_se_tpg; |
47 | struct tcm_loop_hba *tl_hba; | 51 | struct tcm_loop_hba *tl_hba; |