topo_snap.c revision 7aec1d6e253b21f9e9b7ef68b4d81ab9859b51fe
/*
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* 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.
*
* Walks through the tree may be breadth first or depth 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 <pthread.h>
#include <limits.h>
#include <assert.h>
#include <fcntl.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);
}
{
if (version < TOPO_VERSION)
if (version > TOPO_VERSION)
/*
* Install default allocators
*/
} else {
}
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);
}
if (topo_tree_enum_all(thp) < 0) {
return (NULL);
}
}
*errp = ETOPO_NOMEM;
return (ustr);
}
/*ARGSUSED*/
static char *
{
return ((char *)uuid);
}
/*
* Return snapshot id
*/
char *
{
return (NULL);
else
}
/*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
*/
}
}
/*
* Release the file handle
*/
}
}
void
{
return;
}
}
{
/*
* Hold the root node and start walk at the first
* child node
*/
/*
* Nothing to walk
*/
*errp = ETOPO_WALK_EMPTY;
return (NULL);
}
== NULL) {
*errp = ETOPO_NOMEM;
return (NULL);
}
return (wp);
}
}
return (NULL);
}
static int
{
int status;
return (TOPO_WALK_TERMINATE);
if (bottomup == 1)
else
return (status);
}
static int
{
int status;
return (TOPO_WALK_TERMINATE);
if (bottomup == 1)
else
return (status);
}
int
{
int status;
return (TOPO_WALK_ERR);
}
/*
* End of the line
*/
return (TOPO_WALK_TERMINATE);
}
!= TOPO_WALK_NEXT) {
return (status);
}
if (flag == TOPO_WALK_CHILD)
else
/*
* End of the walk, try next child or sibling
*/
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
*/
return (TOPO_WALK_TERMINATE);
}
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);
}