/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <mdb/mdb_modapi.h>
#include <sys/sysmacros.h>
#include <sys/stmf_ioctl.h>
#define IDM_CONN_SM_STRINGS
#define IDM_TASK_SM_STRINGS
#define ISCSIT_TGT_SM_STRINGS
#define ISCSIT_SESS_SM_STRINGS
#define ISCSIT_LOGIN_SM_STRINGS
#define ISCSI_SESS_SM_STRINGS
#define ISCSI_CMD_SM_STRINGS
#define ISCSI_ICS_NAMES
#define ISCSI_LOGIN_STATE_NAMES
#define IDM_CN_NOTIFY_STRINGS
#include <iscsi.h>
#include <iscsit.h>
#include <iscsit_isns.h>
/*
* We want to be able to print multiple levels of object hierarchy with a
* single dcmd information, and preferably also exclude intermediate
* levels if desired. For example some of the target objects have the
* following relationship:
*
* target --> session --> connection --> task
*
* 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 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. 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
* child objects the dcmd calls the internal interface for the child object
* directly. Dcmds invoked from the command line will, of course, call the
* external interface. See iscsi_conn() and iscsi_conn_impl().
*/
typedef struct {
union {
struct {
} child;
} u;
/*
* Our connection dcmd code works off the global connection lists
* in IDM since we want to know about connections even when they
* have not progressed to the point that they have an associated
* session. If we use "::iscsi_sess [-c]" then we only want to
* see connections associated with particular session. To avoid
* writing a separate set of code to print session-specific connection
* the session code should set the sessions kernel address in the
* following field. The connection code will then only print
* connections that match.
*/
typedef struct idm_hba_walk_info {
void **array;
int n_elements;
int cur_element;
void *data;
void *idc_void);
void *idc_void);
void *idc_void);
void *idc_void);
void *idc_void);
void *idc_void);
void *idc_void);
void *idc_void);
void *idc_void);
void *idc);
void *idc_void);
void *idc_void);
void *idc);
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);
static const char *iscsi_iscsit_login_event(unsigned int event);
static const char *iscsi_iscsi_cmd_event(unsigned int event);
static const char *iscsi_iscsi_sess_event(unsigned int event);
static const char *iscsi_idm_conn_state(unsigned int state);
static const char *iscsi_idm_task_state(unsigned int state);
static const char *iscsi_iscsit_tgt_state(unsigned int state);
static const char *iscsi_iscsit_sess_state(unsigned int state);
static const char *iscsi_iscsit_login_state(unsigned int state);
static const char *iscsi_iscsi_cmd_state(unsigned int state);
static const char *iscsi_iscsi_sess_state(unsigned int state);
static const char *iscsi_iscsi_conn_state(unsigned int state);
static const char *iscsi_iscsi_conn_event(unsigned int event);
static const char *iscsi_iscsi_login_state(unsigned int state);
timespec_t *ts);
static void convert2ascii(char *, const in6_addr_t *);
void *data);
void *data);
/*
* ::iscsi_tgt [-scatgpbSRv]
*
* iscsi_tgt - Print out information associated with an iscsit target instance
*
* s Print associated session information
* c Print associated connection information
* a Print IP addresses with connection information
* t Print associated task information
* g Print associated TPG information
* p Print portals with TPG information
* b Print associated buffer information
* S Print recent state events and transitions
* R Print reference count audit data
* v Verbose output about the connection
*/
/*ARGSUSED*/
static int
{
return (DCMD_USAGE);
if (DCMD_HDRSPEC(flags))
/*
* If no address was specified on the command line, we
* print out all tgtions
*/
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("failed to find symbol 'iscsit_global'");
return (DCMD_ERR);
}
mdb_warn("avl walk failed for global target tree");
return (DCMD_ERR);
}
mdb_warn("list walk failed for deleted target list");
return (DCMD_ERR);
}
return (DCMD_OK);
}
}
static int
{
int rc_audit = 0;
return (DCMD_USAGE);
/* Always print tpgs and portals */
if (DCMD_HDRSPEC(flags))
/*
* If no address was specified on the command line, we
* print out all tgtions
*/
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("failed to find symbol 'iscsit_global'");
return (DCMD_ERR);
}
mdb_warn("avl walk failed for global target tree");
return (DCMD_ERR);
}
return (DCMD_OK);
}
}
/*
* ::iscsi_tpgt [-pR]
*
* Print tpgt information.
* R Print reference count audit data
* p Print portal data
*/
static int
{
return (DCMD_USAGE);
if (DCMD_HDRSPEC(flags))
/*
* If no address was specified on the command line,
* print out all tpgts
*/
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("failed to find symbol 'iscsit_global'");
return (DCMD_ERR);
}
mdb_warn("avl walk failed for global target tree");
return (DCMD_ERR);
}
mdb_warn("list walk failed for deleted target list");
return (DCMD_ERR);
}
return (DCMD_OK);
}
}
/*
* ::iscsi_sess [-ablmtvcSRIT]
*
* iscsi_sess - Print out information associated with an iSCSI session
*
* I Print only initiator sessions
* T Print only target sessions
* 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
* v Verbose output about the connection
*/
/*ARGSUSED*/
static int
{
int luns = 0;
return (DCMD_USAGE);
if (DCMD_HDRSPEC(flags))
/*
* If no address was specified on the command line, we
* print out all sessions
*/
if (!(flags & DCMD_ADDRSPEC)) {
return (iscsi_walk_all_sess(&idc));
}
}
/*
* ::iscsi_conn [-abmtvSRIT]
*
* iscsi_conn - Print out information associated with an iSCSI connection
*
* I Print only initiator connections
* T Print only target connections
* 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
*/
/*ARGSUSED*/
static int
{
return (DCMD_USAGE);
if (DCMD_HDRSPEC(flags))
/*
* If no address was specified on the command line, we
* print out all connections
*/
if (!(flags & DCMD_ADDRSPEC)) {
return (iscsi_walk_all_conn(&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
{
int rc_audit = 0;
return (DCMD_USAGE);
if (DCMD_HDRSPEC(flags)) {
}
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("failed to find symbol 'idm'");
return (DCMD_ERR);
}
svc_list_addr) == -1) {
mdb_warn("list walk failed for idm services");
return (DCMD_ERR);
}
return (DCMD_OK);
}
}
/*
* ::iscsi_portal -R
*
* iscsi_portal - Print out information associated with an iSCSI portal
*
* R Print reference count audit data
*/
static int
{
int rc_audit = 0;
return (DCMD_USAGE);
if (DCMD_HDRSPEC(flags)) {
}
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("failed to find symbol 'iscsit_global'");
return (DCMD_ERR);
}
/* get and print the global default tpg */
iscsit_global_addr) != sizeof (iscsit_global_t)) {
mdb_warn("failed to read iscsit_global_t");
return (DCMD_ERR);
}
return (DCMD_ERR);
}
/* Walk the tpgs for the rest of the portals */
tpg_avl_addr) == -1) {
mdb_warn("list walk failed for global tpg tree");
return (DCMD_ERR);
}
return (DCMD_OK);
}
}
/*
* ::iscsi_cmd -S
*
* iscsi_cmd - Print out information associated with an iSCSI cmd
*
* S Print state audit data
*/
static int
{
int states = 0;
return (DCMD_USAGE);
if (DCMD_HDRSPEC(flags)) {
}
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("iscsi cmd hba list walk failed");
return (DCMD_ERR);
}
} else {
sizeof (iscsi_cmd_t)) {
return (DCMD_ERR);
}
}
return (DCMD_OK);
}
static int
mdb_warn("Invalid HBA\n");
return (DCMD_ERR);
}
}
mdb_warn("iscsi_sess_t walk failed");
return (DCMD_ERR);
}
return (DCMD_OK);
}
/*
* ::iscsi_task [-bv]
*
* iscsi_task - Print out information associated with an iSCSI task
*
* b Print associated buffer information
* S Print recent state events and transitions
* R Print reference count audit data
* v Verbose output about the connection
*/
/*ARGSUSED*/
static int
{
int buffer = 0;
return (DCMD_USAGE);
if (DCMD_HDRSPEC(flags))
/*
* If no address was specified on the command line, we
* print out all connections
*/
if (!(flags & DCMD_ADDRSPEC)) {
return (iscsi_walk_all_conn(&idc));
}
}
/*
* ::iscsi_refcnt
*
* iscsi_refcnt - Dump an idm_refcnt_t structure
*
*/
/*ARGSUSED*/
static int
{
if (!(flags & DCMD_ADDRSPEC)) {
return (DCMD_ERR);
}
return (iscsi_refcnt_impl(addr));
}
/*
* ::iscsi_states
*
* iscsi_states - Dump events and state transitions recoreded in an
* idm_sm_audit_t structure
*
*/
/*ARGSUSED*/
static int
{
if (!(flags & DCMD_ADDRSPEC)) {
return (DCMD_ERR);
}
return (iscsi_sm_audit_impl(addr));
}
static int
{
/* Initiator sessions */
/* Always print hba info on this path */
mdb_warn("iscsi cmd hba list walk failed");
return (DCMD_ERR);
}
return (DCMD_OK);
}
/* Target sessions */
/* Walk discovery sessions */
mdb_warn("failed to find symbol 'iscsit_global'");
return (DCMD_ERR);
}
mdb_warn("avl walk failed for discovery sessions");
return (DCMD_ERR);
}
/* Walk targets printing all session info */
return (DCMD_ERR);
}
/* Walk deleting targets printing all session info */
mdb_warn("list walk failed for deleted target list");
return (DCMD_ERR);
}
return (DCMD_OK);
}
static int
{
/* Walk initiator connections */
mdb_warn("failed to find symbol 'idm'");
return (DCMD_ERR);
}
/* Walk connection list associated with the initiator */
mdb_warn("list walk failed for initiator connections");
return (DCMD_ERR);
}
/* Walk connection list associated with the target */
mdb_warn("list walk failed for target service instances");
return (DCMD_ERR);
}
return (DCMD_OK);
}
/*ARGSUSED*/
static int
void *idc_void)
{
/* We don't particularly care about the list walker data */
int rc;
}
/*ARGSUSED*/
static int
void *idc_void)
{
/* We don't particularly care about the list walker data */
int rc;
}
/*ARGSUSED*/
static int
void *idc_void)
{
/* We don't particularly care about the list walker data */
int rc;
}
/*ARGSUSED*/
static int
void *idc_void)
{
/* We don't particularly care about the list walker data */
int rc;
}
/*ARGSUSED*/
static int
void *idc_void)
{
/* We don't particularly care about the list walker data */
int rc;
}
/*ARGSUSED*/
static int
void *idc_void)
{
/* We don't particularly care about the list walker data */
int rc;
/*
* This function is different from iscsi_conn_walk_cb because
* we get an iscsit_conn_t instead of an idm_conn_t
*
* Read iscsit_conn_t, use to get idm_conn_t pointer
*/
sizeof (iscsit_conn_t)) {
return (DCMD_ERR);
}
}
/*ARGSUSED*/
static int
void *idc_void)
{
/* We don't particularly care about the list walker data */
int rc;
}
/*ARGSUSED*/
static int
void *idc_void)
{
/* We don't particularly care about the list walker data */
int rc;
}
/*ARGSUSED*/
static int
void *idc_void)
{
int rc;
}
/*ARGSUSED*/
static int
void *idc_void) {
int rc;
}
static int
{
int rc;
return (WALK_ERR);
}
}
/*ARGSUSED*/
static int
{
int rc;
return (WALK_ERR);
}
/*
* Look up the idm_conn_t in the iscsi_conn_t and call the general
* connection handler.
*/
}
static int
{
int rc;
return (WALK_ERR);
}
}
static int
{
/*
* Read iscsit_tgt_t
*/
sizeof (iscsit_tgt_t)) {
return (DCMD_ERR);
}
/*
* Read target name if available
*/
}
/*
* Brief output
*
* iscsit_tgt_t pointer
* iscsit_tgt_t.target_stmf_state
* iscsit_tgt_t.target_sess_list.avl_numnodes (session count)
* iscsit_tgt_t.target_name;
*/
/* For now we will ignore the verbose flag */
/* Print target data */
if (idc->idc_header) {
mdb_printf("%<u>%-19s %-4s %-8s%</u>\n",
"iscsit_tgt_t", "Sess", "State");
}
/* Indent and disable verbose for any child structures */
mdb_inc_indent(4);
idc->idc_verbose = 0;
}
/*
* Print states if requested
*/
mdb_printf("State History(target_state_audit):\n");
return (DCMD_ERR);
}
/*
* Print refcnt audit data if requested
*/
mdb_printf("Reference History(target_sess_refcnt):\n");
return (DCMD_ERR);
mdb_printf("Reference History(target_refcnt):\n");
return (DCMD_ERR);
}
/* Any child objects to walk? */
}
/* Walk TPGT tree */
avl_addr) == -1) {
mdb_warn("target tpgt list walk failed");
(void) mdb_dec_indent(4);
return (DCMD_ERR);
}
}
}
/* Walk sess tree */
avl_addr) == -1) {
mdb_warn("target sess list walk failed");
(void) mdb_dec_indent(4);
return (DCMD_ERR);
}
}
/* If tgts were handled decrease indent and reset header */
idc->idc_header = 0;
mdb_dec_indent(4);
}
return (DCMD_OK);
}
static int
{
int rc_audit;
/*
* Read iscsit_tpgt_t
*/
sizeof (iscsit_tpgt_t)) {
return (DCMD_ERR);
}
/*
* Read iscsit_tpg_t
*/
sizeof (iscsit_tpg_t)) {
return (DCMD_ERR);
}
/*
* Brief output
*
* iscsit_tpgt_t pointer
* iscsit_tpg_t pointer
* iscsit_tpg_t.tpg_name
* iscsit_tpgt_t.tpgt_tag;
*/
/* For now we will ignore the verbose flag */
/* Print target data */
if (idc->idc_header) {
mdb_printf("%<u>%-?s %-?s %-18s %-6s%</u>\n",
"iscsit_tpgt_t", "iscsit_tpg_t", "Name", "Tag");
}
if (rc_audit) {
(void) mdb_inc_indent(4);
mdb_printf("Reference History(tpgt_refcnt):\n");
return (DCMD_ERR);
(void) mdb_dec_indent(4);
}
}
/*
* Assume for now that anyone interested in TPGT wants to see the
* portals as well. Enable idc_header for the portals.
*/
(void) mdb_inc_indent(4);
mdb_warn("portal list walk failed");
(void) mdb_dec_indent(4);
return (DCMD_ERR);
}
(void) mdb_dec_indent(4);
idc->idc_header = 0;
return (DCMD_OK);
}
static int
{
int rc_audit = 0;
/*
* Read iscsit_tpg_t
*/
sizeof (iscsit_tpg_t)) {
return (DCMD_ERR);
}
/*
* Brief output
*
* iscsit_tpgt_t pointer
* iscsit_tpg_t pointer
* iscsit_tpg_t.tpg_name
* iscsit_tpgt_t.tpgt_tag;
*/
/* Print tpg data */
if (idc->idc_header) {
mdb_printf("%<u>%-?s %-18s%</u>\n",
"iscsit_tpg_t", "Name");
}
(void) mdb_inc_indent(4);
if (rc_audit) {
mdb_printf("Reference History(tpg_refcnt):\n");
return (DCMD_ERR);
}
}
}
}
avl_addr) == -1) {
mdb_warn("portal list walk failed");
(void) mdb_dec_indent(4);
}
return (DCMD_ERR);
}
}
(void) mdb_dec_indent(4);
idc->idc_header = 0;
}
return (DCMD_OK);
}
static int
{
/*
* Read iscsit_portal_t
*/
sizeof (iscsit_portal_t)) {
return (DCMD_ERR);
}
/* Print portal data */
if (idc->idc_header) {
mdb_printf("%<u>%-?s %-?s %-30s%</u>\n",
"iscsit_portal_t", "idm_svc_t", "IP:Port");
idc->idc_header = 0;
}
(void) mdb_inc_indent(4);
mdb_printf("Reference History(portal_refcnt):\n");
return (DCMD_ERR);
}
(void) mdb_dec_indent(4);
}
}
return (DCMD_OK);
}
static int
{
mdb_warn("Failed to read initiator session\n");
return (DCMD_ERR);
}
return (DCMD_ERR);
}
return (DCMD_OK);
}
/*
* Read iscsit_sess_t
*/
sizeof (iscsit_sess_t)) {
return (DCMD_ERR);
}
/*
* Brief output
*
* iscsit_sess_t pointer
* iscsit_sess_t.ist_tsih
* iscsit_sess_t.ist_initiator_name
*/
if (verbose) {
/*
* Read initiator name if available
*/
}
/*
* Read target name if available
*/
}
ini_name);
tgt_name);
idc->idc_verbose = 0;
} else {
/* Print session data */
if (idc->idc_header) {
mdb_printf("%<u>%-?s %10s %-12s %-6s%</u>\n",
"TSIH");
}
mdb_printf("%?p %4d/%-4d %02x%02x%02x%02x%02x%02x "
"0x%04x\n", addr,
}
/*
* Indent for any child structures
*/
(void) mdb_inc_indent(4);
}
/*
* Print states if requested
*/
mdb_printf("State History(ist_state_audit):\n");
return (DCMD_ERR);
/* Don't print state history for child objects */
}
/*
* Print refcnt audit data if requested
*/
mdb_printf("Reference History(ist_refcnt):\n");
return (DCMD_ERR);
/* Don't print audit data for child objects */
}
/* Any child objects to walk? */
/*
* If a session has been printed enable headers for
* any child structs.
*/
}
/* Walk conn list */
list_addr) == -1) {
mdb_warn("session conn list walk failed");
(void) mdb_dec_indent(4);
return (DCMD_ERR);
}
}
/* If a session was handled decrease indent and reset header. */
idc->idc_header = 0;
mdb_dec_indent(4);
}
return (DCMD_OK);
}
static int
{
if (!idc->idc_verbose) {
if (idc->idc_header) {
mdb_printf("%<u>%-?s %-4s %-8s%</u>\n",
"iscsi_sess_t", "Type", "State");
}
} else {
sess->sess_state);
sess->sess_alias);
sess->sess_cmdsn);
idc->idc_verbose = 0;
}
/* Indent for any child structures */
mdb_inc_indent(4);
mdb_printf("State History(sess_state_audit):\n");
(void) mdb_dec_indent(4);
return (DCMD_ERR);
}
}
}
}
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 any other structs printed enable header */
}
== -1) {
mdb_warn("list walk failed for iscsi cmds");
}
}
== -1) {
mdb_warn("list walk failed for iscsi cmds");
}
}
}
/* If connections or cmds requested walk the connections */
/*
* If idc_conn is not set don't enable header or the
* commands may get extraneous headers.
*/
}
mdb_warn("iscsi_ini_conn walk failed");
return (DCMD_ERR);
}
}
/* If sessions were handled decrease indent and reset header */
idc->idc_header = 0;
mdb_dec_indent(4);
}
return (DCMD_OK);
}
static int
{
char *conn_type;
int task_idx;
/*
* Get pointer to task table
*/
mdb_warn("failed to find symbol 'idm'");
return (DCMD_ERR);
}
sizeof (uintptr_t)) {
mdb_warn("Failed to read address of task table");
return (DCMD_ERR);
}
/*
* Read idm_conn_t
*/
return (DCMD_ERR);
}
/*
* If filter bits are set to only print targets or only initiators
* skip entries of the other type.
*/
return (DCMD_OK);
}
/*
* Brief output
*
* idm_conn_t pointer
* idm_conn_t.ic_conn_type
* idm_conn_t.ic_statet+idm_conn_t.ic_ffp
*/
/*
* check and for use below.
*/
sizeof (iscsit_conn_t)) {
mdb_printf("Failed to read target connection "
"handle data\n");
return (DCMD_ERR);
}
}
sizeof (iscsi_conn_t)) {
mdb_printf("Failed to read initiator "
"connection handle data\n");
return (DCMD_ERR);
}
}
if (idc->idc_verbose) {
} else {
}
idc->idc_verbose = 0;
} else {
/* Print connection data */
if (idc->idc_header) {
mdb_printf("%<u>%-?s %-6s %-10s %12s%</u>\n",
"idm_conn_t", "Type", "Transport",
}
(ic.ic_transport_type ==
IDM_TRANSPORT_TYPE_ISER) ? "ISER_IB" :
(ic.ic_transport_type ==
IDM_TRANSPORT_TYPE_SOCKETS) ? "SOCKETS" :
"N/A",
mdb_printf(" L%s R%s\n",
}
}
/* Indent for any child structs */
mdb_inc_indent(4);
}
/*
* Print states if requested
*/
mdb_printf("State History(ic_state_audit):\n");
return (DCMD_ERR);
/*
* If targets are specifically requested show the
* state audit for the target specific connection struct
*/
mdb_printf("State History(icl_state_audit):\n");
return (DCMD_ERR);
}
}
/*
* If initiators are specifically requested show the
* state audit for the initiator specific connection struct
*/
mdb_printf("State History(iscsi_conn_t "
"conn_state_audit):\n");
return (DCMD_ERR);
}
}
/* Don't print state history for child objects */
}
/*
* Print refcnt audit data for the connection struct if requested.
*/
mdb_printf("Reference History(ic_refcnt):\n");
return (DCMD_ERR);
/*
* If targets are specifically requested show the
* Refcounts for the target specific connection struct
*/
mdb_printf("Reference History(ict_refcnt):\n");
return (DCMD_ERR);
}
mdb_printf("Reference History(ict_dispatch_refcnt):\n");
return (DCMD_ERR);
}
}
/* Don't print audit data for child objects */
}
task_idx = 0;
}
while (task_idx < IDM_TASKIDS_MAX) {
/*
* Read the next idm_task_t
*/
mdb_warn("Failed to read task pointer");
return (DCMD_ERR);
}
task_idx++;
continue;
}
!= sizeof (idm_task_t)) {
mdb_warn("Failed to read task pointer");
return (DCMD_ERR);
}
== -1) {
mdb_warn("Failed to walk connection "
"task tree");
return (DCMD_ERR);
}
}
task_idx++;
}
}
}
mdb_warn("list walk failed for iscsi cmds");
}
mdb_warn("list walk failed for iscsi cmds");
}
}
/*
* If connection information was handled unset header and
* decrease indent
*/
idc->idc_header = 0;
mdb_dec_indent(4);
}
return (DCMD_OK);
}
static int
{
sizeof (idm_svc_t)) {
return (DCMD_ERR);
}
if (idc->idc_verbose) {
} else {
if (idc->idc_header) {
mdb_printf("%<u>%-?s %-8s %-8s%</u>\n",
"idm_svc_t", "Port", "Online");
idc->idc_header = 0;
}
}
(void) mdb_inc_indent(4);
mdb_printf("Reference History(is_refcnt):\n");
(void) mdb_dec_indent(4);
return (DCMD_ERR);
}
mdb_printf("Reference History"
"(iser_svc is_refcnt):\n");
/* Sanity check the iser svc struct */
sizeof (iser_svc_t)) {
return (DCMD_ERR);
}
return (DCMD_ERR);
}
}
(void) mdb_dec_indent(4);
}
}
return (DCMD_OK);
}
static void
{
char *csg;
char *nsg;
mdb_printf("**Failed to read conn private data\n");
return;
}
csg = "Security";
break;
csg = "Operational";
break;
case ISCSI_FULL_FEATURE_PHASE:
csg = "FFP";
break;
default:
csg = "Unknown";
}
nsg = "Security";
break;
nsg = "Operational";
break;
case ISCSI_FULL_FEATURE_PHASE:
nsg = "FFP";
break;
default:
nsg = "Unknown";
}
}
}
}
static void
{
mdb_printf("Failed to read conn private data\n");
return;
}
}
static void
{
"Unknown")));
ic->ic_svc_binding);
}
"N/A");
ic->ic_last_state);
"UNKNOWN")));
}
static int
{
if (verbose) {
(void) mdb_inc_indent(2);
if (conn_type == CONN_TYPE_TGT) {
}
(void) mdb_dec_indent(2);
} else {
/* Print task data */
if (idc->idc_header) {
"%<u>%-?s %-16s %-4s %-8s %-8s%</u>\n",
"Tasks:", "State", "Ref",
"TT")), "Handle");
}
}
}
idc->idc_header = 0;
idc->idc_verbose = 0;
/*
* Print states if requested
*/
#if 0
if (states) {
(void) mdb_inc_indent(4);
mdb_printf("State History(idt_state_audit):\n");
return (DCMD_ERR);
/* Don't print state history for child objects */
(void) mdb_dec_indent(4);
}
#endif
/*
* Print refcnt audit data if requested
*/
if (rc_audit) {
(void) mdb_inc_indent(4);
mdb_printf("Reference History(idt_refcnt):\n");
return (DCMD_ERR);
/* Don't print audit data for child objects */
(void) mdb_dec_indent(4);
}
/*
* Buffers are leaf objects and always get headers so the
* user can discern between in and out buffers.
*/
/* Walk in buffer list */
(void) mdb_inc_indent(2);
mdb_printf("In buffers:\n");
(void) mdb_inc_indent(2);
-1) {
mdb_warn("list walk failed for task in buffers");
(void) mdb_dec_indent(4);
return (DCMD_ERR);
}
(void) mdb_dec_indent(2);
/* Walk out buffer list */
mdb_printf("Out buffers:\n");
(void) mdb_inc_indent(2);
-1) {
mdb_warn("list walk failed for task out buffers\n");
(void) mdb_dec_indent(2);
return (DCMD_ERR);
}
(void) mdb_dec_indent(4);
}
return (DCMD_OK);
}
static int
{
/*
* Read idm_conn_t
*/
return (DCMD_ERR);
}
}
static void
{
mdb_printf("**Failed to read idt_private data\n");
return;
}
}
mdb_printf("%20s: %p/%p/%p%s\n",
if (good_scsi_task) {
mdb_printf("%20s: %02x %02x %02x %02x %02x %02x %02x %02x\n",
"LU number",
mdb_printf(" CDB (%d bytes):\n",
(void) mdb_inc_indent(ISCSI_CDB_INDENT);
MDB_DUMP_GROUP(1),
mdb_printf("** Invalid CDB addr (%p)\n",
}
(void) mdb_dec_indent(ISCSI_CDB_INDENT);
}
}
static int
{
if (idc->idc_header) {
mdb_printf("%<u>%-?s %-5s %-10s%</u>\n",
"iscsi_lun_t", "State", "Lun Number");
idc->idc_header = 0;
}
}
return (DCMD_OK);
}
static int
iscsi_dcmd_ctrl_t *idc) {
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",
/*
* Print states if requested
*/
(void) mdb_inc_indent(4);
mdb_printf("State History(cmd_state_audit):\n");
return (DCMD_ERR);
(void) mdb_dec_indent(4);
}
return (DCMD_OK);
}
static int
{
/*
* Read idm_buf_t
*/
return (DCMD_ERR);
}
if (idc->idc_header) {
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;
}
/* Print buffer data */
/* Buffers are leaf objects */
return (DCMD_OK);
}
static int
{
int ctr;
/*
* Print refcnt info
*/
sizeof (idm_refcnt_t)) {
mdb_warn("read refcnt failed");
return (DCMD_ERR);
}
while (ctr) {
char c[MDB_SYM_NAMLEN];
int i;
MDB_SYM_FUZZY, c, sizeof (c),
&sym) == -1) {
continue;
}
mdb_printf("%s+0x%1x", c,
++i;
break;
}
MDB_SYM_FUZZY, c, sizeof (c),
&sym) == -1) {
++i;
continue;
}
mdb_printf("\n\t\t%s+0x%1x", c,
++i;
}
mdb_printf("\n");
}
ctr--;
}
return (DCMD_OK);
}
static int
{
int ctr;
const char *event_name;
const char *state_name;
const char *new_state_name;
/*
* Print refcnt info
*/
sizeof (sm_audit_buf_t)) {
mdb_warn("failed to read audit buf");
return (DCMD_ERR);
}
while (ctr) {
case SAR_STATE_EVENT:
switch (sar->sar_sm_type) {
case SAS_IDM_CONN:
break;
case SAS_ISCSIT_TGT:
break;
case SAS_ISCSIT_SESS:
break;
case SAS_ISCSIT_LOGIN:
break;
case SAS_ISCSI_CMD:
break;
case SAS_ISCSI_SESS:
break;
case SAS_ISCSI_CONN:
break;
default:
break;
}
mdb_printf("%s|%s (%d)\n\t%9s %s (%d) %p\n",
"Event", event_name,
break;
case SAR_STATE_CHANGE:
switch (sar->sar_sm_type) {
case SAS_IDM_CONN:
break;
case SAS_IDM_TASK:
break;
case SAS_ISCSIT_TGT:
break;
case SAS_ISCSIT_SESS:
break;
case SAS_ISCSIT_LOGIN:
sar->sar_new_state);
break;
case SAS_ISCSI_CMD:
break;
case SAS_ISCSI_SESS:
break;
case SAS_ISCSI_CONN:
break;
case SAS_ISCSI_LOGIN:
break;
default:
break;
}
mdb_printf("%s|%s (%d)\n\t%9s %s (%d)\n",
default:
break;
}
ctr--;
}
return (DCMD_OK);
}
static const char *
{
}
static const char *
{
}
static const char *
{
}
static const char *
{
}
static const char *
{
return ((event < ISCSI_CMD_EVENT_MAX) ?
}
static const char *
{
return ((event < ISCSI_SESS_EVENT_MAX) ?
}
static const char *
{
}
static const char *
{
}
/*ARGSUSED*/
static const char *
{
return ("N/A");
}
static const char *
{
}
static const char *
{
}
static const char *
{
}
static const char *
{
return ((state < ISCSI_CMD_STATE_MAX) ?
}
static const char *
{
return ((state < ISCSI_SESS_STATE_MAX) ?
}
static const char *
{
}
static const char *
{
}
/*
* Retrieve connection type given a kernel address
*/
static idm_conn_type_t
{
return (result);
}
/*
* Convert a sockaddr to the string representation, suitable for
* storing in an nvlist or printing out in a list.
*/
static int
{
const char *bufp;
return (EINVAL);
}
buf[0] = '\0';
return (-1);
}
return (-1);
}
} else {
return (EINVAL);
}
return (0);
}
static void
{
}
/*
* Help information for the iscsi_isns dcmd
*/
static void
iscsi_isns_help(void)
{
mdb_printf("iscsi_isns:\n");
mdb_inc_indent(4);
mdb_printf("-e: Print ESI information\n");
mdb_printf("-p: Print portal information\n");
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);
}
/* ARGSUSED */
static int
{
sizeof (isns_esi_tinfo_t)) {
return (WALK_ERR);
}
mdb_printf("ESI thread running : %s\n",
return (WALK_NEXT);
}
static int
{
mdb_warn("failed to find symbol 'esi_list'");
return (DCMD_ERR);
}
return (0);
}
/* ARGSUSED */
static int
{
sizeof (isns_portal_t)) {
return (WALK_ERR);
}
mdb_printf("Portal IP address ");
} else {
}
mdb_printf(" (Default portal)\n");
} else {
mdb_printf("\n");
}
}
mdb_inc_indent(4);
mdb_dec_indent(4);
}
return (WALK_NEXT);
}
static int
{
mdb_printf("All Active Portals:\n");
mdb_warn("failed to find symbol 'isns_all_portals'");
return (DCMD_ERR);
}
mdb_warn("avl walk failed for isns_all_portals");
return (DCMD_ERR);
}
mdb_printf("\nPortals from TPGs:\n");
mdb_warn("failed to find symbol 'isns_tpg_portals'");
return (DCMD_ERR);
}
mdb_warn("avl walk failed for isns_tpg_portals");
return (DCMD_ERR);
}
return (0);
}
/* ARGSUSED */
static int
{
int rc = 0;
int rc_audit = 0;
sizeof (isns_target_t)) {
return (WALK_ERR);
}
mdb_inc_indent(4);
mdb_printf("Registered: %s\n",
mdb_printf("Update needed: %s\n",
/* Prevent target refcounts from showing through this path */
mdb_printf("Reference History(isns_target_info ti_refcnt):\n");
if (iscsi_refcnt_impl(rc_addr) != 0) {
return (WALK_ERR);
}
}
mdb_dec_indent(4);
return (WALK_NEXT);
}
return (WALK_ERR);
}
static int
{
mdb_warn("failed to find symbol 'isns_target_list'");
return (DCMD_ERR);
}
isns_target_list) == -1) {
mdb_warn("avl walk failed for isns_target_list");
return (DCMD_ERR);
}
return (0);
}
/* ARGSUSED */
static int
{
sizeof (iscsit_isns_svr_t)) {
return (WALK_ERR);
}
return (WALK_ERR);
mdb_inc_indent(4);
mdb_printf("IP address ");
} else {
}
mdb_printf("ESI Interval: %d seconds\n",
mdb_printf("Last message: %d seconds ago\n",
mdb_printf("Client registered: %s\n",
mdb_printf("Retry Count: %d\n",
mdb_printf("Targets Changes Pending: %s\n",
mdb_printf("Delete Pending: %s\n",
mdb_printf("Replace-All Needed: %s\n",
if (idc->idc_verbose) {
mdb_inc_indent(2);
avl_addr) == -1) {
mdb_warn("avl walk failed for svr_target_list");
return (WALK_ERR);
}
mdb_dec_indent(2);
}
mdb_dec_indent(4);
return (WALK_NEXT);
}
static int
{
mdb_warn("failed to find symbol 'iscsit_global'");
return (DCMD_ERR);
}
mdb_warn("list walk failed for iSNS servers");
return (DCMD_ERR);
}
return (0);
}
/* ARGSUSED */
static int
{
int rc_audit = 0;
if (flags & DCMD_ADDRSPEC) {
mdb_warn("iscsi_isns is only a global dcmd.");
return (DCMD_ERR);
}
return (DCMD_USAGE);
mdb_printf("Only one of e, p, s, and t must be provided");
return (DCMD_ERR);
}
mdb_printf("Exactly one of e, p, s, or t must be provided");
return (DCMD_ERR);
}
if (esi) {
return (iscsi_isns_esi(&idc));
}
if (portals) {
return (iscsi_isns_portals(&idc));
}
if (servers) {
return (iscsi_isns_servers(&idc));
}
return (iscsi_isns_targets(&idc));
}
static int
mdb_warn("<iscsi_sess_t addr>::walk iscsi_ini_sess");
return (WALK_ERR);
}
mdb_warn("iscsi_ini_sess walk failed");
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
int status;
return (WALK_DONE);
}
!= sizeof (iscsi_sess_t)) {
return (WALK_DONE);
}
wsp->walk_cbdata);
return (status);
}
static int
mdb_warn("<iscsi_conn_t addr>::walk iscsi_ini_conn");
return (WALK_DONE);
}
mdb_warn("iscsi_ini_conn walk failed");
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
int status;
return (WALK_DONE);
}
!= sizeof (iscsi_conn_t)) {
return (WALK_DONE);
}
wsp->walk_cbdata);
return (status);
}
static int
mdb_warn("<iscsi_lun_t addr>::walk iscsi_ini_lun");
return (WALK_DONE);
}
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
int status;
return (WALK_DONE);
}
!= sizeof (iscsi_lun_t)) {
return (WALK_DONE);
}
wsp->walk_cbdata);
return (status);
}
static int
mdb_warn("<iscsi_cmd_t addr>::walk iscsi_ini_cmd");
return (WALK_DONE);
}
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
int status;
return (WALK_DONE);
}
!= sizeof (iscsi_cmd_t)) {
return (WALK_DONE);
}
wsp->walk_cbdata);
return (status);
}
static int
void *vidc) {
int rc;
mdb_warn("list walk failed. Null cmd");
return (WALK_ERR);
}
}
static int
int array_size;
if (!hwi) {
mdb_warn("unable to allocate storage for iscsi_ini_hba walk");
return (WALK_ERR);
}
mdb_warn("iscsi_ini_hba only supports global walk");
return (WALK_ERR);
} else {
/*
* Read in the array and setup the walk struct.
*/
mdb_warn("state variable iscsi_state not found.\n");
mdb_warn("Is the driver loaded ?\n");
return (WALK_ERR);
}
mdb_warn("Cannot read softstate struct "
"(Invalid pointer?).\n");
return (WALK_ERR);
}
/* Where to get the data */
/* Where to put the data */
mdb_warn("list walk failed");
return (WALK_ERR);
}
array_size) {
mdb_warn("Corrupted softstate struct.\n");
return (WALK_ERR);
}
hwi->cur_element = 0;
}
return (WALK_NEXT);
}
static int
int status;
break;
}
}
return (WALK_DONE);
}
return (WALK_DONE);
}
/* 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
* provide a buffer of correct length to store string into.
* Note: this routine is kernel version of inet_ntop. It has similar
* format as iscsi_inet_ntop() defined in rfc2553. But it does not do
* error handling operations exactly as rfc2553 defines. This function
* is used by kernel inet directory routines only for debugging.
* This iscsi_inet_ntop() function, does not return NULL if third argument
* is NULL. The reason is simple that we don't want kernel to panic
* as the output of this function is directly fed to ip<n>dbg macro.
* Instead it uses a local buffer for destination address for
* those calls which purposely pass NULL ptr for the destination
* buffer. This function is thread-safe when the caller passes a non-
* null buffer with the third argument.
*/
/* ARGSUSED */
#if defined(__x86)
#else
#endif
char *
{
char *caddr;
/*
* We don't allow thread unsafe iscsi_inet_ntop calls, they
* must pass a non-null buffer pointer. For DEBUG mode
* we use the ASSERT() and for non-debug kernel it will
* silently allow it for now. Someday we should remove
* the static buffer from this function.
*/
buf[0] = '\0';
/* Let user know politely not to send NULL or unaligned addr */
return (err_buf1);
}
switch (af) {
case AF_INET:
"%03d.%03d.%03d.%03d",
return (buf);
case AF_INET6:
if (IN6_IS_ADDR_V4MAPPED(v6addr)) {
"::ffff:%d.%d.%d.%d",
} else if (IN6_IS_ADDR_V4COMPAT(v6addr)) {
"::%d.%d.%d.%d",
} else if (IN6_IS_ADDR_UNSPECIFIED(v6addr)) {
} else {
}
return (buf);
default:
return (err_buf2);
}
}
/*
*
* v6 formats supported
* General format xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
* The short hand notation :: is used for COMPAT addr
* Other forms : fe80::xxxx:xxxx:xxxx:xxxx
*/
static void
{
int hexdigits;
int head_zero = 0;
int tail_zero = 0;
/* tempbuf must be big enough to hold ffff:\0 */
char *ptr;
/* First count if trailing zeroes higher in number */
if (*addr_component == 0) {
if (hexdigits < 4)
head_zero++;
else
tail_zero++;
}
}
/* if entry is a 0 */
if (*addr_component == 0) {
*ptr++ = '0';
*ptr++ = ':';
} else {
/*
* address starts with 0s ..
* stick in leading ':' of pair
*/
if (hexdigits == 0)
*ptr++ = ':';
/* add another */
*ptr++ = ':';
}
if (hexdigits == 7)
*ptr++ = ':';
continue;
} else {
*ptr++ = '0';
*ptr++ = ':';
}
continue;
}
if (med_zero)
tempbuf[0] = '\0';
sizeof (uint16_t));
}
*--ptr = '\0';
}
/*
* MDB module linkage information:
*
* We declare a list of structures describing our dcmds, a list of structures
* describing our walkers and a function named _mdb_init to return a pointer
* to our module information.
*/
{ "iscsi_tgt", "[-agscptbSRv]",
"iSCSI target information", iscsi_tgt },
{ "iscsi_tpgt", "[-R]",
"iSCSI target portal group tag information", iscsi_tpgt },
{ "iscsi_tpg", "[-R]",
"iSCSI target portal group information", iscsi_tpg },
{ "iscsi_sess", "[-ablmtvcSRIT]",
"iSCSI session information", iscsi_sess },
{ "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 },
{ "iscsi_states", "",
"dump events and state transitions recorded in an\t"
"\t\tidm_sm_audit_t structure", iscsi_states },
{ "iscsi_isns", "[-epstvR]",
{ "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 }
};
/*
* Basic walkers for the initiator linked lists
*/
{ "iscsi_ini_hba", "global walk of the initiator iscsi_hba_t "
{ "iscsi_ini_sess", "walk list of initiator iscsi_sess_t structures",
{ "iscsi_ini_conn", "walk list of initiator iscsi_conn_t structures",
{ "iscsi_ini_lun", "walk list of initiator iscsi_lun_t structures",
{ "iscsi_ini_cmd", "walk list of initiator iscsi_cmd_t structures",
{ NULL }
};
};
const mdb_modinfo_t *
_mdb_init(void)
{
return (&modinfo);
}