wrsm.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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
*/
/*
* Copyright (c) 2001 by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/mdb_modapi.h>
#include <sys/wrsm_common.h>
#include <sys/wrsm_config.h>
#include <sys/wrsm_sess_impl.h>
#include <sys/wrsm_nc_impl.h>
#include <sys/wrsm_memseg.h>
#include <sys/wrsm_memseg_impl.h>
#define AVAIL_STATE_STR(x) \
((x == wrsm_disabled) ? "disabled" : \
(x == wrsm_pending) ? "pending" : \
(x == wrsm_installed) ? "installed" : \
(x == wrsm_installed_up) ? "installed_up" : \
(x == wrsm_enabled) ? "enabled" : \
"unknown")
#define SESS_STATE_STR(x) \
((x == SESS_STATE_UNREACH) ? "unreach" : \
(x == SESS_STATE_DOWN) ? "down" : \
(x == SESS_STATE_ESTAB) ? "enabling" : \
(x == SESS_STATE_UP) ? "up" : \
"unknown")
#define ROUTE_STATE_STR(x) \
((x == ncslice_use_current) ? "use_current" : \
(x == ncslice_use_new_route) ? "use_new_route" : \
(x == ncslice_remove_route) ? "remove_route" : \
(x == ncslice_use_errloopback) ? "use_errloopback" : \
(x == ncslice_no_route) ? "no_route" : \
"unknown")
#define EXPORTSEG_STATE_STR(x) \
((x == memseg_unpublished) ? "unpublished" : \
(x == memseg_wait_for_disconnects) ? "wait_disconnects" : \
(x == memseg_published) ? "published" : \
"unknown")
#define LINKSTATE_STR(x) \
((x == lc_up) ? "up" : \
(x == lc_down) ? "down" : \
(x == lc_not_there) ? "not_there" : \
(x == sc_wait_up) ? "wait_up" : \
(x == sc_wait_down) ? "wait_down" : \
(x == sc_wait_errdown) ? "wait_errdown" : \
"unknown")
/*
* wrsm_ctlr
*/
/*
* Initialize the wrsm_ctlr walker by either using the given starting
* address, or reading the value of the kernel's wrsm_networks pointer.
*/
static int
{
mdb_warn("failed to read 'wrsm_networks'");
return (WALK_ERR);
}
return (WALK_NEXT);
}
/*
* At each step, read a wrsm_network_t into our private storage, and then
* invoke the callback function. We terminate when we reach a NULL next
* pointer.
*/
static int
{
int status;
return (WALK_DONE);
return (WALK_DONE);
}
return (status);
}
/*
* print list of valid nodes in wrsm_network_t
*/
void
{
int i;
mdb_printf("known RSM addresses: ");
for (i = 0; i < WRSM_MAX_CNODES; i++) {
mdb_printf("%d ", i);
}
}
mdb_printf("\n");
}
/*
* dcmd for printing out information about a Wildcat RSM controller
* (wrsm_network_t).
*/
static int
{
int i;
if (argc != 0)
return (DCMD_USAGE);
/*
* If no wrsm_network_t address was specified on the command line,
* we can print out all wrsm networks (controllers) by invoking the
* walker, using this dcmd itself as the callback.
*/
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("failed to walk 'wrsm_ctlr_walk'");
return (DCMD_ERR);
}
return (DCMD_OK);
}
return (DCMD_OK);
}
/*
* print interesting information
*/
mdb_printf("---------------\n");
mdb_printf("availability: %s\nlocal RSM address: %3d\n",
mdb_printf("exported ncslices:");
for (i = 0; i < WRSM_NODE_NCSLICES; i++) {
if (i == 0) {
mdb_printf(" (small)");
} else {
mdb_printf(" (large)");
}
}
}
mdb_printf("\n");
mdb_printf("\n");
return (DCMD_OK);
}
/*
* wrsm_expseg
*/
typedef struct {
int hash_index;
/*
* Initialize the wrsm_expseg walker by either using the given starting
* address, or reading the value of the kernel's wrsm_networks pointer. We
* also allocate and initialize a wrsm_expseg_walk_data_t, and save this
* using the walk_data pointer.
*/
static int
{
mdb_warn("failed to read 'wrsm_networks'");
return (WALK_ERR);
}
return (WALK_DONE);
}
sizeof (expseg_walk_data->all_exportsegs_hash),
"all_exportsegs_hash") !=
sizeof (expseg_walk_data->all_exportsegs_hash)) {
mdb_warn("symbol 'all_exportsegs_hash' not found");
return (WALK_ERR);
}
return (WALK_NEXT);
}
/*
* At each step, find the next exportseg_t structure in the
* all_exportsegs_hash hash that belongs to the current network. We
* terminate when we reach the end of the hash and there are no more
* networks to process.
*/
static int
{
int status;
/* find next exportseg in hash */
do {
if (expseg_walk_data->hash_index ==
break;
}
/*
* At end of all_exportsegs_hash.
*/
if (!expseg_walk_data->walkall) {
/*
* only processing current network's exportsegs
*/
return (WALK_DONE);
}
/*
* Get next network, then refresh copy of hash.
*/
mdb_warn("failed to read wrsm_network "
return (WALK_DONE);
}
/* no more networks to process */
return (WALK_DONE);
}
if (mdb_readsym(
sizeof (expseg_walk_data->all_exportsegs_hash),
"all_exportsegs_hash") !=
sizeof (expseg_walk_data->all_exportsegs_hash)) {
mdb_warn("symbol 'all_exportsegs_hash' "
"not found");
return (WALK_ERR);
}
return (WALK_NEXT);
}
}
sizeof (expseg)) {
return (WALK_ERR);
}
/*
* if exportseg doesn't belong to current network, skip
*/
return (WALK_NEXT);
}
/*
* found exportseg belonging to current network
*/
wsp->walk_cbdata);
return (status);
}
/*
* The walker's fini function is invoked at the end of each walk.
* Free the memory pointed to by wsp->walk_data.
*/
static void
{
}
/*
* dcmd for printing out information about an exportseg_t
*/
static int
{
int i;
if (argc != 0)
return (DCMD_USAGE);
/*
* If no wrsm_expseg_t address was specified on the command line, we
* can print out all wrsm expsegs in all wrsm networks (controllers)
* by invoking the walker, using this dcmd itself as the callback.
*/
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("failed to walk 'wrsm_expseg_walk'");
return (DCMD_ERR);
}
return (DCMD_OK);
}
/*
* If this is the first invocation of the command, print a nice
* header line for the output that will follow.
*/
if (DCMD_HDRSPEC(flags)) {
mdb_printf("%4s %18s %18s %16s %8s %s\n",
"ctlr",
"handle",
"size",
"state",
"segid",
"importing RSMaddrs");
}
return (DCMD_OK);
}
sizeof (net)) {
return (DCMD_OK);
}
/*
* print interesting information
*/
mdb_printf("%4d 0x%016p 0x%016p %16s %8u ",
addr,
for (i = 0; i < WRSM_MAX_CNODES; i++) {
mdb_printf("%d ", i);
}
mdb_printf("\n");
return (DCMD_OK);
}
/*
* wrsm_impseg
*/
typedef struct {
int hash_index;
/*
* Initialize the wrsm_impseg walker by either using the given starting
* address, or reading the value of the kernel's wrsm_networks pointer. We
* also allocate and initialize a wrsm_impseg_walk_data_t, and save this
* using the walk_data pointer.
*/
static int
{
mdb_warn("failed to read 'wrsm_networks'");
return (WALK_ERR);
}
return (WALK_DONE);
}
sizeof (impseg_walk_data->all_importsegs_hash),
"all_importsegs_hash") !=
sizeof (impseg_walk_data->all_importsegs_hash)) {
mdb_warn("symbol 'all_importsegs_hash' not found");
return (WALK_ERR);
}
return (WALK_NEXT);
}
/*
* At each step, find the next importseg_t structure in the
* all_importsegs_hash hash that belongs to the current network. We
* terminate when we reach the end of the hash and there are no more
* networks to process.
*/
static int
{
int status;
/* find next importseg in hash */
do {
if (impseg_walk_data->hash_index ==
break;
}
/*
* At end of all_importsegs_hash.
*/
if (!impseg_walk_data->walkall) {
/*
* only processing current network's importsegs
*/
return (WALK_DONE);
}
/*
* Get next network, then refresh copy of hash.
*/
mdb_warn("failed to read wrsm_network "
return (WALK_DONE);
}
/* no more networks to process */
return (WALK_DONE);
}
if (mdb_readsym(
sizeof (impseg_walk_data->all_importsegs_hash),
"all_importsegs_hash") !=
sizeof (impseg_walk_data->all_importsegs_hash)) {
mdb_warn("symbol 'all_importsegs_hash' "
"not found");
return (WALK_ERR);
}
return (WALK_NEXT);
}
}
sizeof (impseg)) {
return (WALK_ERR);
}
/*
* if importseg doesn't belong to current network, skip
*/
return (WALK_NEXT);
}
/*
* found next importseg belonging to current network
*/
wsp->walk_cbdata);
return (status);
}
/*
* The walker's fini function is invoked at the end of each walk.
* Free the memory pointed to by wsp->walk_data.
*/
static void
{
}
/*
* dcmd for printing out information about an importseg_t
*/
static int
{
if (argc != 0)
return (DCMD_USAGE);
/*
* If no wrsm_impseg_t address was specified on the command line, we
* can print out all wrsm impsegs in all wrsm networks (controllers)
* by invoking the walker, using this dcmd itself as the callback.
*/
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("failed to walk 'wrsm_impseg_walk'");
return (DCMD_ERR);
}
return (DCMD_OK);
}
/*
* If this is the first invocation of the command, print a nice
* header line for the output that will follow.
*/
if (DCMD_HDRSPEC(flags)) {
mdb_printf("%4s %18s %8s %7s %18s %9s %8s\n",
"ctlr",
"handle",
"segid",
"RSMaddr",
"size",
"published",
"mappings");
}
return (DCMD_OK);
}
sizeof (net)) {
return (DCMD_OK);
}
return (DCMD_OK);
}
/*
* print interesting information
*/
mdb_printf("%4d 0x%016p %8u %7d 0x%016p %9s %8s\n",
addr,
return (DCMD_OK);
}
/*
* wrsm_wci
*/
typedef struct {
/*
* Initialize the wrsm_wci walker by either using the given starting
* address, or reading the value of the kernel's wrsm_networks pointer. We
* also allocate a wrsm_wci_walk_data_t for storage, and save this using
* the walk_data pointer.
*/
static int
{
mdb_warn("failed to read 'wrsm_networks'");
return (WALK_ERR);
}
}
return (WALK_NEXT);
}
/*
* At each step, read a wrsm_network_t into our private storage, and then
* invoke the callback function for each wci for which there is a softstate
* structure in that network. We terminate when we reach a NULL
* wrsm_network_t pointer.
*/
static int
{
int status;
return (WALK_DONE);
return (WALK_DONE);
}
return (WALK_DONE);
}
while (next) {
sizeof (wci)) {
break;
}
}
}
return (status);
} else {
return (WALK_DONE);
}
}
/*
* The walker's fini function is invoked at the end of each walk.
* Free the memory pointed to by wsp->walk_data.
*/
static void
{
}
/*
* dcmd for printing out information about a wrsm_wci_t.
*/
static int
{
int rsm_ctlr_id = -1;
int i;
if (argc != 0)
return (DCMD_USAGE);
/*
* If no wrsm_softstate_t address was specified on the command
* line, we can print out all wrsm wcis in all wrsm networks
* (controllers) by invoking the walker, using this dcmd itself as
* the callback.
*/
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("failed to walk 'wrsm_wci_walk'");
return (DCMD_ERR);
}
return (DCMD_OK);
}
return (DCMD_OK);
}
/*
* get controller id if this wci is part of a network
*/
sizeof (ncwci)) {
sizeof (net)) {
mdb_warn("failed to read wrsm_network_t at %p",
return (DCMD_OK);
}
}
/*
* print interesting information
*/
mdb_printf("\nController: %d\nInstance: %d\nExt Safari Portid: %d\n",
mdb_printf("%4s %8s\n",
"link#",
"state");
for (i = 0; i < WRSM_LINKS_PER_WCI; i++) {
mdb_printf("%5d %8s\n",
i,
}
return (DCMD_OK);
}
/*
* wrsm_node
*/
typedef struct {
/*
* Initialize the wrsm_node walker by either using the given starting
* address, or reading the value of the kernel's wrsm_networks pointer. We
* also allocate a wrsm_node_walk_data_t for storage, and save this using
* the walk_data pointer.
*/
static int
{
mdb_warn("failed to read 'wrsm_networks'");
return (WALK_ERR);
}
return (WALK_DONE);
}
return (WALK_NEXT);
}
/*
* At each step, read a wrsm_network_t into our private storage, and then
* invoke the callback function for each valid node in that network. We
* terminate when we reach a NULL wrsm_network_t pointer.
*/
static int
{
int status;
int cnodeid = 0;
return (WALK_DONE);
}
while (cnodeid < WRSM_MAX_CNODES) {
}
cnodeid++;
}
return (status);
} else {
return (WALK_DONE);
}
}
/*
* The walker's fini function is invoked at the end of each walk.
* Free the memory pointed to by wsp->walk_data.
*/
static void
{
}
/*
* dcmd for printing out information about a wrsm_node_t.
*/
static int
{
if (argc != 0)
return (DCMD_USAGE);
/*
* If no wrsm_node_t address was specified on the command line, we
* can print out all wrsm nodes in all wrsm networks (controllers)
* by invoking the walker, using this dcmd itself as the callback.
*/
if (!(flags & DCMD_ADDRSPEC)) {
mdb_warn("failed to walk 'wrsm_node_walk'");
return (DCMD_ERR);
}
return (DCMD_OK);
}
/*
* If this is the first invocation of the command, print a nice
* header line for the output that will follow.
*/
if (DCMD_HDRSPEC(flags)) {
mdb_printf("%4s %7s %12s %6s %8s %15s %s\n",
"", "", "", "have", "", "", "");
mdb_printf("%4s %7s %12s %6s %8s %15s %s\n",
"ctlr",
"RSMaddr",
"availability", "route?", "session", "route state",
"hostname");
}
return (DCMD_OK);
}
sizeof (config)) {
return (DCMD_OK);
}
sizeof (net)) {
return (DCMD_OK);
}
sizeof (sess)) {
return (DCMD_OK);
}
mdb_warn("failed to read wrsm_node_routeinfo_t at %p",
return (DCMD_OK);
}
/*
* print interesting information
*/
mdb_printf("%4d %7d %12s %6s %8s %15s %s\n",
return (DCMD_OK);
}
/*
* setup info
*/
/*
* 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.
*/
static const mdb_dcmd_t dcmds[] = {
wrsm_ctlr },
wrsm_node },
wrsm_expseg },
wrsm_impseg },
wrsm_wci },
{ NULL }
};
static const mdb_walker_t walkers[] = {
{ "wrsm_ctlr", "walk list of wrsm controller structures",
{ "wrsm_node", "walk wrsm node structures in controller",
{ "wrsm_expseg", "walk wrsm expseg structures in controller",
{ "wrsm_impseg", "walk wrsm impseg structures in controller",
{ "wrsm_wci", "walk wrsm WCI structures in controller",
{ NULL }
};
static const mdb_modinfo_t modinfo = {
};
const mdb_modinfo_t *
_mdb_init(void)
{
return (&modinfo);
}