topo_mod.c revision 4557a2a1868181b517f5dfe61ba6eeba58edf4c0
/*
* 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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Topology Plugin Modules
*
* Topology plugin modules are shared libraries that are dlopen'd and
* used to enumerate resources in the system and export per-node method
* operations.
*
* They are loaded by our builtin scheme-specific plugins, other modules or
* by processing a topo map XML file to enumerate and create nodes for
* resources that are present in the system. They may also export a set of
* topology node specific methods that can be invoked directly via
* topo_method_invoke() or indirectly via the
* topo_prop_get* family of functions to access dynamic property data.
*
* Module Plugin API
*
* Enumerators must provide entry points for initialization and clean-up
* (_topo_init() and _topo_fini()). In their _topo_init() function, an
* enumerator should register (topo_mod_register()) its enumeration callback
* and allocate resources required for a subsequent call to the callback.
* Optionally, methods may also be registered with topo_method_register().
*
* In its enumeration callback routine, the module should search for resources
* within its realm of responsibility and create any node ranges,
* topo_node_range_create() and nodes, topo_node_bind(). The Enumerator
* module is handed a node to which it may begin attaching additional
* topology nodes. The enumerator may only access those nodes within its
* current scope of operation: the node passed into its enumeration op and
* any nodes it creates during enumeration. If the enumerator requires walker-
* style access to these nodes, it must use
* topo_mod_walk_init()/topo_walk_step()/topo_walk_fini().
*
* If additional helper modules need to be loaded to complete the enumeration
* the module may do so by calling topo_mod_load(). Enumeration may then
* continue with the module handing off enumeration to its helper module
* by calling topo_mod_enumerate(). Similarly, a module may call
* topo_mod_enummap() to kick-off enumeration according to a given XML
* topology map file. A module *may* not cause re-entrance to itself
* via either of these interfaces. If re-entry is detected an error
* will be returned (ETOPO_ENUM_RECURS).
*
* If the module registers a release callback, it will be called on a node
* by node basis during topo_snap_rele(). Any private node data may be
* deallocated or methods unregistered at that time. Global module data
* should be cleaned up before or at the time that the module _topo_fini
* entry point is called.
*
* Module entry points and method invocations are guaranteed to be
* single-threaded for a given snapshot handle. Applications may have
* more than one topology snapshot open at a time. This means that the
* module operations and methods may be called for different module handles
* (topo_mod_t) asynchronously. The enumerator should not use static or
* global data structures that may become inconsistent in this situation.
* Method operations may be re-entrant if the module invokes one of its own
* methods directly or via dynamic property access. Caution should be
* exercised with method operations to insure that data remains consistent
* within the module and that deadlocks can not occur.
*/
#include <pthread.h>
#include <assert.h>
#include <errno.h>
#include <dirent.h>
#include <limits.h>
#include <alloca.h>
#include <unistd.h>
#include <stdio.h>
#include <topo_alloc.h>
#include <topo_error.h>
#include <topo_file.h>
#include <topo_fmri.h>
#include <topo_module.h>
#include <topo_method.h>
#include <topo_string.h>
#include <topo_subr.h>
#include <topo_tree.h>
#define PLUGIN_PATH "plugins"
{
char *path;
char file[PLUGIN_PATH_LEN];
/*
* Already loaded, topo_mod_lookup will bump the ref count
*/
return (NULL);
}
return (mod);
}
PLUGIN_PATH, name);
== NULL) { /* returned with mod held */
return (NULL);
}
return (mod);
}
void
{
}
static int
{
"module registration failed for %s: %s\n",
}
int
{
if (version != TOPO_VERSION)
== NULL)
sizeof (topo_modops_t))) == NULL)
return (0);
}
void
{
return;
return;
sizeof (topo_modops_t));
}
int
{
int err = 0;
node->tn_instance);
if (err != 0) {
"module %s failed enumeration for "
return (-1);
}
return (0);
}
int
const char *scheme)
{
}
static nvlist_t *
{
return (NULL);
}
nvlist_t *
{
int err;
if (version != FM_HC_SCHEME_VERSION)
/*
* Do we have any args to pass?
*/
}
}
pfmri) != 0) {
}
}
/*
* Add optional payload
*/
serial);
if (hc_specific != NULL)
}
return (nfp);
}
nvlist_t *
const char *devid)
{
int err;
if (version != FM_DEV_SCHEME_VERSION)
}
}
return (nfp);
}
nvlist_t *
const char *serial)
{
int err;
if (version != FM_CPU_SCHEME_VERSION)
}
/*
* Add optional payload
*/
}
return (nfp);
}
nvlist_t *
{
int err;
if (version != FM_MEM_SCHEME_VERSION)
if (flags & TOPO_MEMFMRI_PA)
if (flags & TOPO_MEMFMRI_OFFSET)
if (err != 0) {
}
}
return (nfp);
}
nvlist_t *
{
int err;
if (version != FM_PKG_SCHEME_VERSION)
}
}
return (nfp);
}
nvlist_t *
{
int err;
if (version != FM_MOD_SCHEME_VERSION)
}
}
return (nfp);
}
int
{
int err;
}
return (0);
}
int
{
int err;
char *sp;
}
return (0);
}
void *
{
}
void
{
}
void
{
}
{
}
{
}
void
{
}
/*PRINTFLIKE2*/
void
{
return;
}
static char *
{
}
static char *
{
}
static char *
{
char csn[MAXNAMELEN];
}
return (NULL);
/*
* Terminate CSN at the first white space
*/
*str = '\0';
(unsigned char **)&bufp) != -1) {
} else {
return (NULL);
}
} else {
return (NULL);
}
}
nvlist_t *
{
int err;
return (NULL);
}
/*
* Let's do this the hard way
*/
}
/*
* No luck, return NULL
*/
return (NULL);
}
err = 0;
}
}
}
if (err != 0) {
return (NULL);
}
return (auth);
}
{
return (NULL);
return (wp);
}