/*
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Metadevice database utility.
*/
#include <meta.h>
#define MDDB
#include <sdssc.h>
static void
char *string
)
{
"usage: %s [-s setname] -a [options] mddbnnn\n"
" %s [-s setname] -a [options] device ...\n"
" %s [-s setname] -d [options] mddbnnn\n"
" %s [-s setname] -d [options] device ...\n"
" %s [-s setname] -i \n"
" %s -p [options] [ mddb.cf-file ]\n"
"options:\n"
"-c count number of replicas (for use with -a only)\n"
"-f force adding or deleting of replicas\n"
"-l length specify size of replica (for use with -a only)\n"),
}
static mdname_t *
mdnamelist_t **nlp,
char *name,
)
{
return (NULL);
}
static mdnamelist_t *
mdnamelist_t **nlp,
char *tabname,
int *dbsize,
int *dbcnt,
int *default_size,
)
{
int argc;
char **argv;
char *context;
int c;
/* look in md.tab */
mdclrerror(ep);
return (NULL);
}
goto out;
}
/* parse up entry */
optind = 1;
opterr = 1;
switch (c) {
case 'c':
md_eprintf("%s: %s\n",
}
break;
case 'l':
md_eprintf("%s: %s\n",
}
*default_size = FALSE;
break;
default:
}
}
goto out;
}
}
/* cleanup, return list */
out:
return (*nlp);
}
/*
* built list of all devices which are to be detached
*/
static mdnamelist_t *
int argc,
char **argv,
)
{
int i;
for (i = 0; i < argc; i++) {
/* don't freelist here - already been done */
return (NULL);
}
continue;
}
return (NULL);
}
}
return (dbnlp);
}
/*
* built the next list of devices which are to be attached
* that have the same size and count of replicas.
*/
static mdnamelist_t *
int argc,
char **argv,
int *arg_index,
int *dbsize,
int *dbcnt,
int *default_size,
)
{
int i;
/*
* If we have stuff in the namelist
* return it before processing the mddb entry.
*/
if (dbnlp) {
*arg_index = i;
return (dbnlp);
}
/* don't freelist here - already been done */
return (NULL);
}
*arg_index = i + 1;
return (dbnlp);
}
return (NULL);
}
}
return (dbnlp);
}
static int
int argc,
char *argv[],
)
{
int c;
int i;
int rval = 0;
int suspend1_flag = 0;
/* reset and parse args */
optind = 1;
opterr = 1;
switch (c) {
case 'a':
break;
case 'c':
md_eprintf("%s: %s\n",
}
break;
case 'd':
break;
case 'f':
break;
case 'k':
break;
case 'l':
md_eprintf("%s: %s\n",
}
break;
case 'p':
break;
case 's':
break;
default:
}
}
/*
* If it is a multinode diskset, use appropriate metadb size.
*/
if (! metaislocalset(sp)) {
return (-1);
if (MD_MNSET_DESC(sd)) {
if (default_size)
}
}
if (dbcnt < 1)
"count (-c) must be 1 or more"));
if (argc <= 0) {
"no devices specified to attach or detach"));
}
if (! metaislocalset(sp)) {
if (MD_MNSET_DESC(sd)) {
/* Make sure we are blocking all signals */
mdclrerror(&xep);
/*
* Lock out other metaset or metadb commands
* across the diskset.
*/
while (nd) {
if ((force & MDFORCE_LOCAL) &&
continue;
}
continue;
}
rval = -1;
goto done;
}
}
/*
* Lock out other meta* commands by suspending
* class 1 messages across the diskset.
*/
while (nd) {
continue;
}
MD_MSCF_NO_FLAGS, ep)) {
rval = -1;
goto done;
}
suspend1_flag = 1;
}
} else {
/* Lock the set on current set members */
for (i = 0; i < MD_MAXSIDES; i++) {
/* Skip empty slots */
continue;
if ((force & MDFORCE_LOCAL) &&
continue;
rval = -1;
goto done;
}
}
}
}
rval = -1;
goto done;
}
}
int arg_index = 0;
if (force & MDFORCE_LOCAL)
if (default_size)
mdclrerror(ep);
/*
* Loop through build a new namelist
* for each "mddb" entry or the devices list
* on the command line. This allows each "mddb"
* entry to have unique dbsize and dbcnt.
*/
rval = -1;
goto done;
}
/*
* If using the default size,
* then let's adjust the default to the minimum
* size currently in use.
*/
if (default_size && (nblks > 0))
if (rval) {
break;
}
dbcnt = saved_dbcnt;
}
}
done:
if (! metaislocalset(sp)) {
if (MD_MNSET_DESC(sd)) {
/*
* Unlock diskset by resuming
* class 1 messages across the diskset.
*/
if (suspend1_flag) {
while (nd) {
MD_MN_NODE_ALIVE)) {
continue;
}
MD_MSCF_NO_FLAGS, &xep)) {
mdclrerror(&xep);
}
}
}
while (nd) {
if ((force & MDFORCE_LOCAL) &&
continue;
}
continue;
}
&xep))
mdclrerror(&xep);
}
} else {
for (i = 0; i < MD_MAXSIDES; i++) {
/* Skip empty slots */
continue;
if ((force & MDFORCE_LOCAL) &&
continue;
&xep))
mdclrerror(&xep);
}
}
}
return (rval);
}
static int
info(
int print_headers,
int print_footers,
)
{
md_replica_t *r;
int i;
/* get list of replicas, quit if none */
return (-1);
return (0);
if (print_headers) {
}
for (i = 0; i < MDDB_FLAGS_LEN; i++) {
if (r->r_flags & (1 << i))
(void) putchar(MDDB_FLAGS_STRING[i]);
else
(void) putchar(' ');
}
} else if (r->r_nblk == -1) {
} else {
}
}
return (0);
if (!print_footers)
return (0);
" r - replica does not have device relocation information\n"
" o - replica active prior to last mddb configuration change\n"
" u - replica is up to date\n"
" l - locator for this replica was read successfully\n"
" c - replica's location was in %s\n"
" p - replica's location was patched in kernel\n"
" m - replica is master, this is replica selected as input\n"
" t - tagged data is associated with the replica\n"
" W - replica has device write errors\n"
" a - replica is active, commits are occurring to this replica\n"
" M - replica had problem with master blocks\n"
" D - replica had problem with data blocks\n"
" F - replica had format problems\n"
" S - replica is too small to hold current data base\n"
" R - replica had device read errors\n"
" B - tagged data associated with the replica is not valid\n"),
return (0);
}
int
{
int c;
int error;
int multi_node = 0;
/*
* Get the locale set up before calling any other routines
* with messages to ouput. Just in case we're not in a build
* environment, make sure that TEXT_DOMAIN gets set to
* something.
*/
#if !defined(TEXT_DOMAIN)
#endif
(void) textdomain(TEXT_DOMAIN);
if (sdssc_bind_library() == SDSSC_OKAY)
&error) == SDSSC_PROXY_DONE)
/* parse args */
optind = 1;
opterr = 1;
/* initialize */
}
/* parse args */
optind = 1;
opterr = 1;
switch (c) {
case 'a':
break;
case 'c':
break;
case 'd':
break;
case 'f':
break;
case 'h':
break;
case 'i':
break;
case 'k':
break;
case 'l':
break;
case 'p':
break;
case 's':
break;
case '?':
if (optopt == '?')
/*FALLTHROUGH*/
default:
}
}
/* get set context */
}
/* print status */
"too many arguments"));
}
}
}
if (meta_check_root(ep) != 0) {
}
if (! metaislocalset(sp)) {
}
if (MD_MNSET_DESC(sd)) {
multi_node = 1;
}
}
/*
* Adjust lock for traditional and local diskset.
*
* A MN diskset does not use the set meta_lock but instead
* feature of the rpc.mdcommd. Can't use set meta_lock since
* class 1 messages are grabbing this lock and if this thread
* is holding the set meta_lock then no rpc.mdcommd suspend
* can occur.
*/
}
/* check for ownership */
}
/* snarf MDDB locations */
if (meta_setup_db_locations(ep) != 0) {
}
}
mdclrerror(ep);
}
}
/* patch MDDB locations */
"too many arguments to -p"));
}
if (metaislocalset(sp)) {
}
}
}
}
}
/*NOTREACHED*/
return (0);
}