7 #include "iscsi_sysfs.h"
9 #include "iscsi_settings.h"
11 #include "session_info.h"
12 #include "transport.h"
13 #include "initiator.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
))
27 new = calloc(1, sizeof(*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
);
38 list_for_each_entry(curr
, list
, list
) {
39 if (!strcmp(curr
->targetname
, info
->targetname
)) {
42 if (!strcmp(curr
->address
, info
->address
)) {
45 if (curr
->port
== info
->port
) {
53 list_add_tail(&new->list
, match
? match
->list
.next
: list
);
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
);
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
);
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
);
84 static int print_iscsi_state(int sid
, char *prefix
)
90 char state_buff
[SCSI_MAX_STATE_VALUE
];
91 static char *conn_state
[] = {
100 static char *session_state
[] = {
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");
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
);
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");
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
)
181 char *blockdev
, state
[SCSI_MAX_STATE_VALUE
];
183 printf("%s\t\tscsi%d Channel 00 Id %d Lun: %d\n", prefix
, host_no
,
185 blockdev
= iscsi_sysfs_get_blockdev_from_lun(host_no
, target
, lun
);
187 printf("%s\t\t\tAttached scsi disk %s\t\t", prefix
, blockdev
);
190 if (!iscsi_sysfs_get_device_state(state
, host_no
, target
, lun
))
191 printf("State: %s\n", state
);
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
);
208 printf("%s\t\tUnavailable\n", prefix
);
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
);
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
);
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
);
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
,
244 printf("%s\tCurrent Portal: [%s]:%d,%d\n",
245 prefix
, curr
->address
, curr
->port
,
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
);
253 printf("%s\tPersistent Portal: [%s]:%d,%d\n",
254 prefix
, curr
->persistent_address
,
255 curr
->persistent_port
, curr
->tpgt
);
259 if (flags
& SESSION_INFO_IFACE
) {
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
) +
269 printf("Could not print interface info. "
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",
292 ((curr
->tmo
).tgt_reset_tmo
));
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
));
301 printf("%s\t\tLUN Reset Timeout: %s\n", prefix
,
304 if ((curr
->tmo
).lu_reset_tmo
>= 0)
305 printf("%s\t\tAbort Timeout: %d\n", prefix
,
306 ((curr
->tmo
).abort_tmo
));
308 printf("%s\t\tAbort Timeout: %s\n", prefix
,
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
);
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
);
324 printf("%s\t\tusername: %s\n", prefix
,
326 if (strlen((curr
->chap
).password
))
327 printf("%s\t\tpassword: %s\n", prefix
,
328 (curr
->chap
).password
);
330 printf("%s\t\tpassword: %s\n", prefix
,
332 if (strlen((curr
->chap
).username_in
))
333 printf("%s\t\tusername_in: %s\n", prefix
,
334 (curr
->chap
).username_in
);
336 printf("%s\t\tusername_in: %s\n", prefix
,
338 if (strlen((curr
->chap
).password_in
))
339 printf("%s\t\tpassword_in: %s\n", prefix
,
340 (curr
->chap
).password_in
);
342 printf("%s\t\tpassword_in: %s\n", prefix
,
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
);
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;
361 unsigned int flags
= 0;
363 switch (info_level
) {
367 session_info_print_flat(NULL
, info
);
370 err
= iscsi_sysfs_for_each_session(info
, &num_found
,
371 session_info_print_flat
);
374 version
= iscsi_sysfs_get_iscsi_kernel_version();
376 printf("iSCSI Transport Class version %s\n",
378 printf("version %s\n", ISCSI_VERSION_STR
);
381 flags
|= (SESSION_INFO_SCSI_DEVS
| SESSION_INFO_HOST_DEVS
);
384 flags
|= (SESSION_INFO_ISCSI_PARAMS
| SESSION_INFO_ISCSI_TIM
385 | SESSION_INFO_ISCSI_AUTH
);
388 INIT_LIST_HEAD(&list
);
389 struct session_link_info link_info
;
391 flags
|= (SESSION_INFO_ISCSI_STATE
| SESSION_INFO_IFACE
);
393 INIT_LIST_HEAD(&info
->list
);
394 list_add_tail(&list
, &info
->list
);
395 session_info_print_tree(&list
, "", flags
, do_show
);
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
)
410 session_info_print_tree(&list
, "", flags
, do_show
);
411 session_info_free_list(&list
);
414 log_error("Invalid info level %d. Try 0 - 3.", info_level
);
415 return ISCSI_ERR_INVAL
;
419 log_error("Can not get list of active sessions (%d)", err
);
421 } else if (!num_found
) {
422 log_error("No active sessions.");
423 return ISCSI_ERR_NO_OBJS_FOUND
;