libtopo.c revision 2eeaed14a5e2ed9bd811643ad5bffc3510ca0310
/*
* 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
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/mdb_modapi.h>
#include <libelf.h>
#include <topo_mod.h>
#include <topo_tree.h>
#include <topo_module.h>
#include <stddef.h>
/*
* We use this to keep track of which bucket we're in while walking
* the modhash and we also cache the length of the hash
*/
static topo_modhash_t tmh;
static char *pgrp;
static char *tgt_scheme;
static char parent[255];
/*
* This structure is used by the topo_nodehash walker instances to
* keep track of where they're at in the node hash
*/
typedef struct tnwalk_state {
"Unstable", "Evolving", "Stable", "Standard", "Max"};
/*ARGSUSED*/
static int
{
/*
* Read in the structure and then read in all of the string fields from
* the target's addr space
*/
return (DCMD_ERR);
}
}
}
}
}
< 0) {
th.th_machine);
}
< 0) {
th.th_product);
}
/*
* Dump it all out in a nice pretty format and keep it to 80 chars wide
*/
if (DCMD_HDRSPEC(flags)) {
"DESCR");
}
"Mutex lock protecting handle");
"UUID of the topology snapshot");
"Root directory of plugin paths");
"Machine name");
"Product name");
"Handle to the root of the devinfo tree");
"Handle to the root of the PROM tree");
"Module hash");
"Scheme-specific topo tree list");
"");
"");
"Allocators");
"Debug mask");
"Debug channel");
return (DCMD_OK);
}
/*ARGSUSED*/
static int
{
/*
* Read in the structure and then read in all of the string fields from
* the target's addr space
*/
return (DCMD_ERR);
}
}
}
}
/*
* Dump it all out in a nice pretty format and keep it to 80 chars wide
*/
if (DCMD_HDRSPEC(flags)) {
mdb_printf("%<u>%-12s %-36s %-30s%</u>\n",
"FIELD", "VALUE", "DESCR");
}
"Module condition variable");
"Busy indicator");
else
"Busy indicator");
"Next module in hash chain");
"Topo handle for this module");
"Allocators");
"Basename of module");
"Full pathname of module");
"Relative root directory of module");
"Module reference count");
"Module flags");
"Module init completed");
}
"Module fini completed");
}
"Module registered");
}
"Module unregistered");
}
"Debug printf mask");
"Module class ops vector");
"Module info registered with handle");
"Module errno");
return (DCMD_OK);
}
/*ARGSUSED*/
static int
{
char name[36];
if (!addr)
return (DCMD_ERR);
/*
* Read in the structure and then read in all of the string fields from
* the target's addr space
*/
return (DCMD_ERR);
}
}
/*
* Dump it all out in a nice pretty format and keep it to 80 chars wide
*/
if (DCMD_HDRSPEC(flags)) {
mdb_printf("%<u>%-12s %-36s %-30s%</u>\n",
"FIELD", "VALUE", "DESCR");
}
"Lock protecting node members");
"Node name");
"Node instance");
"Node state");
}
}
}
}
"FMRI flags");
"Node parent");
"Parent hash bucket");
"Topo handle");
"Enumerator module");
"Hash table of child nodes");
"Property group list");
"Registered method list");
"Private enumerator data");
"Node reference count");
return (DCMD_OK);
}
/*ARGSUSED*/
static int
{
char scheme[36];
< 0) {
}
return (WALK_DONE);
}
return (WALK_NEXT);
}
static void
{
char mname[32];
return;
}
}
mdb_printf(" method: %-32s version: %-16d args: %p\n",
}
/*
* Dump the given property value. For the actual property values
* we dump a pointer to the nvlist which can be decoded using the ::nvlist
* dcmd from the libnvpair MDB module
*/
/*ARGSUSED*/
static int
{
!= sizeof (pval)) {
mdb_warn("failed to read topo_propval_t at %p",
return (WALK_ERR);
}
}
default: type = "unknown type";
}
return (WALK_NEXT);
}
/*
* Dumps the contents of the property group.
*/
/*ARGSUSED*/
static int
{
char buf[32];
!= sizeof (ipg)) {
mdb_warn("failed to read topo_ipgroup_info_t at %p",
return (WALK_ERR);
}
return (WALK_ERR);
}
/*
* If this property group is the one we're interested in or if the user
* specified the "all" property group, we'll dump it
*/
mdb_printf(" group: %-32s version: %d, stability: %s/%s\n",
}
return (WALK_NEXT);
}
/*
* Recursive function to dump the specified node and all of it's children
*/
/*ARGSUSED*/
static int
{
if (!addr) {
return (WALK_NEXT);
}
return (WALK_ERR);
}
}
if (is_root) {
is_root = 0;
} else {
if (verbose)
else
}
if (pgrp)
return (WALK_NEXT);
}
/*
* Given a topo_hdl_t *, the topo dcmd dumps the topo tree. The format of the
* output is modeled after fmtopo. Like fmtopo, by default, we'll dump the
* "hc" scheme tree. The user can optionally specify a different tree via the
* "-s <scheme>" option.
*
* Specifying the "-v" option provides more verbose output. Currently it
* outputs the tnode_t * addr for each node, which is useful if you want to
* dump it with the topo_node dcmd.
*
* The functionality of the "-P" option is similar to fmtopo.
*/
/*ARGSUSED*/
static int
{
char *def_scheme = "hc";
!= argc) {
return (DCMD_USAGE);
}
if (opt_s) {
tgt_scheme = opt_s;
} else {
}
is_root = 1;
/*
* Read in the topo_handle and some of its string fields from
* the target's addr space
*/
return (DCMD_ERR);
}
< 0) {
th.th_product);
}
/*
* Walk the list of topo trees, looking for the one that is for the
* scheme we're interested in.
*/
if (! tree_root) {
mdb_warn("failed to find a topo tree for scheme %s\n",
return (DCMD_ERR);
}
}
static int
{
mdb_warn("NULL topo_hdl_t passed in");
return (WALK_ERR);
}
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
{
int rv;
return (WALK_DONE);
!= sizeof (ttree_t)) {
return (WALK_ERR);
}
wsp->walk_cbdata);
return (rv);
}
static void
{
}
static int
{
mdb_warn("NULL topo_hdl_t passed in");
return (WALK_ERR);
}
return (WALK_ERR);
}
== -1) {
return (WALK_DONE);
}
hash_idx = 0;
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
{
int rv;
topo_mod_t *tm;
return (WALK_DONE);
== -1) {
return (WALK_DONE);
}
wsp->walk_cbdata);
mdb_warn("failed to read %u bytes at %p",
return (DCMD_ERR);
}
else
return (rv);
}
static void
{
}
static int
{
mdb_warn("NULL tnode_t passed in");
return (WALK_ERR);
}
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
{
int rv;
return (WALK_DONE);
== -1) {
return (WALK_DONE);
}
wsp->walk_cbdata);
return (rv);
}
static void
{
}
static int
{
mdb_warn("NULL topo_pgroup_t passed in");
return (WALK_ERR);
}
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
{
int rv;
return (WALK_DONE);
== -1) {
mdb_warn("failed to read topo_proplist_t at %p",
return (WALK_DONE);
}
wsp->walk_cbdata);
return (rv);
}
static void
{
}
static int
{
mdb_warn("NULL tnode_t passed in");
return (WALK_ERR);
}
return (WALK_ERR);
}
return (WALK_NEXT);
}
static int
{
return (WALK_DONE);
mdb_warn("failed to read topo_nodehash_t at %p",
return (WALK_ERR);
}
return (WALK_ERR);
}
/*
* move on to the next child hash bucket
*/
}
return (rv);
}
static void
{
}
static const mdb_dcmd_t dcmds[] = {
NULL },
{ "topo_module", "", "print contents of a topo module handle",
topo_module, NULL },
{ "fmtopo", "[-P <pgroup>][-s <scheme>][-v]",
{ NULL }
};
static const mdb_walker_t walkers[] = {
{ "topo_tree", "walk the tree list for a given topo handle",
{ "topo_module", "walk the module hash for a given topo handle",
{ "topo_pgroup", "walk the property groups for a given topo node",
{ "topo_proplist", "walk the property list for a given property group",
{ "topo_nodehash", "walk the child nodehash for a given topo node",
{ NULL }
};
static const mdb_modinfo_t modinfo = {
};
const mdb_modinfo_t *
_mdb_init(void)
{
return (&modinfo);
}