diff options
Diffstat (limited to 'drivers/target/iscsi/iscsi_target_stat.c')
-rw-r--r-- | drivers/target/iscsi/iscsi_target_stat.c | 950 |
1 files changed, 950 insertions, 0 deletions
diff --git a/drivers/target/iscsi/iscsi_target_stat.c b/drivers/target/iscsi/iscsi_target_stat.c new file mode 100644 index 000000000000..bbdbe9301b27 --- /dev/null +++ b/drivers/target/iscsi/iscsi_target_stat.c | |||
@@ -0,0 +1,950 @@ | |||
1 | /******************************************************************************* | ||
2 | * Modern ConfigFS group context specific iSCSI statistics based on original | ||
3 | * iscsi_target_mib.c code | ||
4 | * | ||
5 | * Copyright (c) 2011 Rising Tide Systems | ||
6 | * | ||
7 | * Licensed to the Linux Foundation under the General Public License (GPL) version 2. | ||
8 | * | ||
9 | * Author: Nicholas A. Bellinger <nab@linux-iscsi.org> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | ******************************************************************************/ | ||
21 | |||
22 | #include <linux/configfs.h> | ||
23 | #include <scsi/iscsi_proto.h> | ||
24 | #include <target/target_core_base.h> | ||
25 | #include <target/target_core_transport.h> | ||
26 | #include <target/configfs_macros.h> | ||
27 | |||
28 | #include "iscsi_target_core.h" | ||
29 | #include "iscsi_target_parameters.h" | ||
30 | #include "iscsi_target_device.h" | ||
31 | #include "iscsi_target_tpg.h" | ||
32 | #include "iscsi_target_util.h" | ||
33 | #include "iscsi_target_stat.h" | ||
34 | |||
35 | #ifndef INITIAL_JIFFIES | ||
36 | #define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) | ||
37 | #endif | ||
38 | |||
39 | /* Instance Attributes Table */ | ||
40 | #define ISCSI_INST_NUM_NODES 1 | ||
41 | #define ISCSI_INST_DESCR "Storage Engine Target" | ||
42 | #define ISCSI_INST_LAST_FAILURE_TYPE 0 | ||
43 | #define ISCSI_DISCONTINUITY_TIME 0 | ||
44 | |||
45 | #define ISCSI_NODE_INDEX 1 | ||
46 | |||
47 | #define ISPRINT(a) ((a >= ' ') && (a <= '~')) | ||
48 | |||
49 | /**************************************************************************** | ||
50 | * iSCSI MIB Tables | ||
51 | ****************************************************************************/ | ||
52 | /* | ||
53 | * Instance Attributes Table | ||
54 | */ | ||
55 | CONFIGFS_EATTR_STRUCT(iscsi_stat_instance, iscsi_wwn_stat_grps); | ||
56 | #define ISCSI_STAT_INSTANCE_ATTR(_name, _mode) \ | ||
57 | static struct iscsi_stat_instance_attribute \ | ||
58 | iscsi_stat_instance_##_name = \ | ||
59 | __CONFIGFS_EATTR(_name, _mode, \ | ||
60 | iscsi_stat_instance_show_attr_##_name, \ | ||
61 | iscsi_stat_instance_store_attr_##_name); | ||
62 | |||
63 | #define ISCSI_STAT_INSTANCE_ATTR_RO(_name) \ | ||
64 | static struct iscsi_stat_instance_attribute \ | ||
65 | iscsi_stat_instance_##_name = \ | ||
66 | __CONFIGFS_EATTR_RO(_name, \ | ||
67 | iscsi_stat_instance_show_attr_##_name); | ||
68 | |||
69 | static ssize_t iscsi_stat_instance_show_attr_inst( | ||
70 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
71 | { | ||
72 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
73 | struct iscsi_tiqn, tiqn_stat_grps); | ||
74 | |||
75 | return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index); | ||
76 | } | ||
77 | ISCSI_STAT_INSTANCE_ATTR_RO(inst); | ||
78 | |||
79 | static ssize_t iscsi_stat_instance_show_attr_min_ver( | ||
80 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
81 | { | ||
82 | return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DRAFT20_VERSION); | ||
83 | } | ||
84 | ISCSI_STAT_INSTANCE_ATTR_RO(min_ver); | ||
85 | |||
86 | static ssize_t iscsi_stat_instance_show_attr_max_ver( | ||
87 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
88 | { | ||
89 | return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DRAFT20_VERSION); | ||
90 | } | ||
91 | ISCSI_STAT_INSTANCE_ATTR_RO(max_ver); | ||
92 | |||
93 | static ssize_t iscsi_stat_instance_show_attr_portals( | ||
94 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
95 | { | ||
96 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
97 | struct iscsi_tiqn, tiqn_stat_grps); | ||
98 | |||
99 | return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_num_tpg_nps); | ||
100 | } | ||
101 | ISCSI_STAT_INSTANCE_ATTR_RO(portals); | ||
102 | |||
103 | static ssize_t iscsi_stat_instance_show_attr_nodes( | ||
104 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
105 | { | ||
106 | return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_INST_NUM_NODES); | ||
107 | } | ||
108 | ISCSI_STAT_INSTANCE_ATTR_RO(nodes); | ||
109 | |||
110 | static ssize_t iscsi_stat_instance_show_attr_sessions( | ||
111 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
112 | { | ||
113 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
114 | struct iscsi_tiqn, tiqn_stat_grps); | ||
115 | |||
116 | return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_nsessions); | ||
117 | } | ||
118 | ISCSI_STAT_INSTANCE_ATTR_RO(sessions); | ||
119 | |||
120 | static ssize_t iscsi_stat_instance_show_attr_fail_sess( | ||
121 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
122 | { | ||
123 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
124 | struct iscsi_tiqn, tiqn_stat_grps); | ||
125 | struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats; | ||
126 | u32 sess_err_count; | ||
127 | |||
128 | spin_lock_bh(&sess_err->lock); | ||
129 | sess_err_count = (sess_err->digest_errors + | ||
130 | sess_err->cxn_timeout_errors + | ||
131 | sess_err->pdu_format_errors); | ||
132 | spin_unlock_bh(&sess_err->lock); | ||
133 | |||
134 | return snprintf(page, PAGE_SIZE, "%u\n", sess_err_count); | ||
135 | } | ||
136 | ISCSI_STAT_INSTANCE_ATTR_RO(fail_sess); | ||
137 | |||
138 | static ssize_t iscsi_stat_instance_show_attr_fail_type( | ||
139 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
140 | { | ||
141 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
142 | struct iscsi_tiqn, tiqn_stat_grps); | ||
143 | struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats; | ||
144 | |||
145 | return snprintf(page, PAGE_SIZE, "%u\n", | ||
146 | sess_err->last_sess_failure_type); | ||
147 | } | ||
148 | ISCSI_STAT_INSTANCE_ATTR_RO(fail_type); | ||
149 | |||
150 | static ssize_t iscsi_stat_instance_show_attr_fail_rem_name( | ||
151 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
152 | { | ||
153 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
154 | struct iscsi_tiqn, tiqn_stat_grps); | ||
155 | struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats; | ||
156 | |||
157 | return snprintf(page, PAGE_SIZE, "%s\n", | ||
158 | sess_err->last_sess_fail_rem_name[0] ? | ||
159 | sess_err->last_sess_fail_rem_name : NONE); | ||
160 | } | ||
161 | ISCSI_STAT_INSTANCE_ATTR_RO(fail_rem_name); | ||
162 | |||
163 | static ssize_t iscsi_stat_instance_show_attr_disc_time( | ||
164 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
165 | { | ||
166 | return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_DISCONTINUITY_TIME); | ||
167 | } | ||
168 | ISCSI_STAT_INSTANCE_ATTR_RO(disc_time); | ||
169 | |||
170 | static ssize_t iscsi_stat_instance_show_attr_description( | ||
171 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
172 | { | ||
173 | return snprintf(page, PAGE_SIZE, "%s\n", ISCSI_INST_DESCR); | ||
174 | } | ||
175 | ISCSI_STAT_INSTANCE_ATTR_RO(description); | ||
176 | |||
177 | static ssize_t iscsi_stat_instance_show_attr_vendor( | ||
178 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
179 | { | ||
180 | return snprintf(page, PAGE_SIZE, "RisingTide Systems iSCSI-Target\n"); | ||
181 | } | ||
182 | ISCSI_STAT_INSTANCE_ATTR_RO(vendor); | ||
183 | |||
184 | static ssize_t iscsi_stat_instance_show_attr_version( | ||
185 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
186 | { | ||
187 | return snprintf(page, PAGE_SIZE, "%s\n", ISCSIT_VERSION); | ||
188 | } | ||
189 | ISCSI_STAT_INSTANCE_ATTR_RO(version); | ||
190 | |||
191 | CONFIGFS_EATTR_OPS(iscsi_stat_instance, iscsi_wwn_stat_grps, | ||
192 | iscsi_instance_group); | ||
193 | |||
194 | static struct configfs_attribute *iscsi_stat_instance_attrs[] = { | ||
195 | &iscsi_stat_instance_inst.attr, | ||
196 | &iscsi_stat_instance_min_ver.attr, | ||
197 | &iscsi_stat_instance_max_ver.attr, | ||
198 | &iscsi_stat_instance_portals.attr, | ||
199 | &iscsi_stat_instance_nodes.attr, | ||
200 | &iscsi_stat_instance_sessions.attr, | ||
201 | &iscsi_stat_instance_fail_sess.attr, | ||
202 | &iscsi_stat_instance_fail_type.attr, | ||
203 | &iscsi_stat_instance_fail_rem_name.attr, | ||
204 | &iscsi_stat_instance_disc_time.attr, | ||
205 | &iscsi_stat_instance_description.attr, | ||
206 | &iscsi_stat_instance_vendor.attr, | ||
207 | &iscsi_stat_instance_version.attr, | ||
208 | NULL, | ||
209 | }; | ||
210 | |||
211 | static struct configfs_item_operations iscsi_stat_instance_item_ops = { | ||
212 | .show_attribute = iscsi_stat_instance_attr_show, | ||
213 | .store_attribute = iscsi_stat_instance_attr_store, | ||
214 | }; | ||
215 | |||
216 | struct config_item_type iscsi_stat_instance_cit = { | ||
217 | .ct_item_ops = &iscsi_stat_instance_item_ops, | ||
218 | .ct_attrs = iscsi_stat_instance_attrs, | ||
219 | .ct_owner = THIS_MODULE, | ||
220 | }; | ||
221 | |||
222 | /* | ||
223 | * Instance Session Failure Stats Table | ||
224 | */ | ||
225 | CONFIGFS_EATTR_STRUCT(iscsi_stat_sess_err, iscsi_wwn_stat_grps); | ||
226 | #define ISCSI_STAT_SESS_ERR_ATTR(_name, _mode) \ | ||
227 | static struct iscsi_stat_sess_err_attribute \ | ||
228 | iscsi_stat_sess_err_##_name = \ | ||
229 | __CONFIGFS_EATTR(_name, _mode, \ | ||
230 | iscsi_stat_sess_err_show_attr_##_name, \ | ||
231 | iscsi_stat_sess_err_store_attr_##_name); | ||
232 | |||
233 | #define ISCSI_STAT_SESS_ERR_ATTR_RO(_name) \ | ||
234 | static struct iscsi_stat_sess_err_attribute \ | ||
235 | iscsi_stat_sess_err_##_name = \ | ||
236 | __CONFIGFS_EATTR_RO(_name, \ | ||
237 | iscsi_stat_sess_err_show_attr_##_name); | ||
238 | |||
239 | static ssize_t iscsi_stat_sess_err_show_attr_inst( | ||
240 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
241 | { | ||
242 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
243 | struct iscsi_tiqn, tiqn_stat_grps); | ||
244 | |||
245 | return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index); | ||
246 | } | ||
247 | ISCSI_STAT_SESS_ERR_ATTR_RO(inst); | ||
248 | |||
249 | static ssize_t iscsi_stat_sess_err_show_attr_digest_errors( | ||
250 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
251 | { | ||
252 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
253 | struct iscsi_tiqn, tiqn_stat_grps); | ||
254 | struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats; | ||
255 | |||
256 | return snprintf(page, PAGE_SIZE, "%u\n", sess_err->digest_errors); | ||
257 | } | ||
258 | ISCSI_STAT_SESS_ERR_ATTR_RO(digest_errors); | ||
259 | |||
260 | static ssize_t iscsi_stat_sess_err_show_attr_cxn_errors( | ||
261 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
262 | { | ||
263 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
264 | struct iscsi_tiqn, tiqn_stat_grps); | ||
265 | struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats; | ||
266 | |||
267 | return snprintf(page, PAGE_SIZE, "%u\n", sess_err->cxn_timeout_errors); | ||
268 | } | ||
269 | ISCSI_STAT_SESS_ERR_ATTR_RO(cxn_errors); | ||
270 | |||
271 | static ssize_t iscsi_stat_sess_err_show_attr_format_errors( | ||
272 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
273 | { | ||
274 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
275 | struct iscsi_tiqn, tiqn_stat_grps); | ||
276 | struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats; | ||
277 | |||
278 | return snprintf(page, PAGE_SIZE, "%u\n", sess_err->pdu_format_errors); | ||
279 | } | ||
280 | ISCSI_STAT_SESS_ERR_ATTR_RO(format_errors); | ||
281 | |||
282 | CONFIGFS_EATTR_OPS(iscsi_stat_sess_err, iscsi_wwn_stat_grps, | ||
283 | iscsi_sess_err_group); | ||
284 | |||
285 | static struct configfs_attribute *iscsi_stat_sess_err_attrs[] = { | ||
286 | &iscsi_stat_sess_err_inst.attr, | ||
287 | &iscsi_stat_sess_err_digest_errors.attr, | ||
288 | &iscsi_stat_sess_err_cxn_errors.attr, | ||
289 | &iscsi_stat_sess_err_format_errors.attr, | ||
290 | NULL, | ||
291 | }; | ||
292 | |||
293 | static struct configfs_item_operations iscsi_stat_sess_err_item_ops = { | ||
294 | .show_attribute = iscsi_stat_sess_err_attr_show, | ||
295 | .store_attribute = iscsi_stat_sess_err_attr_store, | ||
296 | }; | ||
297 | |||
298 | struct config_item_type iscsi_stat_sess_err_cit = { | ||
299 | .ct_item_ops = &iscsi_stat_sess_err_item_ops, | ||
300 | .ct_attrs = iscsi_stat_sess_err_attrs, | ||
301 | .ct_owner = THIS_MODULE, | ||
302 | }; | ||
303 | |||
304 | /* | ||
305 | * Target Attributes Table | ||
306 | */ | ||
307 | CONFIGFS_EATTR_STRUCT(iscsi_stat_tgt_attr, iscsi_wwn_stat_grps); | ||
308 | #define ISCSI_STAT_TGT_ATTR(_name, _mode) \ | ||
309 | static struct iscsi_stat_tgt_attr_attribute \ | ||
310 | iscsi_stat_tgt_attr_##_name = \ | ||
311 | __CONFIGFS_EATTR(_name, _mode, \ | ||
312 | iscsi_stat_tgt-attr_show_attr_##_name, \ | ||
313 | iscsi_stat_tgt_attr_store_attr_##_name); | ||
314 | |||
315 | #define ISCSI_STAT_TGT_ATTR_RO(_name) \ | ||
316 | static struct iscsi_stat_tgt_attr_attribute \ | ||
317 | iscsi_stat_tgt_attr_##_name = \ | ||
318 | __CONFIGFS_EATTR_RO(_name, \ | ||
319 | iscsi_stat_tgt_attr_show_attr_##_name); | ||
320 | |||
321 | static ssize_t iscsi_stat_tgt_attr_show_attr_inst( | ||
322 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
323 | { | ||
324 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
325 | struct iscsi_tiqn, tiqn_stat_grps); | ||
326 | |||
327 | return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index); | ||
328 | } | ||
329 | ISCSI_STAT_TGT_ATTR_RO(inst); | ||
330 | |||
331 | static ssize_t iscsi_stat_tgt_attr_show_attr_indx( | ||
332 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
333 | { | ||
334 | return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX); | ||
335 | } | ||
336 | ISCSI_STAT_TGT_ATTR_RO(indx); | ||
337 | |||
338 | static ssize_t iscsi_stat_tgt_attr_show_attr_login_fails( | ||
339 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
340 | { | ||
341 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
342 | struct iscsi_tiqn, tiqn_stat_grps); | ||
343 | struct iscsi_login_stats *lstat = &tiqn->login_stats; | ||
344 | u32 fail_count; | ||
345 | |||
346 | spin_lock(&lstat->lock); | ||
347 | fail_count = (lstat->redirects + lstat->authorize_fails + | ||
348 | lstat->authenticate_fails + lstat->negotiate_fails + | ||
349 | lstat->other_fails); | ||
350 | spin_unlock(&lstat->lock); | ||
351 | |||
352 | return snprintf(page, PAGE_SIZE, "%u\n", fail_count); | ||
353 | } | ||
354 | ISCSI_STAT_TGT_ATTR_RO(login_fails); | ||
355 | |||
356 | static ssize_t iscsi_stat_tgt_attr_show_attr_last_fail_time( | ||
357 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
358 | { | ||
359 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
360 | struct iscsi_tiqn, tiqn_stat_grps); | ||
361 | struct iscsi_login_stats *lstat = &tiqn->login_stats; | ||
362 | u32 last_fail_time; | ||
363 | |||
364 | spin_lock(&lstat->lock); | ||
365 | last_fail_time = lstat->last_fail_time ? | ||
366 | (u32)(((u32)lstat->last_fail_time - | ||
367 | INITIAL_JIFFIES) * 100 / HZ) : 0; | ||
368 | spin_unlock(&lstat->lock); | ||
369 | |||
370 | return snprintf(page, PAGE_SIZE, "%u\n", last_fail_time); | ||
371 | } | ||
372 | ISCSI_STAT_TGT_ATTR_RO(last_fail_time); | ||
373 | |||
374 | static ssize_t iscsi_stat_tgt_attr_show_attr_last_fail_type( | ||
375 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
376 | { | ||
377 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
378 | struct iscsi_tiqn, tiqn_stat_grps); | ||
379 | struct iscsi_login_stats *lstat = &tiqn->login_stats; | ||
380 | u32 last_fail_type; | ||
381 | |||
382 | spin_lock(&lstat->lock); | ||
383 | last_fail_type = lstat->last_fail_type; | ||
384 | spin_unlock(&lstat->lock); | ||
385 | |||
386 | return snprintf(page, PAGE_SIZE, "%u\n", last_fail_type); | ||
387 | } | ||
388 | ISCSI_STAT_TGT_ATTR_RO(last_fail_type); | ||
389 | |||
390 | static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_name( | ||
391 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
392 | { | ||
393 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
394 | struct iscsi_tiqn, tiqn_stat_grps); | ||
395 | struct iscsi_login_stats *lstat = &tiqn->login_stats; | ||
396 | unsigned char buf[224]; | ||
397 | |||
398 | spin_lock(&lstat->lock); | ||
399 | snprintf(buf, 224, "%s", lstat->last_intr_fail_name[0] ? | ||
400 | lstat->last_intr_fail_name : NONE); | ||
401 | spin_unlock(&lstat->lock); | ||
402 | |||
403 | return snprintf(page, PAGE_SIZE, "%s\n", buf); | ||
404 | } | ||
405 | ISCSI_STAT_TGT_ATTR_RO(fail_intr_name); | ||
406 | |||
407 | static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr_type( | ||
408 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
409 | { | ||
410 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
411 | struct iscsi_tiqn, tiqn_stat_grps); | ||
412 | struct iscsi_login_stats *lstat = &tiqn->login_stats; | ||
413 | unsigned char buf[8]; | ||
414 | |||
415 | spin_lock(&lstat->lock); | ||
416 | snprintf(buf, 8, "%s", (lstat->last_intr_fail_ip_addr != NULL) ? | ||
417 | "ipv6" : "ipv4"); | ||
418 | spin_unlock(&lstat->lock); | ||
419 | |||
420 | return snprintf(page, PAGE_SIZE, "%s\n", buf); | ||
421 | } | ||
422 | ISCSI_STAT_TGT_ATTR_RO(fail_intr_addr_type); | ||
423 | |||
424 | static ssize_t iscsi_stat_tgt_attr_show_attr_fail_intr_addr( | ||
425 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
426 | { | ||
427 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
428 | struct iscsi_tiqn, tiqn_stat_grps); | ||
429 | struct iscsi_login_stats *lstat = &tiqn->login_stats; | ||
430 | unsigned char buf[32]; | ||
431 | |||
432 | spin_lock(&lstat->lock); | ||
433 | if (lstat->last_intr_fail_ip_family == AF_INET6) | ||
434 | snprintf(buf, 32, "[%s]", lstat->last_intr_fail_ip_addr); | ||
435 | else | ||
436 | snprintf(buf, 32, "%s", lstat->last_intr_fail_ip_addr); | ||
437 | spin_unlock(&lstat->lock); | ||
438 | |||
439 | return snprintf(page, PAGE_SIZE, "%s\n", buf); | ||
440 | } | ||
441 | ISCSI_STAT_TGT_ATTR_RO(fail_intr_addr); | ||
442 | |||
443 | CONFIGFS_EATTR_OPS(iscsi_stat_tgt_attr, iscsi_wwn_stat_grps, | ||
444 | iscsi_tgt_attr_group); | ||
445 | |||
446 | static struct configfs_attribute *iscsi_stat_tgt_attr_attrs[] = { | ||
447 | &iscsi_stat_tgt_attr_inst.attr, | ||
448 | &iscsi_stat_tgt_attr_indx.attr, | ||
449 | &iscsi_stat_tgt_attr_login_fails.attr, | ||
450 | &iscsi_stat_tgt_attr_last_fail_time.attr, | ||
451 | &iscsi_stat_tgt_attr_last_fail_type.attr, | ||
452 | &iscsi_stat_tgt_attr_fail_intr_name.attr, | ||
453 | &iscsi_stat_tgt_attr_fail_intr_addr_type.attr, | ||
454 | &iscsi_stat_tgt_attr_fail_intr_addr.attr, | ||
455 | NULL, | ||
456 | }; | ||
457 | |||
458 | static struct configfs_item_operations iscsi_stat_tgt_attr_item_ops = { | ||
459 | .show_attribute = iscsi_stat_tgt_attr_attr_show, | ||
460 | .store_attribute = iscsi_stat_tgt_attr_attr_store, | ||
461 | }; | ||
462 | |||
463 | struct config_item_type iscsi_stat_tgt_attr_cit = { | ||
464 | .ct_item_ops = &iscsi_stat_tgt_attr_item_ops, | ||
465 | .ct_attrs = iscsi_stat_tgt_attr_attrs, | ||
466 | .ct_owner = THIS_MODULE, | ||
467 | }; | ||
468 | |||
469 | /* | ||
470 | * Target Login Stats Table | ||
471 | */ | ||
472 | CONFIGFS_EATTR_STRUCT(iscsi_stat_login, iscsi_wwn_stat_grps); | ||
473 | #define ISCSI_STAT_LOGIN(_name, _mode) \ | ||
474 | static struct iscsi_stat_login_attribute \ | ||
475 | iscsi_stat_login_##_name = \ | ||
476 | __CONFIGFS_EATTR(_name, _mode, \ | ||
477 | iscsi_stat_login_show_attr_##_name, \ | ||
478 | iscsi_stat_login_store_attr_##_name); | ||
479 | |||
480 | #define ISCSI_STAT_LOGIN_RO(_name) \ | ||
481 | static struct iscsi_stat_login_attribute \ | ||
482 | iscsi_stat_login_##_name = \ | ||
483 | __CONFIGFS_EATTR_RO(_name, \ | ||
484 | iscsi_stat_login_show_attr_##_name); | ||
485 | |||
486 | static ssize_t iscsi_stat_login_show_attr_inst( | ||
487 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
488 | { | ||
489 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
490 | struct iscsi_tiqn, tiqn_stat_grps); | ||
491 | |||
492 | return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index); | ||
493 | } | ||
494 | ISCSI_STAT_LOGIN_RO(inst); | ||
495 | |||
496 | static ssize_t iscsi_stat_login_show_attr_indx( | ||
497 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
498 | { | ||
499 | return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX); | ||
500 | } | ||
501 | ISCSI_STAT_LOGIN_RO(indx); | ||
502 | |||
503 | static ssize_t iscsi_stat_login_show_attr_accepts( | ||
504 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
505 | { | ||
506 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
507 | struct iscsi_tiqn, tiqn_stat_grps); | ||
508 | struct iscsi_login_stats *lstat = &tiqn->login_stats; | ||
509 | ssize_t ret; | ||
510 | |||
511 | spin_lock(&lstat->lock); | ||
512 | ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->accepts); | ||
513 | spin_unlock(&lstat->lock); | ||
514 | |||
515 | return ret; | ||
516 | } | ||
517 | ISCSI_STAT_LOGIN_RO(accepts); | ||
518 | |||
519 | static ssize_t iscsi_stat_login_show_attr_other_fails( | ||
520 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
521 | { | ||
522 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
523 | struct iscsi_tiqn, tiqn_stat_grps); | ||
524 | struct iscsi_login_stats *lstat = &tiqn->login_stats; | ||
525 | ssize_t ret; | ||
526 | |||
527 | spin_lock(&lstat->lock); | ||
528 | ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->other_fails); | ||
529 | spin_unlock(&lstat->lock); | ||
530 | |||
531 | return ret; | ||
532 | } | ||
533 | ISCSI_STAT_LOGIN_RO(other_fails); | ||
534 | |||
535 | static ssize_t iscsi_stat_login_show_attr_redirects( | ||
536 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
537 | { | ||
538 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
539 | struct iscsi_tiqn, tiqn_stat_grps); | ||
540 | struct iscsi_login_stats *lstat = &tiqn->login_stats; | ||
541 | ssize_t ret; | ||
542 | |||
543 | spin_lock(&lstat->lock); | ||
544 | ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->redirects); | ||
545 | spin_unlock(&lstat->lock); | ||
546 | |||
547 | return ret; | ||
548 | } | ||
549 | ISCSI_STAT_LOGIN_RO(redirects); | ||
550 | |||
551 | static ssize_t iscsi_stat_login_show_attr_authorize_fails( | ||
552 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
553 | { | ||
554 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
555 | struct iscsi_tiqn, tiqn_stat_grps); | ||
556 | struct iscsi_login_stats *lstat = &tiqn->login_stats; | ||
557 | ssize_t ret; | ||
558 | |||
559 | spin_lock(&lstat->lock); | ||
560 | ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->authorize_fails); | ||
561 | spin_unlock(&lstat->lock); | ||
562 | |||
563 | return ret; | ||
564 | } | ||
565 | ISCSI_STAT_LOGIN_RO(authorize_fails); | ||
566 | |||
567 | static ssize_t iscsi_stat_login_show_attr_authenticate_fails( | ||
568 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
569 | { | ||
570 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
571 | struct iscsi_tiqn, tiqn_stat_grps); | ||
572 | struct iscsi_login_stats *lstat = &tiqn->login_stats; | ||
573 | ssize_t ret; | ||
574 | |||
575 | spin_lock(&lstat->lock); | ||
576 | ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->authenticate_fails); | ||
577 | spin_unlock(&lstat->lock); | ||
578 | |||
579 | return ret; | ||
580 | } | ||
581 | ISCSI_STAT_LOGIN_RO(authenticate_fails); | ||
582 | |||
583 | static ssize_t iscsi_stat_login_show_attr_negotiate_fails( | ||
584 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
585 | { | ||
586 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
587 | struct iscsi_tiqn, tiqn_stat_grps); | ||
588 | struct iscsi_login_stats *lstat = &tiqn->login_stats; | ||
589 | ssize_t ret; | ||
590 | |||
591 | spin_lock(&lstat->lock); | ||
592 | ret = snprintf(page, PAGE_SIZE, "%u\n", lstat->negotiate_fails); | ||
593 | spin_unlock(&lstat->lock); | ||
594 | |||
595 | return ret; | ||
596 | } | ||
597 | ISCSI_STAT_LOGIN_RO(negotiate_fails); | ||
598 | |||
599 | CONFIGFS_EATTR_OPS(iscsi_stat_login, iscsi_wwn_stat_grps, | ||
600 | iscsi_login_stats_group); | ||
601 | |||
602 | static struct configfs_attribute *iscsi_stat_login_stats_attrs[] = { | ||
603 | &iscsi_stat_login_inst.attr, | ||
604 | &iscsi_stat_login_indx.attr, | ||
605 | &iscsi_stat_login_accepts.attr, | ||
606 | &iscsi_stat_login_other_fails.attr, | ||
607 | &iscsi_stat_login_redirects.attr, | ||
608 | &iscsi_stat_login_authorize_fails.attr, | ||
609 | &iscsi_stat_login_authenticate_fails.attr, | ||
610 | &iscsi_stat_login_negotiate_fails.attr, | ||
611 | NULL, | ||
612 | }; | ||
613 | |||
614 | static struct configfs_item_operations iscsi_stat_login_stats_item_ops = { | ||
615 | .show_attribute = iscsi_stat_login_attr_show, | ||
616 | .store_attribute = iscsi_stat_login_attr_store, | ||
617 | }; | ||
618 | |||
619 | struct config_item_type iscsi_stat_login_cit = { | ||
620 | .ct_item_ops = &iscsi_stat_login_stats_item_ops, | ||
621 | .ct_attrs = iscsi_stat_login_stats_attrs, | ||
622 | .ct_owner = THIS_MODULE, | ||
623 | }; | ||
624 | |||
625 | /* | ||
626 | * Target Logout Stats Table | ||
627 | */ | ||
628 | |||
629 | CONFIGFS_EATTR_STRUCT(iscsi_stat_logout, iscsi_wwn_stat_grps); | ||
630 | #define ISCSI_STAT_LOGOUT(_name, _mode) \ | ||
631 | static struct iscsi_stat_logout_attribute \ | ||
632 | iscsi_stat_logout_##_name = \ | ||
633 | __CONFIGFS_EATTR(_name, _mode, \ | ||
634 | iscsi_stat_logout_show_attr_##_name, \ | ||
635 | iscsi_stat_logout_store_attr_##_name); | ||
636 | |||
637 | #define ISCSI_STAT_LOGOUT_RO(_name) \ | ||
638 | static struct iscsi_stat_logout_attribute \ | ||
639 | iscsi_stat_logout_##_name = \ | ||
640 | __CONFIGFS_EATTR_RO(_name, \ | ||
641 | iscsi_stat_logout_show_attr_##_name); | ||
642 | |||
643 | static ssize_t iscsi_stat_logout_show_attr_inst( | ||
644 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
645 | { | ||
646 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
647 | struct iscsi_tiqn, tiqn_stat_grps); | ||
648 | |||
649 | return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index); | ||
650 | } | ||
651 | ISCSI_STAT_LOGOUT_RO(inst); | ||
652 | |||
653 | static ssize_t iscsi_stat_logout_show_attr_indx( | ||
654 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
655 | { | ||
656 | return snprintf(page, PAGE_SIZE, "%u\n", ISCSI_NODE_INDEX); | ||
657 | } | ||
658 | ISCSI_STAT_LOGOUT_RO(indx); | ||
659 | |||
660 | static ssize_t iscsi_stat_logout_show_attr_normal_logouts( | ||
661 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
662 | { | ||
663 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
664 | struct iscsi_tiqn, tiqn_stat_grps); | ||
665 | struct iscsi_logout_stats *lstats = &tiqn->logout_stats; | ||
666 | |||
667 | return snprintf(page, PAGE_SIZE, "%u\n", lstats->normal_logouts); | ||
668 | } | ||
669 | ISCSI_STAT_LOGOUT_RO(normal_logouts); | ||
670 | |||
671 | static ssize_t iscsi_stat_logout_show_attr_abnormal_logouts( | ||
672 | struct iscsi_wwn_stat_grps *igrps, char *page) | ||
673 | { | ||
674 | struct iscsi_tiqn *tiqn = container_of(igrps, | ||
675 | struct iscsi_tiqn, tiqn_stat_grps); | ||
676 | struct iscsi_logout_stats *lstats = &tiqn->logout_stats; | ||
677 | |||
678 | return snprintf(page, PAGE_SIZE, "%u\n", lstats->abnormal_logouts); | ||
679 | } | ||
680 | ISCSI_STAT_LOGOUT_RO(abnormal_logouts); | ||
681 | |||
682 | CONFIGFS_EATTR_OPS(iscsi_stat_logout, iscsi_wwn_stat_grps, | ||
683 | iscsi_logout_stats_group); | ||
684 | |||
685 | static struct configfs_attribute *iscsi_stat_logout_stats_attrs[] = { | ||
686 | &iscsi_stat_logout_inst.attr, | ||
687 | &iscsi_stat_logout_indx.attr, | ||
688 | &iscsi_stat_logout_normal_logouts.attr, | ||
689 | &iscsi_stat_logout_abnormal_logouts.attr, | ||
690 | NULL, | ||
691 | }; | ||
692 | |||
693 | static struct configfs_item_operations iscsi_stat_logout_stats_item_ops = { | ||
694 | .show_attribute = iscsi_stat_logout_attr_show, | ||
695 | .store_attribute = iscsi_stat_logout_attr_store, | ||
696 | }; | ||
697 | |||
698 | struct config_item_type iscsi_stat_logout_cit = { | ||
699 | .ct_item_ops = &iscsi_stat_logout_stats_item_ops, | ||
700 | .ct_attrs = iscsi_stat_logout_stats_attrs, | ||
701 | .ct_owner = THIS_MODULE, | ||
702 | }; | ||
703 | |||
704 | /* | ||
705 | * Session Stats Table | ||
706 | */ | ||
707 | |||
708 | CONFIGFS_EATTR_STRUCT(iscsi_stat_sess, iscsi_node_stat_grps); | ||
709 | #define ISCSI_STAT_SESS(_name, _mode) \ | ||
710 | static struct iscsi_stat_sess_attribute \ | ||
711 | iscsi_stat_sess_##_name = \ | ||
712 | __CONFIGFS_EATTR(_name, _mode, \ | ||
713 | iscsi_stat_sess_show_attr_##_name, \ | ||
714 | iscsi_stat_sess_store_attr_##_name); | ||
715 | |||
716 | #define ISCSI_STAT_SESS_RO(_name) \ | ||
717 | static struct iscsi_stat_sess_attribute \ | ||
718 | iscsi_stat_sess_##_name = \ | ||
719 | __CONFIGFS_EATTR_RO(_name, \ | ||
720 | iscsi_stat_sess_show_attr_##_name); | ||
721 | |||
722 | static ssize_t iscsi_stat_sess_show_attr_inst( | ||
723 | struct iscsi_node_stat_grps *igrps, char *page) | ||
724 | { | ||
725 | struct iscsi_node_acl *acl = container_of(igrps, | ||
726 | struct iscsi_node_acl, node_stat_grps); | ||
727 | struct se_wwn *wwn = acl->se_node_acl.se_tpg->se_tpg_wwn; | ||
728 | struct iscsi_tiqn *tiqn = container_of(wwn, | ||
729 | struct iscsi_tiqn, tiqn_wwn); | ||
730 | |||
731 | return snprintf(page, PAGE_SIZE, "%u\n", tiqn->tiqn_index); | ||
732 | } | ||
733 | ISCSI_STAT_SESS_RO(inst); | ||
734 | |||
735 | static ssize_t iscsi_stat_sess_show_attr_node( | ||
736 | struct iscsi_node_stat_grps *igrps, char *page) | ||
737 | { | ||
738 | struct iscsi_node_acl *acl = container_of(igrps, | ||
739 | struct iscsi_node_acl, node_stat_grps); | ||
740 | struct se_node_acl *se_nacl = &acl->se_node_acl; | ||
741 | struct iscsi_session *sess; | ||
742 | struct se_session *se_sess; | ||
743 | ssize_t ret = 0; | ||
744 | |||
745 | spin_lock_bh(&se_nacl->nacl_sess_lock); | ||
746 | se_sess = se_nacl->nacl_sess; | ||
747 | if (se_sess) { | ||
748 | sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; | ||
749 | if (sess) | ||
750 | ret = snprintf(page, PAGE_SIZE, "%u\n", | ||
751 | sess->sess_ops->SessionType ? 0 : ISCSI_NODE_INDEX); | ||
752 | } | ||
753 | spin_unlock_bh(&se_nacl->nacl_sess_lock); | ||
754 | |||
755 | return ret; | ||
756 | } | ||
757 | ISCSI_STAT_SESS_RO(node); | ||
758 | |||
759 | static ssize_t iscsi_stat_sess_show_attr_indx( | ||
760 | struct iscsi_node_stat_grps *igrps, char *page) | ||
761 | { | ||
762 | struct iscsi_node_acl *acl = container_of(igrps, | ||
763 | struct iscsi_node_acl, node_stat_grps); | ||
764 | struct se_node_acl *se_nacl = &acl->se_node_acl; | ||
765 | struct iscsi_session *sess; | ||
766 | struct se_session *se_sess; | ||
767 | ssize_t ret = 0; | ||
768 | |||
769 | spin_lock_bh(&se_nacl->nacl_sess_lock); | ||
770 | se_sess = se_nacl->nacl_sess; | ||
771 | if (se_sess) { | ||
772 | sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; | ||
773 | if (sess) | ||
774 | ret = snprintf(page, PAGE_SIZE, "%u\n", | ||
775 | sess->session_index); | ||
776 | } | ||
777 | spin_unlock_bh(&se_nacl->nacl_sess_lock); | ||
778 | |||
779 | return ret; | ||
780 | } | ||
781 | ISCSI_STAT_SESS_RO(indx); | ||
782 | |||
783 | static ssize_t iscsi_stat_sess_show_attr_cmd_pdus( | ||
784 | struct iscsi_node_stat_grps *igrps, char *page) | ||
785 | { | ||
786 | struct iscsi_node_acl *acl = container_of(igrps, | ||
787 | struct iscsi_node_acl, node_stat_grps); | ||
788 | struct se_node_acl *se_nacl = &acl->se_node_acl; | ||
789 | struct iscsi_session *sess; | ||
790 | struct se_session *se_sess; | ||
791 | ssize_t ret = 0; | ||
792 | |||
793 | spin_lock_bh(&se_nacl->nacl_sess_lock); | ||
794 | se_sess = se_nacl->nacl_sess; | ||
795 | if (se_sess) { | ||
796 | sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; | ||
797 | if (sess) | ||
798 | ret = snprintf(page, PAGE_SIZE, "%u\n", sess->cmd_pdus); | ||
799 | } | ||
800 | spin_unlock_bh(&se_nacl->nacl_sess_lock); | ||
801 | |||
802 | return ret; | ||
803 | } | ||
804 | ISCSI_STAT_SESS_RO(cmd_pdus); | ||
805 | |||
806 | static ssize_t iscsi_stat_sess_show_attr_rsp_pdus( | ||
807 | struct iscsi_node_stat_grps *igrps, char *page) | ||
808 | { | ||
809 | struct iscsi_node_acl *acl = container_of(igrps, | ||
810 | struct iscsi_node_acl, node_stat_grps); | ||
811 | struct se_node_acl *se_nacl = &acl->se_node_acl; | ||
812 | struct iscsi_session *sess; | ||
813 | struct se_session *se_sess; | ||
814 | ssize_t ret = 0; | ||
815 | |||
816 | spin_lock_bh(&se_nacl->nacl_sess_lock); | ||
817 | se_sess = se_nacl->nacl_sess; | ||
818 | if (se_sess) { | ||
819 | sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; | ||
820 | if (sess) | ||
821 | ret = snprintf(page, PAGE_SIZE, "%u\n", sess->rsp_pdus); | ||
822 | } | ||
823 | spin_unlock_bh(&se_nacl->nacl_sess_lock); | ||
824 | |||
825 | return ret; | ||
826 | } | ||
827 | ISCSI_STAT_SESS_RO(rsp_pdus); | ||
828 | |||
829 | static ssize_t iscsi_stat_sess_show_attr_txdata_octs( | ||
830 | struct iscsi_node_stat_grps *igrps, char *page) | ||
831 | { | ||
832 | struct iscsi_node_acl *acl = container_of(igrps, | ||
833 | struct iscsi_node_acl, node_stat_grps); | ||
834 | struct se_node_acl *se_nacl = &acl->se_node_acl; | ||
835 | struct iscsi_session *sess; | ||
836 | struct se_session *se_sess; | ||
837 | ssize_t ret = 0; | ||
838 | |||
839 | spin_lock_bh(&se_nacl->nacl_sess_lock); | ||
840 | se_sess = se_nacl->nacl_sess; | ||
841 | if (se_sess) { | ||
842 | sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; | ||
843 | if (sess) | ||
844 | ret = snprintf(page, PAGE_SIZE, "%llu\n", | ||
845 | (unsigned long long)sess->tx_data_octets); | ||
846 | } | ||
847 | spin_unlock_bh(&se_nacl->nacl_sess_lock); | ||
848 | |||
849 | return ret; | ||
850 | } | ||
851 | ISCSI_STAT_SESS_RO(txdata_octs); | ||
852 | |||
853 | static ssize_t iscsi_stat_sess_show_attr_rxdata_octs( | ||
854 | struct iscsi_node_stat_grps *igrps, char *page) | ||
855 | { | ||
856 | struct iscsi_node_acl *acl = container_of(igrps, | ||
857 | struct iscsi_node_acl, node_stat_grps); | ||
858 | struct se_node_acl *se_nacl = &acl->se_node_acl; | ||
859 | struct iscsi_session *sess; | ||
860 | struct se_session *se_sess; | ||
861 | ssize_t ret = 0; | ||
862 | |||
863 | spin_lock_bh(&se_nacl->nacl_sess_lock); | ||
864 | se_sess = se_nacl->nacl_sess; | ||
865 | if (se_sess) { | ||
866 | sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; | ||
867 | if (sess) | ||
868 | ret = snprintf(page, PAGE_SIZE, "%llu\n", | ||
869 | (unsigned long long)sess->rx_data_octets); | ||
870 | } | ||
871 | spin_unlock_bh(&se_nacl->nacl_sess_lock); | ||
872 | |||
873 | return ret; | ||
874 | } | ||
875 | ISCSI_STAT_SESS_RO(rxdata_octs); | ||
876 | |||
877 | static ssize_t iscsi_stat_sess_show_attr_conn_digest_errors( | ||
878 | struct iscsi_node_stat_grps *igrps, char *page) | ||
879 | { | ||
880 | struct iscsi_node_acl *acl = container_of(igrps, | ||
881 | struct iscsi_node_acl, node_stat_grps); | ||
882 | struct se_node_acl *se_nacl = &acl->se_node_acl; | ||
883 | struct iscsi_session *sess; | ||
884 | struct se_session *se_sess; | ||
885 | ssize_t ret = 0; | ||
886 | |||
887 | spin_lock_bh(&se_nacl->nacl_sess_lock); | ||
888 | se_sess = se_nacl->nacl_sess; | ||
889 | if (se_sess) { | ||
890 | sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; | ||
891 | if (sess) | ||
892 | ret = snprintf(page, PAGE_SIZE, "%u\n", | ||
893 | sess->conn_digest_errors); | ||
894 | } | ||
895 | spin_unlock_bh(&se_nacl->nacl_sess_lock); | ||
896 | |||
897 | return ret; | ||
898 | } | ||
899 | ISCSI_STAT_SESS_RO(conn_digest_errors); | ||
900 | |||
901 | static ssize_t iscsi_stat_sess_show_attr_conn_timeout_errors( | ||
902 | struct iscsi_node_stat_grps *igrps, char *page) | ||
903 | { | ||
904 | struct iscsi_node_acl *acl = container_of(igrps, | ||
905 | struct iscsi_node_acl, node_stat_grps); | ||
906 | struct se_node_acl *se_nacl = &acl->se_node_acl; | ||
907 | struct iscsi_session *sess; | ||
908 | struct se_session *se_sess; | ||
909 | ssize_t ret = 0; | ||
910 | |||
911 | spin_lock_bh(&se_nacl->nacl_sess_lock); | ||
912 | se_sess = se_nacl->nacl_sess; | ||
913 | if (se_sess) { | ||
914 | sess = (struct iscsi_session *)se_sess->fabric_sess_ptr; | ||
915 | if (sess) | ||
916 | ret = snprintf(page, PAGE_SIZE, "%u\n", | ||
917 | sess->conn_timeout_errors); | ||
918 | } | ||
919 | spin_unlock_bh(&se_nacl->nacl_sess_lock); | ||
920 | |||
921 | return ret; | ||
922 | } | ||
923 | ISCSI_STAT_SESS_RO(conn_timeout_errors); | ||
924 | |||
925 | CONFIGFS_EATTR_OPS(iscsi_stat_sess, iscsi_node_stat_grps, | ||
926 | iscsi_sess_stats_group); | ||
927 | |||
928 | static struct configfs_attribute *iscsi_stat_sess_stats_attrs[] = { | ||
929 | &iscsi_stat_sess_inst.attr, | ||
930 | &iscsi_stat_sess_node.attr, | ||
931 | &iscsi_stat_sess_indx.attr, | ||
932 | &iscsi_stat_sess_cmd_pdus.attr, | ||
933 | &iscsi_stat_sess_rsp_pdus.attr, | ||
934 | &iscsi_stat_sess_txdata_octs.attr, | ||
935 | &iscsi_stat_sess_rxdata_octs.attr, | ||
936 | &iscsi_stat_sess_conn_digest_errors.attr, | ||
937 | &iscsi_stat_sess_conn_timeout_errors.attr, | ||
938 | NULL, | ||
939 | }; | ||
940 | |||
941 | static struct configfs_item_operations iscsi_stat_sess_stats_item_ops = { | ||
942 | .show_attribute = iscsi_stat_sess_attr_show, | ||
943 | .store_attribute = iscsi_stat_sess_attr_store, | ||
944 | }; | ||
945 | |||
946 | struct config_item_type iscsi_stat_sess_cit = { | ||
947 | .ct_item_ops = &iscsi_stat_sess_stats_item_ops, | ||
948 | .ct_attrs = iscsi_stat_sess_stats_attrs, | ||
949 | .ct_owner = THIS_MODULE, | ||
950 | }; | ||