/*
* 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.
*/
/*
* Gathers properties exported by libtopo and uses them to construct diskmon
* data structures, which hold the configuration information for the
* DE.
*/
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <pthread.h>
#include <libnvpair.h>
#include <config_admin.h>
#include "disk.h"
#include "disk_monitor.h"
#include "hotplug_mgr.h"
#include "topo_gather.h"
/*
* The following function template is required for nvlists that were
* create with no flags (so there can be multiple identical name or name-value
* pairs). The function defined below returns the first match for the name
* provided.
*/
static int \
{ \
continue; \
} \
return (ENOENT); \
}
static diskmon_t *
{
char ch;
*lastsl = 0;
}
return (p);
}
{
char *buf;
int err;
return (NULL);
return (NULL);
}
return (diskp);
}
static nvlist_t *
{
int err;
char *pgroup_name;
/*
* topo_prop_get_all() returns an nvlist that contains other
* nvlists (some of which are property groups). Since the private
* property group we need will be among the list of property
* groups returned (hopefully), we need to walk the list of nvlists
* in the topo node's properties to find the property groups, then
* check inside each embedded nvlist to see if it's the pgroup we're
* looking for.
*/
/*
* Go through the list of nvlists, looking for the
* property group we need.
*/
continue;
pgroup_name = NULL;
TOPO_PROP_GROUP_NAME, &pgroup_name) != 0 ||
continue;
else {
/*
* Duplicate the nvlist so that when the
* master nvlist is freed (below), we will
* still refer to allocated memory.
*/
else
break;
}
}
}
return (disk_monitor_pgrp);
}
/*
* Look up the FMRI corresponding to the node in the global
* hash table and return the pointer stored (if any). Save the
* FMRI string in *str if str is non-NULL.
*/
static void *
{
void *p = NULL;
return (NULL);
return (NULL);
}
}
return (p);
}
typedef struct walk_diskmon {
char *pfmri;
static int
{
char *label;
int err;
return (0);
}
/* Skip this disk: */
return (0);
}
/* If we were called upon to update a particular disk, do it */
return (0);
}
/*
* Update the diskmon's location field with the disk's label
*/
} else
/*
* Check for a device path property (if the disk is configured,
* it will be present) and add it to the diskmon's properties)
*/
/*
* Consumers of the DISK_PROP_DEVPATH property expect a raw
* minor device node
*/
devp);
}
/*
* Add the logical disk node, if it exists
*/
devpath);
}
/*
* Add the FRU information (if present in the node) to the diskmon's
* fru data structure:
*/
if (model)
if (manuf)
if (serial)
if (firmrev)
if (capacity)
/* Add the fru information to the diskmon: */
return (0);
}
static int
{
return (-1);
}
return (0);
}
static int
{
/* The Indicator name is of the form: "[+-][A-Za-z][A-Za-z0-9]+" */
char *name;
return (-1);
return (0);
}
static hotplug_state_t
{
return (HPS_CONFIGURED);
return (HPS_UNCONFIGURED);
return (HPS_ABSENT);
return (HPS_PRESENT);
} else
return (HPS_UNKNOWN);
}
static int
{
/* The state string is of the form "{STATE}>{STATE}" */
*p = 0;
*p = '>';
!= E_NO_ERROR) {
}
/* Actions are of the form "{ACTION}[&{ACTION}]" */
/* At least 2 tokens */
do {
break;
}
} else if (!failed) {
/* One token */
return (-1);
}
}
if (failed) {
return (-1);
} else
return (0);
}
static int
{
int err = 0, i;
char *label;
void *p;
void *ptr;
/* No private properties -- just ignore the port */
return (0);
/*
* Look for a diskmon based on this node's FMRI string.
* Once a diskmon has been created, it's not re-created. This is
* essential for the times when the tree-walk is called after a
* disk is inserted (or removed) -- in that case, the disk node
* handler simply updates the FRU information in the diskmon.
*/
/*
* Delete the FRU information from the diskmon. If a disk
* is connected, its FRU information will be refreshed by
* the disk node code.
*/
diskp == target_diskp)) {
}
return (0);
}
/*
* Determine the physical path to the attachment point
*/
} else {
/* unadj_physid cannot have been allocated */
if (cstr)
return (-1);
}
/*
*/
/*
* Process the properties. If we encounter a property that
* is not an indicator name, action, or rule, add it to the
* disk's props list.
*/
/* Process indicators */
i = 0;
do {
indicator_action) != 0) {
}
}
break;
break;
i++;
indicator_action != NULL);
}
/* Process state rules and indicator actions */
i = 0;
do {
indrule_actions) != 0) {
}
}
break;
i);
break;
i++;
indrule_actions != NULL);
!= E_NO_ERROR ||
}
/*
* Now collect miscellaneous properties.
* Each property is stored as an embedded nvlist named
* TOPO_PROP_VAL. The property name is stored in the value for
* key=TOPO_PROP_VAL_NAME and the property's value is
* stored in the value for key=TOPO_PROP_VAL_VAL. This is all
* necessary so we can subtractively decode the properties that
* we do not directly handle (so that these properties are added to
* the per-disk properties nvlist), increasing flexibility.
*/
/* Only care about embedded nvlists named TOPO_PROP_VAL */
continue;
TOPO_PROP_VAL_NAME, &prop_name) != 0)
continue;
/* Filter out indicator properties */
continue;
&prop_value) != 0)
continue;
/* Add the property to the disk's prop list: */
"Could not add disk property `%s' with "
}
/*
* Set the diskmon's location to the value in this port's label.
* If there's a disk plugged in, the location will be updated
* to be the disk label (e.g. HD_ID_00). Until a disk is
* inserted, though, there won't be a disk libtopo node
* created.
*/
/* Pass physid without the leading "/devices": */
} else
/* Add this diskmon to the disk list */
"Could not add pointer to nvlist "
"for `%s'!\n", cstr);
}
} else {
if (indp)
if (indrp)
}
}
return (0);
}
/*ARGSUSED*/
static int
{
? TOPO_WALK_ERR : TOPO_WALK_NEXT);
? TOPO_WALK_ERR : TOPO_WALK_NEXT);
return (TOPO_WALK_NEXT);
}
/*ARGSUSED*/
int
{
int err;
return (TOPO_OPEN_ERROR);
}
}
return (TOPO_WALK_ERROR);
}
return (TOPO_SUCCESS);
}
int
{
}
void
{
if (g_topo2diskmon) {
}
}