/*
* 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 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "mhd_local.h"
/*
* manipulate set list
*/
/*
* global set list
*/
/*
* add drive to set
*/
void
)
{
/* check locks */
/* add to set */
/* adjust backlink */
}
/*
* delete drive from set
*/
void
)
{
/* check locks */
/* delete from set */
/* adjust backlink */
}
/*
* find set in list
*/
static mhd_drive_set_t *
char *setname
)
{
uint_t i;
/* check lock */
/* look for set */
for (i = 0; (i < mhd_nset); ++i) {
return (sp);
}
/* not found */
return (NULL);
}
/*
* wait for operation to complete
*/
static void
)
{
/* check lock */
/* wait for complete */
for (;;) {
uint_t i;
/* kick threads */
/* IDLE or ERRORED */
if (state == DRIVE_IDLE) {
if (DRIVE_IS_IDLE(dp))
continue;
}
/* operation complete */
else {
continue;
}
/* kick thread */
++cnt;
}
/* if complete, quit */
if (cnt == 0)
break;
/* wait for something to happen */
}
}
/*
* idle set
*/
static int
)
{
uint_t i;
/* check lock */
/* disarm any failfast */
return (-1);
}
/* set IDLING */
if (! DRIVE_IS_IDLE(dp)) {
return (-1);
}
}
/* wait for IDLE */
/* return success */
return (0);
}
/*
* create or update new set
*/
)
{
char *setname;
uint_t i;
/* check locks */
/* get setname */
setname = "";
else
/* find or create set */
/* allocate and initialize set */
/* append to set list */
++mhd_nset;
}
/* if just grabbing null set, return */
return (sp);
/* get null set */
/* grab set lock */
/* save options */
if (options & MHD_SERIAL)
else
/* move drives no longer in set to null set */
if (! (options & MHD_PARTIAL_SET)) {
uint_t j;
/* check still there */
break;
}
++i;
continue;
}
/* idle the drive */
/* move to null set */
}
}
/* add new drives to lists */
uint_t j;
/* check already there */
break;
}
continue;
}
/* add drive to set */
continue;
}
}
/* debug */
#ifdef MHD_DEBUG
if (mhd_debug > 0) {
for (i = 0; (i < mhd_nset); ++i) {
uint_t j;
char *p;
++p;
else
}
}
}
#endif /* MHD_DEBUG */
/* unlock, return set */
return (sp);
}
/*
* find drive
*/
char *rname
)
{
uint_t i;
/* check locks */
/* for each set */
for (i = 0; (i < mhd_nset); ++i) {
uint_t j;
/* for each drive */
return (dp);
}
}
/* not found */
return (NULL);
}
/*
* list all the drives
*/
int
char *path,
)
{
/* grab lock */
/* add path to list */
return (-1);
}
/* get what we want */
state = 0;
if (flags & MHD_DID_SERIAL)
state |= DRIVE_SERIALING;
if (flags & MHD_DID_TIME)
state |= DRIVE_VTOCING;
if (flags & MHD_DID_CINFO)
state |= DRIVE_CINFOING;
/* ident and count drives */
/* count drives */
/* ident drives */
if (state != 0) {
return (-1);
}
}
}
}
/* build list */
for (c = 0, i = 0; (i < mhd_nset); ++i) {
}
}
/* unlock, return count */
return (ndrive);
}
/*
* release drives
*/
static int
)
{
uint_t i;
/* check locks */
/* idle set */
return (-1);
/* release drives */
return (-1);
}
/* return success */
return (0);
}
/*
* release drives in set
*/
int
)
{
int rval;
/* grab global lock */
/* create or update set */
mhd_free_list(&dl);
return (-1);
}
/* lock set */
/* release drives */
/* unlock, return success */
out:
mhd_free_list(&dl);
return (rval);
}
/*
* reserve drives
*/
static int
)
{
int rval = 0;
/* check locks */
/* idle set, idle everyone if cancelling failfast */
if (ff == 0) {
return (-1);
} else {
return (-1);
}
/*
* Try to take ownership of the drives twice. This helps
* to avoid the situation where the other machine retakes
* ownership of a majority drives back, but then kills itself
* leaving no owners.
*/
if ((retry == 0) ||
return (-1);
}
}
}
/*
* Did the take ownership succeed on a majority of the drives?
*/
ok = 0;
++ok;
}
/*
* Let the replica majority be the deciding factor, if able to get
* at least a single drive reserved.
*/
if (ok == 0) {
goto out;
}
/*
* Enable the failfast probes if we haven't given up yet.
*/
switch (sp->sr_ff_mode) {
/* do nothing */
default:
assert(0);
/* FALLTHROUGH */
case MHD_FF_NONE:
goto out;
/* old style per drive failfast */
case MHD_FF_DRIVER:
mhep) != 0) {
rval = -1;
goto out;
}
}
}
break;
/* failfast probe threads */
case MHD_FF_DEBUG:
case MHD_FF_HALT:
case MHD_FF_PANIC:
if (ff != 0) {
rval = -1;
goto out;
}
mhep) != 0) {
rval = -1;
goto out;
}
}
}
break;
}
/* cleanup, return success */
out:
if (rval != 0) {
}
return (rval);
}
/*
* reserve drives in set
*/
int
)
{
int rval;
/* grab global lock */
/* create or update set */
mhd_free_list(&dl);
return (-1);
}
/* lock set */
/* can't change mode or timeouts of partial set */
(options & MHD_PARTIAL_SET)) {
mhd_eprintf("%s: invalid ff_mode %d now %d\n",
}
mhd_eprintf("%s: invalid mh_ff %d now %d\n",
}
}
/* save timouts and mode */
/* reserve drives */
/* unlock, return success */
out:
mhd_free_list(&dl);
return (rval);
}
/*
* status drives
*/
static int
)
{
uint_t i;
/* check locks */
/* status drives */
return (-1);
}
/* return success */
return (0);
}
/*
* status drives in set
*/
int
)
{
uint_t i;
int rval = 0;
/* grab global lock */
/* create or update set */
mhd_free_list(&dl);
return (-1);
}
/* lock set */
/* status drives */
rval = -1;
goto out;
}
/* build list */
}
/* unlock, return count */
out:
mhd_free_list(&dl);
return (rval);
}