/*
* 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"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <thread.h>
#include <pthread.h>
#include <synch.h>
#include <unistd.h>
#include <stropts.h>
#include <fcntl.h>
#include <note.h>
#include <errno.h>
#include <ctype.h>
#include <libintl.h>
#include <libscf.h>
#include <pool.h>
#include <signal.h>
#include <sys/priocntl.h>
#include "pool_internal.h"
#include "pool_impl.h"
/*
* libpool Interface Routines
*
* pool.c implements (most of) the external interface to libpool
* users. Some of the interface is implemented in pool_internal.c for
* reasons of internal code organisation. The core requirements for
* pool.c are:
*
* Data Abstraction
*
* The abstraction of the actual datastore so that no details of the
* underlying data representation mechanism are revealed to users of
* the library. For instance, the fact that we use the kernel or files
* to store our configurations is completely abstracted via the
* various libpool APIs.
*
* External Interaction
*
* libpool users manipulate configuration components via the API
* defined in pool.h. Most functions in this file act as interceptors,
* validating parameters before redirecting the request into a
* specific datastore implementation for the actual work to be done.
*
* These main sets of requirements have driven the design so that it
* is possible to replace the entire datastore type without having to
* modify the external (or internal provider) APIs. It is possible to
* modify the storage technology used by libpool by implementing a new
* set of datastore provider operations. Simply modify the
* pool_conf_open() routine to establish a new datastore as the
* provider for a configuration.
*
* The key components in a libpool configuration are :
* pool_conf_t - This represents a complete configuration instance
* pool_t - A pool inside a configuration
* pool_resource_t - A resource inside a configuration
* pool_component_t - A component of a resource
*
*/
/*
* Used to control transfer setup.
*/
#ifndef TEXT_DOMAIN
#endif /* TEXT_DOMAIN */
/*
* Static data
*/
/*
* libpool error code
*/
/*
* libpool version
*/
static const char *data_type_tags[] = {
"uint",
"int",
"float",
"boolean",
"string"
};
/*
* static functions
*/
static int pool_elem_remove(pool_elem_t *);
static int is_valid_prop_name(const char *);
pool_value_t *, void *);
static int pool_conf_check(const pool_conf_t *);
static void free_value_list(int, pool_value_t **);
/*
* Return the "static" location string for libpool.
*/
const char *
pool_static_location(void)
{
return (static_location);
}
/*
* Return the "dynamic" location string for libpool.
*/
const char *
pool_dynamic_location(void)
{
return (dynamic_location);
}
/*
* Return the status for a configuration. If the configuration has
* been successfully opened, then the status will be POF_VALID or
* POF_DESTROY. If the configuration failed to open properly or has
* been closed or removed, then the status will be POF_INVALID.
*/
{
}
/*
* Bind idtype id to the pool name.
*/
int
{
int result;
return (PO_FAIL);
return (PO_FAIL);
}
(void) pool_conf_close(conf);
return (result);
}
/*
* pool_get_resource_binding() returns the binding for a pid to the supplied
* type of resource. If a binding cannot be determined, NULL is returned.
*/
char *
{
char *result;
PREC_INVALID) {
return (NULL);
}
return (NULL);
!= PO_SUCCESS) {
return (NULL);
}
(void) pool_conf_close(conf);
return (result);
}
/*
* pool_get_binding() returns the binding for a pid to a pool. If a
* binding cannot be determined, NULL is returned.
*/
char *
{
char *result;
return (NULL);
!= PO_SUCCESS) {
return (NULL);
}
(void) pool_conf_close(conf);
return (result);
}
/*ARGSUSED*/
int
{
uint64_t u;
int64_t i;
uchar_t bool;
const char *str;
double d;
/*
* Ignore "type" and "<type>.name" properties as these are not
* to be displayed by this function
*/
return (PO_SUCCESS);
return (PO_FAIL);
switch (type) {
case POC_UINT:
(void) pool_value_get_uint64(pval, &u);
return (PO_FAIL);
break;
case POC_INT:
(void) pool_value_get_int64(pval, &i);
return (PO_FAIL);
break;
case POC_STRING:
return (PO_FAIL);
break;
case POC_BOOL:
(void) pool_value_get_bool(pval, &bool);
if (bool == 0) {
return (PO_FAIL);
} else {
return (PO_FAIL);
}
break;
case POC_DOUBLE:
(void) pool_value_get_double(pval, &d);
return (PO_FAIL);
break;
case POC_INVAL: /* Do nothing */
break;
default:
return (PO_FAIL);
}
return (PO_SUCCESS);
}
/*
* Return a buffer which describes the element
* pe is a pointer to the element
*/
char *
{
const char *sres;
uint_t i;
return (NULL);
/*
* Populate the buffer with element details
*/
return (ret);
}
return (NULL);
}
return (NULL);
}
}
/*
* Add in some details about the element
*/
prop_buf_build_cb) == PO_FAIL) {
"Cannot access the properties of this element.");
return (NULL);
}
return (NULL);
/*
* A shallow display of a pool only lists the resources by name
*/
return (NULL);
}
for (i = 0; i < nelem; i++) {
const char *str;
return (NULL);
}
POC_STRING) {
return (NULL);
}
return (NULL);
}
}
}
>= CB_TAB_BUF_SIZE) {
return (NULL);
}
case PEC_SYSTEM:
NULL) { /* process the pools */
for (i = 0; i < nelem; i++) {
return (NULL);
}
}
}
NULL) {
for (i = 0; i < nelem; i++) {
return (NULL);
}
}
}
break;
case PEC_POOL:
return (NULL);
for (i = 0; i < nelem; i++) {
return (NULL);
}
}
break;
case PEC_RES_COMP:
for (i = 0; i < nelem; i++) {
return (NULL);
}
}
}
break;
case PEC_RES_AGG:
case PEC_COMP:
break;
default:
/*NOTREACHED*/
break;
}
if (cb->cb_tab_buf[0] != 0)
}
}
/*
* Returns The information on the specified pool or NULL.
*
* Errors If the status of the conf is INVALID or the supplied
* value of deep is illegal, POE_BADPARAM.
*
* The caller is responsible for free(3c)ing the string returned.
*/
char *
{
return (NULL);
}
return (NULL);
}
}
/*
* Returns The information on the specified resource or NULL.
*
* Errors If the status of the conf is INVALID or the supplied
* value of deep is illegal, POE_BADPARAM.
*
* The caller is responsible for free(3c)ing the string returned.
*/
char *
int deep)
{
return (NULL);
}
return (NULL);
}
}
/*
* Returns The information on the specified component or NULL.
*
* Errors If the status of the conf is INVALID or the supplied
* value of deep is illegal, POE_BADPARAM.
*
* The caller is responsible for free(3c)ing the string returned.
*/
char *
int deep)
{
return (NULL);
}
return (NULL);
}
}
/*
* Returns The information on the specified conf or NULL.
*
* Errors If the status of the conf is INVALID or the supplied
* value of deep is illegal, POE_BADPARAM.
*
* The caller is responsible for free(3c)ing the string returned.
*/
char *
{
return (NULL);
}
return (NULL);
}
}
/*
* Set the thread specific error value.
*/
void
{
if (thr_main()) {
return;
}
(void) thr_keycreate_once(&errkey, 0);
}
/*
* Return the current value of the error code.
* Returns: int error code
*/
int
pool_error(void)
{
if (thr_main())
return (pool_errval);
if (errkey == THR_ONCE_KEY)
return (POE_OK);
}
/*
* Return the text represenation for the current value of the error code.
* Returns: const char * error string
*/
const char *
{
char *str;
switch (error) {
case POE_OK:
break;
case POE_BAD_PROP_TYPE:
"Attempted to retrieve the wrong property type");
break;
case POE_INVALID_CONF:
break;
case POE_NOTSUP:
break;
case POE_INVALID_SEARCH:
break;
case POE_BADPARAM:
break;
case POE_PUTPROP:
break;
case POE_DATASTORE:
break;
case POE_SYSTEM:
break;
case POE_ACCESS:
break;
default:
}
return (str);
}
int
{
int fd;
return (PO_FAIL);
}
return (PO_FAIL);
}
return (PO_SUCCESS);
}
int
{
int old_state;
return (PO_FAIL);
}
int fd;
char *fmri;
/*
* Changing the status of pools is performed by enabling
* or disabling the pools service instance. If this
* function has not been invoked by startd then we simply
*
* There is no way to specify that state changes must be
* synchronous using the library API as yet, so we use
* the -s option provided by svcadm.
*/
FILE *p;
char *cmd;
if (state != 0) {
} else {
}
return (PO_FAIL);
}
return (PO_SUCCESS);
}
return (PO_FAIL);
}
/*
* enable the smf service instance. This must be done
* asynchronously as one service cannot synchronously
*/
int res;
if (state != 0)
else
if (res != 0) {
return (PO_FAIL);
}
}
return (PO_FAIL);
}
}
return (PO_SUCCESS);
}
/*
* General Data Provider Independent Access Methods
*/
/*
* Property manipulation code.
*
* The pool_(get|rm|set)_property() functions consult the plugins before
* looking at the actual configuration. This allows plugins to provide
* "virtual" properties that may not exist in the configuration file per se,
* but behave like regular properties. This also allows plugins to reserve
* certain properties as read-only, non-removable, etc.
*
* A negative value returned from the plugin denotes error, 0 means that the
* property request should be forwarded to the backend, and 1 means the request
* was satisfied by the plugin and should not be processed further.
*
* The (get|rm|set)_property() functions bypass the plugin layer completely,
* and hence should not be generally used.
*/
/*
* Return true if the string passed in matches the pattern
* [A-Za-z][A-Za-z0-9,._-]*
*/
int
{
int i;
char c;
return (PO_FALSE);
return (PO_FALSE);
return (PO_FALSE);
}
return (PO_TRUE);
}
/*
* Return true if the string passed in matches the pattern
* [A-Za-z_][A-Za-z0-9,._-]*
* A property name starting with a '_' is an "invisible" property that does not
* show up in a property walk.
*/
int
{
int i;
char c;
return (PO_FALSE);
return (PO_FALSE);
return (PO_FALSE);
}
return (PO_TRUE);
}
/*
* Return the specified property value.
*
* POC_INVAL is returned if an error is detected and the error code is updated
* to indicate the cause of the error.
*/
{
return (POC_INVAL);
}
return (POC_INVAL);
}
/*
* Check to see if this is a property we are managing. If it
* is and it has an interceptor installed for property
* retrieval, use it.
*/
return (POC_INVAL);
else
return (pool_value_get_type(val));
}
}
/*
* Return the specified property value with the namespace prepended.
* e.g. If this function is used to get the property "name" on a pool, it will
* attempt to retrieve "pool.name".
*
* POC_INVAL is returned if an error is detected and the error code is updated
* to indicate the cause of the error.
*/
{
int ret;
return (POC_INVAL);
PO_FAIL) {
return (POC_INVAL);
}
return (ret);
}
/*
* Update the specified property value.
*
* PO_FAIL is returned if an error is detected and the error code is updated
* to indicate the cause of the error.
*/
int
const pool_value_t *val)
{
return (PO_FAIL);
return (NULL);
}
/* Don't allow (re)setting of the "temporary" property */
return (PO_FAIL);
}
}
if (rename) {
return (PO_FAIL);
}
}
/*
* Check to see if this is a property we are managing. If it is,
* ensure that we are happy with what the user is doing.
*/
return (PO_FAIL);
}
return (PO_FAIL);
}
}
/*
* Set temporary property to flag as a temporary element.
*
* PO_FAIL is returned if an error is detected and the error code is updated
* to indicate the cause of the error.
*/
int
{
int res;
return (PO_FAIL);
return (PO_FAIL);
}
/* create property name based on element type */
return (PO_FAIL);
}
return (PO_FAIL);
return (res);
}
/*
* Update the specified property value with the namespace prepended.
* e.g. If this function is used to update the property "name" on a pool, it
* will attempt to update "pool.name".
*
* PO_FAIL is returned if an error is detected and the error code is updated
* to indicate the cause of the error.
*/
int
const pool_value_t *val)
{
int ret;
return (PO_FAIL);
PO_FAIL) {
return (PO_FAIL);
}
return (ret);
}
/*
* Update the specified property value. Do not use the property
* protection mechanism. This function should only be used for cases
* where the library must bypass the normal property protection
* mechanism. The only known use is to update properties in the static
* configuration when performing a commit.
*
* PO_FAIL is returned if an error is detected and the error code is
* updated to indicate the cause of the error.
*/
int
const pool_value_t *val)
{
if (!is_valid_prop_name(name)) {
return (PO_FAIL);
}
}
/*
* Update the specified property value with the namespace prepended.
* e.g. If this function is used to update the property "name" on a pool, it
* will attempt to update "pool.name".
*
* PO_FAIL is returned if an error is detected and the error code is updated
* to indicate the cause of the error.
*/
int
const pool_value_t *val)
{
int ret;
return (PO_FAIL);
PO_FAIL) {
return (PO_FAIL);
}
return (ret);
}
/*
* Remove the specified property value. Note that some properties are
* mandatory and thus failure to remove these properties is inevitable.
* PO_FAIL is returned if an error is detected and the error code is updated
* to indicate the cause of the error.
*/
int
{
return (PO_FAIL);
return (NULL);
}
/* Don't allow removal of the "temporary" property */
return (PO_FAIL);
}
/*
* Check to see if this is a property we are managing. If it is,
* ensure that we are happy with what the user is doing.
*/
return (PO_FAIL);
}
}
}
/*
* Check if the supplied name is a namespace protected property for the supplied
* element, pe. If it is, return the prefix, otherwise just return NULL.
*/
const char *
{
const char *prefix;
return (prefix);
}
return (NULL);
}
/*
* Check if the supplied name is a namespace protected property for the supplied
* element, pe. If it is, return the property name with the namespace stripped,
* otherwise just return the name.
*/
const char *
{
const char *prefix;
}
return (name);
}
/*
* Create an element to represent a pool and add it to the supplied
* configuration.
*/
pool_t *
{
return (NULL);
/*
* A pool with the same name exists. Reject.
*/
return (NULL);
}
PCEC_INVALID)) == NULL) {
return (NULL);
}
int i;
if (prop_is_init(&default_props[i]) &&
return (NULL);
}
}
}
return (NULL);
}
return (NULL);
}
/*
* If we are creating a temporary pool configuration, flag the pool.
*/
return (NULL);
}
}
return (pool_elem_pool(pe));
}
/*
* Create an element to represent a res.
*/
{
int is_default = 0;
return (NULL);
PREC_INVALID) {
return (NULL);
}
return (NULL);
}
NULL) {
/*
* Resources must be unique by name+type.
*/
return (NULL);
}
return (NULL);
}
/*
* This is the first representative of this type; when it's
* created it should be created with 'default' = 'true'.
*/
is_default = 1;
} else {
}
/*
* TODO: If Additional PEC_RES_COMP types are added to
* pool_impl.h, this would need to be extended.
*/
switch (type) {
case PREC_PSET:
break;
default:
break;
}
PCEC_INVALID)) == NULL) {
return (NULL);
}
/*
* The plugins contain a list of default properties and their values
* for resources. The resource returned, hence, is fully initialized.
*/
int i;
if (prop_is_init(&default_props[i]) &&
(void) pool_resource_destroy(conf,
pool_elem_res(pe));
return (NULL);
}
}
}
return (NULL);
}
if (is_default) {
PO_SUCCESS) {
return (NULL);
}
}
/*
* If we are creating a temporary pool configuration, flag the resource.
*/
return (NULL);
}
}
return (pool_elem_res(pe));
}
/*
* Create an element to represent a resource component.
*/
{
return (NULL);
}
/*
* TODO: If additional PEC_COMP types are added in pool_impl.h,
* this would need to be extended.
*/
/* Now set the container for this comp */
return (NULL);
}
/*
* The plugins contain a list of default properties and their values
* for resources. The resource returned, hence, is fully initialized.
*/
int i;
if (prop_is_init(&default_props[i]) &&
(void) pool_component_destroy(
pool_elem_comp(pe));
return (NULL);
}
}
}
/*
* Set additional attributes/properties on component.
*/
return (NULL);
}
return (NULL);
}
return (NULL);
}
return (NULL);
}
return (pool_elem_comp(pe));
}
/*
* Return the location of a configuration.
*/
const char *
{
return (NULL);
}
return (conf->pc_location);
}
/*
* Close a configuration, freeing all associated resources. Once a
* configuration is closed, it can no longer be used.
*/
int
{
int rv;
return (PO_FAIL);
}
return (rv);
}
/*
* Remove a configuration, freeing all associated resources. Once a
* configuration is removed, it can no longer be accessed and is forever
* gone.
*/
int
{
int rv;
return (PO_FAIL);
}
return (rv);
}
/*
* pool_conf_alloc() allocate the resources to represent a configuration.
*/
pool_conf_alloc(void)
{
return (NULL);
}
return (conf);
}
/*
* pool_conf_free() frees the resources associated with a configuration.
*/
void
{
}
/*
* pool_conf_open() opens a configuration, establishing all required
* connections to the data source.
*/
int
{
/*
* Since you can't do anything to a pool configuration without opening
* it, this represents a good point to intialise structures that would
* otherwise need to be initialised in a .init section.
*/
/*
* Already opened configuration, return PO_FAIL
*/
return (PO_FAIL);
}
PO_TEMP)) {
return (PO_FAIL);
}
/*
* Creating a configuration implies read-write access, so make
* sure that PO_RDWR is set in addition if PO_CREAT is set.
*/
/* location is ignored when creating a temporary configuration */
location = "";
return (PO_FAIL);
}
/*
* This is the crossover point into the actual data provider
* implementation, allocate a data provider of the appropriate
* type for your data storage medium. In this case it's either a kernel
* or xml data provider. To use a different data provider, write some
* code to implement all the required interfaces and then change the
* following code to allocate a data provider which uses your new code.
* All data provider routines can be static, apart from the allocation
* routine.
*
* For temporary pools (PO_TEMP) we start with a copy of the current
* dynamic configuration and do all of the updates in-memory.
*/
return (PO_FAIL);
}
/* set rdwr flag so we can updated the in-memory config. */
return (PO_FAIL);
}
} else {
return (PO_FAIL);
}
}
return (PO_SUCCESS);
}
/*
* Rollback a configuration. This will undo all changes to the configuration
* since the last time pool_conf_commit was called.
*/
int
{
return (PO_FAIL);
}
}
/*
* Commit a configuration. This will apply all changes to the
* configuration to the permanent data store. The active parameter
* indicates whether the configuration should be used to update the
* dynamic configuration from the supplied (static) configuration or
* whether it should be written back to persistent store.
*/
int
{
int retval;
return (PO_FAIL);
}
if (active) {
int oflags;
return (PO_FAIL);
}
/*
* Pretend that the configuration was opened PO_RDWR
* so that a configuration which was opened PO_RDONLY
* can be committed. The original flags are preserved
* in oflags and restored after pool_conf_commit_sys()
* returns.
*/
} else {
/*
* Write the configuration back to the backing store.
*/
}
return (retval);
}
/*
* Export a configuration. This will export a configuration in the specified
* format (fmt) to the specified location.
*/
int
{
return (PO_FAIL);
}
}
/*
* Validate a configuration. This will validate a configuration at the
* specified level.
*/
int
{
return (PO_FAIL);
}
}
/*
* Update the snapshot of a configuration. This can only be used on a
* dynamic configuration.
*/
int
{
return (PO_FAIL);
}
/*
* Since this function only makes sense for dynamic
* configurations, just call directly into the appropriate
* function. This could be added into the pool_connection_t
* interface if it was ever required.
*/
if (changed)
*changed = 0;
}
/*
* Walk the properties of the supplied elem, calling the user supplied
* function repeatedly as long as the user function returns
* PO_SUCCESS.
*/
int
pool_value_t *, void *))
{
}
void
{
int j;
for (j = 0; j < npvals; j++) {
if (pvals[j])
pool_value_free(pvals[j]);
}
}
/*
* Walk the properties of the supplied elem, calling the user supplied
* function repeatedly as long as the user function returns
* PO_SUCCESS.
* The list of properties to be walked is retrieved from the element
*/
int
pool_value_t *, void *), int any)
{
int i;
return (PO_FAIL);
}
return (PO_FAIL);
}
return (PO_FAIL);
/*
* Now walk the managed properties. As we find managed
* properties removed them from the list of all properties to
* prevent duplication.
*/
int j;
/*
* Special processing for type
*/
PO_FAIL) {
return (PO_FAIL);
}
PO_FAIL) {
return (PO_FAIL);
}
return (PO_FAIL);
}
}
continue;
}
for (j = 0; j < npvals; j++) {
break;
}
/*
* If we have found the property, then j < npvals. Process it
* according to our property attributes. Otherwise, it's not
* a managed property, so just ignore it until later.
*/
if (j < npvals) {
if (pool_value_set_name(pvals[j],
return (PO_FAIL);
}
return (PO_FAIL);
}
}
return (PO_FAIL);
}
}
pool_value_free(pvals[j]);
}
}
for (i = 0; i < npvals; i++) {
if (pvals[i]) {
arg) != PO_SUCCESS) {
return (PO_FAIL);
}
}
pool_value_free(pvals[i]);
}
}
return (PO_SUCCESS);
}
/*
* Return a pool, searching the supplied configuration for a pool with the
* supplied name. The search is case sensitive.
*/
pool_t *
{
return (NULL);
}
return (NULL);
}
return (NULL);
}
if (size != 1) {
return (NULL);
}
return (ret);
}
/*
* Return a result set of pools, searching the supplied configuration
* for pools which match the supplied property criteria. props is a null
* terminated list of properties which will be used to match qualifying
* pools. size is updated with the size of the pool
*/
pool_t **
{
int i = 0;
return (NULL);
}
return (NULL);
}
(void) pool_rs_close(rs);
return (NULL);
}
(void) pool_rs_close(rs);
return (NULL);
}
(void) pool_rs_close(rs);
return (NULL);
}
}
(void) pool_rs_close(rs);
return (result);
}
/*
* Return an res, searching the supplied configuration for an res with the
* supplied name. The search is case sensitive.
*/
const char *name)
{
return (NULL);
}
return (NULL);
}
return (NULL);
return (NULL);
}
return (NULL);
}
return (NULL);
}
return (NULL);
}
return (NULL);
}
if (size != 1) {
return (NULL);
}
return (ret);
}
/*
* Return a result set of res (actually as pool_elem_ts), searching the
* supplied configuration for res which match the supplied property
* criteria. props is a null terminated list of properties which will be used
* to match qualifying res.
*/
{
int i = 0;
return (NULL);
}
*size = 0;
return (NULL);
}
(void) pool_rs_close(rs);
return (NULL);
}
== NULL) {
(void) pool_rs_close(rs);
return (NULL);
}
(void) pool_rs_close(rs);
return (NULL);
}
}
(void) pool_rs_close(rs);
return (result);
}
/*
* Return a result set of comp (actually as pool_elem_ts), searching the
* supplied configuration for comp which match the supplied property
* criteria. props is a null terminated list of properties which will be used
* to match qualifying comp.
*/
{
}
/*
* Destroy a pool. If the pool cannot be found or removed an error is
* returned. This is basically a wrapper around pool_elem_remove to ensure
* some type safety for the pool subtype.
*/
int
{
return (PO_FAIL);
/*
* Cannot destroy the default pool.
*/
return (PO_FAIL);
}
return (PO_FAIL);
return (PO_SUCCESS);
}
/*
* Destroy an res. If the res cannot be found or removed an error is
* returned. This is basically a wrapper around pool_elem_remove to ensure
* some type safety for the res subtype.
*/
int
{
int i;
return (PO_FAIL);
return (PO_FAIL);
}
/*
* Walk all the pools and dissociate any pools which are using
* this resource.
*/
for (i = 0; i < npool; i++) {
int j;
for (j = 0; j < nres; j++) {
rl[j]) != PO_SUCCESS) {
return (PO_FAIL);
}
break;
}
}
}
}
}
/*
* Use the xtransfer option to move comp around
*/
return (PO_FAIL);
}
}
}
return (PO_FAIL);
return (PO_SUCCESS);
}
/*
* Destroy a comp. If the comp cannot be found or removed an error is
* returned. This is basically a wrapper around pool_elem_remove to ensure
* some type safety for the comp subtype.
*/
int
{
return (PO_FAIL);
return (PO_SUCCESS);
}
/*
* Remove a pool_elem_t from a configuration. This has been "hidden" away as
* a static routine since the only elements which are currently being removed
* are pools, res & comp and the wrapper functions above provide type-safe
* access. However, if there is a need to remove other types of elements
* then this could be promoted to pool_impl.h or more wrappers could
* be added to pool_impl.h.
*/
int
{
}
/*
* Execute a query to search for a qualifying set of elements.
*/
{
props));
}
/*
* Get the next result from a result set of elements.
*/
{
}
/*
* Get the previous result from a result set of elements.
*/
{
}
/*
* Get the first result from a result set of elements.
*/
{
}
/*
* Get the last result from a result set of elements.
*/
{
}
/*
* Get the count for a result set of elements.
*/
int
{
}
/*
* Get the index for a result set of elements.
*/
int
{
}
/*
* Set the index for a result set of elements.
*/
int
{
}
/*
* Close a result set of elements, freeing all associated resources.
*/
int
{
}
/*
* When transferring resource components using pool_resource_transfer,
* this function is invoked to choose which actual components will be
* transferred.
*/
int
{
int i;
if (size == 0)
return (PO_SUCCESS);
/*
* Get the component list from our src component.
*/
return (PO_FAIL);
}
/*
* Components that aren't specifically requested by the resource
* should be transferred out first.
*/
if (!cpu_is_requested(components[i])) {
moved[0] = components[i];
PO_SUCCESS) {
size--;
}
}
}
/*
* If we couldn't find enough "un-requested" components, select random
* requested components.
*/
if (cpu_is_requested(components[i])) {
moved[0] = components[i];
PO_SUCCESS) {
size--;
}
}
}
/*
* If we couldn't transfer out all the resources we asked for, then
* return error.
*/
}
/*
* Common processing for a resource transfer (xfer or xxfer).
*
* - Return XFER_CONTINUE if the transfer should proceeed
* - Return XFER_FAIL if the transfer should be stopped in failure
* - Return XFER_SUCCESS if the transfer should be stopped in success
*/
int
{
return (XFER_FAIL);
/*
* Makes sure the two resources are of the same type
*/
return (XFER_FAIL);
}
/*
* Transferring to yourself is a no-op
*/
return (XFER_SUCCESS);
/*
* Transferring nothing is a no-op
*/
if (size == 0)
return (XFER_SUCCESS);
return (XFER_FAIL);
}
/*
* src_size - donating >= src.min
* size + receiving <= tgt.max (except for default)
*/
#ifdef DEBUG
#endif /* DEBUG */
return (XFER_FAIL);
}
}
return (XFER_CONTINUE);
}
/*
* Transfer resource quantities from one resource set to another.
*/
int
{
int ret;
!= XFER_CONTINUE)
return (ret);
/*
* If this resource is a res_comp we must call move components
*/
/*
* Now do the transfer.
*/
/*
* Modify the sizes of the resource sets if the process was
* successful
*/
if (ret == PO_SUCCESS) {
&val);
&val);
}
return (ret);
}
/*
* Transfer resource components from one resource set to another.
*/
int
{
int i;
int ret;
/*
* Make sure the components are all contained in 'src'. This
* processing must be done before setup_transfer so that size
* is known.
*/
#ifdef DEBUG
dprintf("resource xtransfer\n");
dprintf("transferring component\n");
dprintf("from\n");
dprintf("to\n");
#endif /* DEBUG */
return (PO_FAIL);
}
}
!= XFER_CONTINUE)
return (ret);
/*
* Modify the sizes of the resource sets if the process was
* successful
*/
if (ret == PO_SUCCESS) {
#ifdef DEBUG
#endif /* DEBUG */
&val);
&val);
}
return (ret);
}
/*
* Find the owning resource for a resource component.
*/
{
return (NULL);
}
}
/*
* pool_get_container() returns the container of pc.
*/
{
}
/*
* pool_set_container() moves pc so that it is contained by pp.
*
* Returns PO_SUCCESS/PO_FAIL
*/
int
{
}
/*
* Conversion routines for converting to and from elem and it's various
* subtypes of system, pool, res and comp.
*/
{
return ((pool_elem_t *)ph);
}
{
return (NULL);
}
return (NULL);
}
return (pool_system_elem(sys));
}
{
return (NULL);
}
return ((pool_elem_t *)pp);
}
{
return (NULL);
}
return ((pool_elem_t *)prs);
}
{
return (NULL);
}
return ((pool_elem_t *)pr);
}
/*
* Walk all the pools of the configuration calling the user supplied function
* as long as the user function continues to return PO_TRUE
*/
int
{
int i;
return (PO_FAIL);
}
return (PO_SUCCESS);
for (i = 0; i < size; i++)
break;
}
return (error);
}
/*
* Walk all the comp of the res calling the user supplied function
* as long as the user function continues to return PO_TRUE
*/
int
{
int i;
return (PO_FAIL);
}
NULL)
return (PO_SUCCESS); /* None */
for (i = 0; i < size; i++)
break;
}
return (error);
}
/*
* Return an array of all matching res for the supplied pool.
*/
{
int i = 0;
return (NULL);
}
return (NULL);
}
(void) pool_rs_close(rs);
return (NULL);
}
== NULL) {
(void) pool_rs_close(rs);
return (NULL);
}
(void) pool_rs_close(rs);
return (NULL);
}
}
(void) pool_rs_close(rs);
return (result);
}
/*
* Walk all the res of the pool calling the user supplied function
* as long as the user function continues to return PO_TRUE
*/
int
{
int i;
return (PO_FAIL);
}
return (PO_SUCCESS); /* None */
for (i = 0; i < size; i++)
break;
}
return (error);
}
/*
* Return a result set of all comp for the supplied res.
*/
{
int i = 0;
return (NULL);
}
return (NULL);
}
(void) pool_rs_close(rs);
return (NULL);
}
== NULL) {
(void) pool_rs_close(rs);
return (NULL);
}
(void) pool_rs_close(rs);
return (NULL);
}
}
(void) pool_rs_close(rs);
return (result);
}
/*
* pool_version() returns the version of this library, depending on the supplied
* parameter.
*
* Returns: library version depening on the supplied ver parameter.
*/
{
switch (ver) {
case POOL_VER_NONE:
break;
case POOL_VER_CURRENT:
pool_workver = ver;
break;
default:
return (POOL_VER_NONE);
}
return (pool_workver);
}
/*
* pool_associate() associates the supplied resource to the supplied pool.
*
* Returns: PO_SUCCESS/PO_FAIL
*/
int
{
return (PO_FAIL);
}
/*
* pool_dissociate() dissociates the supplied resource from the supplied pool.
*
* Returns: PO_SUCCESS/PO_FAIL
*/
int
{
return (PO_FAIL);
return (PO_SUCCESS);
}
/*
* Compare two elements for purposes of ordering.
* Return:
* < 0 if e1 is "before" e2
* 0 if e1 "equals" e2
* > 0 if e1 comes after e2
*/
int
{
int retval;
/*
* We may be asked to compare two elements from different classes.
* They are different so return (1).
*/
return (1);
/*
* If the class is PEC_SYSTEM, always match them
*/
return (0);
/*
* If we are going to compare components, then use sys_id
*/
return (-1);
}
return (-1);
}
} else {
return (-1);
}
return (-1);
}
return (-1);
}
}
return (retval);
}
/*
* Compare two elements for purposes of ordering.
* Return:
* < 0 if e1 is "before" e2
* 0 if e1 "equals" e2
* > 0 if e1 comes after e2
*/
int
{
/*
* We may be asked to compare two elements from different classes.
* They are different so return the difference in their classes
*/
return (1);
/*
* If the class is PEC_SYSTEM, always match them
*/
return (0);
/*
* Compare with sys_id
*/
assert(!"no sys_id on e1\n");
}
assert(!"no sys_id on e2\n");
}
}
/*
* Return PO_TRUE if the supplied elems are of the same class.
*/
int
{
return (PO_FALSE);
/*
* Check to make sure the fundamental class of the elements match
*/
if (pool_resource_elem_class(e1) !=
return (PO_FALSE);
if (pool_component_elem_class(e1) !=
return (PO_FALSE);
return (PO_TRUE);
}
/*
* pool_conf_check() checks that the configuration state isn't invalid
* and that the configuration was opened for modification.
*/
int
{
return (PO_FAIL);
}
return (PO_FAIL);
}
return (PO_SUCCESS);
}