1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /******************************************************************************* |
3 | * Modern ConfigFS group context specific iSCSI statistics based on original |
4 | * iscsi_target_mib.c code |
5 | * |
6 | * Copyright (c) 2011-2013 Datera, Inc. |
7 | * |
8 | * Author: Nicholas A. Bellinger <nab@linux-iscsi.org> |
9 | * |
10 | ******************************************************************************/ |
11 | |
12 | #include <linux/configfs.h> |
13 | #include <linux/export.h> |
14 | #include <scsi/iscsi_proto.h> |
15 | #include <target/target_core_base.h> |
16 | |
17 | #include <target/iscsi/iscsi_target_core.h> |
18 | #include "iscsi_target_parameters.h" |
19 | #include "iscsi_target_device.h" |
20 | #include "iscsi_target_tpg.h" |
21 | #include "iscsi_target_util.h" |
22 | #include <target/iscsi/iscsi_target_stat.h> |
23 | |
24 | #ifndef INITIAL_JIFFIES |
25 | #define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) |
26 | #endif |
27 | |
28 | /* Instance Attributes Table */ |
29 | #define ISCSI_INST_NUM_NODES 1 |
30 | #define ISCSI_INST_DESCR "Storage Engine Target" |
31 | #define ISCSI_DISCONTINUITY_TIME 0 |
32 | |
33 | #define ISCSI_NODE_INDEX 1 |
34 | |
35 | #define ISPRINT(a) ((a >= ' ') && (a <= '~')) |
36 | |
37 | /**************************************************************************** |
38 | * iSCSI MIB Tables |
39 | ****************************************************************************/ |
40 | /* |
41 | * Instance Attributes Table |
42 | */ |
43 | static struct iscsi_tiqn *iscsi_instance_tiqn(struct config_item *item) |
44 | { |
45 | struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item), |
46 | struct iscsi_wwn_stat_grps, iscsi_instance_group); |
47 | return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps); |
48 | } |
49 | |
50 | static ssize_t iscsi_stat_instance_inst_show(struct config_item *item, |
51 | char *page) |
52 | { |
53 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , |
54 | iscsi_instance_tiqn(item)->tiqn_index); |
55 | } |
56 | |
57 | static ssize_t iscsi_stat_instance_min_ver_show(struct config_item *item, |
58 | char *page) |
59 | { |
60 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , ISCSI_DRAFT20_VERSION); |
61 | } |
62 | |
63 | static ssize_t iscsi_stat_instance_max_ver_show(struct config_item *item, |
64 | char *page) |
65 | { |
66 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , ISCSI_DRAFT20_VERSION); |
67 | } |
68 | |
69 | static ssize_t iscsi_stat_instance_portals_show(struct config_item *item, |
70 | char *page) |
71 | { |
72 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , |
73 | iscsi_instance_tiqn(item)->tiqn_num_tpg_nps); |
74 | } |
75 | |
76 | static ssize_t iscsi_stat_instance_nodes_show(struct config_item *item, |
77 | char *page) |
78 | { |
79 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , ISCSI_INST_NUM_NODES); |
80 | } |
81 | |
82 | static ssize_t iscsi_stat_instance_sessions_show(struct config_item *item, |
83 | char *page) |
84 | { |
85 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , |
86 | iscsi_instance_tiqn(item)->tiqn_nsessions); |
87 | } |
88 | |
89 | static ssize_t iscsi_stat_instance_fail_sess_show(struct config_item *item, |
90 | char *page) |
91 | { |
92 | struct iscsi_tiqn *tiqn = iscsi_instance_tiqn(item); |
93 | struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats; |
94 | u32 sess_err_count; |
95 | |
96 | spin_lock_bh(lock: &sess_err->lock); |
97 | sess_err_count = (sess_err->digest_errors + |
98 | sess_err->cxn_timeout_errors + |
99 | sess_err->pdu_format_errors); |
100 | spin_unlock_bh(lock: &sess_err->lock); |
101 | |
102 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , sess_err_count); |
103 | } |
104 | |
105 | static ssize_t iscsi_stat_instance_fail_type_show(struct config_item *item, |
106 | char *page) |
107 | { |
108 | struct iscsi_tiqn *tiqn = iscsi_instance_tiqn(item); |
109 | struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats; |
110 | |
111 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , |
112 | sess_err->last_sess_failure_type); |
113 | } |
114 | |
115 | static ssize_t iscsi_stat_instance_fail_rem_name_show(struct config_item *item, |
116 | char *page) |
117 | { |
118 | struct iscsi_tiqn *tiqn = iscsi_instance_tiqn(item); |
119 | struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats; |
120 | |
121 | return snprintf(buf: page, PAGE_SIZE, fmt: "%s\n" , |
122 | sess_err->last_sess_fail_rem_name[0] ? |
123 | sess_err->last_sess_fail_rem_name : NONE); |
124 | } |
125 | |
126 | static ssize_t iscsi_stat_instance_disc_time_show(struct config_item *item, |
127 | char *page) |
128 | { |
129 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , ISCSI_DISCONTINUITY_TIME); |
130 | } |
131 | |
132 | static ssize_t iscsi_stat_instance_description_show(struct config_item *item, |
133 | char *page) |
134 | { |
135 | return snprintf(buf: page, PAGE_SIZE, fmt: "%s\n" , ISCSI_INST_DESCR); |
136 | } |
137 | |
138 | static ssize_t iscsi_stat_instance_vendor_show(struct config_item *item, |
139 | char *page) |
140 | { |
141 | return snprintf(buf: page, PAGE_SIZE, fmt: "Datera, Inc. iSCSI-Target\n" ); |
142 | } |
143 | |
144 | static ssize_t iscsi_stat_instance_version_show(struct config_item *item, |
145 | char *page) |
146 | { |
147 | return snprintf(buf: page, PAGE_SIZE, fmt: "%s\n" , ISCSIT_VERSION); |
148 | } |
149 | |
150 | CONFIGFS_ATTR_RO(iscsi_stat_instance_, inst); |
151 | CONFIGFS_ATTR_RO(iscsi_stat_instance_, min_ver); |
152 | CONFIGFS_ATTR_RO(iscsi_stat_instance_, max_ver); |
153 | CONFIGFS_ATTR_RO(iscsi_stat_instance_, portals); |
154 | CONFIGFS_ATTR_RO(iscsi_stat_instance_, nodes); |
155 | CONFIGFS_ATTR_RO(iscsi_stat_instance_, sessions); |
156 | CONFIGFS_ATTR_RO(iscsi_stat_instance_, fail_sess); |
157 | CONFIGFS_ATTR_RO(iscsi_stat_instance_, fail_type); |
158 | CONFIGFS_ATTR_RO(iscsi_stat_instance_, fail_rem_name); |
159 | CONFIGFS_ATTR_RO(iscsi_stat_instance_, disc_time); |
160 | CONFIGFS_ATTR_RO(iscsi_stat_instance_, description); |
161 | CONFIGFS_ATTR_RO(iscsi_stat_instance_, vendor); |
162 | CONFIGFS_ATTR_RO(iscsi_stat_instance_, version); |
163 | |
164 | static struct configfs_attribute *iscsi_stat_instance_attrs[] = { |
165 | &iscsi_stat_instance_attr_inst, |
166 | &iscsi_stat_instance_attr_min_ver, |
167 | &iscsi_stat_instance_attr_max_ver, |
168 | &iscsi_stat_instance_attr_portals, |
169 | &iscsi_stat_instance_attr_nodes, |
170 | &iscsi_stat_instance_attr_sessions, |
171 | &iscsi_stat_instance_attr_fail_sess, |
172 | &iscsi_stat_instance_attr_fail_type, |
173 | &iscsi_stat_instance_attr_fail_rem_name, |
174 | &iscsi_stat_instance_attr_disc_time, |
175 | &iscsi_stat_instance_attr_description, |
176 | &iscsi_stat_instance_attr_vendor, |
177 | &iscsi_stat_instance_attr_version, |
178 | NULL, |
179 | }; |
180 | |
181 | const struct config_item_type iscsi_stat_instance_cit = { |
182 | .ct_attrs = iscsi_stat_instance_attrs, |
183 | .ct_owner = THIS_MODULE, |
184 | }; |
185 | |
186 | /* |
187 | * Instance Session Failure Stats Table |
188 | */ |
189 | static struct iscsi_tiqn *iscsi_sess_err_tiqn(struct config_item *item) |
190 | { |
191 | struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item), |
192 | struct iscsi_wwn_stat_grps, iscsi_sess_err_group); |
193 | return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps); |
194 | } |
195 | |
196 | static ssize_t iscsi_stat_sess_err_inst_show(struct config_item *item, |
197 | char *page) |
198 | { |
199 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , |
200 | iscsi_sess_err_tiqn(item)->tiqn_index); |
201 | } |
202 | |
203 | static ssize_t iscsi_stat_sess_err_digest_errors_show(struct config_item *item, |
204 | char *page) |
205 | { |
206 | struct iscsi_tiqn *tiqn = iscsi_sess_err_tiqn(item); |
207 | struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats; |
208 | |
209 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , sess_err->digest_errors); |
210 | } |
211 | |
212 | static ssize_t iscsi_stat_sess_err_cxn_errors_show(struct config_item *item, |
213 | char *page) |
214 | { |
215 | struct iscsi_tiqn *tiqn = iscsi_sess_err_tiqn(item); |
216 | struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats; |
217 | |
218 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , sess_err->cxn_timeout_errors); |
219 | } |
220 | |
221 | static ssize_t iscsi_stat_sess_err_format_errors_show(struct config_item *item, |
222 | char *page) |
223 | { |
224 | struct iscsi_tiqn *tiqn = iscsi_sess_err_tiqn(item); |
225 | struct iscsi_sess_err_stats *sess_err = &tiqn->sess_err_stats; |
226 | |
227 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , sess_err->pdu_format_errors); |
228 | } |
229 | |
230 | CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, inst); |
231 | CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, digest_errors); |
232 | CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, cxn_errors); |
233 | CONFIGFS_ATTR_RO(iscsi_stat_sess_err_, format_errors); |
234 | |
235 | static struct configfs_attribute *iscsi_stat_sess_err_attrs[] = { |
236 | &iscsi_stat_sess_err_attr_inst, |
237 | &iscsi_stat_sess_err_attr_digest_errors, |
238 | &iscsi_stat_sess_err_attr_cxn_errors, |
239 | &iscsi_stat_sess_err_attr_format_errors, |
240 | NULL, |
241 | }; |
242 | |
243 | const struct config_item_type iscsi_stat_sess_err_cit = { |
244 | .ct_attrs = iscsi_stat_sess_err_attrs, |
245 | .ct_owner = THIS_MODULE, |
246 | }; |
247 | |
248 | /* |
249 | * Target Attributes Table |
250 | */ |
251 | static struct iscsi_tiqn *iscsi_tgt_attr_tiqn(struct config_item *item) |
252 | { |
253 | struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item), |
254 | struct iscsi_wwn_stat_grps, iscsi_tgt_attr_group); |
255 | return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps); |
256 | } |
257 | |
258 | static ssize_t iscsi_stat_tgt_attr_inst_show(struct config_item *item, |
259 | char *page) |
260 | { |
261 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , |
262 | iscsi_tgt_attr_tiqn(item)->tiqn_index); |
263 | } |
264 | |
265 | static ssize_t iscsi_stat_tgt_attr_indx_show(struct config_item *item, |
266 | char *page) |
267 | { |
268 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , ISCSI_NODE_INDEX); |
269 | } |
270 | |
271 | static ssize_t iscsi_stat_tgt_attr_login_fails_show(struct config_item *item, |
272 | char *page) |
273 | { |
274 | struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item); |
275 | struct iscsi_login_stats *lstat = &tiqn->login_stats; |
276 | u32 fail_count; |
277 | |
278 | spin_lock(lock: &lstat->lock); |
279 | fail_count = (lstat->redirects + lstat->authorize_fails + |
280 | lstat->authenticate_fails + lstat->negotiate_fails + |
281 | lstat->other_fails); |
282 | spin_unlock(lock: &lstat->lock); |
283 | |
284 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , fail_count); |
285 | } |
286 | |
287 | static ssize_t iscsi_stat_tgt_attr_last_fail_time_show(struct config_item *item, |
288 | char *page) |
289 | { |
290 | struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item); |
291 | struct iscsi_login_stats *lstat = &tiqn->login_stats; |
292 | u32 last_fail_time; |
293 | |
294 | spin_lock(lock: &lstat->lock); |
295 | last_fail_time = lstat->last_fail_time ? |
296 | (u32)(((u32)lstat->last_fail_time - |
297 | INITIAL_JIFFIES) * 100 / HZ) : 0; |
298 | spin_unlock(lock: &lstat->lock); |
299 | |
300 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , last_fail_time); |
301 | } |
302 | |
303 | static ssize_t iscsi_stat_tgt_attr_last_fail_type_show(struct config_item *item, |
304 | char *page) |
305 | { |
306 | struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item); |
307 | struct iscsi_login_stats *lstat = &tiqn->login_stats; |
308 | u32 last_fail_type; |
309 | |
310 | spin_lock(lock: &lstat->lock); |
311 | last_fail_type = lstat->last_fail_type; |
312 | spin_unlock(lock: &lstat->lock); |
313 | |
314 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , last_fail_type); |
315 | } |
316 | |
317 | static ssize_t iscsi_stat_tgt_attr_fail_intr_name_show(struct config_item *item, |
318 | char *page) |
319 | { |
320 | struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item); |
321 | struct iscsi_login_stats *lstat = &tiqn->login_stats; |
322 | unsigned char buf[ISCSI_IQN_LEN]; |
323 | |
324 | spin_lock(lock: &lstat->lock); |
325 | snprintf(buf, ISCSI_IQN_LEN, fmt: "%s" , lstat->last_intr_fail_name[0] ? |
326 | lstat->last_intr_fail_name : NONE); |
327 | spin_unlock(lock: &lstat->lock); |
328 | |
329 | return snprintf(buf: page, PAGE_SIZE, fmt: "%s\n" , buf); |
330 | } |
331 | |
332 | static ssize_t iscsi_stat_tgt_attr_fail_intr_addr_type_show(struct config_item *item, |
333 | char *page) |
334 | { |
335 | struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item); |
336 | struct iscsi_login_stats *lstat = &tiqn->login_stats; |
337 | int ret; |
338 | |
339 | spin_lock(lock: &lstat->lock); |
340 | if (lstat->last_intr_fail_ip_family == AF_INET6) |
341 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "ipv6\n" ); |
342 | else |
343 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "ipv4\n" ); |
344 | spin_unlock(lock: &lstat->lock); |
345 | |
346 | return ret; |
347 | } |
348 | |
349 | static ssize_t iscsi_stat_tgt_attr_fail_intr_addr_show(struct config_item *item, |
350 | char *page) |
351 | { |
352 | struct iscsi_tiqn *tiqn = iscsi_tgt_attr_tiqn(item); |
353 | struct iscsi_login_stats *lstat = &tiqn->login_stats; |
354 | int ret; |
355 | |
356 | spin_lock(lock: &lstat->lock); |
357 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%pISc\n" , &lstat->last_intr_fail_sockaddr); |
358 | spin_unlock(lock: &lstat->lock); |
359 | |
360 | return ret; |
361 | } |
362 | |
363 | CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, inst); |
364 | CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, indx); |
365 | CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, login_fails); |
366 | CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, last_fail_time); |
367 | CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, last_fail_type); |
368 | CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, fail_intr_name); |
369 | CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, fail_intr_addr_type); |
370 | CONFIGFS_ATTR_RO(iscsi_stat_tgt_attr_, fail_intr_addr); |
371 | |
372 | static struct configfs_attribute *iscsi_stat_tgt_attr_attrs[] = { |
373 | &iscsi_stat_tgt_attr_attr_inst, |
374 | &iscsi_stat_tgt_attr_attr_indx, |
375 | &iscsi_stat_tgt_attr_attr_login_fails, |
376 | &iscsi_stat_tgt_attr_attr_last_fail_time, |
377 | &iscsi_stat_tgt_attr_attr_last_fail_type, |
378 | &iscsi_stat_tgt_attr_attr_fail_intr_name, |
379 | &iscsi_stat_tgt_attr_attr_fail_intr_addr_type, |
380 | &iscsi_stat_tgt_attr_attr_fail_intr_addr, |
381 | NULL, |
382 | }; |
383 | |
384 | const struct config_item_type iscsi_stat_tgt_attr_cit = { |
385 | .ct_attrs = iscsi_stat_tgt_attr_attrs, |
386 | .ct_owner = THIS_MODULE, |
387 | }; |
388 | |
389 | /* |
390 | * Target Login Stats Table |
391 | */ |
392 | static struct iscsi_tiqn *iscsi_login_stat_tiqn(struct config_item *item) |
393 | { |
394 | struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item), |
395 | struct iscsi_wwn_stat_grps, iscsi_login_stats_group); |
396 | return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps); |
397 | } |
398 | |
399 | static ssize_t iscsi_stat_login_inst_show(struct config_item *item, char *page) |
400 | { |
401 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , |
402 | iscsi_login_stat_tiqn(item)->tiqn_index); |
403 | } |
404 | |
405 | static ssize_t iscsi_stat_login_indx_show(struct config_item *item, |
406 | char *page) |
407 | { |
408 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , ISCSI_NODE_INDEX); |
409 | } |
410 | |
411 | static ssize_t iscsi_stat_login_accepts_show(struct config_item *item, |
412 | char *page) |
413 | { |
414 | struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item); |
415 | struct iscsi_login_stats *lstat = &tiqn->login_stats; |
416 | ssize_t ret; |
417 | |
418 | spin_lock(lock: &lstat->lock); |
419 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , lstat->accepts); |
420 | spin_unlock(lock: &lstat->lock); |
421 | |
422 | return ret; |
423 | } |
424 | |
425 | static ssize_t iscsi_stat_login_other_fails_show(struct config_item *item, |
426 | char *page) |
427 | { |
428 | struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item); |
429 | struct iscsi_login_stats *lstat = &tiqn->login_stats; |
430 | ssize_t ret; |
431 | |
432 | spin_lock(lock: &lstat->lock); |
433 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , lstat->other_fails); |
434 | spin_unlock(lock: &lstat->lock); |
435 | |
436 | return ret; |
437 | } |
438 | |
439 | static ssize_t iscsi_stat_login_redirects_show(struct config_item *item, |
440 | char *page) |
441 | { |
442 | struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item); |
443 | struct iscsi_login_stats *lstat = &tiqn->login_stats; |
444 | ssize_t ret; |
445 | |
446 | spin_lock(lock: &lstat->lock); |
447 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , lstat->redirects); |
448 | spin_unlock(lock: &lstat->lock); |
449 | |
450 | return ret; |
451 | } |
452 | |
453 | static ssize_t iscsi_stat_login_authorize_fails_show(struct config_item *item, |
454 | char *page) |
455 | { |
456 | struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item); |
457 | struct iscsi_login_stats *lstat = &tiqn->login_stats; |
458 | ssize_t ret; |
459 | |
460 | spin_lock(lock: &lstat->lock); |
461 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , lstat->authorize_fails); |
462 | spin_unlock(lock: &lstat->lock); |
463 | |
464 | return ret; |
465 | } |
466 | |
467 | static ssize_t iscsi_stat_login_authenticate_fails_show( |
468 | struct config_item *item, char *page) |
469 | { |
470 | struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item); |
471 | struct iscsi_login_stats *lstat = &tiqn->login_stats; |
472 | ssize_t ret; |
473 | |
474 | spin_lock(lock: &lstat->lock); |
475 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , lstat->authenticate_fails); |
476 | spin_unlock(lock: &lstat->lock); |
477 | |
478 | return ret; |
479 | } |
480 | |
481 | static ssize_t iscsi_stat_login_negotiate_fails_show(struct config_item *item, |
482 | char *page) |
483 | { |
484 | struct iscsi_tiqn *tiqn = iscsi_login_stat_tiqn(item); |
485 | struct iscsi_login_stats *lstat = &tiqn->login_stats; |
486 | ssize_t ret; |
487 | |
488 | spin_lock(lock: &lstat->lock); |
489 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , lstat->negotiate_fails); |
490 | spin_unlock(lock: &lstat->lock); |
491 | |
492 | return ret; |
493 | } |
494 | |
495 | CONFIGFS_ATTR_RO(iscsi_stat_login_, inst); |
496 | CONFIGFS_ATTR_RO(iscsi_stat_login_, indx); |
497 | CONFIGFS_ATTR_RO(iscsi_stat_login_, accepts); |
498 | CONFIGFS_ATTR_RO(iscsi_stat_login_, other_fails); |
499 | CONFIGFS_ATTR_RO(iscsi_stat_login_, redirects); |
500 | CONFIGFS_ATTR_RO(iscsi_stat_login_, authorize_fails); |
501 | CONFIGFS_ATTR_RO(iscsi_stat_login_, authenticate_fails); |
502 | CONFIGFS_ATTR_RO(iscsi_stat_login_, negotiate_fails); |
503 | |
504 | static struct configfs_attribute *iscsi_stat_login_stats_attrs[] = { |
505 | &iscsi_stat_login_attr_inst, |
506 | &iscsi_stat_login_attr_indx, |
507 | &iscsi_stat_login_attr_accepts, |
508 | &iscsi_stat_login_attr_other_fails, |
509 | &iscsi_stat_login_attr_redirects, |
510 | &iscsi_stat_login_attr_authorize_fails, |
511 | &iscsi_stat_login_attr_authenticate_fails, |
512 | &iscsi_stat_login_attr_negotiate_fails, |
513 | NULL, |
514 | }; |
515 | |
516 | const struct config_item_type iscsi_stat_login_cit = { |
517 | .ct_attrs = iscsi_stat_login_stats_attrs, |
518 | .ct_owner = THIS_MODULE, |
519 | }; |
520 | |
521 | /* |
522 | * Target Logout Stats Table |
523 | */ |
524 | static struct iscsi_tiqn *iscsi_logout_stat_tiqn(struct config_item *item) |
525 | { |
526 | struct iscsi_wwn_stat_grps *igrps = container_of(to_config_group(item), |
527 | struct iscsi_wwn_stat_grps, iscsi_logout_stats_group); |
528 | return container_of(igrps, struct iscsi_tiqn, tiqn_stat_grps); |
529 | } |
530 | |
531 | static ssize_t iscsi_stat_logout_inst_show(struct config_item *item, char *page) |
532 | { |
533 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , |
534 | iscsi_logout_stat_tiqn(item)->tiqn_index); |
535 | } |
536 | |
537 | static ssize_t iscsi_stat_logout_indx_show(struct config_item *item, char *page) |
538 | { |
539 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , ISCSI_NODE_INDEX); |
540 | } |
541 | |
542 | static ssize_t iscsi_stat_logout_normal_logouts_show(struct config_item *item, |
543 | char *page) |
544 | { |
545 | struct iscsi_tiqn *tiqn = iscsi_logout_stat_tiqn(item); |
546 | struct iscsi_logout_stats *lstats = &tiqn->logout_stats; |
547 | |
548 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , lstats->normal_logouts); |
549 | } |
550 | |
551 | static ssize_t iscsi_stat_logout_abnormal_logouts_show(struct config_item *item, |
552 | char *page) |
553 | { |
554 | struct iscsi_tiqn *tiqn = iscsi_logout_stat_tiqn(item); |
555 | struct iscsi_logout_stats *lstats = &tiqn->logout_stats; |
556 | |
557 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , lstats->abnormal_logouts); |
558 | } |
559 | |
560 | CONFIGFS_ATTR_RO(iscsi_stat_logout_, inst); |
561 | CONFIGFS_ATTR_RO(iscsi_stat_logout_, indx); |
562 | CONFIGFS_ATTR_RO(iscsi_stat_logout_, normal_logouts); |
563 | CONFIGFS_ATTR_RO(iscsi_stat_logout_, abnormal_logouts); |
564 | |
565 | static struct configfs_attribute *iscsi_stat_logout_stats_attrs[] = { |
566 | &iscsi_stat_logout_attr_inst, |
567 | &iscsi_stat_logout_attr_indx, |
568 | &iscsi_stat_logout_attr_normal_logouts, |
569 | &iscsi_stat_logout_attr_abnormal_logouts, |
570 | NULL, |
571 | }; |
572 | |
573 | const struct config_item_type iscsi_stat_logout_cit = { |
574 | .ct_attrs = iscsi_stat_logout_stats_attrs, |
575 | .ct_owner = THIS_MODULE, |
576 | }; |
577 | |
578 | /* |
579 | * Session Stats Table |
580 | */ |
581 | static struct iscsi_node_acl *iscsi_stat_nacl(struct config_item *item) |
582 | { |
583 | struct iscsi_node_stat_grps *igrps = container_of(to_config_group(item), |
584 | struct iscsi_node_stat_grps, iscsi_sess_stats_group); |
585 | return container_of(igrps, struct iscsi_node_acl, node_stat_grps); |
586 | } |
587 | |
588 | static ssize_t iscsi_stat_sess_inst_show(struct config_item *item, char *page) |
589 | { |
590 | struct iscsi_node_acl *acl = iscsi_stat_nacl(item); |
591 | struct se_wwn *wwn = acl->se_node_acl.se_tpg->se_tpg_wwn; |
592 | struct iscsi_tiqn *tiqn = container_of(wwn, |
593 | struct iscsi_tiqn, tiqn_wwn); |
594 | |
595 | return snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , tiqn->tiqn_index); |
596 | } |
597 | |
598 | static ssize_t iscsi_stat_sess_node_show(struct config_item *item, char *page) |
599 | { |
600 | struct iscsi_node_acl *acl = iscsi_stat_nacl(item); |
601 | struct se_node_acl *se_nacl = &acl->se_node_acl; |
602 | struct iscsit_session *sess; |
603 | struct se_session *se_sess; |
604 | ssize_t ret = 0; |
605 | |
606 | spin_lock_bh(lock: &se_nacl->nacl_sess_lock); |
607 | se_sess = se_nacl->nacl_sess; |
608 | if (se_sess) { |
609 | sess = se_sess->fabric_sess_ptr; |
610 | if (sess) |
611 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , |
612 | sess->sess_ops->SessionType ? 0 : ISCSI_NODE_INDEX); |
613 | } |
614 | spin_unlock_bh(lock: &se_nacl->nacl_sess_lock); |
615 | |
616 | return ret; |
617 | } |
618 | |
619 | static ssize_t iscsi_stat_sess_indx_show(struct config_item *item, char *page) |
620 | { |
621 | struct iscsi_node_acl *acl = iscsi_stat_nacl(item); |
622 | struct se_node_acl *se_nacl = &acl->se_node_acl; |
623 | struct iscsit_session *sess; |
624 | struct se_session *se_sess; |
625 | ssize_t ret = 0; |
626 | |
627 | spin_lock_bh(lock: &se_nacl->nacl_sess_lock); |
628 | se_sess = se_nacl->nacl_sess; |
629 | if (se_sess) { |
630 | sess = se_sess->fabric_sess_ptr; |
631 | if (sess) |
632 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%u\n" , |
633 | sess->session_index); |
634 | } |
635 | spin_unlock_bh(lock: &se_nacl->nacl_sess_lock); |
636 | |
637 | return ret; |
638 | } |
639 | |
640 | static ssize_t iscsi_stat_sess_cmd_pdus_show(struct config_item *item, |
641 | char *page) |
642 | { |
643 | struct iscsi_node_acl *acl = iscsi_stat_nacl(item); |
644 | struct se_node_acl *se_nacl = &acl->se_node_acl; |
645 | struct iscsit_session *sess; |
646 | struct se_session *se_sess; |
647 | ssize_t ret = 0; |
648 | |
649 | spin_lock_bh(lock: &se_nacl->nacl_sess_lock); |
650 | se_sess = se_nacl->nacl_sess; |
651 | if (se_sess) { |
652 | sess = se_sess->fabric_sess_ptr; |
653 | if (sess) |
654 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%lu\n" , |
655 | atomic_long_read(v: &sess->cmd_pdus)); |
656 | } |
657 | spin_unlock_bh(lock: &se_nacl->nacl_sess_lock); |
658 | |
659 | return ret; |
660 | } |
661 | |
662 | static ssize_t iscsi_stat_sess_rsp_pdus_show(struct config_item *item, |
663 | char *page) |
664 | { |
665 | struct iscsi_node_acl *acl = iscsi_stat_nacl(item); |
666 | struct se_node_acl *se_nacl = &acl->se_node_acl; |
667 | struct iscsit_session *sess; |
668 | struct se_session *se_sess; |
669 | ssize_t ret = 0; |
670 | |
671 | spin_lock_bh(lock: &se_nacl->nacl_sess_lock); |
672 | se_sess = se_nacl->nacl_sess; |
673 | if (se_sess) { |
674 | sess = se_sess->fabric_sess_ptr; |
675 | if (sess) |
676 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%lu\n" , |
677 | atomic_long_read(v: &sess->rsp_pdus)); |
678 | } |
679 | spin_unlock_bh(lock: &se_nacl->nacl_sess_lock); |
680 | |
681 | return ret; |
682 | } |
683 | |
684 | static ssize_t iscsi_stat_sess_txdata_octs_show(struct config_item *item, |
685 | char *page) |
686 | { |
687 | struct iscsi_node_acl *acl = iscsi_stat_nacl(item); |
688 | struct se_node_acl *se_nacl = &acl->se_node_acl; |
689 | struct iscsit_session *sess; |
690 | struct se_session *se_sess; |
691 | ssize_t ret = 0; |
692 | |
693 | spin_lock_bh(lock: &se_nacl->nacl_sess_lock); |
694 | se_sess = se_nacl->nacl_sess; |
695 | if (se_sess) { |
696 | sess = se_sess->fabric_sess_ptr; |
697 | if (sess) |
698 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%lu\n" , |
699 | atomic_long_read(v: &sess->tx_data_octets)); |
700 | } |
701 | spin_unlock_bh(lock: &se_nacl->nacl_sess_lock); |
702 | |
703 | return ret; |
704 | } |
705 | |
706 | static ssize_t iscsi_stat_sess_rxdata_octs_show(struct config_item *item, |
707 | char *page) |
708 | { |
709 | struct iscsi_node_acl *acl = iscsi_stat_nacl(item); |
710 | struct se_node_acl *se_nacl = &acl->se_node_acl; |
711 | struct iscsit_session *sess; |
712 | struct se_session *se_sess; |
713 | ssize_t ret = 0; |
714 | |
715 | spin_lock_bh(lock: &se_nacl->nacl_sess_lock); |
716 | se_sess = se_nacl->nacl_sess; |
717 | if (se_sess) { |
718 | sess = se_sess->fabric_sess_ptr; |
719 | if (sess) |
720 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%lu\n" , |
721 | atomic_long_read(v: &sess->rx_data_octets)); |
722 | } |
723 | spin_unlock_bh(lock: &se_nacl->nacl_sess_lock); |
724 | |
725 | return ret; |
726 | } |
727 | |
728 | static ssize_t iscsi_stat_sess_conn_digest_errors_show(struct config_item *item, |
729 | char *page) |
730 | { |
731 | struct iscsi_node_acl *acl = iscsi_stat_nacl(item); |
732 | struct se_node_acl *se_nacl = &acl->se_node_acl; |
733 | struct iscsit_session *sess; |
734 | struct se_session *se_sess; |
735 | ssize_t ret = 0; |
736 | |
737 | spin_lock_bh(lock: &se_nacl->nacl_sess_lock); |
738 | se_sess = se_nacl->nacl_sess; |
739 | if (se_sess) { |
740 | sess = se_sess->fabric_sess_ptr; |
741 | if (sess) |
742 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%lu\n" , |
743 | atomic_long_read(v: &sess->conn_digest_errors)); |
744 | } |
745 | spin_unlock_bh(lock: &se_nacl->nacl_sess_lock); |
746 | |
747 | return ret; |
748 | } |
749 | |
750 | static ssize_t iscsi_stat_sess_conn_timeout_errors_show( |
751 | struct config_item *item, char *page) |
752 | { |
753 | struct iscsi_node_acl *acl = iscsi_stat_nacl(item); |
754 | struct se_node_acl *se_nacl = &acl->se_node_acl; |
755 | struct iscsit_session *sess; |
756 | struct se_session *se_sess; |
757 | ssize_t ret = 0; |
758 | |
759 | spin_lock_bh(lock: &se_nacl->nacl_sess_lock); |
760 | se_sess = se_nacl->nacl_sess; |
761 | if (se_sess) { |
762 | sess = se_sess->fabric_sess_ptr; |
763 | if (sess) |
764 | ret = snprintf(buf: page, PAGE_SIZE, fmt: "%lu\n" , |
765 | atomic_long_read(v: &sess->conn_timeout_errors)); |
766 | } |
767 | spin_unlock_bh(lock: &se_nacl->nacl_sess_lock); |
768 | |
769 | return ret; |
770 | } |
771 | |
772 | CONFIGFS_ATTR_RO(iscsi_stat_sess_, inst); |
773 | CONFIGFS_ATTR_RO(iscsi_stat_sess_, node); |
774 | CONFIGFS_ATTR_RO(iscsi_stat_sess_, indx); |
775 | CONFIGFS_ATTR_RO(iscsi_stat_sess_, cmd_pdus); |
776 | CONFIGFS_ATTR_RO(iscsi_stat_sess_, rsp_pdus); |
777 | CONFIGFS_ATTR_RO(iscsi_stat_sess_, txdata_octs); |
778 | CONFIGFS_ATTR_RO(iscsi_stat_sess_, rxdata_octs); |
779 | CONFIGFS_ATTR_RO(iscsi_stat_sess_, conn_digest_errors); |
780 | CONFIGFS_ATTR_RO(iscsi_stat_sess_, conn_timeout_errors); |
781 | |
782 | static struct configfs_attribute *iscsi_stat_sess_stats_attrs[] = { |
783 | &iscsi_stat_sess_attr_inst, |
784 | &iscsi_stat_sess_attr_node, |
785 | &iscsi_stat_sess_attr_indx, |
786 | &iscsi_stat_sess_attr_cmd_pdus, |
787 | &iscsi_stat_sess_attr_rsp_pdus, |
788 | &iscsi_stat_sess_attr_txdata_octs, |
789 | &iscsi_stat_sess_attr_rxdata_octs, |
790 | &iscsi_stat_sess_attr_conn_digest_errors, |
791 | &iscsi_stat_sess_attr_conn_timeout_errors, |
792 | NULL, |
793 | }; |
794 | |
795 | const struct config_item_type iscsi_stat_sess_cit = { |
796 | .ct_attrs = iscsi_stat_sess_stats_attrs, |
797 | .ct_owner = THIS_MODULE, |
798 | }; |
799 | |