xref: /titanic_41/usr/src/cmd/lvm/util/metadb.c (revision 2fb876ae0cefcbd01f8d8490242aa4501caddbc3)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5d7cd8252Stw21770  * Common Development and Distribution License (the "License").
6d7cd8252Stw21770  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22d7cd8252Stw21770  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * Metadevice database utility.
307c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <meta.h>
337c478bd9Sstevel@tonic-gate #define	MDDB
347c478bd9Sstevel@tonic-gate #include <sys/lvm/md_mddb.h>
357c478bd9Sstevel@tonic-gate #include <sdssc.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate enum mddb_cmd {none, attach, detach, patch, infolong, infoshort};
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate extern int	procsigs(int block, sigset_t *oldsigs, md_error_t *ep);
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate static void
usage(mdsetname_t * sp,char * string)427c478bd9Sstevel@tonic-gate usage(
437c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
447c478bd9Sstevel@tonic-gate 	char		*string
457c478bd9Sstevel@tonic-gate )
467c478bd9Sstevel@tonic-gate {
477c478bd9Sstevel@tonic-gate 	if ((string != NULL) && (*string != '\0'))
487c478bd9Sstevel@tonic-gate 		md_eprintf("%s\n", string);
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
517c478bd9Sstevel@tonic-gate "usage:  %s [-s setname] -a [options] mddbnnn\n"
527c478bd9Sstevel@tonic-gate "	%s [-s setname] -a [options] device ...\n"
537c478bd9Sstevel@tonic-gate "	%s [-s setname] -d [options] mddbnnn\n"
547c478bd9Sstevel@tonic-gate "	%s [-s setname] -d [options] device ...\n"
557c478bd9Sstevel@tonic-gate "	%s [-s setname] -i \n"
567c478bd9Sstevel@tonic-gate "	%s -p [options] [ mddb.cf-file ]\n"
577c478bd9Sstevel@tonic-gate "options:\n"
587c478bd9Sstevel@tonic-gate "-c count	number of replicas (for use with -a only)\n"
597c478bd9Sstevel@tonic-gate "-f		force adding or deleting of replicas\n"
607c478bd9Sstevel@tonic-gate "-k filename	alternate /etc/system file\n"
617c478bd9Sstevel@tonic-gate "-l length	specify size of replica (for use with -a only)\n"),
627c478bd9Sstevel@tonic-gate 	    myname, myname, myname, myname, myname, myname);
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate 	md_exit(sp, (string == NULL) ? 0 : 1);
657c478bd9Sstevel@tonic-gate }
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate static mdname_t *
make_dbname(mdsetname_t * sp,mdnamelist_t ** nlp,char * name,md_error_t * ep)687c478bd9Sstevel@tonic-gate make_dbname(
697c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
707c478bd9Sstevel@tonic-gate 	mdnamelist_t	**nlp,
717c478bd9Sstevel@tonic-gate 	char		*name,
727c478bd9Sstevel@tonic-gate 	md_error_t	*ep
737c478bd9Sstevel@tonic-gate )
747c478bd9Sstevel@tonic-gate {
757c478bd9Sstevel@tonic-gate 	mdname_t	*np;
767c478bd9Sstevel@tonic-gate 
77d7cd8252Stw21770 	if ((np = metaname(&sp, name, LOGICAL_DEVICE, ep)) == NULL)
787c478bd9Sstevel@tonic-gate 		return (NULL);
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate 	return (metanamelist_append(nlp, np));
817c478bd9Sstevel@tonic-gate }
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate static mdnamelist_t *
get_dbnames_fromfile(mdsetname_t * sp,mdnamelist_t ** nlp,char * tabname,int * dbsize,int * dbcnt,int * default_size,md_error_t * ep)847c478bd9Sstevel@tonic-gate get_dbnames_fromfile(
857c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
867c478bd9Sstevel@tonic-gate 	mdnamelist_t	**nlp,
877c478bd9Sstevel@tonic-gate 	char		*tabname,
887c478bd9Sstevel@tonic-gate 	int		*dbsize,
897c478bd9Sstevel@tonic-gate 	int		*dbcnt,
907c478bd9Sstevel@tonic-gate 	int		*default_size,
917c478bd9Sstevel@tonic-gate 	md_error_t	*ep
927c478bd9Sstevel@tonic-gate )
937c478bd9Sstevel@tonic-gate {
947c478bd9Sstevel@tonic-gate 	md_tab_t	*tabp = NULL;
957c478bd9Sstevel@tonic-gate 	md_tab_line_t	*linep = NULL;
967c478bd9Sstevel@tonic-gate 	int		argc;
977c478bd9Sstevel@tonic-gate 	char		**argv;
987c478bd9Sstevel@tonic-gate 	char		*context;
997c478bd9Sstevel@tonic-gate 	int		save = optind;
1007c478bd9Sstevel@tonic-gate 	int		c;
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate 	/* look in md.tab */
1037c478bd9Sstevel@tonic-gate 	if ((tabp = meta_tab_parse(NULL, ep)) == NULL) {
1047c478bd9Sstevel@tonic-gate 		if (! mdissyserror(ep, ENOENT))
1057c478bd9Sstevel@tonic-gate 			mde_perror(ep, "");
1067c478bd9Sstevel@tonic-gate 		mdclrerror(ep);
1077c478bd9Sstevel@tonic-gate 		return (NULL);
1087c478bd9Sstevel@tonic-gate 	}
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	if ((linep = meta_tab_find(sp, tabp, tabname, TAB_MDDB)) == NULL) {
1117c478bd9Sstevel@tonic-gate 		(void) mdsyserror(ep, ENOENT, tabname);
1127c478bd9Sstevel@tonic-gate 		goto out;
1137c478bd9Sstevel@tonic-gate 	}
1147c478bd9Sstevel@tonic-gate 	argc = linep->argc;
1157c478bd9Sstevel@tonic-gate 	argv = linep->argv;
1167c478bd9Sstevel@tonic-gate 	context = linep->context;
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 	/* parse up entry */
1197c478bd9Sstevel@tonic-gate 	optind = 1;
1207c478bd9Sstevel@tonic-gate 	opterr = 1;
1217c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "c:l:")) != -1) {
1227c478bd9Sstevel@tonic-gate 		switch (c) {
1237c478bd9Sstevel@tonic-gate 		case 'c':
1247c478bd9Sstevel@tonic-gate 			if (sscanf(optarg, "%d", dbcnt) != 1) {
1257c478bd9Sstevel@tonic-gate 				md_eprintf("%s: %s\n",
1267c478bd9Sstevel@tonic-gate 				    context, gettext("bad format"));
1277c478bd9Sstevel@tonic-gate 				usage(sp, "");
1287c478bd9Sstevel@tonic-gate 			}
1297c478bd9Sstevel@tonic-gate 			break;
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 		case 'l':
1327c478bd9Sstevel@tonic-gate 			if (sscanf(optarg, "%d", dbsize) != 1) {
1337c478bd9Sstevel@tonic-gate 				md_eprintf("%s: %s\n",
1347c478bd9Sstevel@tonic-gate 				    context, gettext("bad format"));
1357c478bd9Sstevel@tonic-gate 				usage(sp, "");
1367c478bd9Sstevel@tonic-gate 			}
1377c478bd9Sstevel@tonic-gate 			*default_size = FALSE;
1387c478bd9Sstevel@tonic-gate 			break;
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate 		default:
1417c478bd9Sstevel@tonic-gate 			usage(sp, "");
1427c478bd9Sstevel@tonic-gate 		}
1437c478bd9Sstevel@tonic-gate 	}
1447c478bd9Sstevel@tonic-gate 	argc -= optind;
1457c478bd9Sstevel@tonic-gate 	argv += optind;
1467c478bd9Sstevel@tonic-gate 	for (; (argc > 0); --argc, ++argv) {
1477c478bd9Sstevel@tonic-gate 		char	*token = argv[0];
1487c478bd9Sstevel@tonic-gate 
1497c478bd9Sstevel@tonic-gate 		if (make_dbname(sp, nlp, token, ep) == NULL) {
1507c478bd9Sstevel@tonic-gate 			metafreenamelist(*nlp);
1517c478bd9Sstevel@tonic-gate 			*nlp = NULL;
1527c478bd9Sstevel@tonic-gate 			goto out;
1537c478bd9Sstevel@tonic-gate 		}
1547c478bd9Sstevel@tonic-gate 	}
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 	/* cleanup, return list */
1577c478bd9Sstevel@tonic-gate out:
1587c478bd9Sstevel@tonic-gate 	if (tabp != NULL)
1597c478bd9Sstevel@tonic-gate 		meta_tab_free(tabp);
1607c478bd9Sstevel@tonic-gate 	optind = save;
1617c478bd9Sstevel@tonic-gate 	return (*nlp);
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate /*
1657c478bd9Sstevel@tonic-gate  * built list of all devices which are to be detached
1667c478bd9Sstevel@tonic-gate  */
1677c478bd9Sstevel@tonic-gate static mdnamelist_t *
build_a_namelist(mdsetname_t * sp,int argc,char ** argv,md_error_t * ep)1687c478bd9Sstevel@tonic-gate build_a_namelist(
1697c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
1707c478bd9Sstevel@tonic-gate 	int		argc,
1717c478bd9Sstevel@tonic-gate 	char		**argv,
1727c478bd9Sstevel@tonic-gate 	md_error_t	*ep
1737c478bd9Sstevel@tonic-gate )
1747c478bd9Sstevel@tonic-gate {
1757c478bd9Sstevel@tonic-gate 	int		i;
1767c478bd9Sstevel@tonic-gate 	int		dbsize, dbcnt, default_size;
1777c478bd9Sstevel@tonic-gate 	mdnamelist_t	*dbnlp = NULL;
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	for (i = 0; i < argc; i++) {
1807c478bd9Sstevel@tonic-gate 		if (strncmp(argv[i], "mddb", 4) == 0) {
1817c478bd9Sstevel@tonic-gate 			if (get_dbnames_fromfile(sp, &dbnlp, argv[i],
1827c478bd9Sstevel@tonic-gate 			    &dbsize, &dbcnt, &default_size, ep) == NULL) {
1837c478bd9Sstevel@tonic-gate 				/* don't freelist here - already been done */
1847c478bd9Sstevel@tonic-gate 				return (NULL);
1857c478bd9Sstevel@tonic-gate 			}
1867c478bd9Sstevel@tonic-gate 			continue;
1877c478bd9Sstevel@tonic-gate 		}
1887c478bd9Sstevel@tonic-gate 		if (make_dbname(sp, &dbnlp, argv[i], ep) == NULL) {
1897c478bd9Sstevel@tonic-gate 			metafreenamelist(dbnlp);
1907c478bd9Sstevel@tonic-gate 			return (NULL);
1917c478bd9Sstevel@tonic-gate 		}
1927c478bd9Sstevel@tonic-gate 	}
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	return (dbnlp);
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate /*
1997c478bd9Sstevel@tonic-gate  * built the next list of devices which are to be attached
2007c478bd9Sstevel@tonic-gate  * that have the same size and count of replicas.
2017c478bd9Sstevel@tonic-gate  */
2027c478bd9Sstevel@tonic-gate static mdnamelist_t *
build_next_namelist(mdsetname_t * sp,int argc,char ** argv,int * arg_index,int * dbsize,int * dbcnt,int * default_size,md_error_t * ep)2037c478bd9Sstevel@tonic-gate build_next_namelist(
2047c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
2057c478bd9Sstevel@tonic-gate 	int		argc,
2067c478bd9Sstevel@tonic-gate 	char		**argv,
2077c478bd9Sstevel@tonic-gate 	int		*arg_index,
2087c478bd9Sstevel@tonic-gate 	int		*dbsize,
2097c478bd9Sstevel@tonic-gate 	int		*dbcnt,
2107c478bd9Sstevel@tonic-gate 	int		*default_size,
2117c478bd9Sstevel@tonic-gate 	md_error_t	*ep
2127c478bd9Sstevel@tonic-gate )
2137c478bd9Sstevel@tonic-gate {
2147c478bd9Sstevel@tonic-gate 	int		i;
2157c478bd9Sstevel@tonic-gate 	mdnamelist_t	*dbnlp = NULL;
2167c478bd9Sstevel@tonic-gate 
2177c478bd9Sstevel@tonic-gate 	for (i = *arg_index; i < argc; i++) {
2187c478bd9Sstevel@tonic-gate 		if (strncmp(argv[i], "mddb", 4) == 0) {
2197c478bd9Sstevel@tonic-gate 			/*
2207c478bd9Sstevel@tonic-gate 			 * If we have stuff in the namelist
2217c478bd9Sstevel@tonic-gate 			 * return it before processing the mddb entry.
2227c478bd9Sstevel@tonic-gate 			 */
2237c478bd9Sstevel@tonic-gate 			if (dbnlp) {
2247c478bd9Sstevel@tonic-gate 				*arg_index = i;
2257c478bd9Sstevel@tonic-gate 				return (dbnlp);
2267c478bd9Sstevel@tonic-gate 			}
2277c478bd9Sstevel@tonic-gate 			if (get_dbnames_fromfile(sp, &dbnlp, argv[i],
2287c478bd9Sstevel@tonic-gate 			    dbsize, dbcnt, default_size, ep) == NULL) {
2297c478bd9Sstevel@tonic-gate 				/* don't freelist here - already been done */
2307c478bd9Sstevel@tonic-gate 				return (NULL);
2317c478bd9Sstevel@tonic-gate 			}
2327c478bd9Sstevel@tonic-gate 			*arg_index = i + 1;
2337c478bd9Sstevel@tonic-gate 			return (dbnlp);
2347c478bd9Sstevel@tonic-gate 		}
2357c478bd9Sstevel@tonic-gate 		if (make_dbname(sp, &dbnlp, argv[i], ep) == NULL) {
2367c478bd9Sstevel@tonic-gate 			metafreenamelist(dbnlp);
2377c478bd9Sstevel@tonic-gate 			return (NULL);
2387c478bd9Sstevel@tonic-gate 		}
2397c478bd9Sstevel@tonic-gate 	}
2407c478bd9Sstevel@tonic-gate 	*arg_index = argc;
2417c478bd9Sstevel@tonic-gate 	return (dbnlp);
2427c478bd9Sstevel@tonic-gate }
2437c478bd9Sstevel@tonic-gate 
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate static int
chngdb(mdsetname_t * sp,enum mddb_cmd cmd,int argc,char * argv[],uint_t options,md_error_t * ep)2467c478bd9Sstevel@tonic-gate chngdb(
2477c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
2487c478bd9Sstevel@tonic-gate 	enum mddb_cmd	cmd,
2497c478bd9Sstevel@tonic-gate 	int		argc,
2507c478bd9Sstevel@tonic-gate 	char		*argv[],
2517c478bd9Sstevel@tonic-gate 	uint_t		options,
2527c478bd9Sstevel@tonic-gate 	md_error_t	*ep
2537c478bd9Sstevel@tonic-gate )
2547c478bd9Sstevel@tonic-gate {
2557c478bd9Sstevel@tonic-gate 	int		c;
2567c478bd9Sstevel@tonic-gate 	int		i;
2577c478bd9Sstevel@tonic-gate 	md_error_t	xep = mdnullerror;
2587c478bd9Sstevel@tonic-gate 	mdnamelist_t	*dbnlp = NULL;
2597c478bd9Sstevel@tonic-gate 	int		dbsize = MD_DBSIZE;
2607c478bd9Sstevel@tonic-gate 	int		maxblks = MDDB_MAXBLKS;
2617c478bd9Sstevel@tonic-gate 	int		minblks = MDDB_MINBLKS;
2627c478bd9Sstevel@tonic-gate 	int		dbcnt = 1;
2637c478bd9Sstevel@tonic-gate 	mdforceopts_t	force = MDFORCE_NONE;
2647c478bd9Sstevel@tonic-gate 	int		rval = 0;
2657c478bd9Sstevel@tonic-gate 	char		*sysfilename = NULL;
2667c478bd9Sstevel@tonic-gate 	int		default_size = TRUE;
2677c478bd9Sstevel@tonic-gate 	md_set_desc	*sd;
2687c478bd9Sstevel@tonic-gate 	md_setkey_t	*cl_sk;
2697c478bd9Sstevel@tonic-gate 	md_mnnode_desc	*nd;
2707c478bd9Sstevel@tonic-gate 	int		suspend1_flag = 0;
2717c478bd9Sstevel@tonic-gate 
2727c478bd9Sstevel@tonic-gate 	/* reset and parse args */
2737c478bd9Sstevel@tonic-gate 	optind = 1;
2747c478bd9Sstevel@tonic-gate 	opterr = 1;
2757c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "ac:dfk:pl:s:")) != -1) {
2767c478bd9Sstevel@tonic-gate 		switch (c) {
2777c478bd9Sstevel@tonic-gate 		case 'a':
2787c478bd9Sstevel@tonic-gate 			break;
2797c478bd9Sstevel@tonic-gate 		case 'c':
2807c478bd9Sstevel@tonic-gate 			if (sscanf(optarg, "%d", &dbcnt) != 1) {
2817c478bd9Sstevel@tonic-gate 				md_eprintf("%s: %s\n",
2827c478bd9Sstevel@tonic-gate 				    optarg, gettext("bad format"));
2837c478bd9Sstevel@tonic-gate 				usage(sp, "");
2847c478bd9Sstevel@tonic-gate 			}
2857c478bd9Sstevel@tonic-gate 			break;
2867c478bd9Sstevel@tonic-gate 		case 'd':
2877c478bd9Sstevel@tonic-gate 			break;
2887c478bd9Sstevel@tonic-gate 		case 'f':
2897c478bd9Sstevel@tonic-gate 			force = MDFORCE_LOCAL;
2907c478bd9Sstevel@tonic-gate 			break;
2917c478bd9Sstevel@tonic-gate 		case 'k':
2927c478bd9Sstevel@tonic-gate 			sysfilename = optarg;
2937c478bd9Sstevel@tonic-gate 			break;
2947c478bd9Sstevel@tonic-gate 		case 'l':
2957c478bd9Sstevel@tonic-gate 			if (sscanf(optarg, "%d", &dbsize) != 1) {
2967c478bd9Sstevel@tonic-gate 				md_eprintf("%s: %s\n",
2977c478bd9Sstevel@tonic-gate 				    optarg, gettext("bad format"));
2987c478bd9Sstevel@tonic-gate 				usage(sp, "");
2997c478bd9Sstevel@tonic-gate 			}
3007c478bd9Sstevel@tonic-gate 			default_size = FALSE;
3017c478bd9Sstevel@tonic-gate 			break;
3027c478bd9Sstevel@tonic-gate 		case 'p':
3037c478bd9Sstevel@tonic-gate 			break;
3047c478bd9Sstevel@tonic-gate 		case 's':
3057c478bd9Sstevel@tonic-gate 			break;
3067c478bd9Sstevel@tonic-gate 		default:
3077c478bd9Sstevel@tonic-gate 			usage(sp, "");
3087c478bd9Sstevel@tonic-gate 		}
3097c478bd9Sstevel@tonic-gate 	}
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate 	/*
3127c478bd9Sstevel@tonic-gate 	 * If it is a multinode diskset, use appropriate metadb size.
3137c478bd9Sstevel@tonic-gate 	 */
3147c478bd9Sstevel@tonic-gate 	if (! metaislocalset(sp)) {
3157c478bd9Sstevel@tonic-gate 		if ((sd = metaget_setdesc(sp, ep)) == NULL)
3167c478bd9Sstevel@tonic-gate 			return (-1);
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate 		if (MD_MNSET_DESC(sd)) {
3197c478bd9Sstevel@tonic-gate 			maxblks = MDDB_MN_MAXBLKS;
3207c478bd9Sstevel@tonic-gate 			minblks = MDDB_MN_MINBLKS;
3217c478bd9Sstevel@tonic-gate 			if (default_size)
3227c478bd9Sstevel@tonic-gate 				dbsize = MD_MN_DBSIZE;
3237c478bd9Sstevel@tonic-gate 		}
3247c478bd9Sstevel@tonic-gate 	}
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate 	if (dbsize > maxblks)
3277c478bd9Sstevel@tonic-gate 		usage(sp, gettext("size (-l) is too big"));
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 	if (dbsize < minblks)
3317c478bd9Sstevel@tonic-gate 		usage(sp, gettext("size (-l) is too small"));
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 	if (dbcnt < 1)
3347c478bd9Sstevel@tonic-gate 		usage(sp, gettext(
3357c478bd9Sstevel@tonic-gate 		    "count (-c) must be 1 or more"));
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate 	argc -= optind;
3397c478bd9Sstevel@tonic-gate 	argv += optind;
3407c478bd9Sstevel@tonic-gate 	if (argc <= 0) {
3417c478bd9Sstevel@tonic-gate 		usage(sp, gettext(
3427c478bd9Sstevel@tonic-gate 		    "no devices specified to attach or detach"));
3437c478bd9Sstevel@tonic-gate 	}
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 	if (! metaislocalset(sp)) {
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate 		if (MD_MNSET_DESC(sd)) {
3487c478bd9Sstevel@tonic-gate 			md_error_t xep = mdnullerror;
3497c478bd9Sstevel@tonic-gate 			sigset_t sigs;
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate 			/* Make sure we are blocking all signals */
3527c478bd9Sstevel@tonic-gate 			if (procsigs(TRUE, &sigs, &xep) < 0)
3537c478bd9Sstevel@tonic-gate 				mdclrerror(&xep);
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 			/*
3567c478bd9Sstevel@tonic-gate 			 * Lock out other metaset or metadb commands
3577c478bd9Sstevel@tonic-gate 			 * across the diskset.
3587c478bd9Sstevel@tonic-gate 			 */
3597c478bd9Sstevel@tonic-gate 			nd = sd->sd_nodelist;
3607c478bd9Sstevel@tonic-gate 			while (nd) {
3617c478bd9Sstevel@tonic-gate 				if ((force & MDFORCE_LOCAL) &&
3627c478bd9Sstevel@tonic-gate 				    strcmp(nd->nd_nodename, mynode()) != 0) {
3637c478bd9Sstevel@tonic-gate 					nd = nd->nd_next;
3647c478bd9Sstevel@tonic-gate 					continue;
3657c478bd9Sstevel@tonic-gate 				}
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 				if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
3687c478bd9Sstevel@tonic-gate 					nd = nd->nd_next;
3697c478bd9Sstevel@tonic-gate 					continue;
3707c478bd9Sstevel@tonic-gate 				}
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 				if (clnt_lock_set(nd->nd_nodename, sp, ep)) {
3737c478bd9Sstevel@tonic-gate 					rval = -1;
3747c478bd9Sstevel@tonic-gate 					goto done;
3757c478bd9Sstevel@tonic-gate 				}
3767c478bd9Sstevel@tonic-gate 				nd = nd->nd_next;
3777c478bd9Sstevel@tonic-gate 			}
3787c478bd9Sstevel@tonic-gate 			/*
3797c478bd9Sstevel@tonic-gate 			 * Lock out other meta* commands by suspending
3807c478bd9Sstevel@tonic-gate 			 * class 1 messages across the diskset.
3817c478bd9Sstevel@tonic-gate 			 */
3827c478bd9Sstevel@tonic-gate 			nd = sd->sd_nodelist;
3837c478bd9Sstevel@tonic-gate 			while (nd) {
3847c478bd9Sstevel@tonic-gate 				if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
3857c478bd9Sstevel@tonic-gate 					nd = nd->nd_next;
3867c478bd9Sstevel@tonic-gate 					continue;
3877c478bd9Sstevel@tonic-gate 				}
3887c478bd9Sstevel@tonic-gate 
3897c478bd9Sstevel@tonic-gate 				if (clnt_mdcommdctl(nd->nd_nodename,
3907c478bd9Sstevel@tonic-gate 				    COMMDCTL_SUSPEND, sp, MD_MSG_CLASS1,
3917c478bd9Sstevel@tonic-gate 				    MD_MSCF_NO_FLAGS, ep)) {
3927c478bd9Sstevel@tonic-gate 					rval = -1;
3937c478bd9Sstevel@tonic-gate 					goto done;
3947c478bd9Sstevel@tonic-gate 				}
3957c478bd9Sstevel@tonic-gate 				suspend1_flag = 1;
3967c478bd9Sstevel@tonic-gate 				nd = nd->nd_next;
3977c478bd9Sstevel@tonic-gate 			}
3987c478bd9Sstevel@tonic-gate 		} else {
3997c478bd9Sstevel@tonic-gate 			/* Lock the set on current set members */
4007c478bd9Sstevel@tonic-gate 			for (i = 0; i < MD_MAXSIDES; i++) {
4017c478bd9Sstevel@tonic-gate 				/* Skip empty slots */
4027c478bd9Sstevel@tonic-gate 				if (sd->sd_nodes[i][0] == '\0')
4037c478bd9Sstevel@tonic-gate 					continue;
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 				if ((force & MDFORCE_LOCAL) &&
4067c478bd9Sstevel@tonic-gate 				    strcmp(sd->sd_nodes[i], mynode()) != 0)
4077c478bd9Sstevel@tonic-gate 					continue;
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 				if (clnt_lock_set(sd->sd_nodes[i], sp, ep)) {
4107c478bd9Sstevel@tonic-gate 					rval = -1;
4117c478bd9Sstevel@tonic-gate 					goto done;
4127c478bd9Sstevel@tonic-gate 				}
4137c478bd9Sstevel@tonic-gate 			}
4147c478bd9Sstevel@tonic-gate 		}
4157c478bd9Sstevel@tonic-gate 
4167c478bd9Sstevel@tonic-gate 		force |= MDFORCE_SET_LOCKED;
4177c478bd9Sstevel@tonic-gate 		options |= MDCHK_SET_LOCKED;
4187c478bd9Sstevel@tonic-gate 	}
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate 	if (cmd == detach) {
4217c478bd9Sstevel@tonic-gate 		if ((dbnlp = build_a_namelist(sp, argc, argv, ep)) == NULL) {
4227c478bd9Sstevel@tonic-gate 			rval = -1;
4237c478bd9Sstevel@tonic-gate 			goto done;
4247c478bd9Sstevel@tonic-gate 		}
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate 		rval = meta_db_detach(sp, dbnlp, force, sysfilename, ep);
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate 		metafreenamelist(dbnlp);
4297c478bd9Sstevel@tonic-gate 	}
4307c478bd9Sstevel@tonic-gate 
4317c478bd9Sstevel@tonic-gate 	if (cmd == attach) {
4327c478bd9Sstevel@tonic-gate 		daddr_t	nblks = 0;
4337c478bd9Sstevel@tonic-gate 		int	arg_index = 0;
4347c478bd9Sstevel@tonic-gate 		int	saved_dbsize = dbsize;
4357c478bd9Sstevel@tonic-gate 		int	saved_dbcnt = dbcnt;
4367c478bd9Sstevel@tonic-gate 		int	saved_default_size = default_size;
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate 		if (force & MDFORCE_LOCAL)
4397c478bd9Sstevel@tonic-gate 			options |= MDCHK_SET_FORCE;
4407c478bd9Sstevel@tonic-gate 
4417c478bd9Sstevel@tonic-gate 		if (default_size)
4427c478bd9Sstevel@tonic-gate 			if ((nblks = meta_db_minreplica(sp, ep)) < 0)
4437c478bd9Sstevel@tonic-gate 				mdclrerror(ep);
4447c478bd9Sstevel@tonic-gate 		/*
4457c478bd9Sstevel@tonic-gate 		 * Loop through build a new namelist
4467c478bd9Sstevel@tonic-gate 		 * for each "mddb" entry or the devices list
4477c478bd9Sstevel@tonic-gate 		 * on the command line.  This allows each "mddb"
4487c478bd9Sstevel@tonic-gate 		 * entry to have unique dbsize and dbcnt.
4497c478bd9Sstevel@tonic-gate 		 */
4507c478bd9Sstevel@tonic-gate 		while (arg_index < argc) {
4517c478bd9Sstevel@tonic-gate 
4527c478bd9Sstevel@tonic-gate 			dbnlp = build_next_namelist(sp, argc, argv,
4537c478bd9Sstevel@tonic-gate 			    &arg_index, &dbsize, &dbcnt, &default_size, ep);
4547c478bd9Sstevel@tonic-gate 			if (dbnlp == NULL) {
4557c478bd9Sstevel@tonic-gate 				rval = -1;
4567c478bd9Sstevel@tonic-gate 				goto done;
4577c478bd9Sstevel@tonic-gate 			}
4587c478bd9Sstevel@tonic-gate 			/*
4597c478bd9Sstevel@tonic-gate 			 * If using the default size,
4607c478bd9Sstevel@tonic-gate 			 *   then let's adjust the default to the minimum
4617c478bd9Sstevel@tonic-gate 			 *   size currently in use.
4627c478bd9Sstevel@tonic-gate 			 */
4637c478bd9Sstevel@tonic-gate 			if (default_size && (nblks > 0))
4647c478bd9Sstevel@tonic-gate 				dbsize = nblks;	/* adjust replica size */
4657c478bd9Sstevel@tonic-gate 
466*2fb876aeSjeanm 			if (dbsize > maxblks)
467*2fb876aeSjeanm 				usage(sp, gettext("size (-l) is too big"));
468*2fb876aeSjeanm 
4697c478bd9Sstevel@tonic-gate 			rval = meta_db_attach(sp, dbnlp, options, NULL, dbcnt,
4707c478bd9Sstevel@tonic-gate 			    dbsize, sysfilename, ep);
4717c478bd9Sstevel@tonic-gate 			if (rval) {
4727c478bd9Sstevel@tonic-gate 				metafreenamelist(dbnlp);
4737c478bd9Sstevel@tonic-gate 				break;
4747c478bd9Sstevel@tonic-gate 			}
4757c478bd9Sstevel@tonic-gate 			dbsize = saved_dbsize;
4767c478bd9Sstevel@tonic-gate 			dbcnt = saved_dbcnt;
4777c478bd9Sstevel@tonic-gate 			default_size = saved_default_size;
4787c478bd9Sstevel@tonic-gate 
4797c478bd9Sstevel@tonic-gate 			metafreenamelist(dbnlp);
4807c478bd9Sstevel@tonic-gate 		}
4817c478bd9Sstevel@tonic-gate 	}
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate done:
4847c478bd9Sstevel@tonic-gate 	if (! metaislocalset(sp)) {
4857c478bd9Sstevel@tonic-gate 		cl_sk = cl_get_setkey(sp->setno, sp->setname);
4867c478bd9Sstevel@tonic-gate 		if (MD_MNSET_DESC(sd)) {
4877c478bd9Sstevel@tonic-gate 			/*
4887c478bd9Sstevel@tonic-gate 			 * Unlock diskset by resuming
4897c478bd9Sstevel@tonic-gate 			 * class 1 messages across the diskset.
4907c478bd9Sstevel@tonic-gate 			 */
4917c478bd9Sstevel@tonic-gate 			if (suspend1_flag) {
4927c478bd9Sstevel@tonic-gate 				nd = sd->sd_nodelist;
4937c478bd9Sstevel@tonic-gate 				while (nd) {
4947c478bd9Sstevel@tonic-gate 					if (!(nd->nd_flags &
4957c478bd9Sstevel@tonic-gate 					    MD_MN_NODE_ALIVE)) {
4967c478bd9Sstevel@tonic-gate 						nd = nd->nd_next;
4977c478bd9Sstevel@tonic-gate 						continue;
4987c478bd9Sstevel@tonic-gate 					}
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 					if (clnt_mdcommdctl(nd->nd_nodename,
5017c478bd9Sstevel@tonic-gate 					    COMMDCTL_RESUME, sp,
5027c478bd9Sstevel@tonic-gate 					    MD_MSG_CLASS1,
5037c478bd9Sstevel@tonic-gate 					    MD_MSCF_NO_FLAGS, &xep)) {
5047c478bd9Sstevel@tonic-gate 						mde_perror(&xep, "");
5057c478bd9Sstevel@tonic-gate 						mdclrerror(&xep);
5067c478bd9Sstevel@tonic-gate 					}
5077c478bd9Sstevel@tonic-gate 					nd = nd->nd_next;
5087c478bd9Sstevel@tonic-gate 				}
5097c478bd9Sstevel@tonic-gate 			}
5107c478bd9Sstevel@tonic-gate 			nd = sd->sd_nodelist;
5117c478bd9Sstevel@tonic-gate 			while (nd) {
5127c478bd9Sstevel@tonic-gate 				if ((force & MDFORCE_LOCAL) &&
5137c478bd9Sstevel@tonic-gate 				    strcmp(nd->nd_nodename, mynode()) != 0) {
5147c478bd9Sstevel@tonic-gate 					nd = nd->nd_next;
5157c478bd9Sstevel@tonic-gate 					continue;
5167c478bd9Sstevel@tonic-gate 				}
5177c478bd9Sstevel@tonic-gate 				if (!(nd->nd_flags & MD_MN_NODE_ALIVE)) {
5187c478bd9Sstevel@tonic-gate 					nd = nd->nd_next;
5197c478bd9Sstevel@tonic-gate 					continue;
5207c478bd9Sstevel@tonic-gate 				}
5217c478bd9Sstevel@tonic-gate 
5227c478bd9Sstevel@tonic-gate 				if (clnt_unlock_set(nd->nd_nodename, cl_sk,
5237c478bd9Sstevel@tonic-gate 				    &xep))
5247c478bd9Sstevel@tonic-gate 					mdclrerror(&xep);
5257c478bd9Sstevel@tonic-gate 				nd = nd->nd_next;
5267c478bd9Sstevel@tonic-gate 			}
5277c478bd9Sstevel@tonic-gate 		} else {
5287c478bd9Sstevel@tonic-gate 			for (i = 0; i < MD_MAXSIDES; i++) {
5297c478bd9Sstevel@tonic-gate 				/* Skip empty slots */
5307c478bd9Sstevel@tonic-gate 				if (sd->sd_nodes[i][0] == '\0')
5317c478bd9Sstevel@tonic-gate 					continue;
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate 				if ((force & MDFORCE_LOCAL) &&
5347c478bd9Sstevel@tonic-gate 				    strcmp(sd->sd_nodes[i], mynode()) != 0)
5357c478bd9Sstevel@tonic-gate 					continue;
5367c478bd9Sstevel@tonic-gate 
5377c478bd9Sstevel@tonic-gate 				if (clnt_unlock_set(sd->sd_nodes[i], cl_sk,
5387c478bd9Sstevel@tonic-gate 				    &xep))
5397c478bd9Sstevel@tonic-gate 					mdclrerror(&xep);
5407c478bd9Sstevel@tonic-gate 			}
5417c478bd9Sstevel@tonic-gate 		}
5427c478bd9Sstevel@tonic-gate 		cl_set_setkey(NULL);
5437c478bd9Sstevel@tonic-gate 	}
5447c478bd9Sstevel@tonic-gate 
5457c478bd9Sstevel@tonic-gate 	return (rval);
5467c478bd9Sstevel@tonic-gate }
5477c478bd9Sstevel@tonic-gate 
5487c478bd9Sstevel@tonic-gate static int
info(mdsetname_t * sp,enum mddb_cmd cmd,int print_headers,int print_footers,md_error_t * ep)5497c478bd9Sstevel@tonic-gate info(
5507c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp,
5517c478bd9Sstevel@tonic-gate 	enum mddb_cmd	cmd,
5527c478bd9Sstevel@tonic-gate 	int		print_headers,
5537c478bd9Sstevel@tonic-gate 	int		print_footers,
5547c478bd9Sstevel@tonic-gate 	md_error_t	*ep
5557c478bd9Sstevel@tonic-gate )
5567c478bd9Sstevel@tonic-gate {
5577c478bd9Sstevel@tonic-gate 	md_replicalist_t	*rlp = NULL;
5587c478bd9Sstevel@tonic-gate 	md_replicalist_t	*rl;
5597c478bd9Sstevel@tonic-gate 	md_replica_t		*r;
5607c478bd9Sstevel@tonic-gate 	int			i;
5617c478bd9Sstevel@tonic-gate 	char			*unk_str = NULL;
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate 	/* get list of replicas, quit if none */
5647c478bd9Sstevel@tonic-gate 	if (metareplicalist(sp, (MD_BASICNAME_OK | PRINT_FAST), &rlp, ep) < 0)
5657c478bd9Sstevel@tonic-gate 		return (-1);
5667c478bd9Sstevel@tonic-gate 	else if (rlp == NULL)
5677c478bd9Sstevel@tonic-gate 		return (0);
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate 	if (print_headers) {
5707c478bd9Sstevel@tonic-gate 		(void) printf("\t%5.5s\t\t%9.9s\t%11.11s\n", gettext("flags"),
5717c478bd9Sstevel@tonic-gate 		    gettext("first blk"), gettext("block count"));
5727c478bd9Sstevel@tonic-gate 	}
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate 	unk_str = gettext("unknown");
5757c478bd9Sstevel@tonic-gate 	for (rl = rlp; rl != NULL; rl = rl->rl_next) {
5767c478bd9Sstevel@tonic-gate 		r = rl->rl_repp;
5777c478bd9Sstevel@tonic-gate 
5787c478bd9Sstevel@tonic-gate 		for (i = 0; i < MDDB_FLAGS_LEN; i++) {
5797c478bd9Sstevel@tonic-gate 			if (r->r_flags & (1 << i))
5807c478bd9Sstevel@tonic-gate 				(void) putchar(MDDB_FLAGS_STRING[i]);
5817c478bd9Sstevel@tonic-gate 			else
5827c478bd9Sstevel@tonic-gate 				(void) putchar(' ');
5837c478bd9Sstevel@tonic-gate 		}
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate 		if ((r->r_blkno == -1) && (r->r_nblk == -1)) {
5867c478bd9Sstevel@tonic-gate 			(void) printf("\t%7.7s\t\t%7.7s\t", unk_str, unk_str);
5877c478bd9Sstevel@tonic-gate 		} else if (r->r_nblk == -1) {
5887c478bd9Sstevel@tonic-gate 			(void) printf("\t%ld\t\t%7.7s\t", r->r_blkno, unk_str);
5897c478bd9Sstevel@tonic-gate 		} else {
5907c478bd9Sstevel@tonic-gate 			(void) printf("\t%ld\t\t%ld\t", r->r_blkno, r->r_nblk);
5917c478bd9Sstevel@tonic-gate 		}
5927c478bd9Sstevel@tonic-gate 
5937c478bd9Sstevel@tonic-gate 		(void) printf("\t%s\n", r->r_namep->bname);
5947c478bd9Sstevel@tonic-gate 
5957c478bd9Sstevel@tonic-gate 	}
5967c478bd9Sstevel@tonic-gate 
5977c478bd9Sstevel@tonic-gate 	metafreereplicalist(rlp);
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate 	if (cmd == infoshort)
6007c478bd9Sstevel@tonic-gate 		return (0);
6017c478bd9Sstevel@tonic-gate 
6027c478bd9Sstevel@tonic-gate 	if (!print_footers)
6037c478bd9Sstevel@tonic-gate 		return (0);
6047c478bd9Sstevel@tonic-gate 
6057c478bd9Sstevel@tonic-gate 	(void) printf(gettext(
6067c478bd9Sstevel@tonic-gate 	    " r - replica does not have device relocation information\n"
6077c478bd9Sstevel@tonic-gate 	    " o - replica active prior to last mddb configuration change\n"
6087c478bd9Sstevel@tonic-gate 	    " u - replica is up to date\n"
6097c478bd9Sstevel@tonic-gate 	    " l - locator for this replica was read successfully\n"
6107c478bd9Sstevel@tonic-gate 	    " c - replica's location was in %s\n"
6117c478bd9Sstevel@tonic-gate 	    " p - replica's location was patched in kernel\n"
6127c478bd9Sstevel@tonic-gate 	    " m - replica is master, this is replica selected as input\n"
613*2fb876aeSjeanm 	    " t - tagged data is associated with the replica\n"
6147c478bd9Sstevel@tonic-gate 	    " W - replica has device write errors\n"
6157c478bd9Sstevel@tonic-gate 	    " a - replica is active, commits are occurring to this replica\n"
6167c478bd9Sstevel@tonic-gate 	    " M - replica had problem with master blocks\n"
6177c478bd9Sstevel@tonic-gate 	    " D - replica had problem with data blocks\n"
6187c478bd9Sstevel@tonic-gate 	    " F - replica had format problems\n"
6197c478bd9Sstevel@tonic-gate 	    " S - replica is too small to hold current data base\n"
620*2fb876aeSjeanm 	    " R - replica had device read errors\n"
621*2fb876aeSjeanm 	    " B - tagged data associated with the replica is not valid\n"),
6227c478bd9Sstevel@tonic-gate 	    META_DBCONF);
6237c478bd9Sstevel@tonic-gate 	return (0);
6247c478bd9Sstevel@tonic-gate }
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)6277c478bd9Sstevel@tonic-gate main(int argc, char **argv)
6287c478bd9Sstevel@tonic-gate {
6297c478bd9Sstevel@tonic-gate 	mdsetname_t	*sp = NULL;
6307c478bd9Sstevel@tonic-gate 	int		c;
6317c478bd9Sstevel@tonic-gate 	enum mddb_cmd	cmd = none;
6327c478bd9Sstevel@tonic-gate 	char		*sname = MD_LOCAL_NAME;
6337c478bd9Sstevel@tonic-gate 	char		*cffilename = NULL;
6347c478bd9Sstevel@tonic-gate 	char		*sysfilename = NULL;
6357c478bd9Sstevel@tonic-gate 	int		forceflg = FALSE;
6367c478bd9Sstevel@tonic-gate 	mdchkopts_t	options = 0;
6377c478bd9Sstevel@tonic-gate 	md_error_t	status = mdnullerror;
6387c478bd9Sstevel@tonic-gate 	md_error_t	*ep = &status;
6397c478bd9Sstevel@tonic-gate 	int		error;
6407c478bd9Sstevel@tonic-gate 	md_set_desc	*sd;
6417c478bd9Sstevel@tonic-gate 	int		multi_node = 0;
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate 	/*
6447c478bd9Sstevel@tonic-gate 	 * Get the locale set up before calling any other routines
6457c478bd9Sstevel@tonic-gate 	 * with messages to ouput.  Just in case we're not in a build
6467c478bd9Sstevel@tonic-gate 	 * environment, make sure that TEXT_DOMAIN gets set to
6477c478bd9Sstevel@tonic-gate 	 * something.
6487c478bd9Sstevel@tonic-gate 	 */
6497c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
6507c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
6517c478bd9Sstevel@tonic-gate #endif
6527c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
6537c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
6547c478bd9Sstevel@tonic-gate 
6557c478bd9Sstevel@tonic-gate 	if (sdssc_bind_library() == SDSSC_OKAY)
6567c478bd9Sstevel@tonic-gate 		if (sdssc_cmd_proxy(argc, argv, SDSSC_PROXY_PRIMARY,
6577c478bd9Sstevel@tonic-gate 		    &error) == SDSSC_PROXY_DONE)
6587c478bd9Sstevel@tonic-gate 			exit(error);
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate 	/* parse args */
6617c478bd9Sstevel@tonic-gate 	optind = 1;
6627c478bd9Sstevel@tonic-gate 	opterr = 1;
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate 	/* initialize */
6657c478bd9Sstevel@tonic-gate 	if (md_init(argc, argv, 0, 1, ep) != 0) {
6667c478bd9Sstevel@tonic-gate 		mde_perror(ep, "");
6677c478bd9Sstevel@tonic-gate 		md_exit(sp, 1);
6687c478bd9Sstevel@tonic-gate 	}
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate 	/* parse args */
6717c478bd9Sstevel@tonic-gate 	optind = 1;
6727c478bd9Sstevel@tonic-gate 	opterr = 1;
6737c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "ac:dfhik:l:ps:?")) != -1) {
6747c478bd9Sstevel@tonic-gate 		switch (c) {
6757c478bd9Sstevel@tonic-gate 		case 'a':
6767c478bd9Sstevel@tonic-gate 			cmd = attach;
6777c478bd9Sstevel@tonic-gate 			break;
6787c478bd9Sstevel@tonic-gate 		case 'c':
6797c478bd9Sstevel@tonic-gate 			break;
6807c478bd9Sstevel@tonic-gate 		case 'd':
6817c478bd9Sstevel@tonic-gate 			cmd = detach;
6827c478bd9Sstevel@tonic-gate 			break;
6837c478bd9Sstevel@tonic-gate 		case 'f':
6847c478bd9Sstevel@tonic-gate 			forceflg = TRUE;
6857c478bd9Sstevel@tonic-gate 			break;
6867c478bd9Sstevel@tonic-gate 		case 'h':
6877c478bd9Sstevel@tonic-gate 			usage(sp, (char *)0);
6887c478bd9Sstevel@tonic-gate 			break;
6897c478bd9Sstevel@tonic-gate 		case 'i':
6907c478bd9Sstevel@tonic-gate 			cmd = infolong;
6917c478bd9Sstevel@tonic-gate 			break;
6927c478bd9Sstevel@tonic-gate 		case 'k':
6937c478bd9Sstevel@tonic-gate 			sysfilename = optarg;
6947c478bd9Sstevel@tonic-gate 			break;
6957c478bd9Sstevel@tonic-gate 		case 'l':
6967c478bd9Sstevel@tonic-gate 			break;
6977c478bd9Sstevel@tonic-gate 		case 'p':
6987c478bd9Sstevel@tonic-gate 			cmd = patch;
6997c478bd9Sstevel@tonic-gate 			break;
7007c478bd9Sstevel@tonic-gate 		case 's':
7017c478bd9Sstevel@tonic-gate 			sname = optarg;
7027c478bd9Sstevel@tonic-gate 			break;
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate 		case '?':
7057c478bd9Sstevel@tonic-gate 			if (optopt == '?')
7067c478bd9Sstevel@tonic-gate 				usage(sp, NULL);
7077c478bd9Sstevel@tonic-gate 			/*FALLTHROUGH*/
7087c478bd9Sstevel@tonic-gate 		default:
7097c478bd9Sstevel@tonic-gate 			usage(sp, gettext("unknown command"));
7107c478bd9Sstevel@tonic-gate 		}
7117c478bd9Sstevel@tonic-gate 	}
7127c478bd9Sstevel@tonic-gate 	if (cmd == none)
7137c478bd9Sstevel@tonic-gate 		cmd = infoshort;
7147c478bd9Sstevel@tonic-gate 
7157c478bd9Sstevel@tonic-gate 	/* get set context */
7167c478bd9Sstevel@tonic-gate 	if ((sp = metasetname(sname, ep)) == NULL) {
7177c478bd9Sstevel@tonic-gate 		mde_perror(ep, "");
7187c478bd9Sstevel@tonic-gate 		md_exit(sp, 1);
7197c478bd9Sstevel@tonic-gate 	}
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate 	/* print status */
7227c478bd9Sstevel@tonic-gate 	if (cmd == infoshort || cmd == infolong) {
7237c478bd9Sstevel@tonic-gate 		if (optind != argc)
7247c478bd9Sstevel@tonic-gate 			usage(sp, gettext(
7257c478bd9Sstevel@tonic-gate 				"too many arguments"));
7267c478bd9Sstevel@tonic-gate 
7277c478bd9Sstevel@tonic-gate 		if (info(sp, cmd, 1, 1, ep)) {
7287c478bd9Sstevel@tonic-gate 			mde_perror(ep, "");
7297c478bd9Sstevel@tonic-gate 			md_exit(sp, 1);
7307c478bd9Sstevel@tonic-gate 		}
7317c478bd9Sstevel@tonic-gate 
7327c478bd9Sstevel@tonic-gate 		if (meta_smf_isonline(meta_smf_getmask(), ep) == 0) {
7337c478bd9Sstevel@tonic-gate 			mde_perror(ep, "");
7347c478bd9Sstevel@tonic-gate 			md_exit(sp, 1);
7357c478bd9Sstevel@tonic-gate 		}
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate 		md_exit(sp, 0);
7387c478bd9Sstevel@tonic-gate 	}
7397c478bd9Sstevel@tonic-gate 
7407c478bd9Sstevel@tonic-gate 	if (meta_check_root(ep) != 0) {
7417c478bd9Sstevel@tonic-gate 		mde_perror(ep, "");
7427c478bd9Sstevel@tonic-gate 		md_exit(sp, 1);
7437c478bd9Sstevel@tonic-gate 	}
7447c478bd9Sstevel@tonic-gate 
7457c478bd9Sstevel@tonic-gate 	if (! metaislocalset(sp)) {
7467c478bd9Sstevel@tonic-gate 		if ((sd = metaget_setdesc(sp, ep)) == NULL) {
7477c478bd9Sstevel@tonic-gate 			mde_perror(ep, "");
7487c478bd9Sstevel@tonic-gate 			md_exit(sp, 1);
7497c478bd9Sstevel@tonic-gate 		}
7507c478bd9Sstevel@tonic-gate 		if (MD_MNSET_DESC(sd)) {
7517c478bd9Sstevel@tonic-gate 			multi_node = 1;
7527c478bd9Sstevel@tonic-gate 		}
7537c478bd9Sstevel@tonic-gate 	}
7547c478bd9Sstevel@tonic-gate 
7557c478bd9Sstevel@tonic-gate 	/*
7567c478bd9Sstevel@tonic-gate 	 * Adjust lock for traditional and local diskset.
7577c478bd9Sstevel@tonic-gate 	 *
7587c478bd9Sstevel@tonic-gate 	 * A MN diskset does not use the set meta_lock but instead
7597c478bd9Sstevel@tonic-gate 	 * uses the clnt_lock of rpc.metad and the suspend/resume
7607c478bd9Sstevel@tonic-gate 	 * feature of the rpc.mdcommd.  Can't use set meta_lock since
7617c478bd9Sstevel@tonic-gate 	 * class 1 messages are grabbing this lock and if this thread
7627c478bd9Sstevel@tonic-gate 	 * is holding the set meta_lock then no rpc.mdcommd suspend
7637c478bd9Sstevel@tonic-gate 	 * can occur.
7647c478bd9Sstevel@tonic-gate 	 */
7657c478bd9Sstevel@tonic-gate 	if ((!multi_node) && (meta_lock(sp, TRUE, ep) != 0)) {
7667c478bd9Sstevel@tonic-gate 		mde_perror(ep, "");
7677c478bd9Sstevel@tonic-gate 		md_exit(sp, 1);
7687c478bd9Sstevel@tonic-gate 	}
7697c478bd9Sstevel@tonic-gate 
7707c478bd9Sstevel@tonic-gate 	/* check for ownership */
7717c478bd9Sstevel@tonic-gate 	if (meta_check_ownership(sp, ep) != 0) {
7727c478bd9Sstevel@tonic-gate 		mde_perror(ep, "");
7737c478bd9Sstevel@tonic-gate 		md_exit(sp, 1);
7747c478bd9Sstevel@tonic-gate 	}
7757c478bd9Sstevel@tonic-gate 
7767c478bd9Sstevel@tonic-gate 	/* snarf MDDB locations */
7777c478bd9Sstevel@tonic-gate 	if (cmd != patch) {
7787c478bd9Sstevel@tonic-gate 		if (meta_setup_db_locations(ep) != 0) {
7797c478bd9Sstevel@tonic-gate 			if (! mdismddberror(ep, MDE_DB_STALE)) {
7807c478bd9Sstevel@tonic-gate 				if (forceflg == FALSE) {
7817c478bd9Sstevel@tonic-gate 					mde_perror(ep, "");
7827c478bd9Sstevel@tonic-gate 					md_exit(sp, 1);
7837c478bd9Sstevel@tonic-gate 				}
7847c478bd9Sstevel@tonic-gate 				options = MDCHK_ALLOW_NODBS;
7857c478bd9Sstevel@tonic-gate 			}
7867c478bd9Sstevel@tonic-gate 			mdclrerror(ep);
7877c478bd9Sstevel@tonic-gate 		}
7887c478bd9Sstevel@tonic-gate 	}
7897c478bd9Sstevel@tonic-gate 
7907c478bd9Sstevel@tonic-gate 	/* patch MDDB locations */
7917c478bd9Sstevel@tonic-gate 	if (cmd == patch) {
7927c478bd9Sstevel@tonic-gate 		if (optind < (argc - 1)) {
7937c478bd9Sstevel@tonic-gate 			usage(sp, gettext(
7947c478bd9Sstevel@tonic-gate 			    "too many arguments to -p"));
7957c478bd9Sstevel@tonic-gate 		}
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate 		if (optind == (argc - 1))
7987c478bd9Sstevel@tonic-gate 			cffilename = argv[optind];
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate 		if (metaislocalset(sp)) {
8017c478bd9Sstevel@tonic-gate 			if (meta_db_patch(sysfilename, cffilename, 1, ep)) {
8027c478bd9Sstevel@tonic-gate 				mde_perror(ep, "");
8037c478bd9Sstevel@tonic-gate 				md_exit(sp, 1);
8047c478bd9Sstevel@tonic-gate 			}
8057c478bd9Sstevel@tonic-gate 		}
8067c478bd9Sstevel@tonic-gate 	}
8077c478bd9Sstevel@tonic-gate 
8087c478bd9Sstevel@tonic-gate 	/* add/delete replicas */
8097c478bd9Sstevel@tonic-gate 	if (cmd == attach || cmd == detach) {
8107c478bd9Sstevel@tonic-gate 		if (chngdb(sp, cmd, argc, argv, options, ep)) {
8117c478bd9Sstevel@tonic-gate 			mde_perror(ep, "");
8127c478bd9Sstevel@tonic-gate 			md_exit(sp, 1);
8137c478bd9Sstevel@tonic-gate 		}
8147c478bd9Sstevel@tonic-gate 	}
8157c478bd9Sstevel@tonic-gate 
8167c478bd9Sstevel@tonic-gate 	md_exit(sp, 0);
8177c478bd9Sstevel@tonic-gate 	/*NOTREACHED*/
8187c478bd9Sstevel@tonic-gate 	return (0);
8197c478bd9Sstevel@tonic-gate }
820