usr/config.h: fix comment for struct iscsi_session_timeout_config
[open-iscsi.git] / usr / session_info.c
blob1f84c49a808eb3ff901680e639302d074714b5a4
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <errno.h>
5 #include "list.h"
6 #include "log.h"
7 #include "iscsi_sysfs.h"
8 #include "version.h"
9 #include "iscsi_settings.h"
10 #include "mgmt_ipc.h"
11 #include "session_info.h"
12 #include "transport.h"
13 #include "initiator.h"
14 #include "iface.h"
15 #include "iscsid_req.h"
16 #include "iscsi_err.h"
18 int session_info_create_list(void *data, struct session_info *info)
20 struct session_link_info *link_info = data;
21 struct list_head *list = link_info->list;
22 struct session_info *new, *curr, *match = NULL;
24 if (link_info->match_fn && !link_info->match_fn(link_info->data, info))
25 return -1;
27 new = calloc(1, sizeof(*new));
28 if (!new)
29 return ISCSI_ERR_NOMEM;
30 memcpy(new, info, sizeof(*new));
31 INIT_LIST_HEAD(&new->list);
33 if (list_empty(list)) {
34 list_add_tail(&new->list, list);
35 return 0;
38 list_for_each_entry(curr, list, list) {
39 if (!strcmp(curr->targetname, info->targetname)) {
40 match = curr;
42 if (!strcmp(curr->address, info->address)) {
43 match = curr;
45 if (curr->port == info->port) {
46 match = curr;
47 break;
53 list_add_tail(&new->list, match ? match->list.next : list);
54 return 0;
57 void session_info_free_list(struct list_head *list)
59 struct session_info *curr, *tmp;
61 list_for_each_entry_safe(curr, tmp, list, list) {
62 list_del(&curr->list);
63 free(curr);
67 static int session_info_print_flat(void *data, struct session_info *info)
69 struct iscsi_transport *t = iscsi_sysfs_get_transport_by_sid(info->sid);
71 if (strchr(info->persistent_address, '.'))
72 printf("%s: [%d] %s:%d,%d %s\n",
73 t ? t->name : UNKNOWN_VALUE,
74 info->sid, info->persistent_address,
75 info->persistent_port, info->tpgt, info->targetname);
76 else
77 printf("%s: [%d] [%s]:%d,%d %s\n",
78 t ? t->name : UNKNOWN_VALUE,
79 info->sid, info->persistent_address,
80 info->persistent_port, info->tpgt, info->targetname);
81 return 0;
84 static int print_iscsi_state(int sid, char *prefix)
86 iscsiadm_req_t req;
87 iscsiadm_rsp_t rsp;
88 int err;
89 char *state = NULL;
90 char state_buff[SCSI_MAX_STATE_VALUE];
91 static char *conn_state[] = {
92 "FREE",
93 "TRANSPORT WAIT",
94 "IN LOGIN",
95 "LOGGED IN",
96 "IN LOGOUT",
97 "LOGOUT REQUESTED",
98 "CLEANUP WAIT",
100 static char *session_state[] = {
101 "NO CHANGE",
102 "CLEANUP",
103 "REOPEN",
104 "REDIRECT",
107 memset(&req, 0, sizeof(iscsiadm_req_t));
108 req.command = MGMT_IPC_SESSION_INFO;
109 req.u.session.sid = sid;
111 err = iscsid_exec_req(&req, &rsp, 1);
113 * for drivers like qla4xxx, iscsid does not display
114 * anything here since it does not know about it.
116 if (!err && rsp.u.session_state.conn_state >= 0 &&
117 rsp.u.session_state.conn_state <= ISCSI_CONN_STATE_CLEANUP_WAIT)
118 state = conn_state[rsp.u.session_state.conn_state];
119 printf("%s\t\tiSCSI Connection State: %s\n", prefix,
120 state ? state : "Unknown");
121 state = NULL;
123 memset(state_buff, 0, SCSI_MAX_STATE_VALUE);
124 if (!iscsi_sysfs_get_session_state(state_buff, sid))
125 printf("%s\t\tiSCSI Session State: %s\n", prefix, state_buff);
126 else
127 printf("%s\t\tiSCSI Session State: Unknown\n", prefix);
129 if (!err && rsp.u.session_state.session_state >= 0 &&
130 rsp.u.session_state.session_state <= R_STAGE_SESSION_REDIRECT)
131 state = session_state[rsp.u.session_state.session_state];
132 printf("%s\t\tInternal iscsid Session State: %s\n", prefix,
133 state ? state : "Unknown");
134 return 0;
137 static void print_iscsi_params(int sid, char *prefix)
139 struct iscsi_session_operational_config session_conf;
140 struct iscsi_conn_operational_config conn_conf;
142 iscsi_sysfs_get_negotiated_session_conf(sid, &session_conf);
143 iscsi_sysfs_get_negotiated_conn_conf(sid, &conn_conf);
145 printf("%s\t\t************************\n", prefix);
146 printf("%s\t\tNegotiated iSCSI params:\n", prefix);
147 printf("%s\t\t************************\n", prefix);
149 if (is_valid_operational_value(conn_conf.HeaderDigest))
150 printf("%s\t\tHeaderDigest: %s\n", prefix,
151 conn_conf.HeaderDigest ? "CRC32C" : "None");
152 if (is_valid_operational_value(conn_conf.DataDigest))
153 printf("%s\t\tDataDigest: %s\n", prefix,
154 conn_conf.DataDigest ? "CRC32C" : "None");
155 if (is_valid_operational_value(conn_conf.MaxRecvDataSegmentLength))
156 printf("%s\t\tMaxRecvDataSegmentLength: %d\n", prefix,
157 conn_conf.MaxRecvDataSegmentLength);
158 if (is_valid_operational_value(conn_conf.MaxXmitDataSegmentLength))
159 printf("%s\t\tMaxXmitDataSegmentLength: %d\n", prefix,
160 conn_conf.MaxXmitDataSegmentLength);
161 if (is_valid_operational_value(session_conf.FirstBurstLength))
162 printf("%s\t\tFirstBurstLength: %d\n", prefix,
163 session_conf.FirstBurstLength);
164 if (is_valid_operational_value(session_conf.MaxBurstLength))
165 printf("%s\t\tMaxBurstLength: %d\n", prefix,
166 session_conf.MaxBurstLength);
167 if (is_valid_operational_value(session_conf.ImmediateData))
168 printf("%s\t\tImmediateData: %s\n", prefix,
169 session_conf.ImmediateData ? "Yes" : "No");
170 if (is_valid_operational_value(session_conf.InitialR2T))
171 printf("%s\t\tInitialR2T: %s\n", prefix,
172 session_conf.InitialR2T ? "Yes" : "No");
173 if (is_valid_operational_value(session_conf.MaxOutstandingR2T))
174 printf("%s\t\tMaxOutstandingR2T: %d\n", prefix,
175 session_conf.MaxOutstandingR2T);
178 static void print_scsi_device_info(void *data, int host_no, int target, int lun)
180 char *prefix = data;
181 char *blockdev, state[SCSI_MAX_STATE_VALUE];
183 printf("%s\t\tscsi%d Channel 00 Id %d Lun: %d\n", prefix, host_no,
184 target, lun);
185 blockdev = iscsi_sysfs_get_blockdev_from_lun(host_no, target, lun);
186 if (blockdev) {
187 printf("%s\t\t\tAttached scsi disk %s\t\t", prefix, blockdev);
188 free(blockdev);
190 if (!iscsi_sysfs_get_device_state(state, host_no, target, lun))
191 printf("State: %s\n", state);
192 else
193 printf("State: Unknown\n");
197 static int print_scsi_state(int sid, char *prefix, unsigned int flags)
199 int host_no = -1, err = 0;
200 char state[SCSI_MAX_STATE_VALUE];
202 printf("%s\t\t************************\n", prefix);
203 printf("%s\t\tAttached SCSI devices:\n", prefix);
204 printf("%s\t\t************************\n", prefix);
206 host_no = iscsi_sysfs_get_host_no_from_sid(sid, &err);
207 if (err) {
208 printf("%s\t\tUnavailable\n", prefix);
209 return err;
212 if (flags & SESSION_INFO_HOST_DEVS) {
213 printf("%s\t\tHost Number: %d\t", prefix, host_no);
214 if (!iscsi_sysfs_get_host_state(state, host_no))
215 printf("State: %s\n", state);
216 else
217 printf("State: Unknown\n");
220 if (flags & SESSION_INFO_SCSI_DEVS)
221 iscsi_sysfs_for_each_device(prefix, host_no, sid,
222 print_scsi_device_info);
223 return 0;
226 void session_info_print_tree(struct list_head *list, char *prefix,
227 unsigned int flags, int do_show)
229 struct session_info *curr, *prev = NULL;
231 list_for_each_entry(curr, list, list) {
232 if (!prev || strcmp(prev->targetname, curr->targetname)) {
233 printf("%sTarget: %s\n", prefix, curr->targetname);
234 prev = NULL;
237 if (!prev || (strcmp(prev->address, curr->address) ||
238 prev->port != curr->port)) {
239 if (strchr(curr->address, '.'))
240 printf("%s\tCurrent Portal: %s:%d,%d\n",
241 prefix, curr->address, curr->port,
242 curr->tpgt);
243 else
244 printf("%s\tCurrent Portal: [%s]:%d,%d\n",
245 prefix, curr->address, curr->port,
246 curr->tpgt);
248 if (strchr(curr->persistent_address, '.'))
249 printf("%s\tPersistent Portal: %s:%d,%d\n",
250 prefix, curr->persistent_address,
251 curr->persistent_port, curr->tpgt);
252 else
253 printf("%s\tPersistent Portal: [%s]:%d,%d\n",
254 prefix, curr->persistent_address,
255 curr->persistent_port, curr->tpgt);
256 } else
257 printf("\n");
259 if (flags & SESSION_INFO_IFACE) {
260 char *new_prefix;
262 printf("%s\t\t**********\n", prefix);
263 printf("%s\t\tInterface:\n", prefix);
264 printf("%s\t\t**********\n", prefix);
266 new_prefix = calloc(1, 1 + strlen(prefix) +
267 strlen("\t\t"));
268 if (!new_prefix)
269 printf("Could not print interface info. "
270 "Out of Memory.\n");
271 else {
272 sprintf(new_prefix, "%s%s", prefix, "\t\t");
273 iface_print(&curr->iface, new_prefix);
277 if (flags & SESSION_INFO_ISCSI_STATE) {
278 printf("%s\t\tSID: %d\n", prefix, curr->sid);
279 print_iscsi_state(curr->sid, prefix);
281 if (flags & SESSION_INFO_ISCSI_TIM) {
282 printf("%s\t\t*********\n", prefix);
283 printf("%s\t\tTimeouts:\n", prefix);
284 printf("%s\t\t*********\n", prefix);
286 printf("%s\t\tRecovery Timeout: %d\n", prefix,
287 ((curr->tmo).recovery_tmo));
289 if ((curr->tmo).tgt_reset_tmo >= 0)
290 printf("%s\t\tTarget Reset Timeout: %d\n",
291 prefix,
292 ((curr->tmo).tgt_reset_tmo));
293 else
294 printf("%s\t\tTarget Reset Timeout: %s\n",
295 prefix, UNKNOWN_VALUE);
297 if ((curr->tmo).lu_reset_tmo >= 0)
298 printf("%s\t\tLUN Reset Timeout: %d\n", prefix,
299 ((curr->tmo).lu_reset_tmo));
300 else
301 printf("%s\t\tLUN Reset Timeout: %s\n", prefix,
302 UNKNOWN_VALUE);
304 if ((curr->tmo).lu_reset_tmo >= 0)
305 printf("%s\t\tAbort Timeout: %d\n", prefix,
306 ((curr->tmo).abort_tmo));
307 else
308 printf("%s\t\tAbort Timeout: %s\n", prefix,
309 UNKNOWN_VALUE);
312 if (flags & SESSION_INFO_ISCSI_AUTH) {
313 printf("%s\t\t*****\n", prefix);
314 printf("%s\t\tCHAP:\n", prefix);
315 printf("%s\t\t*****\n", prefix);
316 if (!do_show) {
317 strcpy(curr->chap.password, "********");
318 strcpy(curr->chap.password_in, "********");
320 if (strlen((curr->chap).username))
321 printf("%s\t\tusername: %s\n", prefix,
322 (curr->chap).username);
323 else
324 printf("%s\t\tusername: %s\n", prefix,
325 UNKNOWN_VALUE);
326 if (strlen((curr->chap).password))
327 printf("%s\t\tpassword: %s\n", prefix,
328 (curr->chap).password);
329 else
330 printf("%s\t\tpassword: %s\n", prefix,
331 UNKNOWN_VALUE);
332 if (strlen((curr->chap).username_in))
333 printf("%s\t\tusername_in: %s\n", prefix,
334 (curr->chap).username_in);
335 else
336 printf("%s\t\tusername_in: %s\n", prefix,
337 UNKNOWN_VALUE);
338 if (strlen((curr->chap).password_in))
339 printf("%s\t\tpassword_in: %s\n", prefix,
340 (curr->chap).password_in);
341 else
342 printf("%s\t\tpassword_in: %s\n", prefix,
343 UNKNOWN_VALUE);
346 if (flags & SESSION_INFO_ISCSI_PARAMS)
347 print_iscsi_params(curr->sid, prefix);
349 if (flags & (SESSION_INFO_SCSI_DEVS | SESSION_INFO_HOST_DEVS))
350 print_scsi_state(curr->sid, prefix, flags);
352 prev = curr;
356 int session_info_print(int info_level, struct session_info *info, int do_show)
358 struct list_head list;
359 int num_found = 0, err = 0;
360 char *version;
361 unsigned int flags = 0;
363 switch (info_level) {
364 case 0:
365 case -1:
366 if (info) {
367 session_info_print_flat(NULL, info);
368 num_found = 1;
369 } else
370 err = iscsi_sysfs_for_each_session(info, &num_found,
371 session_info_print_flat);
372 break;
373 case 3:
374 version = iscsi_sysfs_get_iscsi_kernel_version();
375 if (version) {
376 printf("iSCSI Transport Class version %s\n",
377 version);
378 printf("version %s\n", ISCSI_VERSION_STR);
381 flags |= (SESSION_INFO_SCSI_DEVS | SESSION_INFO_HOST_DEVS);
382 /* fall through */
383 case 2:
384 flags |= (SESSION_INFO_ISCSI_PARAMS | SESSION_INFO_ISCSI_TIM
385 | SESSION_INFO_ISCSI_AUTH);
386 /* fall through */
387 case 1:
388 INIT_LIST_HEAD(&list);
389 struct session_link_info link_info;
391 flags |= (SESSION_INFO_ISCSI_STATE | SESSION_INFO_IFACE);
392 if (info) {
393 INIT_LIST_HEAD(&info->list);
394 list_add_tail(&list, &info->list);
395 session_info_print_tree(&list, "", flags, do_show);
396 num_found = 1;
397 break;
400 memset(&link_info, 0, sizeof(link_info));
401 link_info.list = &list;
402 link_info.data = NULL;
403 link_info.match_fn = NULL;
405 err = iscsi_sysfs_for_each_session(&link_info, &num_found,
406 session_info_create_list);
407 if (err || !num_found)
408 break;
410 session_info_print_tree(&list, "", flags, do_show);
411 session_info_free_list(&list);
412 break;
413 default:
414 log_error("Invalid info level %d. Try 0 - 3.", info_level);
415 return ISCSI_ERR_INVAL;
418 if (err) {
419 log_error("Can not get list of active sessions (%d)", err);
420 return err;
421 } else if (!num_found) {
422 log_error("No active sessions.");
423 return ISCSI_ERR_NO_OBJS_FOUND;
425 return 0;