topo_snap.c revision c93c462eec9d46f84d567abf52eb29a27c2e134b
/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Snapshot Library Interfaces
*
* Consumers of topology data may use the interfaces in this file to open,
* snapshot and close a topology exported by FMRI scheme (hc, mem and cpu)
* builtin plugins and their helper modules. A topology handle is obtained
* by calling topo_open(). Upon a successful return, the caller may use this
* handle to open a new snapshot. Each snapshot is assigned a Universally
* Unique Identifier that in a future enchancement to the libtopo API will be
* a previously captured snapshot. topo_snap_hold() will capture the current
* system topology. All consumers of the topo_hdl_t argument will be
* blocked from accessing the topology trees until the snapshot completes.
*
* A snapshot may be cleared by calling topo_snap_rele(). As with
* topo_snap_hold(), all topology accesses are blocked until the topology
* trees have been released and deallocated.
*
* Walker Library Interfaces
*
* Once a snapshot has been taken with topo_snap_hold(), topo_hdl_t holders
* may initiate topology tree walks on a scheme-tree basis. topo_walk_init()
* will initiate the data structures required to walk any one one of the
* FMRI scheme trees. The walker data structure, topo_walk_t, is an opaque
* handle passed to topo_walk_step to begin the walk. At each node in the
* topology tree, a callback function is called with access to the node at
* which our current walk falls. The callback function is passed in during
* calls to topo_walk_init() and used throughout the walk_step of the
* scheme tree. At any time, the callback may terminate the walk by returning
* TOPO_WALK_TERMINATE or TOPO_WALK_ERR. TOPO_WALK_NEXT will continue the walk.
*
* The type of walk through the tree may be sibling first or child first by
* respectively passing in TOPO_WALK_SIBLING or TOPO_WALK_CHILD to
* the topo_walk_step() function. Topology nodes
* associated with an outstanding walk are held in place and will not be
* deallocated until the walk through that node completes.
*
* Once the walk has terminated, the walking process should call
* topo_walk_fini() to clean-up resources created in topo_walk_init()
* and release nodes that may be still held.
*/
#include <alloca.h>
#include <ctype.h>
#include <pthread.h>
#include <limits.h>
#include <assert.h>
#include <fcntl.h>
#include <smbios.h>
#include <sys/systeminfo.h>
#include <topo_alloc.h>
#include <topo_builtin.h>
#include <topo_string.h>
#include <topo_error.h>
#include <topo_subr.h>
static void topo_snap_destroy(topo_hdl_t *);
static topo_hdl_t *
{
}
return (NULL);
}
{
char platform[MAXNAMELEN];
char isa[MAXNAMELEN];
if (version != TOPO_VERSION)
/*
* Install default allocators
*/
/*
* Set-up system information and search paths for modules
* and topology map files
*/
} else {
int len;
char *rpath;
} else {
}
}
platform[0] = '\0';
isa[0] = '\0';
(char *)s2.smbi_product);
}
}
} else {
}
"failed to load builtin modules: %s\n",
return (NULL);
}
return (thp);
}
void
{
/*
* Clean-up snapshot
*/
/*
* Clean-up trees
*/
}
/*
* Unload all plugins
*/
}
static char *
{
*errp = ETOPO_HDL_UUID;
return (NULL);
}
*errp = ETOPO_NOMEM;
topo_strerror(*errp));
return (NULL);
}
*errp = ETOPO_NOMEM;
return (NULL);
}
if (topo_tree_enum_all(thp) < 0) {
}
}
return (NULL);
}
}
"failed to refresh IPMI sdr repository: %s\n",
}
return (ustr);
}
/*ARGSUSED*/
static char *
{
return ((char *)uuid);
}
/*ARGSUSED*/
static int
{
int err;
/*
* If the facility enumeration method fails, note the failure,
* but continue on with the walk.
*/
&err) != 0) {
"facility enumeration method failed on node %s=%d "
}
}
return (TOPO_WALK_NEXT);
}
/*
* Return snapshot id
*/
char *
{
return (NULL);
char *ret;
/*
* Now walk the tree and invoke any facility enumeration methods
*/
return (ret);
}
}
return (ret);
}
}
/*ARGSUSED*/
static int
{
return (TOPO_WALK_NEXT);
return (TOPO_WALK_NEXT);
}
static void
{
int i;
/*
* Clean-up tree nodes from the bottom-up
*/
}
/*
* Tidy-up the root node
*/
}
}
}
/*
* Clean-up our cached devinfo and prom tree handles.
*/
}
}
}
}
void
{
return;
}
{
/*
* Hold the root node and start walk at the first
* child node
*/
return (NULL);
return (wp);
}
}
return (NULL);
}
static int
{
int status;
"step_child: TOPO_WALK_TERMINATE for %s=%d\n",
return (TOPO_WALK_TERMINATE);
}
"step_child: walk through node %s=%d to %s=%d\n",
if (bottomup == 1)
else
return (status);
}
static int
{
int status;
"step_sibling: TOPO_WALK_TERMINATE for %s=%d\n",
return (TOPO_WALK_TERMINATE);
}
"step_sibling: through sibling node %s=%d to %s=%d\n",
if (bottomup == 1)
else
return (status);
}
int
{
int status;
return (TOPO_WALK_TERMINATE);
else
return (status);
}
int
{
int status;
return (status);
}
int
{
int status;
return (TOPO_WALK_ERR);
}
/*
* No more nodes to walk
*/
"walk_step terminated\n");
return (TOPO_WALK_TERMINATE);
}
else
/*
* Walker callback says we're done
*/
if (status != TOPO_WALK_NEXT) {
return (status);
}
if (flag == TOPO_WALK_CHILD)
else
/*
* No more nodes in this hash, skip to next node hash by stepping
* to next sibling (child-first walk) or next child (sibling-first
* walk).
*/
if (status == TOPO_WALK_TERMINATE) {
if (flag == TOPO_WALK_CHILD)
else
}
return (status);
}
void
{
return;
}
int
{
int status;
return (TOPO_WALK_ERR);
return (TOPO_WALK_ERR);
}
/*
* End of the line
*/
"walk_bottomup terminated\n");
return (TOPO_WALK_TERMINATE);
}
"%s walk_bottomup through node %s=%d\n",
if (flag == TOPO_WALK_CHILD)
else
/*
* At a leaf, run the callback
*/
if (status == TOPO_WALK_TERMINATE) {
!= TOPO_WALK_NEXT) {
return (status);
}
}
/*
* Try next child or sibling
*/
if (status == TOPO_WALK_NEXT) {
if (flag == TOPO_WALK_CHILD)
else
}
return (status);
}
{
}
{
}