--- a/usr/src/cmd/mdb/common/modules/idm/idm.c Fri Apr 09 11:20:11 2010 -0700
+++ b/usr/src/cmd/mdb/common/modules/idm/idm.c Fri Apr 09 14:59:31 2010 -0400
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <mdb/mdb_modapi.h>
@@ -54,6 +53,7 @@
#include <iscsi.h>
#include <iscsit.h>
#include <iscsit_isns.h>
+#include <sys/ib/clients/iser/iser.h>
/*
* We want to be able to print multiple levels of object hierarchy with a
@@ -66,9 +66,12 @@
* The session dcmd should allow the printing of all associated tasks for the
* sessions without printing all the associated connections. To accomplish
* this the following structure contains a bit for each object type. Dcmds
- * should invoked the functions for child objects if any bits are set
+ * should invoke the functions for child objects if any bits are set
* in iscsi_dcmd_ctrl_t but the functions for the child object should only
- * print data if their associated bit is set.
+ * print data if their associated bit is set. Each object type should print
+ * a header for its first occurrence or if it is being printed as a child
+ * object for the first occurrence under each parent. For the model to follow
+ * see how idc->idc_header is handled in iscsi_sess_impl.
*
* Each dcmd should provide an external interface with the standard MDB API
* and an internal interface that accepts iscsi_dcmd_ctrl_t. To display
@@ -82,17 +85,20 @@
uint32_t idc_children;
struct {
uint32_t idc_tgt:1,
+ idc_tpg:1,
idc_tpgt:1,
idc_portal:1,
idc_sess:1,
idc_conn:1,
+ idc_svc:1,
idc_print_ip:1,
idc_task:1,
idc_buffer:1,
idc_states:1,
idc_rc_audit:1,
idc_lun:1,
- idc_hba:1;
+ idc_hba:1,
+ idc_cmd:1;
} child;
} u;
boolean_t idc_ini;
@@ -113,8 +119,14 @@
uintptr_t idc_assoc_session;
} iscsi_dcmd_ctrl_t;
+typedef struct idm_hba_walk_info {
+ void **array;
+ int n_elements;
+ int cur_element;
+ void *data;
+} idm_hba_walk_info_t;
+
static int iscsi_walk_all_sess(iscsi_dcmd_ctrl_t *idc);
-static int iscsi_walk_ini_sessions(uintptr_t array_addr);
static int iscsi_walk_all_conn(iscsi_dcmd_ctrl_t *idc);
static int iscsi_tgt_walk_cb(uintptr_t addr, const void *list_walker_data,
void *idc_void);
@@ -130,6 +142,18 @@
void *idc_void);
static int iscsi_buffer_walk_cb(uintptr_t addr, const void *list_walker_data,
void *idc_void);
+static int iscsi_svc_walk_cb(uintptr_t addr, const void *list_walker_data,
+ void *idc_void);
+static int iscsi_ini_hba_walk_cb(uintptr_t addr, const void *vhba,
+ void *idc_void);
+static int iscsi_ini_sess_walk_cb(uintptr_t addr, const void *vsess,
+ void *idc);
+static int iscsi_ini_conn_walk_cb(uintptr_t addr, const void *vconn,
+ void *idc_void);
+static int iscsi_ini_lun_walk_cb(uintptr_t addr, const void *vlun,
+ void *idc_void);
+static int iscsi_ini_cmd_walk_cb(uintptr_t addr, const void *vcmd,
+ void *idc);
static int iscsi_tgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
static int iscsi_tpgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
static int iscsi_tpg_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
@@ -137,6 +161,7 @@
static int iscsi_sess_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
static int iscsi_conn_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
static void iscsi_print_iscsit_conn_data(idm_conn_t *ict);
+static void iscsi_print_ini_conn_data(idm_conn_t *ict);
static void iscsi_print_idm_conn_data(idm_conn_t *ict);
static int iscsi_task_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
static void iscsi_print_iscsit_task_data(idm_task_t *idt);
@@ -148,7 +173,22 @@
static int iscsi_sm_audit_impl(uintptr_t addr);
static int iscsi_isns(uintptr_t addr, uint_t flags, int argc,
const mdb_arg_t *argv);
-
+static int iscsi_svc_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
+static int iscsi_ini_hba_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc);
+static int iscsi_print_ini_sess(uintptr_t addr, iscsi_sess_t *sess,
+ iscsi_dcmd_ctrl_t *idc);
+static int iscsi_print_ini_lun(uintptr_t addr, const iscsi_lun_t *lun,
+ iscsi_dcmd_ctrl_t *idc);
+static int iscsi_print_ini_cmd(uintptr_t addr, const iscsi_cmd_t *cmd,
+ iscsi_dcmd_ctrl_t *idc);
+static int iscsi_ini_sess_walk_init(mdb_walk_state_t *wsp);
+static int iscsi_ini_sess_step(mdb_walk_state_t *wsp);
+static int iscsi_ini_conn_walk_init(mdb_walk_state_t *wsp);
+static int iscsi_ini_conn_step(mdb_walk_state_t *wsp);
+static int iscsi_ini_lun_walk_init(mdb_walk_state_t *wsp);
+static int iscsi_ini_lun_step(mdb_walk_state_t *wsp);
+static int iscsi_ini_cmd_walk_init(mdb_walk_state_t *wsp);
+static int iscsi_ini_cmd_step(mdb_walk_state_t *wsp);
static const char *iscsi_idm_conn_event(unsigned int event);
static const char *iscsi_iscsit_tgt_event(unsigned int event);
static const char *iscsi_iscsit_sess_event(unsigned int event);
@@ -258,10 +298,8 @@
return (DCMD_ERR);
}
return (DCMD_OK);
- } else {
- return (iscsi_tgt_impl(addr, &idc));
}
- /*NOTREACHED*/
+ return (iscsi_tgt_impl(addr, &idc));
}
static int
@@ -270,14 +308,18 @@
iscsi_dcmd_ctrl_t idc;
uintptr_t iscsit_global_addr, avl_addr;
GElf_Sym sym;
+ int rc_audit = 0;
bzero(&idc, sizeof (idc));
if (mdb_getopts(argc, argv,
- 'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
+ 'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
NULL) != argc)
return (DCMD_USAGE);
- idc.u.child.idc_portal = 1; /* Always print portals */
+ /* Always print tpgs and portals */
+ idc.u.child.idc_tpg = 1;
+ idc.u.child.idc_portal = 1;
+ idc.u.child.idc_rc_audit = rc_audit;
if (DCMD_HDRSPEC(flags))
idc.idc_header = 1;
@@ -298,14 +340,68 @@
return (DCMD_ERR);
}
return (DCMD_OK);
- } else {
- return (iscsi_tpg_impl(addr, &idc));
}
- /*NOTREACHED*/
+ return (iscsi_tpg_impl(addr, &idc));
}
/*
- * ::iscsi_sess [-bctvIT]
+ * ::iscsi_tpgt [-pR]
+ *
+ * Print tpgt information.
+ * R Print reference count audit data
+ * p Print portal data
+ */
+static int
+iscsi_tpgt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ iscsi_dcmd_ctrl_t idc;
+ uintptr_t iscsit_global_addr, avl_addr, list_addr;
+ GElf_Sym sym;
+ int rc_audit = 0, portal = 0;
+
+ bzero(&idc, sizeof (idc));
+ if (mdb_getopts(argc, argv,
+ 'p', MDB_OPT_SETBITS, TRUE, &portal,
+ 'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
+ NULL) != argc)
+ return (DCMD_USAGE);
+
+ idc.u.child.idc_tpgt = 1;
+ idc.u.child.idc_portal = portal;
+ idc.u.child.idc_rc_audit = rc_audit;
+ if (DCMD_HDRSPEC(flags))
+ idc.idc_header = 1;
+
+ /*
+ * If no address was specified on the command line,
+ * print out all tpgts
+ */
+ if (!(flags & DCMD_ADDRSPEC)) {
+ if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
+ mdb_warn("failed to find symbol 'iscsit_global'");
+ return (DCMD_ERR);
+ }
+ iscsit_global_addr = (uintptr_t)sym.st_value;
+ avl_addr = iscsit_global_addr +
+ offsetof(iscsit_global_t, global_target_list);
+ if (mdb_pwalk("avl", iscsi_tgt_walk_cb, &idc, avl_addr) == -1) {
+ mdb_warn("avl walk failed for global target tree");
+ return (DCMD_ERR);
+ }
+ list_addr = iscsit_global_addr +
+ offsetof(iscsit_global_t, global_deleted_target_list);
+ if (mdb_pwalk("list", iscsi_tgt_walk_cb,
+ &idc, list_addr) == -1) {
+ mdb_warn("list walk failed for deleted target list");
+ return (DCMD_ERR);
+ }
+ return (DCMD_OK);
+ }
+ return (iscsi_tpgt_impl(addr, &idc));
+}
+
+/*
+ * ::iscsi_sess [-ablmtvcSRIT]
*
* iscsi_sess - Print out information associated with an iSCSI session
*
@@ -314,6 +410,8 @@
* c Print associated connection information
* a Print IP addresses with connection information
* t Print associated task information
+ * l Print associated lun information (with -I)
+ * m Print associated initiator command information (with -I)
* b Print associated buffer information
* S Print recent state events and transitions
* R Print reference count audit data
@@ -325,7 +423,8 @@
{
iscsi_dcmd_ctrl_t idc;
int buffer = 0, task = 0, conn = 0, print_ip = 0;
- int states = 0, rc_audit = 0;
+ int states = 0, rc_audit = 0, commands = 0;
+ int luns = 0;
bzero(&idc, sizeof (idc));
if (mdb_getopts(argc, argv,
@@ -334,6 +433,8 @@
'a', MDB_OPT_SETBITS, TRUE, &print_ip,
'c', MDB_OPT_SETBITS, TRUE, &conn,
't', MDB_OPT_SETBITS, TRUE, &task,
+ 'l', MDB_OPT_SETBITS, TRUE, &luns,
+ 'm', MDB_OPT_SETBITS, TRUE, &commands,
'b', MDB_OPT_SETBITS, TRUE, &buffer,
'S', MDB_OPT_SETBITS, TRUE, &states,
'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
@@ -345,6 +446,8 @@
idc.u.child.idc_print_ip = print_ip;
idc.u.child.idc_conn = conn;
idc.u.child.idc_task = task;
+ idc.u.child.idc_cmd = commands;
+ idc.u.child.idc_lun = luns;
idc.u.child.idc_buffer = buffer;
idc.u.child.idc_states = states;
idc.u.child.idc_rc_audit = rc_audit;
@@ -357,16 +460,14 @@
*/
if (!(flags & DCMD_ADDRSPEC)) {
return (iscsi_walk_all_sess(&idc));
- } else {
- return (iscsi_sess_impl(addr, &idc));
}
- /*NOTREACHED*/
+ return (iscsi_sess_impl(addr, &idc));
}
/*
- * ::iscsi_conn [-btvIT]
+ * ::iscsi_conn [-abmtvSRIT]
*
* iscsi_conn - Print out information associated with an iSCSI connection
*
@@ -375,6 +476,7 @@
* a Print IP addresses with connection information
* t Print associated task information
* b Print associated buffer information
+ * m Print associated initiator commands (with -I)
* S Print recent state events and transitions
* R Print reference count audit data
* v Verbose output about the connection
@@ -385,7 +487,7 @@
{
iscsi_dcmd_ctrl_t idc;
int buffer = 0, task = 0, print_ip = 0;
- int states = 0, rc_audit = 0;
+ int states = 0, rc_audit = 0, commands = 0;
bzero(&idc, sizeof (idc));
if (mdb_getopts(argc, argv,
@@ -394,6 +496,7 @@
'a', MDB_OPT_SETBITS, TRUE, &print_ip,
't', MDB_OPT_SETBITS, TRUE, &task,
'b', MDB_OPT_SETBITS, TRUE, &buffer,
+ 'm', MDB_OPT_SETBITS, TRUE, &commands,
'S', MDB_OPT_SETBITS, TRUE, &states,
'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
@@ -404,6 +507,7 @@
idc.u.child.idc_print_ip = print_ip;
idc.u.child.idc_task = task;
idc.u.child.idc_buffer = buffer;
+ idc.u.child.idc_cmd = commands;
idc.u.child.idc_states = states;
idc.u.child.idc_rc_audit = rc_audit;
if (DCMD_HDRSPEC(flags))
@@ -415,10 +519,188 @@
*/
if (!(flags & DCMD_ADDRSPEC)) {
return (iscsi_walk_all_conn(&idc));
+ }
+ return (iscsi_conn_impl(addr, &idc));
+}
+
+
+/*
+ * ::iscsi_svc [-vR]
+ *
+ * iscsi_svc - Print out information associated with an iSCSI svc
+ *
+ * R Print reference count audit data
+ * v Verbose output about the service
+ */
+static int
+iscsi_svc(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ iscsi_dcmd_ctrl_t idc;
+ GElf_Sym sym;
+ uintptr_t idm_addr;
+ uintptr_t svc_list_addr;
+ int rc_audit = 0;
+
+ bzero(&idc, sizeof (iscsi_dcmd_ctrl_t));
+
+ if (mdb_getopts(argc, argv,
+ 'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
+ 'v', MDB_OPT_SETBITS, TRUE, &idc.idc_verbose,
+ NULL) != argc)
+ return (DCMD_USAGE);
+
+ idc.u.child.idc_svc = 1;
+ idc.u.child.idc_rc_audit = rc_audit;
+ if (DCMD_HDRSPEC(flags)) {
+ idc.idc_header = 1;
+ }
+
+ if (!(flags & DCMD_ADDRSPEC)) {
+ if (mdb_lookup_by_name("idm", &sym) == -1) {
+ mdb_warn("failed to find symbol 'idm'");
+ return (DCMD_ERR);
+ }
+ idm_addr = (uintptr_t)sym.st_value;
+ svc_list_addr = idm_addr + offsetof(idm_global_t,
+ idm_tgt_svc_list);
+
+ if (mdb_pwalk("list", iscsi_svc_walk_cb, &idc,
+ svc_list_addr) == -1) {
+ mdb_warn("list walk failed for idm services");
+ return (DCMD_ERR);
+ }
+ return (DCMD_OK);
+ }
+ return (iscsi_svc_impl(addr, &idc));
+}
+
+/*
+ * ::iscsi_portal -R
+ *
+ * iscsi_portal - Print out information associated with an iSCSI portal
+ *
+ * R Print reference count audit data
+ */
+static int
+iscsi_portal(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ iscsi_dcmd_ctrl_t idc;
+ GElf_Sym sym;
+ iscsit_global_t iscsit_global;
+ uintptr_t iscsit_global_addr;
+ uintptr_t tpg_avl_addr;
+ int rc_audit = 0;
+
+ bzero(&idc, sizeof (iscsi_dcmd_ctrl_t));
+
+ if (mdb_getopts(argc, argv,
+ 'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
+ NULL) != argc)
+ return (DCMD_USAGE);
+
+ idc.u.child.idc_rc_audit = rc_audit;
+ idc.u.child.idc_portal = 1;
+ if (DCMD_HDRSPEC(flags)) {
+ idc.idc_header = 1;
+ }
+
+ if (!(flags & DCMD_ADDRSPEC)) {
+ if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
+ mdb_warn("failed to find symbol 'iscsit_global'");
+ return (DCMD_ERR);
+ }
+
+ iscsit_global_addr = (uintptr_t)sym.st_value;
+
+ /* get and print the global default tpg */
+ if (mdb_vread(&iscsit_global, sizeof (iscsit_global_t),
+ iscsit_global_addr) != sizeof (iscsit_global_t)) {
+ mdb_warn("failed to read iscsit_global_t");
+ return (DCMD_ERR);
+ }
+ if (iscsi_tpg_impl((uintptr_t)iscsit_global.global_default_tpg,
+ &idc) != DCMD_OK) {
+ return (DCMD_ERR);
+ }
+
+ /* Walk the tpgs for the rest of the portals */
+ tpg_avl_addr = iscsit_global_addr + offsetof(iscsit_global_t,
+ global_tpg_list);
+ if (mdb_pwalk("avl", iscsi_tpg_walk_cb, &idc,
+ tpg_avl_addr) == -1) {
+ mdb_warn("list walk failed for global tpg tree");
+ return (DCMD_ERR);
+ }
+ return (DCMD_OK);
+ }
+ return (iscsi_portal_impl(addr, &idc));
+}
+
+
+/*
+ * ::iscsi_cmd -S
+ *
+ * iscsi_cmd - Print out information associated with an iSCSI cmd
+ *
+ * S Print state audit data
+ */
+static int
+iscsi_cmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
+{
+ iscsi_dcmd_ctrl_t idc;
+ iscsi_cmd_t cmd;
+ int states = 0;
+
+ bzero(&idc, sizeof (iscsi_dcmd_ctrl_t));
+
+ if (mdb_getopts(argc, argv,
+ 'S', MDB_OPT_SETBITS, TRUE, &states,
+ NULL) != argc)
+ return (DCMD_USAGE);
+
+ idc.u.child.idc_states = states;
+ idc.u.child.idc_cmd = 1;
+ idc.idc_ini = 1;
+ if (DCMD_HDRSPEC(flags)) {
+ idc.idc_header = 1;
+ }
+
+ if (!(flags & DCMD_ADDRSPEC)) {
+ if (mdb_pwalk("iscsi_ini_hba", iscsi_ini_hba_walk_cb,
+ &idc, NULL) == -1) {
+ mdb_warn("iscsi cmd hba list walk failed");
+ return (DCMD_ERR);
+ }
} else {
- return (iscsi_conn_impl(addr, &idc));
+ if (mdb_vread(&cmd, sizeof (iscsi_cmd_t), addr) !=
+ sizeof (iscsi_cmd_t)) {
+ return (DCMD_ERR);
+ }
+ return (iscsi_print_ini_cmd(addr, &cmd, &idc));
}
- /*NOTREACHED*/
+ return (DCMD_OK);
+}
+
+
+static int
+iscsi_ini_hba_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc) {
+ iscsi_hba_t ih;
+
+ if (mdb_vread(&ih, sizeof (ih), addr) != sizeof (ih)) {
+ mdb_warn("Invalid HBA\n");
+ return (DCMD_ERR);
+ }
+
+ if (idc->u.child.idc_hba) {
+ mdb_printf("iscsi_hba %p sessions: \n", addr);
+ }
+
+ if (mdb_pwalk("iscsi_ini_sess", iscsi_ini_sess_walk_cb, idc,
+ (uintptr_t)ih.hba_sess_list) == -1) {
+ mdb_warn("iscsi_sess_t walk failed");
+ return (DCMD_ERR);
+ }
+ return (DCMD_OK);
}
/*
@@ -462,10 +744,8 @@
*/
if (!(flags & DCMD_ADDRSPEC)) {
return (iscsi_walk_all_conn(&idc));
- } else {
- return (iscsi_task_impl(addr, &idc));
}
- /*NOTREACHED*/
+ return (iscsi_task_impl(addr, &idc));
}
/*
@@ -480,10 +760,8 @@
{
if (!(flags & DCMD_ADDRSPEC)) {
return (DCMD_ERR);
- } else {
- return (iscsi_refcnt_impl(addr));
}
- /*NOTREACHED*/
+ return (iscsi_refcnt_impl(addr));
}
/*
@@ -499,64 +777,10 @@
{
if (!(flags & DCMD_ADDRSPEC)) {
return (DCMD_ERR);
- } else {
- return (iscsi_sm_audit_impl(addr));
}
- /*NOTREACHED*/
+ return (iscsi_sm_audit_impl(addr));
}
-/*
- * Helper function to list all the initiator sessions
- */
-static int
-iscsi_walk_ini_sessions(uintptr_t array_vaddr)
-{
- iscsi_hba_t ihp;
- int i;
- int array_size;
- struct i_ddi_soft_state *ss;
- iscsi_sess_t *isp;
-
- ss = (struct i_ddi_soft_state *)mdb_alloc(sizeof (*ss),
- UM_SLEEP|UM_GC);
- if (mdb_vread(ss, sizeof (*ss), array_vaddr) != sizeof (*ss)) {
- mdb_warn("Cannot read softstate struct (Invalid pointer?).\n");
- return (DCMD_ERR);
- }
- array_size = ss->n_items * (sizeof (void *));
- array_vaddr = (uintptr_t)ss->array;
- ss->array = mdb_alloc(array_size, UM_SLEEP|UM_GC);
- if (mdb_vread(ss->array, array_size, array_vaddr) != array_size) {
- mdb_warn("Corrupted softstate struct.\n");
- return (DCMD_ERR);
- }
- for (i = 0; i < ss->n_items; i++) {
- if (ss->array[i] == 0)
- continue;
-
- if (mdb_vread(&ihp, sizeof (ihp), (uintptr_t)ss->array[i])
- != sizeof (ihp)) {
- mdb_warn("Corrupted softstate struct.\n");
- return (DCMD_ERR);
- }
- mdb_printf("iscsi_hba %p sessions: \n", ihp);
- mdb_printf("%<u>%-19s %-4s %-8s%</u>\n",
- "Session", "Type", "State");
- for (isp = ihp.hba_sess_list; isp; ) {
- iscsi_sess_t sess;
- if ((mdb_vread(&sess, sizeof (iscsi_sess_t),
- (uintptr_t)isp)) != sizeof (iscsi_sess_t)) {
- mdb_warn("Failed to read session\n");
- return (DCMD_ERR);
- }
- mdb_printf("%-19p %-4d %-8d\n", isp,
- sess.sess_type,
- sess.sess_state);
- isp = sess.sess_next;
- }
- }
- return (DCMD_OK);
-}
static int
iscsi_walk_all_sess(iscsi_dcmd_ctrl_t *idc)
@@ -565,17 +789,19 @@
uintptr_t avl_addr;
uintptr_t list_addr;
GElf_Sym sym;
- uintptr_t adr;
+
/* Initiator sessions */
if (idc->idc_ini) {
- if (mdb_readvar(&adr, "iscsi_state") == -1) {
-
- mdb_warn("state variable iscsi_state not found.\n");
- mdb_warn("Is the driver loaded ?\n");
+ /* Always print hba info on this path */
+ idc->u.child.idc_hba = 1;
+ if (mdb_pwalk("iscsi_ini_hba", iscsi_ini_hba_walk_cb,
+ idc, NULL) == -1) {
+ mdb_warn("iscsi cmd hba list walk failed");
return (DCMD_ERR);
}
- return (iscsi_walk_ini_sessions(adr));
+ return (DCMD_OK);
}
+
/* Target sessions */
/* Walk discovery sessions */
if (mdb_lookup_by_name("iscsit_global", &sym) == -1) {
@@ -762,6 +988,84 @@
return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
}
+/*ARGSUSED*/
+static int
+iscsi_svc_walk_cb(uintptr_t addr, const void *list_walker_data,
+ void *idc_void)
+{
+ iscsi_dcmd_ctrl_t *idc = idc_void;
+ int rc;
+
+ rc = iscsi_svc_impl(addr, idc);
+
+ return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
+}
+
+/*ARGSUSED*/
+static int
+iscsi_ini_hba_walk_cb(uintptr_t addr, const void *vhba,
+ void *idc_void) {
+
+ iscsi_dcmd_ctrl_t *idc = idc_void;
+ int rc;
+
+ rc = iscsi_ini_hba_impl(addr, idc);
+
+ return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
+}
+
+static int
+iscsi_ini_sess_walk_cb(uintptr_t addr, const void *vsess, void *idc_void)
+{
+ int rc;
+
+ if (vsess == NULL) {
+ return (WALK_ERR);
+ }
+
+ rc = iscsi_print_ini_sess(addr, (iscsi_sess_t *)vsess,
+ (iscsi_dcmd_ctrl_t *)idc_void);
+
+ return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
+}
+
+/*ARGSUSED*/
+static int
+iscsi_ini_conn_walk_cb(uintptr_t addr, const void *vconn, void *idc_void)
+{
+ const iscsi_conn_t *ict = vconn;
+ int rc;
+
+ if (vconn == NULL) {
+ return (WALK_ERR);
+ }
+
+ /*
+ * Look up the idm_conn_t in the iscsi_conn_t and call the general
+ * connection handler.
+ */
+ rc = iscsi_conn_impl((uintptr_t)ict->conn_ic,
+ (iscsi_dcmd_ctrl_t *)idc_void);
+
+ return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
+}
+
+static int
+iscsi_ini_lun_walk_cb(uintptr_t addr, const void *vlun, void *idc_void)
+{
+ int rc;
+
+ if (vlun == NULL) {
+ return (WALK_ERR);
+ }
+
+ rc = iscsi_print_ini_lun(addr, (iscsi_lun_t *)vlun,
+ (iscsi_dcmd_ctrl_t *)idc_void);
+
+ return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
+}
+
+
static int
iscsi_tgt_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
{
@@ -811,53 +1115,51 @@
tgt.target_sess_list.avl_numnodes,
tgt.target_state);
mdb_printf(" %s\n", tgt_name);
+
+ /* Indent and disable verbose for any child structures */
+ mdb_inc_indent(4);
+ idc->idc_verbose = 0;
}
- idc->idc_header = 0;
- idc->idc_verbose = 0;
-
/*
* Print states if requested
*/
if (idc->u.child.idc_tgt && states) {
states_addr = addr + offsetof(iscsit_tgt_t, target_state_audit);
- (void) mdb_inc_indent(4);
- mdb_printf("State History:\n");
+ mdb_printf("State History(target_state_audit):\n");
if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
return (DCMD_ERR);
idc->u.child.idc_states = 0;
- (void) mdb_dec_indent(4);
}
/*
* Print refcnt audit data if requested
*/
if (idc->u.child.idc_tgt && rc_audit) {
- (void) mdb_inc_indent(4);
- mdb_printf("target_sess_refcnt:\n");
+ mdb_printf("Reference History(target_sess_refcnt):\n");
rc_addr = addr +
offsetof(iscsit_tgt_t, target_sess_refcnt);
if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
return (DCMD_ERR);
- mdb_printf("target_refcnt:\n");
+ mdb_printf("Reference History(target_refcnt):\n");
rc_addr = addr +
offsetof(iscsit_tgt_t, target_refcnt);
if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
return (DCMD_ERR);
idc->u.child.idc_rc_audit = 0;
- (void) mdb_dec_indent(4);
}
/* Any child objects to walk? */
- if (idc->u.child.idc_tpgt || idc->u.child.idc_sess ||
- idc->u.child.idc_conn || idc->u.child.idc_task ||
- idc->u.child.idc_buffer) {
+ if (idc->u.child.idc_tpgt || idc->u.child.idc_portal) {
+
+ if (idc->u.child.idc_tgt) {
+ idc->idc_header = 1;
+ }
+
/* Walk TPGT tree */
- idc->idc_header = 1;
- (void) mdb_inc_indent(4);
avl_addr = addr +
offsetof(iscsit_tgt_t, target_tpgt_list);
if (mdb_pwalk("avl", iscsi_tpgt_walk_cb, idc,
@@ -866,11 +1168,17 @@
(void) mdb_dec_indent(4);
return (DCMD_ERR);
}
- (void) mdb_dec_indent(4);
+ }
+
+ if (idc->u.child.idc_sess || idc->u.child.idc_conn ||
+ idc->u.child.idc_task || idc->u.child.idc_buffer) {
+
+ if (idc->u.child.idc_tgt || idc->u.child.idc_tpgt ||
+ idc->u.child.idc_portal) {
+ idc->idc_header = 1;
+ }
/* Walk sess tree */
- idc->idc_header = 1;
- (void) mdb_inc_indent(4);
avl_addr = addr + offsetof(iscsit_tgt_t, target_sess_list);
if (mdb_pwalk("avl", iscsi_sess_walk_cb, idc,
avl_addr) == -1) {
@@ -878,9 +1186,12 @@
(void) mdb_dec_indent(4);
return (DCMD_ERR);
}
- (void) mdb_dec_indent(4);
-
+ }
+
+ /* If tgts were handled decrease indent and reset header */
+ if (idc->u.child.idc_tgt) {
idc->idc_header = 0;
+ mdb_dec_indent(4);
}
idc->idc_verbose = verbose;
@@ -894,7 +1205,8 @@
{
iscsit_tpgt_t tpgt;
iscsit_tpg_t tpg;
- uintptr_t avl_addr, tpg_addr;
+ uintptr_t avl_addr, tpg_addr, rc_addr;
+ int rc_audit;
/*
* Read iscsit_tpgt_t
@@ -914,6 +1226,8 @@
return (DCMD_ERR);
}
+ rc_audit = idc->u.child.idc_rc_audit;
+
/*
* Brief output
*
@@ -932,11 +1246,23 @@
}
mdb_printf("%?p %?p %-18s 0x%04x\n", addr, tpgt.tpgt_tpg,
tpg.tpg_name, tpgt.tpgt_tag);
+
+ if (rc_audit) {
+ (void) mdb_inc_indent(4);
+
+ mdb_printf("Reference History(tpgt_refcnt):\n");
+ rc_addr = addr + offsetof(iscsit_tpgt_t, tpgt_refcnt);
+ if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
+ return (DCMD_ERR);
+
+ idc->u.child.idc_rc_audit = 0;
+ (void) mdb_dec_indent(4);
+ }
}
/*
* Assume for now that anyone interested in TPGT wants to see the
- * portals as well.
+ * portals as well. Enable idc_header for the portals.
*/
idc->idc_header = 1;
(void) mdb_inc_indent(4);
@@ -949,6 +1275,7 @@
(void) mdb_dec_indent(4);
idc->idc_header = 0;
+ idc->u.child.idc_rc_audit = rc_audit;
return (DCMD_OK);
}
@@ -956,7 +1283,10 @@
iscsi_tpg_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
{
iscsit_tpg_t tpg;
- uintptr_t avl_addr;
+ uintptr_t avl_addr, rc_addr;
+ int rc_audit = 0;
+
+ rc_audit = idc->u.child.idc_rc_audit;
/*
* Read iscsit_tpg_t
@@ -975,31 +1305,48 @@
* iscsit_tpgt_t.tpgt_tag;
*/
- /* For now we will ignore the verbose flag */
-
- /* Print target data */
- if (idc->idc_header) {
- mdb_printf("%<u>%-?s %-18s%</u>\n",
- "iscsit_tpg_t", "Name");
+ /* Print tpg data */
+ if (idc->u.child.idc_tpg) {
+ if (idc->idc_header) {
+ mdb_printf("%<u>%-?s %-18s%</u>\n",
+ "iscsit_tpg_t", "Name");
+ }
+ mdb_printf("%?p %-18s\n", addr, tpg.tpg_name);
+
+ (void) mdb_inc_indent(4);
+
+ if (rc_audit) {
+ mdb_printf("Reference History(tpg_refcnt):\n");
+ rc_addr = addr + offsetof(iscsit_tpg_t, tpg_refcnt);
+ if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
+ return (DCMD_ERR);
+ }
+ idc->u.child.idc_rc_audit = 0;
+ }
}
- mdb_printf("%?p %-18s\n", addr, tpg.tpg_name);
-
-
- /*
- * Assume for now that anyone interested in TPG wants to see the
- * portals as well.
- */
- idc->idc_header = 1;
- (void) mdb_inc_indent(4);
- avl_addr = addr + offsetof(iscsit_tpg_t, tpg_portal_list);
- if (mdb_pwalk("avl", iscsi_portal_walk_cb, idc, avl_addr) == -1) {
- mdb_warn("portal list walk failed");
+
+ if (idc->u.child.idc_portal) {
+ if (idc->u.child.idc_tpg) {
+ idc->idc_header = 1;
+ }
+
+ avl_addr = addr + offsetof(iscsit_tpg_t, tpg_portal_list);
+ if (mdb_pwalk("avl", iscsi_portal_walk_cb, idc,
+ avl_addr) == -1) {
+ mdb_warn("portal list walk failed");
+ if (idc->u.child.idc_tpg) {
+ (void) mdb_dec_indent(4);
+ }
+ return (DCMD_ERR);
+ }
+ }
+
+ if (idc->u.child.idc_tpg) {
(void) mdb_dec_indent(4);
- return (DCMD_ERR);
+ idc->idc_header = 0;
}
- (void) mdb_dec_indent(4);
- idc->idc_header = 0;
-
+
+ idc->u.child.idc_rc_audit = rc_audit;
return (DCMD_OK);
}
@@ -1008,6 +1355,8 @@
{
iscsit_portal_t portal;
char portal_addr[PORTAL_STR_LEN];
+ uintptr_t rc_addr;
+
if (idc->u.child.idc_portal) {
/*
* Read iscsit_portal_t
@@ -1021,10 +1370,22 @@
if (idc->idc_header) {
mdb_printf("%<u>%-?s %-?s %-30s%</u>\n",
"iscsit_portal_t", "idm_svc_t", "IP:Port");
+ idc->idc_header = 0;
}
sa_to_str(&portal.portal_addr, portal_addr);
mdb_printf("%?p %?p %s\n", addr, portal.portal_svc,
- portal_addr);
+ portal.portal_default ? "(Default)" : portal_addr);
+
+ if (idc->u.child.idc_rc_audit) {
+ (void) mdb_inc_indent(4);
+ mdb_printf("Reference History(portal_refcnt):\n");
+ rc_addr = addr + offsetof(iscsit_portal_t,
+ portal_refcnt);
+ if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
+ return (DCMD_ERR);
+ }
+ (void) mdb_dec_indent(4);
+ }
}
return (DCMD_OK);
@@ -1034,11 +1395,23 @@
iscsi_sess_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
{
iscsit_sess_t ist;
+ iscsi_sess_t ini_sess;
uintptr_t list_addr, states_addr, rc_addr;
char ini_name[80];
char tgt_name[80];
int verbose, states, rc_audit;
+ if (idc->idc_ini) {
+ if ((mdb_vread(&ini_sess, sizeof (iscsi_sess_t),
+ (uintptr_t)addr)) != sizeof (iscsi_sess_t)) {
+ mdb_warn("Failed to read initiator session\n");
+ return (DCMD_ERR);
+ }
+ if (iscsi_print_ini_sess(addr, &ini_sess, idc) != DCMD_OK) {
+ return (DCMD_ERR);
+ }
+ return (DCMD_OK);
+ }
/*
* Read iscsit_sess_t
*/
@@ -1100,6 +1473,8 @@
ist.ist_expcmdsn);
mdb_printf("%16s: %08x\n", "MaxCmdSN",
ist.ist_maxcmdsn);
+
+ idc->idc_verbose = 0;
} else {
/* Print session data */
if (idc->idc_header) {
@@ -1114,33 +1489,32 @@
ist.ist_isid[3], ist.ist_isid[4], ist.ist_isid[5],
ist.ist_tsih);
}
- idc->idc_header = 0;
+
+ /*
+ * Indent for any child structures
+ */
+ (void) mdb_inc_indent(4);
}
- idc->idc_verbose = 0;
-
/*
* Print states if requested
*/
- if (states) {
+ if (idc->u.child.idc_sess && states) {
states_addr = addr + offsetof(iscsit_sess_t, ist_state_audit);
- (void) mdb_inc_indent(4);
- mdb_printf("State History:\n");
+ mdb_printf("State History(ist_state_audit):\n");
if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
return (DCMD_ERR);
/* Don't print state history for child objects */
idc->u.child.idc_states = 0;
- (void) mdb_dec_indent(4);
}
/*
* Print refcnt audit data if requested
*/
- if (rc_audit) {
- (void) mdb_inc_indent(4);
- mdb_printf("Reference History:\n");
+ if (idc->u.child.idc_sess && rc_audit) {
+ mdb_printf("Reference History(ist_refcnt):\n");
rc_addr = addr +
offsetof(iscsit_sess_t, ist_refcnt);
if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
@@ -1148,15 +1522,20 @@
/* Don't print audit data for child objects */
idc->u.child.idc_rc_audit = 0;
- (void) mdb_dec_indent(4);
}
/* Any child objects to walk? */
if (idc->u.child.idc_conn || idc->u.child.idc_task ||
idc->u.child.idc_buffer) {
+ /*
+ * If a session has been printed enable headers for
+ * any child structs.
+ */
+ if (idc->u.child.idc_sess) {
+ idc->idc_header = 1;
+ }
+
/* Walk conn list */
- idc->idc_header = 1;
- (void) mdb_inc_indent(4);
list_addr = addr + offsetof(iscsit_sess_t, ist_conn_list);
if (mdb_pwalk("list", iscsi_sess_conn_walk_cb, idc,
list_addr) == -1) {
@@ -1164,8 +1543,12 @@
(void) mdb_dec_indent(4);
return (DCMD_ERR);
}
- (void) mdb_dec_indent(4);
+ }
+
+ /* If a session was handled decrease indent and reset header. */
+ if (idc->u.child.idc_sess) {
idc->idc_header = 0;
+ mdb_dec_indent(4);
}
idc->idc_verbose = verbose;
@@ -1176,6 +1559,134 @@
}
static int
+iscsi_print_ini_sess(uintptr_t addr, iscsi_sess_t *sess,
+ iscsi_dcmd_ctrl_t *idc)
+{
+
+ int verbose, states;
+ uintptr_t states_addr;
+
+ verbose = idc->idc_verbose;
+ states = idc->u.child.idc_states;
+
+
+ if (idc->u.child.idc_sess) {
+ if (!idc->idc_verbose) {
+ if (idc->idc_header) {
+ mdb_printf("%<u>%-?s %-4s %-8s%</u>\n",
+ "iscsi_sess_t", "Type", "State");
+ }
+ mdb_printf("%-19p %-4d %-8d\n", addr,
+ sess->sess_type, sess->sess_state);
+ } else {
+ mdb_printf("Session %p\n", addr);
+ mdb_printf("%22s: %d\n", "State",
+ sess->sess_state);
+ mdb_printf("%22s: %d\n", "Last State",
+ sess->sess_prev_state);
+ mdb_printf("%22s: %s\n", "Session Name",
+ sess->sess_name);
+ mdb_printf("%22s: %s\n", "Alias",
+ sess->sess_alias);
+ mdb_printf("%22s: %08x\n", "CmdSN",
+ sess->sess_cmdsn);
+ mdb_printf("%22s: %08x\n", "ExpCmdSN",
+ sess->sess_expcmdsn);
+ mdb_printf("%22s: %08x\n", "MaxCmdSN",
+ sess->sess_maxcmdsn);
+ mdb_printf("%22s: %p\n", "Pending Queue Head",
+ sess->sess_queue_pending.head);
+ mdb_printf("%22s: %p\n", "Completion Queue Head",
+ sess->sess_queue_completion.head);
+ mdb_printf("%22s: %p\n", "Connnection List Head",
+ sess->sess_conn_list);
+
+ idc->idc_verbose = 0;
+ }
+
+ /* Indent for any child structures */
+ mdb_inc_indent(4);
+
+ if (idc->u.child.idc_states) {
+ states_addr = (uintptr_t)addr +
+ offsetof(iscsi_sess_t, sess_state_audit);
+
+ mdb_printf("State History(sess_state_audit):\n");
+ if (iscsi_sm_audit_impl(states_addr) != DCMD_OK) {
+ (void) mdb_dec_indent(4);
+ return (DCMD_ERR);
+ }
+ idc->u.child.idc_states = 0;
+ }
+ }
+
+ if (idc->u.child.idc_lun && sess->sess_lun_list) {
+ if (idc->u.child.idc_sess) {
+ idc->idc_header = 1;
+ }
+
+ if (mdb_pwalk("iscsi_ini_lun", iscsi_ini_lun_walk_cb, idc,
+ (uintptr_t)sess->sess_lun_list) == -1) {
+ mdb_warn("iscsi_ini_lun walk failed");
+ (void) mdb_dec_indent(4);
+ return (DCMD_ERR);
+ }
+ }
+
+
+ /* If requested print the cmds in the session queue */
+ if (idc->u.child.idc_cmd) {
+
+ /* If any other structs printed enable header */
+ if (idc->u.child.idc_sess || idc->u.child.idc_lun) {
+ idc->idc_header = 1;
+ }
+
+ if (sess->sess_queue_pending.head) {
+ if (mdb_pwalk("iscsi_ini_cmd", iscsi_ini_cmd_walk_cb,
+ idc, (uintptr_t)sess->sess_queue_pending.head)
+ == -1) {
+ mdb_warn("list walk failed for iscsi cmds");
+ }
+ }
+ if (sess->sess_queue_completion.head) {
+ if (mdb_pwalk("iscsi_ini_cmd", iscsi_ini_cmd_walk_cb,
+ idc, (uintptr_t)sess->sess_queue_completion.head)
+ == -1) {
+ mdb_warn("list walk failed for iscsi cmds");
+ }
+ }
+ }
+
+ /* If connections or cmds requested walk the connections */
+ if (idc->u.child.idc_conn || idc->u.child.idc_cmd) {
+ /*
+ * If idc_conn is not set don't enable header or the
+ * commands may get extraneous headers.
+ */
+ if (idc->u.child.idc_conn) {
+ idc->idc_header = 1;
+ }
+ if (mdb_pwalk("iscsi_ini_conn", iscsi_ini_conn_walk_cb, idc,
+ (uintptr_t)sess->sess_conn_list) == -1) {
+ mdb_warn("iscsi_ini_conn walk failed");
+ return (DCMD_ERR);
+ }
+ }
+
+ /* If sessions were handled decrease indent and reset header */
+ if (idc->u.child.idc_sess) {
+ idc->idc_header = 0;
+ mdb_dec_indent(4);
+ }
+
+ idc->u.child.idc_states = states;
+ idc->idc_verbose = verbose;
+ return (DCMD_OK);
+}
+
+
+static int
iscsi_conn_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
{
uintptr_t idm_global_addr, states_addr, rc_addr;
@@ -1183,6 +1694,8 @@
GElf_Sym sym;
idm_task_t idt;
idm_conn_t ic;
+ iscsit_conn_t ict;
+ iscsi_conn_t ini_conn;
char *conn_type;
int task_idx;
char laddr[PORTAL_STR_LEN];
@@ -1213,6 +1726,18 @@
if (mdb_vread(&ic, sizeof (idm_conn_t), addr) != sizeof (idm_conn_t)) {
return (DCMD_ERR);
}
+
+ /*
+ * If filter bits are set to only print targets or only initiators
+ * skip entries of the other type.
+ */
+ if (!(idc->idc_ini && idc->idc_tgt) &&
+ ((idc->idc_ini && (ic.ic_conn_type != CONN_TYPE_INI)) ||
+ (idc->idc_tgt && (ic.ic_conn_type != CONN_TYPE_TGT)))) {
+ return (DCMD_OK);
+ }
+
+
conn_type = (ic.ic_conn_type == CONN_TYPE_INI) ? "Ini" :
(ic.ic_conn_type == CONN_TYPE_TGT) ? "Tgt" : "Unk";
@@ -1228,14 +1753,40 @@
states = idc->u.child.idc_states;
rc_audit = idc->u.child.idc_rc_audit;
+ /*
+ * If targets(-T) and/or initiators (-I) are specifically requested,
+ * fetch the iscsit_conn_t and/or iscsi_conn_t struct as a sanity
+ * check and for use below.
+ */
+ if (idc->idc_tgt && IDM_CONN_ISTGT(&ic)) {
+ if (mdb_vread(&ict, sizeof (iscsit_conn_t),
+ (uintptr_t)ic.ic_handle) !=
+ sizeof (iscsit_conn_t)) {
+ mdb_printf("Failed to read target connection "
+ "handle data\n");
+ return (DCMD_ERR);
+ }
+ }
+
+ if (idc->idc_ini && IDM_CONN_ISINI(&ic)) {
+ if (mdb_vread(&ini_conn, sizeof (iscsi_conn_t),
+ (uintptr_t)ic.ic_handle) !=
+ sizeof (iscsi_conn_t)) {
+ mdb_printf("Failed to read initiator "
+ "connection handle data\n");
+ return (DCMD_ERR);
+ }
+ }
+
if (idc->u.child.idc_conn) {
if (idc->idc_verbose) {
mdb_printf("IDM Conn %p\n", addr);
if (ic.ic_conn_type == CONN_TYPE_TGT) {
iscsi_print_iscsit_conn_data(&ic);
} else {
- iscsi_print_idm_conn_data(&ic);
+ iscsi_print_ini_conn_data(&ic);
}
+ idc->idc_verbose = 0;
} else {
/* Print connection data */
if (idc->idc_header) {
@@ -1257,53 +1808,100 @@
laddr, raddr);
}
}
+
+ /* Indent for any child structs */
+ mdb_inc_indent(4);
}
- idc->idc_header = 0;
-
- idc->idc_verbose = 0;
/*
* Print states if requested
*/
- if (states) {
+ if (idc->u.child.idc_conn && states) {
states_addr = addr + offsetof(idm_conn_t, ic_state_audit);
- (void) mdb_inc_indent(4);
- mdb_printf("State History:\n");
+ mdb_printf("State History(ic_state_audit):\n");
if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
return (DCMD_ERR);
+ /*
+ * If targets are specifically requested show the
+ * state audit for the target specific connection struct
+ */
+ if (idc->idc_tgt && IDM_CONN_ISTGT(&ic)) {
+ states_addr = (uintptr_t)ic.ic_handle +
+ offsetof(iscsit_conn_t, ict_login_sm) +
+ offsetof(iscsit_conn_login_t, icl_state_audit);
+
+ mdb_printf("State History(icl_state_audit):\n");
+ if (iscsi_sm_audit_impl(states_addr) != DCMD_OK) {
+ return (DCMD_ERR);
+ }
+ }
+
+ /*
+ * If initiators are specifically requested show the
+ * state audit for the initiator specific connection struct
+ */
+ if (idc->idc_ini && IDM_CONN_ISINI(&ic)) {
+ states_addr = (uintptr_t)ic.ic_handle +
+ offsetof(iscsi_conn_t, conn_state_audit);
+
+ mdb_printf("State History(iscsi_conn_t "
+ "conn_state_audit):\n");
+ if (iscsi_sm_audit_impl(states_addr) != DCMD_OK) {
+ return (DCMD_ERR);
+ }
+ }
+
/* Don't print state history for child objects */
idc->u.child.idc_states = 0;
- (void) mdb_dec_indent(4);
}
/*
- * Print refcnt audit data if requested
+ * Print refcnt audit data for the connection struct if requested.
*/
- if (rc_audit) {
- (void) mdb_inc_indent(4);
- mdb_printf("Reference History:\n");
+ if (idc->u.child.idc_conn && rc_audit) {
+ mdb_printf("Reference History(ic_refcnt):\n");
rc_addr = addr + offsetof(idm_conn_t, ic_refcnt);
if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
return (DCMD_ERR);
+ /*
+ * If targets are specifically requested show the
+ * Refcounts for the target specific connection struct
+ */
+ if (idc->idc_tgt && IDM_CONN_ISTGT(&ic)) {
+ mdb_printf("Reference History(ict_refcnt):\n");
+ rc_addr = (uintptr_t)ic.ic_handle +
+ offsetof(iscsit_conn_t, ict_refcnt);
+ if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
+ return (DCMD_ERR);
+ }
+
+ mdb_printf("Reference History(ict_dispatch_refcnt):\n");
+ rc_addr = (uintptr_t)ic.ic_handle +
+ offsetof(iscsit_conn_t, ict_dispatch_refcnt);
+ if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
+ return (DCMD_ERR);
+ }
+ }
+
/* Don't print audit data for child objects */
idc->u.child.idc_rc_audit = 0;
- (void) mdb_dec_indent(4);
}
task_idx = 0;
- /* Any child objects to walk? */
if (idc->u.child.idc_task || idc->u.child.idc_buffer) {
- idc->idc_header = 1;
+
+ if (idc->u.child.idc_conn) {
+ idc->idc_header = 1;
+ }
+
while (task_idx < IDM_TASKIDS_MAX) {
-
/*
* Read the next idm_task_t
*/
-
if (mdb_vread(&task_addr, sizeof (uintptr_t),
task_ptr) != sizeof (uintptr_t)) {
mdb_warn("Failed to read task pointer");
@@ -1324,21 +1922,42 @@
if (((uintptr_t)idt.idt_ic == addr) &&
(idt.idt_state != TASK_IDLE)) {
- (void) mdb_inc_indent(4);
if (iscsi_i_task_impl(&idt, task_addr, idc)
== -1) {
mdb_warn("Failed to walk connection "
"task tree");
- (void) mdb_dec_indent(4);
return (DCMD_ERR);
}
- (void) mdb_dec_indent(4);
}
task_ptr += sizeof (uintptr_t);
task_idx++;
}
+ }
+
+ if (idc->idc_ini && IDM_CONN_ISINI(&ic) && idc->u.child.idc_cmd) {
+ if (idc->u.child.idc_conn || idc->u.child.idc_task) {
+ idc->idc_header = 1;
+ }
+ if (ini_conn.conn_queue_active.head &&
+ (mdb_pwalk("iscsi_ini_cmd", iscsi_ini_cmd_walk_cb, idc,
+ (uintptr_t)ini_conn.conn_queue_active.head) == -1)) {
+ mdb_warn("list walk failed for iscsi cmds");
+ }
+ if (ini_conn.conn_queue_idm_aborting.head &&
+ (mdb_pwalk("iscsi_ini_cmd", iscsi_ini_cmd_walk_cb, idc,
+ (uintptr_t)ini_conn.conn_queue_idm_aborting.head) == -1)) {
+ mdb_warn("list walk failed for iscsi cmds");
+ }
+ }
+
+ /*
+ * If connection information was handled unset header and
+ * decrease indent
+ */
+ if (idc->u.child.idc_conn) {
idc->idc_header = 0;
+ mdb_dec_indent(4);
}
idc->idc_verbose = verbose;
@@ -1348,6 +1967,73 @@
return (DCMD_OK);
}
+static int
+iscsi_svc_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
+{
+ idm_svc_t svc;
+ iser_svc_t iser_svc;
+ uintptr_t rc_addr;
+
+ if (mdb_vread(&svc, sizeof (idm_svc_t), addr) !=
+ sizeof (idm_svc_t)) {
+ return (DCMD_ERR);
+ }
+
+ if (idc->u.child.idc_svc) {
+ if (idc->idc_verbose) {
+ mdb_printf("Service %p\n", addr);
+ mdb_printf("%20s: %d\n", "Port",
+ svc.is_svc_req.sr_port);
+ mdb_printf("%20s: %d\n", "Online",
+ svc.is_online);
+ mdb_printf("%20s: %p\n", "Socket Service",
+ svc.is_so_svc);
+ mdb_printf("%20s: %p\n", "iSER Service",
+ svc.is_iser_svc);
+ } else {
+ if (idc->idc_header) {
+ mdb_printf("%<u>%-?s %-8s %-8s%</u>\n",
+ "idm_svc_t", "Port", "Online");
+ idc->idc_header = 0;
+ }
+
+ mdb_printf("%?p %-8d %-8d\n", addr,
+ svc.is_svc_req.sr_port, svc.is_online);
+ }
+
+ if (idc->u.child.idc_rc_audit) {
+ (void) mdb_inc_indent(4);
+ mdb_printf("Reference History(is_refcnt):\n");
+ rc_addr = addr + offsetof(idm_svc_t, is_refcnt);
+ if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
+ (void) mdb_dec_indent(4);
+ return (DCMD_ERR);
+ }
+
+ if (svc.is_iser_svc != NULL) {
+ mdb_printf("Reference History"
+ "(iser_svc is_refcnt):\n");
+
+ /* Sanity check the iser svc struct */
+ if (mdb_vread(&iser_svc, sizeof (iser_svc_t),
+ (uintptr_t)svc.is_iser_svc) !=
+ sizeof (iser_svc_t)) {
+ return (DCMD_ERR);
+ }
+
+ rc_addr = (uintptr_t)svc.is_iser_svc +
+ offsetof(iser_svc_t, is_refcnt);
+
+ if (iscsi_refcnt_impl(rc_addr) != DCMD_OK) {
+ return (DCMD_ERR);
+ }
+ }
+ (void) mdb_dec_indent(4);
+ }
+ }
+ return (DCMD_OK);
+}
+
static void
iscsi_print_iscsit_conn_data(idm_conn_t *ic)
{
@@ -1363,6 +2049,9 @@
return;
}
+ mdb_printf("%20s: %p\n", "iSCSIT TGT Conn",
+ ic->ic_handle);
+
if (ict.ict_login_sm.icl_login_state != ILS_LOGIN_DONE) {
switch (ict.ict_login_sm.icl_login_csg) {
case ISCSI_SECURITY_NEGOTIATION_STAGE:
@@ -1416,6 +2105,41 @@
}
static void
+iscsi_print_ini_conn_data(idm_conn_t *ic)
+{
+ iscsi_conn_t ini_conn;
+
+ iscsi_print_idm_conn_data(ic);
+
+ if (mdb_vread(&ini_conn, sizeof (iscsi_conn_t),
+ (uintptr_t)ic->ic_handle) != sizeof (iscsi_conn_t)) {
+ mdb_printf("Failed to read conn private data\n");
+ return;
+ }
+
+ mdb_printf("%20s: %p\n", "iSCSI Ini Conn",
+ ic->ic_handle);
+ mdb_printf("%20s: %p\n", "Parent Session",
+ ini_conn.conn_sess);
+ mdb_printf("%20s: %d\n", "Conn State",
+ ini_conn.conn_state);
+ mdb_printf("%20s: %d\n", "Last Conn State",
+ ini_conn.conn_prev_state);
+
+ mdb_printf("%20s: %d\n", "Login Stage",
+ ini_conn.conn_current_stage);
+ mdb_printf("%20s: %d\n", "Next Login Stage",
+ ini_conn.conn_next_stage);
+
+ mdb_printf("%20s: 0x%08x\n", "Expected StatSN",
+ ini_conn.conn_expstatsn);
+ mdb_printf("%20s: %p\n", "Active Queue Head",
+ ini_conn.conn_queue_active.head);
+ mdb_printf("%20s: %d\n", "Abort Queue Head",
+ ini_conn.conn_queue_idm_aborting.head);
+}
+
+static void
iscsi_print_idm_conn_data(idm_conn_t *ic)
{
char laddr[PORTAL_STR_LEN];
@@ -1499,7 +2223,7 @@
states_addr = addr + offsetof(idm_task_t, idt_state_audit);
(void) mdb_inc_indent(4);
- mdb_printf("State History:\n");
+ mdb_printf("State History(idt_state_audit):\n");
if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
return (DCMD_ERR);
@@ -1514,7 +2238,7 @@
*/
if (rc_audit) {
(void) mdb_inc_indent(4);
- mdb_printf("Reference History:\n");
+ mdb_printf("Reference History(idt_refcnt):\n");
rc_addr = addr +
offsetof(idm_task_t, idt_refcnt);
if (iscsi_refcnt_impl(rc_addr) != DCMD_OK)
@@ -1526,7 +2250,10 @@
}
- /* Buffers are leaf objects */
+ /*
+ * Buffers are leaf objects and always get headers so the
+ * user can discern between in and out buffers.
+ */
if (idc->u.child.idc_buffer) {
/* Walk in buffer list */
(void) mdb_inc_indent(2);
@@ -1647,6 +2374,56 @@
}
static int
+iscsi_print_ini_lun(uintptr_t addr, const iscsi_lun_t *lun,
+ iscsi_dcmd_ctrl_t *idc)
+{
+
+ if (idc->u.child.idc_lun) {
+ if (idc->idc_header) {
+ mdb_printf("%<u>%-?s %-5s %-10s%</u>\n",
+ "iscsi_lun_t", "State", "Lun Number");
+ idc->idc_header = 0;
+ }
+ mdb_printf("%?p %-5d %-10d\n", addr,
+ lun->lun_state, lun->lun_num);
+ }
+ return (DCMD_OK);
+}
+
+static int
+iscsi_print_ini_cmd(uintptr_t addr, const iscsi_cmd_t *cmd,
+ iscsi_dcmd_ctrl_t *idc) {
+
+ uintptr_t states_addr;
+
+ if (idc->idc_header) {
+ mdb_printf("%<u>%-?s %-?s %4s %6s/%-6s %-?s%</u>\n",
+ "iscsi_cmd_t", "idm_task_t", "Type",
+ "State", "Prev", "iscsi_lun_t");
+ idc->idc_header = 0;
+ }
+
+ mdb_printf("%?p %?p %4d %6d/%-6d %?p\n",
+ addr, cmd->cmd_itp, cmd->cmd_type, cmd->cmd_state,
+ cmd->cmd_prev_state, cmd->cmd_lun);
+
+ /*
+ * Print states if requested
+ */
+ if (idc->u.child.idc_states) {
+ states_addr = addr + offsetof(iscsi_cmd_t, cmd_state_audit);
+
+ (void) mdb_inc_indent(4);
+ mdb_printf("State History(cmd_state_audit):\n");
+ if (iscsi_sm_audit_impl(states_addr) != DCMD_OK)
+ return (DCMD_ERR);
+ idc->u.child.idc_states = 0;
+ (void) mdb_dec_indent(4);
+ }
+ return (DCMD_OK);
+}
+
+static int
iscsi_buffer_impl(uintptr_t addr, iscsi_dcmd_ctrl_t *idc)
{
idm_buf_t idb;
@@ -1663,8 +2440,8 @@
mdb_printf("%<u>%-?s %?s/%-8s %8s %8s %8s%</u>\n",
"idm_buf_t", "Mem Rgn", "Length",
"Rel Off", "Xfer Len", "Exp. Off");
+ idc->idc_header = 0;
}
- idc->idc_header = 0;
/* Print buffer data */
mdb_printf("%?p %?p/%08x %8x %8x %08x\n", addr,
@@ -1690,6 +2467,7 @@
*/
if (mdb_vread(&refcnt, sizeof (idm_refcnt_t), addr) !=
sizeof (idm_refcnt_t)) {
+ mdb_warn("read refcnt failed");
return (DCMD_ERR);
}
@@ -1760,6 +2538,7 @@
*/
if (mdb_vread(&audit_buf, sizeof (sm_audit_buf_t), addr) !=
sizeof (sm_audit_buf_t)) {
+ mdb_warn("failed to read audit buf");
return (DCMD_ERR);
}
@@ -2096,6 +2875,7 @@
mdb_printf("-s: Print iSNS server information\n");
mdb_printf("-t: Print target information\n");
mdb_printf("-v: Add verbosity to the other options' output\n");
+ mdb_printf("-R: Add Refcount information to '-t' output\n");
mdb_dec_indent(4);
}
@@ -2169,11 +2949,11 @@
mdb_printf("\n");
}
if (portal.portal_iscsit != NULL) {
- mdb_printf("(Part of TPG: 0x%x)\n", portal.portal_iscsit);
+ mdb_printf("(Part of TPG: 0x%p)\n", portal.portal_iscsit);
}
iscsi_format_timestamp(ts_string, 40, &portal.portal_esi_timestamp);
- mdb_printf("Portal ESI timestamp: 0x%p\n\n", ts_string);
+ mdb_printf("Portal ESI timestamp: %s\n\n", ts_string);
if ((portal.portal_iscsit != NULL) && (idc->idc_verbose)) {
mdb_inc_indent(4);
@@ -2231,6 +3011,8 @@
iscsi_dcmd_ctrl_t *idc = (iscsi_dcmd_ctrl_t *)data;
isns_target_t itarget;
int rc = 0;
+ int rc_audit = 0;
+ uintptr_t rc_addr;
if (mdb_vread(&itarget, sizeof (isns_target_t), addr) !=
sizeof (isns_target_t)) {
@@ -2238,6 +3020,7 @@
}
idc->idc_header = 1;
+ rc_audit = idc->u.child.idc_rc_audit;
mdb_printf("Target: %p\n", addr);
mdb_inc_indent(4);
@@ -2247,8 +3030,21 @@
(itarget.target_update_needed) ? "Yes" : "No");
mdb_printf("Target Info: %p\n", itarget.target_info);
+ /* Prevent target refcounts from showing through this path */
+ idc->u.child.idc_rc_audit = 0;
rc = iscsi_tgt_impl((uintptr_t)itarget.target, idc);
+ idc->u.child.idc_rc_audit = rc_audit;
+ if (idc->u.child.idc_rc_audit) {
+ rc_addr = (uintptr_t)itarget.target_info +
+ offsetof(isns_target_info_t, ti_refcnt);
+
+ mdb_printf("Reference History(isns_target_info ti_refcnt):\n");
+ if (iscsi_refcnt_impl(rc_addr) != 0) {
+ return (WALK_ERR);
+ }
+ }
+
mdb_dec_indent(4);
if (rc == DCMD_OK) {
@@ -2379,6 +3175,7 @@
{
iscsi_dcmd_ctrl_t idc;
int portals = 0, esi = 0, targets = 0, verbose = 0, servers = 0;
+ int rc_audit = 0;
if (flags & DCMD_ADDRSPEC) {
mdb_warn("iscsi_isns is only a global dcmd.");
@@ -2392,6 +3189,7 @@
's', MDB_OPT_SETBITS, TRUE, &servers,
't', MDB_OPT_SETBITS, TRUE, &targets,
'v', MDB_OPT_SETBITS, TRUE, &verbose,
+ 'R', MDB_OPT_SETBITS, TRUE, &rc_audit,
NULL) != argc)
return (DCMD_USAGE);
@@ -2406,6 +3204,7 @@
}
idc.idc_verbose = verbose;
+ idc.u.child.idc_rc_audit = rc_audit;
if (esi) {
return (iscsi_isns_esi(&idc));
@@ -2422,6 +3221,277 @@
return (iscsi_isns_targets(&idc));
}
+static int
+iscsi_ini_sess_walk_init(mdb_walk_state_t *wsp) {
+
+
+ if (wsp->walk_addr == NULL) {
+ mdb_warn("<iscsi_sess_t addr>::walk iscsi_ini_sess");
+ return (WALK_ERR);
+ }
+
+ wsp->walk_data = mdb_alloc(sizeof (iscsi_sess_t), UM_SLEEP|UM_GC);
+ if (!wsp->walk_data) {
+ mdb_warn("iscsi_ini_sess walk failed");
+ return (WALK_ERR);
+ }
+
+ return (WALK_NEXT);
+}
+
+static int
+iscsi_ini_sess_step(mdb_walk_state_t *wsp) {
+ int status;
+
+ if (wsp->walk_addr == NULL) {
+ return (WALK_DONE);
+ }
+
+ if (mdb_vread(wsp->walk_data, sizeof (iscsi_sess_t), wsp->walk_addr)
+ != sizeof (iscsi_sess_t)) {
+ mdb_warn("failed to read iscsi_sess_t at %p", wsp->walk_addr);
+ return (WALK_DONE);
+ }
+
+ status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
+ wsp->walk_cbdata);
+
+ wsp->walk_addr =
+ (uintptr_t)(((iscsi_sess_t *)wsp->walk_data)->sess_next);
+
+ return (status);
+}
+
+static int
+iscsi_ini_conn_walk_init(mdb_walk_state_t *wsp) {
+
+ if (wsp->walk_addr == NULL) {
+ mdb_warn("<iscsi_conn_t addr>::walk iscsi_ini_conn");
+ return (WALK_DONE);
+ }
+
+ wsp->walk_data = mdb_alloc(sizeof (iscsi_conn_t), UM_SLEEP|UM_GC);
+ if (!wsp->walk_data) {
+ mdb_warn("iscsi_ini_conn walk failed");
+ return (WALK_ERR);
+ }
+
+ return (WALK_NEXT);
+}
+
+static int
+iscsi_ini_conn_step(mdb_walk_state_t *wsp) {
+ int status;
+
+ if (wsp->walk_addr == NULL) {
+ return (WALK_DONE);
+ }
+
+ if (mdb_vread(wsp->walk_data, sizeof (iscsi_conn_t), wsp->walk_addr)
+ != sizeof (iscsi_conn_t)) {
+ mdb_warn("failed to read iscsi_conn_t at %p", wsp->walk_addr);
+ return (WALK_DONE);
+ }
+
+
+ status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
+ wsp->walk_cbdata);
+
+ wsp->walk_addr =
+ (uintptr_t)(((iscsi_conn_t *)wsp->walk_data)->conn_next);
+
+ return (status);
+}
+
+static int
+iscsi_ini_lun_walk_init(mdb_walk_state_t *wsp) {
+
+ if (wsp->walk_addr == NULL) {
+ mdb_warn("<iscsi_lun_t addr>::walk iscsi_ini_lun");
+ return (WALK_DONE);
+ }
+
+ wsp->walk_data = mdb_alloc(sizeof (iscsi_lun_t), UM_SLEEP|UM_GC);
+ if (!wsp->walk_data) {
+ return (WALK_ERR);
+ }
+
+ return (WALK_NEXT);
+}
+
+static int
+iscsi_ini_lun_step(mdb_walk_state_t *wsp) {
+ int status;
+
+ if (wsp->walk_addr == NULL) {
+ return (WALK_DONE);
+ }
+
+ if (mdb_vread(wsp->walk_data, sizeof (iscsi_lun_t), wsp->walk_addr)
+ != sizeof (iscsi_lun_t)) {
+ mdb_warn("failed to read iscsi_lun_t at %p", wsp->walk_addr);
+ return (WALK_DONE);
+ }
+
+ status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
+ wsp->walk_cbdata);
+
+ wsp->walk_addr =
+ (uintptr_t)(((iscsi_lun_t *)wsp->walk_data)->lun_next);
+
+ return (status);
+}
+
+static int
+iscsi_ini_cmd_walk_init(mdb_walk_state_t *wsp) {
+
+ if (wsp->walk_addr == NULL) {
+ mdb_warn("<iscsi_cmd_t addr>::walk iscsi_ini_cmd");
+ return (WALK_DONE);
+ }
+
+ wsp->walk_data = mdb_alloc(sizeof (iscsi_cmd_t), UM_SLEEP|UM_GC);
+ if (!wsp->walk_data) {
+ return (WALK_ERR);
+ }
+
+ return (WALK_NEXT);
+}
+
+static int
+iscsi_ini_cmd_step(mdb_walk_state_t *wsp) {
+ int status;
+
+ if (wsp->walk_addr == NULL) {
+ return (WALK_DONE);
+ }
+
+ if (mdb_vread(wsp->walk_data, sizeof (iscsi_cmd_t), wsp->walk_addr)
+ != sizeof (iscsi_cmd_t)) {
+ mdb_warn("failed to read iscsi_cmd_t at %p", wsp->walk_addr);
+ return (WALK_DONE);
+ }
+
+ status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
+ wsp->walk_cbdata);
+
+ wsp->walk_addr =
+ (uintptr_t)(((iscsi_cmd_t *)wsp->walk_data)->cmd_next);
+
+ return (status);
+}
+
+static int
+iscsi_ini_cmd_walk_cb(uintptr_t addr, const void *vcmd,
+ void *vidc) {
+
+ const iscsi_cmd_t *cmd = vcmd;
+ iscsi_dcmd_ctrl_t *idc = vidc;
+ int rc;
+
+ if (cmd == NULL) {
+ mdb_warn("list walk failed. Null cmd");
+ return (WALK_ERR);
+ }
+
+ rc = iscsi_print_ini_cmd(addr, cmd, idc);
+
+ return ((rc == DCMD_OK) ? WALK_NEXT : WALK_ERR);
+}
+
+static int
+iscsi_ini_hba_walk_init(mdb_walk_state_t *wsp) {
+ uintptr_t state_addr, array_addr;
+ int array_size;
+ struct i_ddi_soft_state *ss;
+ idm_hba_walk_info_t *hwi;
+
+
+ hwi = (idm_hba_walk_info_t *)mdb_zalloc(
+ sizeof (idm_hba_walk_info_t), UM_SLEEP|UM_GC);
+
+ if (!hwi) {
+ mdb_warn("unable to allocate storage for iscsi_ini_hba walk");
+ return (WALK_ERR);
+ }
+
+ if (wsp->walk_addr != NULL) {
+ mdb_warn("iscsi_ini_hba only supports global walk");
+ return (WALK_ERR);
+ } else {
+
+ /*
+ * Read in the array and setup the walk struct.
+ */
+ if (mdb_readvar(&state_addr, "iscsi_state") == -1) {
+ mdb_warn("state variable iscsi_state not found.\n");
+ mdb_warn("Is the driver loaded ?\n");
+ return (WALK_ERR);
+ }
+
+ ss = (struct i_ddi_soft_state *)mdb_alloc(sizeof (*ss),
+ UM_SLEEP|UM_GC);
+ if (mdb_vread(ss, sizeof (*ss), state_addr) != sizeof (*ss)) {
+ mdb_warn("Cannot read softstate struct "
+ "(Invalid pointer?).\n");
+ return (WALK_ERR);
+ }
+
+ /* Where to get the data */
+ array_size = ss->n_items * (sizeof (void *));
+ array_addr = (uintptr_t)ss->array;
+
+ /* Where to put the data */
+ hwi->n_elements = ss->n_items;
+ hwi->array = mdb_alloc(array_size, UM_SLEEP|UM_GC);
+ if (!hwi->array) {
+ mdb_warn("list walk failed");
+ return (WALK_ERR);
+ }
+ if (mdb_vread(hwi->array, array_size, array_addr) !=
+ array_size) {
+ mdb_warn("Corrupted softstate struct.\n");
+ return (WALK_ERR);
+ }
+ hwi->cur_element = 0;
+ wsp->walk_data = hwi;
+ }
+
+ return (WALK_NEXT);
+}
+
+static int
+iscsi_ini_hba_step(mdb_walk_state_t *wsp) {
+ int status;
+ idm_hba_walk_info_t *hwi = (idm_hba_walk_info_t *)wsp->walk_data;
+
+ for (; hwi->cur_element < hwi->n_elements; hwi->cur_element++) {
+ if (hwi->array[hwi->cur_element] != NULL) {
+ break;
+ }
+ }
+ if (hwi->cur_element >= hwi->n_elements) {
+ return (WALK_DONE);
+ }
+
+ hwi->data = (iscsi_hba_t *)mdb_alloc(sizeof (iscsi_hba_t),
+ UM_SLEEP|UM_GC);
+ if (mdb_vread(hwi->data, sizeof (iscsi_hba_t),
+ (uintptr_t)hwi->array[hwi->cur_element]) != sizeof (iscsi_hba_t)) {
+ mdb_warn("failed to read iscsi_sess_t at %p", wsp->walk_addr);
+ return (WALK_DONE);
+ }
+
+
+ status = wsp->walk_callback((uintptr_t)hwi->array[hwi->cur_element],
+ hwi->data, wsp->walk_cbdata);
+
+ /* Increment cur_element for next iteration */
+ hwi->cur_element++;
+
+ return (status);
+}
+
/*
* iscsi_inet_ntop -- Convert an IPv4 or IPv6 address in binary form into
* printable form, and return a pointer to that string. Caller should
@@ -2602,7 +3672,6 @@
*--ptr = '\0';
}
-
/*
* MDB module linkage information:
*
@@ -2611,32 +3680,53 @@
* to our module information.
*/
static const mdb_dcmd_t dcmds[] = {
- { "iscsi_tgt", "[-agsctbSRv]",
+ { "iscsi_tgt", "[-agscptbSRv]",
"iSCSI target information", iscsi_tgt },
- { "iscsi_tpg", "[-v]",
+ { "iscsi_tpgt", "[-R]",
+ "iSCSI target portal group tag information", iscsi_tpgt },
+ { "iscsi_tpg", "[-R]",
"iSCSI target portal group information", iscsi_tpg },
- { "iscsi_sess", "[-abtvcSRIT]",
+ { "iscsi_sess", "[-ablmtvcSRIT]",
"iSCSI session information", iscsi_sess },
- { "iscsi_conn", "[-abtvSRIT]",
+ { "iscsi_conn", "[-abmtvSRIT]",
"iSCSI connection information", iscsi_conn },
{ "iscsi_task", "[-bSRv]",
"iSCSI task information", iscsi_task },
{ "iscsi_refcnt", "",
- "Print audit informtion for idm_refcnt_t", iscsi_refcnt },
+ "print audit informtion for idm_refcnt_t", iscsi_refcnt },
{ "iscsi_states", "",
- "Dump events and state transitions recorded in an\t"
+ "dump events and state transitions recorded in an\t"
"\t\tidm_sm_audit_t structure", iscsi_states },
- { "iscsi_isns", "[-epstv]",
- "Print iscsit iSNS information", iscsi_isns, iscsi_isns_help },
+ { "iscsi_isns", "[-epstvR]",
+ "print iscsit iSNS information", iscsi_isns, iscsi_isns_help },
+ { "iscsi_svc", "[-vR]",
+ "iSCSI service information", iscsi_svc },
+ { "iscsi_portal", "[-R]",
+ "iSCSI portal information", iscsi_portal },
+ { "iscsi_cmd", "[-S]",
+ "iSCSI command information (initiator only)", iscsi_cmd },
{ NULL }
};
/*
- * No walkers for now. Initiator might need some since it doesn't use list_t
+ * Basic walkers for the initiator linked lists
*/
+static const mdb_walker_t walkers[] = {
+ { "iscsi_ini_hba", "global walk of the initiator iscsi_hba_t "
+ "list", iscsi_ini_hba_walk_init, iscsi_ini_hba_step, NULL},
+ { "iscsi_ini_sess", "walk list of initiator iscsi_sess_t structures",
+ iscsi_ini_sess_walk_init, iscsi_ini_sess_step, NULL },
+ { "iscsi_ini_conn", "walk list of initiator iscsi_conn_t structures",
+ iscsi_ini_conn_walk_init, iscsi_ini_conn_step, NULL },
+ { "iscsi_ini_lun", "walk list of initiator iscsi_lun_t structures",
+ iscsi_ini_lun_walk_init, iscsi_ini_lun_step, NULL },
+ { "iscsi_ini_cmd", "walk list of initiator iscsi_cmd_t structures",
+ iscsi_ini_cmd_walk_init, iscsi_ini_cmd_step, NULL },
+ { NULL }
+};
static const mdb_modinfo_t modinfo = {
- MDB_API_VERSION, dcmds, NULL
+ MDB_API_VERSION, dcmds, walkers
};
const mdb_modinfo_t *