xref: /onnv-gate/usr/src/lib/lvm/libmeta/common/meta_metad.c (revision 1945:74cee1cd404b)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*1945Sjeanm  * Common Development and Distribution License (the "License").
6*1945Sjeanm  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*1945Sjeanm  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * Just in case we're not in a build environment, make sure that
300Sstevel@tonic-gate  * TEXT_DOMAIN gets set to something.
310Sstevel@tonic-gate  */
320Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
330Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
340Sstevel@tonic-gate #endif
350Sstevel@tonic-gate 
360Sstevel@tonic-gate #include <meta.h>
370Sstevel@tonic-gate #include <metad.h>
380Sstevel@tonic-gate #include <devid.h>
390Sstevel@tonic-gate 
400Sstevel@tonic-gate static md_setkey_t	*my_cl_sk = NULL;
410Sstevel@tonic-gate 
420Sstevel@tonic-gate #define	CL_DEF_TMO	30L
430Sstevel@tonic-gate 
440Sstevel@tonic-gate /*
450Sstevel@tonic-gate  * Convert an old style mddrivename_t into a new style
460Sstevel@tonic-gate  * mddrivename_t. Meant to be used *ONLY* by rpc.metad
470Sstevel@tonic-gate  */
480Sstevel@tonic-gate void
meta_conv_drvname_old2new(o_mddrivename_t * v1_dp,mddrivename_t * v2_dp)490Sstevel@tonic-gate meta_conv_drvname_old2new(
500Sstevel@tonic-gate 	o_mddrivename_t		*v1_dp,
510Sstevel@tonic-gate 	mddrivename_t		*v2_dp
520Sstevel@tonic-gate )
530Sstevel@tonic-gate {
540Sstevel@tonic-gate 	int 		sliceno;
550Sstevel@tonic-gate 	o_mdname_t	*v1_np;
560Sstevel@tonic-gate 	mdname_t	*v2_np;
570Sstevel@tonic-gate 
580Sstevel@tonic-gate 	/* fields that haven't changed */
590Sstevel@tonic-gate 	v2_dp->cname   = v1_dp->cname;
600Sstevel@tonic-gate 	v2_dp->rname   = v1_dp->rname;
610Sstevel@tonic-gate 	v2_dp->type    = v1_dp->type;
620Sstevel@tonic-gate 	v2_dp->errnum  = v1_dp->errnum;
630Sstevel@tonic-gate 
640Sstevel@tonic-gate 	/* geometry information */
650Sstevel@tonic-gate 	v2_dp->geom.ncyl  = v1_dp->geom.ncyl;
660Sstevel@tonic-gate 	v2_dp->geom.nhead = v1_dp->geom.nhead;
670Sstevel@tonic-gate 	v2_dp->geom.nsect = v1_dp->geom.nsect;
680Sstevel@tonic-gate 	v2_dp->geom.rpm   = v1_dp->geom.rpm;
690Sstevel@tonic-gate 	v2_dp->geom.write_reinstruct = v1_dp->geom.write_reinstruct;
700Sstevel@tonic-gate 	v2_dp->geom.read_reinstruct  = v1_dp->geom.read_reinstruct;
710Sstevel@tonic-gate 	v2_dp->geom.blk_sz = 0;
720Sstevel@tonic-gate 
730Sstevel@tonic-gate 	/* controller information */
740Sstevel@tonic-gate 	v2_dp->cinfo = v1_dp->cinfo;
750Sstevel@tonic-gate 
760Sstevel@tonic-gate 	/* vtoc information */
770Sstevel@tonic-gate 	v2_dp->vtoc.nparts    = v1_dp->vtoc.nparts;
780Sstevel@tonic-gate 	v2_dp->vtoc.first_lba = 0;
790Sstevel@tonic-gate 	v2_dp->vtoc.last_lba  = 0;
800Sstevel@tonic-gate 	v2_dp->vtoc.lbasize   = 0;
810Sstevel@tonic-gate 
820Sstevel@tonic-gate 	for (sliceno = 0; sliceno < (MD_MAX_PARTS - 1); sliceno++) {
830Sstevel@tonic-gate 		v2_dp->vtoc.parts[sliceno].start =
840Sstevel@tonic-gate 		    (diskaddr_t)v1_dp->vtoc.parts[sliceno].start;
850Sstevel@tonic-gate 		v2_dp->vtoc.parts[sliceno].size =
860Sstevel@tonic-gate 		    (diskaddr_t)v1_dp->vtoc.parts[sliceno].size;
870Sstevel@tonic-gate 		v2_dp->vtoc.parts[sliceno].tag =
880Sstevel@tonic-gate 		    v1_dp->vtoc.parts[sliceno].tag;
890Sstevel@tonic-gate 		v2_dp->vtoc.parts[sliceno].flag =
900Sstevel@tonic-gate 		    v1_dp->vtoc.parts[sliceno].flag;
910Sstevel@tonic-gate 		v2_dp->vtoc.parts[sliceno].label =
920Sstevel@tonic-gate 		    (diskaddr_t)v1_dp->vtoc.parts[sliceno].label;
930Sstevel@tonic-gate 	}
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 	/* The new style vtoc has 17 partitions */
960Sstevel@tonic-gate 	v2_dp->vtoc.parts[MD_MAX_PARTS - 1].start = 0;
970Sstevel@tonic-gate 	v2_dp->vtoc.parts[MD_MAX_PARTS - 1].size  = 0;
980Sstevel@tonic-gate 	v2_dp->vtoc.parts[MD_MAX_PARTS - 1].tag   = 0;
990Sstevel@tonic-gate 	v2_dp->vtoc.parts[MD_MAX_PARTS - 1].flag  = 0;
1000Sstevel@tonic-gate 	v2_dp->vtoc.parts[MD_MAX_PARTS - 1].label = 0;
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 	v2_dp->vtoc.typename = v1_dp->vtoc.typename;
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate 	/* partition information */
1050Sstevel@tonic-gate 	v2_dp->parts.parts_len = v1_dp->parts.parts_len;
1060Sstevel@tonic-gate 	for (sliceno = 0; sliceno < v1_dp->parts.parts_len; sliceno++) {
1070Sstevel@tonic-gate 		v1_np = &v1_dp->parts.parts_val[sliceno];
1080Sstevel@tonic-gate 		v2_np = &v2_dp->parts.parts_val[sliceno];
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate 		/*
1110Sstevel@tonic-gate 		 * We speculate that if cname for a particular
1120Sstevel@tonic-gate 		 * partition does not exist, the other fields
1130Sstevel@tonic-gate 		 * don't exist either. In such a case, we don't
1140Sstevel@tonic-gate 		 * need to do anything for that partition.
1150Sstevel@tonic-gate 		 */
1160Sstevel@tonic-gate 		if (v1_np->cname != NULL) {
1170Sstevel@tonic-gate 			v2_np->cname = v1_np->cname;
1180Sstevel@tonic-gate 			v2_np->bname = v1_np->bname;
1190Sstevel@tonic-gate 			v2_np->rname = v1_np->rname;
1200Sstevel@tonic-gate 			v2_np->devicesname = v1_np->devicesname;
1210Sstevel@tonic-gate 			v2_np->dev = meta_expldev(v1_np->dev);
1220Sstevel@tonic-gate 			v2_np->key = v1_np->key;
1230Sstevel@tonic-gate 			v2_np->end_blk = (diskaddr_t)v1_np->end_blk;
1240Sstevel@tonic-gate 			v2_np->start_blk = (diskaddr_t)v1_np->start_blk;
1250Sstevel@tonic-gate 		}
1260Sstevel@tonic-gate 		v2_np->drivenamep = v2_dp;
1270Sstevel@tonic-gate 	}
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 	/* We don't care about the rest of the fields */
1300Sstevel@tonic-gate 	v2_dp->side_names = v1_dp->side_names;
1310Sstevel@tonic-gate 	v2_dp->side_names_key = v1_dp->side_names_key;
1320Sstevel@tonic-gate 	v2_dp->miscname = v1_dp->miscname;
1330Sstevel@tonic-gate }
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate /*
1360Sstevel@tonic-gate  * Convert a new style mddrivename_t into an old style
1370Sstevel@tonic-gate  * mddrivename_t. Meant to be used *ONLY* by rpc.metad
1380Sstevel@tonic-gate  */
1390Sstevel@tonic-gate void
meta_conv_drvname_new2old(o_mddrivename_t * v1_dp,mddrivename_t * v2_dp)1400Sstevel@tonic-gate meta_conv_drvname_new2old(
1410Sstevel@tonic-gate 	o_mddrivename_t		*v1_dp,
1420Sstevel@tonic-gate 	mddrivename_t		*v2_dp
1430Sstevel@tonic-gate )
1440Sstevel@tonic-gate {
1450Sstevel@tonic-gate 	int 		sliceno;
1460Sstevel@tonic-gate 	o_mdname_t	*v1_np;
1470Sstevel@tonic-gate 	mdname_t	*v2_np;
1480Sstevel@tonic-gate 
1490Sstevel@tonic-gate 	/* fields that haven't changed */
1500Sstevel@tonic-gate 	v1_dp->cname   = v2_dp->cname;
1510Sstevel@tonic-gate 	v1_dp->rname   = v2_dp->rname;
1520Sstevel@tonic-gate 	v1_dp->type    = v2_dp->type;
1530Sstevel@tonic-gate 	v1_dp->errnum  = v2_dp->errnum;
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate 	/* geometry information */
1560Sstevel@tonic-gate 	v1_dp->geom.ncyl  = v2_dp->geom.ncyl;
1570Sstevel@tonic-gate 	v1_dp->geom.nhead = v2_dp->geom.nhead;
1580Sstevel@tonic-gate 	v1_dp->geom.nsect = v2_dp->geom.nsect;
1590Sstevel@tonic-gate 	v1_dp->geom.rpm   = v2_dp->geom.rpm;
1600Sstevel@tonic-gate 	v1_dp->geom.write_reinstruct = v2_dp->geom.write_reinstruct;
1610Sstevel@tonic-gate 	v1_dp->geom.read_reinstruct  = v2_dp->geom.read_reinstruct;
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 	/* controller information */
1640Sstevel@tonic-gate 	v1_dp->cinfo = v2_dp->cinfo;
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate 	/* vtoc information */
1670Sstevel@tonic-gate 	v1_dp->vtoc.typename = v2_dp->vtoc.typename;
1680Sstevel@tonic-gate 	v1_dp->vtoc.nparts   = v2_dp->vtoc.nparts;
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate 	for (sliceno = 0; sliceno < (MD_MAX_PARTS - 1); sliceno++) {
1710Sstevel@tonic-gate 		v1_dp->vtoc.parts[sliceno].start =
1720Sstevel@tonic-gate 		    (daddr_t)v2_dp->vtoc.parts[sliceno].start;
1730Sstevel@tonic-gate 		v1_dp->vtoc.parts[sliceno].size  =
1740Sstevel@tonic-gate 		    (daddr_t)v2_dp->vtoc.parts[sliceno].size;
1750Sstevel@tonic-gate 		v1_dp->vtoc.parts[sliceno].tag   =
1760Sstevel@tonic-gate 		    v2_dp->vtoc.parts[sliceno].tag;
1770Sstevel@tonic-gate 		v1_dp->vtoc.parts[sliceno].flag  =
1780Sstevel@tonic-gate 		    v2_dp->vtoc.parts[sliceno].flag;
1790Sstevel@tonic-gate 		v1_dp->vtoc.parts[sliceno].label =
1800Sstevel@tonic-gate 		    (daddr_t)v2_dp->vtoc.parts[sliceno].label;
1810Sstevel@tonic-gate 	}
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate 	/* partition information */
1840Sstevel@tonic-gate 	v1_dp->parts.parts_len = v2_dp->parts.parts_len;
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 	for (sliceno = 0; sliceno < v2_dp->parts.parts_len; sliceno++) {
1870Sstevel@tonic-gate 		v1_np = &v1_dp->parts.parts_val[sliceno];
1880Sstevel@tonic-gate 		v2_np = &v2_dp->parts.parts_val[sliceno];
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate 		/*
1910Sstevel@tonic-gate 		 * We speculate that if cname for a particular
1920Sstevel@tonic-gate 		 * partition does not exist then the rest of
1930Sstevel@tonic-gate 		 * the fields a partition don't exist either.
1940Sstevel@tonic-gate 		 * In such a case, we don't need to do anything
1950Sstevel@tonic-gate 		 * for that partition.
1960Sstevel@tonic-gate 		 */
1970Sstevel@tonic-gate 		if (v2_np->cname != NULL) {
1980Sstevel@tonic-gate 			v1_np->cname = v2_np->cname;
1990Sstevel@tonic-gate 			v1_np->bname = v2_np->bname;
2000Sstevel@tonic-gate 			v1_np->rname = v2_np->rname;
2010Sstevel@tonic-gate 			v1_np->devicesname = v2_np->devicesname;
2020Sstevel@tonic-gate 			v1_np->dev = meta_cmpldev(v2_np->dev);
2030Sstevel@tonic-gate 			v1_np->key = v2_np->key;
2040Sstevel@tonic-gate 			v1_np->end_blk = (daddr_t)v2_np->end_blk;
2050Sstevel@tonic-gate 			v1_np->start_blk = (daddr_t)v2_np->start_blk;
2060Sstevel@tonic-gate 		}
2070Sstevel@tonic-gate 		v1_np->drivenamep = v1_dp;
2080Sstevel@tonic-gate 	}
2090Sstevel@tonic-gate 
2100Sstevel@tonic-gate 	/* We don't care about the rest of the fields */
2110Sstevel@tonic-gate 	v1_dp->side_names = v2_dp->side_names;
2120Sstevel@tonic-gate 	v1_dp->side_names_key = v2_dp->side_names_key;
2130Sstevel@tonic-gate 	v1_dp->miscname = v2_dp->miscname;
2140Sstevel@tonic-gate }
2150Sstevel@tonic-gate 
2160Sstevel@tonic-gate /*
2170Sstevel@tonic-gate  * Convert an old style md_drive_desc_t into a new style
2180Sstevel@tonic-gate  * md_drive_desc_t. Meant to be used *ONLY* by rpc.metad
2190Sstevel@tonic-gate  */
2200Sstevel@tonic-gate void
meta_conv_drvdesc_old2new(o_md_drive_desc * v1_dd,md_drive_desc * v2_dd)2210Sstevel@tonic-gate meta_conv_drvdesc_old2new(
2220Sstevel@tonic-gate 	o_md_drive_desc		*v1_dd,
2230Sstevel@tonic-gate 	md_drive_desc		*v2_dd
2240Sstevel@tonic-gate )
2250Sstevel@tonic-gate {
2260Sstevel@tonic-gate 	md_drive_desc	*dd;
2270Sstevel@tonic-gate 	o_md_drive_desc	*o_dd;
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 	dd = v2_dd;
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate 	for (o_dd = v1_dd; o_dd != NULL; o_dd = o_dd->dd_next) {
2320Sstevel@tonic-gate 		dd->dd_ctime = o_dd->dd_ctime;
2330Sstevel@tonic-gate 		dd->dd_genid = o_dd->dd_genid;
2340Sstevel@tonic-gate 		dd->dd_flags = o_dd->dd_flags;
2350Sstevel@tonic-gate 		meta_conv_drvname_old2new(o_dd->dd_dnp, dd->dd_dnp);
2360Sstevel@tonic-gate 		dd->dd_dbcnt = o_dd->dd_dbcnt;
2370Sstevel@tonic-gate 		dd->dd_dbsize = o_dd->dd_dbsize;
2380Sstevel@tonic-gate 		dd = dd->dd_next;
2390Sstevel@tonic-gate 	}
2400Sstevel@tonic-gate }
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate /*
2430Sstevel@tonic-gate  * Convert an new style md_drive_desc_t into a old style
2440Sstevel@tonic-gate  * md_drive_desc_t. Meant to be used *ONLY* by rpc.metad
2450Sstevel@tonic-gate  */
2460Sstevel@tonic-gate void
meta_conv_drvdesc_new2old(o_md_drive_desc * v1_dd,md_drive_desc * v2_dd)2470Sstevel@tonic-gate meta_conv_drvdesc_new2old(
2480Sstevel@tonic-gate 	o_md_drive_desc		*v1_dd,
2490Sstevel@tonic-gate 	md_drive_desc		*v2_dd
2500Sstevel@tonic-gate )
2510Sstevel@tonic-gate {
2520Sstevel@tonic-gate 	md_drive_desc	*dd;
2530Sstevel@tonic-gate 	o_md_drive_desc	*o_dd;
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate 	o_dd = v1_dd;
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 	for (dd = v2_dd; dd != NULL; dd = dd->dd_next) {
2580Sstevel@tonic-gate 		o_dd->dd_ctime = dd->dd_ctime;
2590Sstevel@tonic-gate 		o_dd->dd_genid = dd->dd_genid;
2600Sstevel@tonic-gate 		o_dd->dd_flags = dd->dd_flags;
2610Sstevel@tonic-gate 		meta_conv_drvname_new2old(o_dd->dd_dnp, dd->dd_dnp);
2620Sstevel@tonic-gate 		o_dd->dd_dbcnt = dd->dd_dbcnt;
2630Sstevel@tonic-gate 		o_dd->dd_dbsize = dd->dd_dbsize;
2640Sstevel@tonic-gate 		o_dd = o_dd->dd_next;
2650Sstevel@tonic-gate 	}
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate 
2680Sstevel@tonic-gate /*
2690Sstevel@tonic-gate  * Allocate memory for v1 drive descriptor
2700Sstevel@tonic-gate  * depending upon the number of drives in the
2710Sstevel@tonic-gate  * v2 drive descriptor
2720Sstevel@tonic-gate  */
2730Sstevel@tonic-gate void
alloc_olddrvdesc(o_md_drive_desc ** v1_dd,md_drive_desc * v2_dd)2740Sstevel@tonic-gate alloc_olddrvdesc(
2750Sstevel@tonic-gate 	o_md_drive_desc		**v1_dd,
2760Sstevel@tonic-gate 	md_drive_desc		*v2_dd
2770Sstevel@tonic-gate )
2780Sstevel@tonic-gate {
2790Sstevel@tonic-gate 	md_drive_desc	*dd;
2800Sstevel@tonic-gate 	o_md_drive_desc *new, *head;
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate 	head = NULL;
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 	for (dd = v2_dd; dd != NULL; dd = dd->dd_next) {
2850Sstevel@tonic-gate 		new = Zalloc(sizeof (o_md_drive_desc));
2860Sstevel@tonic-gate 		new->dd_dnp = Zalloc(sizeof (o_mddrivename_t));
2870Sstevel@tonic-gate 		new->dd_dnp->parts.parts_val = Zalloc(sizeof (o_mdname_t) *
2880Sstevel@tonic-gate 		    dd->dd_dnp->parts.parts_len);
2890Sstevel@tonic-gate 		new->dd_next = head;
2900Sstevel@tonic-gate 		head = new;
2910Sstevel@tonic-gate 	}
2920Sstevel@tonic-gate 	*v1_dd = head;
2930Sstevel@tonic-gate }
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate /*
2960Sstevel@tonic-gate  * Allocate memory for v2 drive descriptor
2970Sstevel@tonic-gate  * depending upon the number of drives in the
2980Sstevel@tonic-gate  * v1 drive descriptor
2990Sstevel@tonic-gate  */
3000Sstevel@tonic-gate void
alloc_newdrvdesc(o_md_drive_desc * v1_dd,md_drive_desc ** v2_dd)3010Sstevel@tonic-gate alloc_newdrvdesc(
3020Sstevel@tonic-gate 	o_md_drive_desc		*v1_dd,
3030Sstevel@tonic-gate 	md_drive_desc		**v2_dd
3040Sstevel@tonic-gate )
3050Sstevel@tonic-gate {
3060Sstevel@tonic-gate 	md_drive_desc	*new, *head;
3070Sstevel@tonic-gate 	o_md_drive_desc	*o_dd;
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate 	head = NULL;
3100Sstevel@tonic-gate 
3110Sstevel@tonic-gate 	for (o_dd = v1_dd; o_dd != NULL; o_dd = o_dd->dd_next) {
3120Sstevel@tonic-gate 		new = Zalloc(sizeof (md_drive_desc));
3130Sstevel@tonic-gate 		new->dd_dnp = Zalloc(sizeof (mddrivename_t));
3140Sstevel@tonic-gate 		new->dd_dnp->parts.parts_val = Zalloc(sizeof (mdname_t) *
3150Sstevel@tonic-gate 		    o_dd->dd_dnp->parts.parts_len);
3160Sstevel@tonic-gate 		new->dd_next = head;
3170Sstevel@tonic-gate 		head = new;
3180Sstevel@tonic-gate 	}
3190Sstevel@tonic-gate 	*v2_dd = head;
3200Sstevel@tonic-gate }
3210Sstevel@tonic-gate 
3220Sstevel@tonic-gate void
free_olddrvdesc(o_md_drive_desc * v1_dd)3230Sstevel@tonic-gate free_olddrvdesc(
3240Sstevel@tonic-gate 	o_md_drive_desc		*v1_dd
3250Sstevel@tonic-gate )
3260Sstevel@tonic-gate {
3270Sstevel@tonic-gate 	o_md_drive_desc	*o_dd, *head;
3280Sstevel@tonic-gate 
3290Sstevel@tonic-gate 	head = v1_dd;
3300Sstevel@tonic-gate 
3310Sstevel@tonic-gate 	while (head != NULL) {
3320Sstevel@tonic-gate 		o_dd = head;
3330Sstevel@tonic-gate 		head = head->dd_next;
3340Sstevel@tonic-gate 		free(o_dd->dd_dnp->parts.parts_val);
3350Sstevel@tonic-gate 		free(o_dd->dd_dnp);
3360Sstevel@tonic-gate 		free(o_dd);
3370Sstevel@tonic-gate 	}
3380Sstevel@tonic-gate }
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate void
free_newdrvdesc(md_drive_desc * v2_dd)3410Sstevel@tonic-gate free_newdrvdesc(
3420Sstevel@tonic-gate 	md_drive_desc		*v2_dd
3430Sstevel@tonic-gate )
3440Sstevel@tonic-gate {
3450Sstevel@tonic-gate 	md_drive_desc	*dd, *head;
3460Sstevel@tonic-gate 
3470Sstevel@tonic-gate 	head = v2_dd;
3480Sstevel@tonic-gate 
3490Sstevel@tonic-gate 	while (head != NULL) {
3500Sstevel@tonic-gate 		dd = head;
3510Sstevel@tonic-gate 		head = head->dd_next;
3520Sstevel@tonic-gate 		free(dd->dd_dnp->parts.parts_val);
3530Sstevel@tonic-gate 		free(dd->dd_dnp);
3540Sstevel@tonic-gate 		free(dd);
3550Sstevel@tonic-gate 	}
3560Sstevel@tonic-gate }
3570Sstevel@tonic-gate 
3580Sstevel@tonic-gate /*
3590Sstevel@tonic-gate  * Return the device id for a given device
3600Sstevel@tonic-gate  */
3610Sstevel@tonic-gate char *
meta_get_devid(char * rname)3620Sstevel@tonic-gate meta_get_devid(
3630Sstevel@tonic-gate 	char	*rname
3640Sstevel@tonic-gate )
3650Sstevel@tonic-gate {
3660Sstevel@tonic-gate 	ddi_devid_t	devid;
3670Sstevel@tonic-gate 	int		fd;
3680Sstevel@tonic-gate 	char		*enc_devid, *dup_enc_devid = NULL;
3690Sstevel@tonic-gate 
3700Sstevel@tonic-gate 	if ((fd = open(rname, O_RDWR | O_NDELAY, 0)) < 0)
3710Sstevel@tonic-gate 		return (NULL);
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate 	if (devid_get(fd, &devid) == -1) {
3740Sstevel@tonic-gate 		(void) close(fd);
3750Sstevel@tonic-gate 		return (NULL);
3760Sstevel@tonic-gate 	}
3770Sstevel@tonic-gate 	(void) close(fd);
3780Sstevel@tonic-gate 
3790Sstevel@tonic-gate 	enc_devid = devid_str_encode(devid, NULL);
3800Sstevel@tonic-gate 	devid_free(devid);
3810Sstevel@tonic-gate 
3820Sstevel@tonic-gate 	if (enc_devid != NULL) {
3830Sstevel@tonic-gate 		dup_enc_devid = strdup(enc_devid);
3840Sstevel@tonic-gate 		devid_str_free(enc_devid);
3850Sstevel@tonic-gate 	}
3860Sstevel@tonic-gate 
3870Sstevel@tonic-gate 	return (dup_enc_devid);
3880Sstevel@tonic-gate }
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate /*
3910Sstevel@tonic-gate  * Add side names for the diskset drive records
3920Sstevel@tonic-gate  * NOTE: these go into the local set's namespace.
3930Sstevel@tonic-gate  */
3940Sstevel@tonic-gate int
clnt_add_drv_sidenms(char * hostname,char * this_host,mdsetname_t * sp,md_set_desc * sd,int node_c,char ** node_v,md_error_t * ep)3950Sstevel@tonic-gate clnt_add_drv_sidenms(
3960Sstevel@tonic-gate 	char			*hostname,
3970Sstevel@tonic-gate 	char			*this_host,
3980Sstevel@tonic-gate 	mdsetname_t		*sp,
3990Sstevel@tonic-gate 	md_set_desc		*sd,
4000Sstevel@tonic-gate 	int			node_c,
4010Sstevel@tonic-gate 	char			**node_v,
4020Sstevel@tonic-gate 	md_error_t		*ep
4030Sstevel@tonic-gate )
4040Sstevel@tonic-gate {
4050Sstevel@tonic-gate 	CLIENT				*clntp;
4060Sstevel@tonic-gate 	mdrpc_drv_sidenm_args		v1_args;
4070Sstevel@tonic-gate 	mdrpc_drv_sidenm_2_args		v2_args;
4080Sstevel@tonic-gate 	mdrpc_drv_sidenm_2_args_r1	*v21_args;
4090Sstevel@tonic-gate 	mdrpc_generic_res		res;
4100Sstevel@tonic-gate 	int				rval;
4110Sstevel@tonic-gate 	int				version;
4120Sstevel@tonic-gate 	int				i, j;
4130Sstevel@tonic-gate 
4140Sstevel@tonic-gate 	/* initialize */
4150Sstevel@tonic-gate 	mdclrerror(ep);
4160Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
4170Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
4180Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
4190Sstevel@tonic-gate 
4200Sstevel@tonic-gate 	/* build args */
4210Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
4220Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_drv_sidenm_2_args_u.rev1;
4230Sstevel@tonic-gate 	v21_args->hostname = this_host;
4240Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
4250Sstevel@tonic-gate 	v21_args->sp = sp;
4260Sstevel@tonic-gate 	v21_args->sd = sd;
4270Sstevel@tonic-gate 	v21_args->node_v.node_v_len = node_c;
4280Sstevel@tonic-gate 	v21_args->node_v.node_v_val = node_v;
4290Sstevel@tonic-gate 
4300Sstevel@tonic-gate 	/* do it */
4310Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
4320Sstevel@tonic-gate 		int	bool;
4330Sstevel@tonic-gate 
4340Sstevel@tonic-gate 		/*
4350Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
4360Sstevel@tonic-gate 		 */
4370Sstevel@tonic-gate 		bool = mdrpc_add_drv_sidenms_2_svc(&v2_args, &res, NULL);
4380Sstevel@tonic-gate 		assert(bool == TRUE);
4390Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
4400Sstevel@tonic-gate 	} else {
4410Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
4420Sstevel@tonic-gate 			return (-1);
4430Sstevel@tonic-gate 
4440Sstevel@tonic-gate 		/*
4450Sstevel@tonic-gate 		 * Check the client handle for the version
4460Sstevel@tonic-gate 		 * and invoke the appropriate version of the
4470Sstevel@tonic-gate 		 * remote procedure
4480Sstevel@tonic-gate 		 */
4490Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
4500Sstevel@tonic-gate 
4510Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
4520Sstevel@tonic-gate 
4530Sstevel@tonic-gate 			v1_args.sd = Zalloc(sizeof (o_md_set_desc));
4540Sstevel@tonic-gate 			alloc_olddrvdesc(&v1_args.sd->sd_drvs, sd->sd_drvs);
4550Sstevel@tonic-gate 
4560Sstevel@tonic-gate 			/* build args */
4570Sstevel@tonic-gate 			v1_args.hostname = this_host;
4580Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
4590Sstevel@tonic-gate 			v1_args.sp = sp;
4600Sstevel@tonic-gate 			/* set descriptor */
4610Sstevel@tonic-gate 			v1_args.sd->sd_ctime = sd->sd_ctime;
4620Sstevel@tonic-gate 			v1_args.sd->sd_genid = sd->sd_genid;
4630Sstevel@tonic-gate 			v1_args.sd->sd_setno = sd->sd_setno;
4640Sstevel@tonic-gate 			v1_args.sd->sd_flags = sd->sd_flags;
4650Sstevel@tonic-gate 			for (i = 0; i < MD_MAXSIDES; i++) {
4660Sstevel@tonic-gate 				v1_args.sd->sd_isown[i] = sd->sd_isown[i];
4670Sstevel@tonic-gate 
4680Sstevel@tonic-gate 				for (j = 0; j < MD_MAX_NODENAME_PLUS_1; j ++)
4690Sstevel@tonic-gate 					v1_args.sd->sd_nodes[i][j] =
4700Sstevel@tonic-gate 					    sd->sd_nodes[i][j];
4710Sstevel@tonic-gate 			}
4720Sstevel@tonic-gate 			v1_args.sd->sd_med = sd->sd_med;
4730Sstevel@tonic-gate 			meta_conv_drvdesc_new2old(v1_args.sd->sd_drvs,
4740Sstevel@tonic-gate 			    sd->sd_drvs);
4750Sstevel@tonic-gate 			v1_args.node_v.node_v_len = node_c;
4760Sstevel@tonic-gate 			v1_args.node_v.node_v_val = node_v;
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate 			rval = mdrpc_add_drv_sidenms_1(&v1_args, &res, clntp);
4790Sstevel@tonic-gate 
4800Sstevel@tonic-gate 			free_olddrvdesc(v1_args.sd->sd_drvs);
4810Sstevel@tonic-gate 			free(v1_args.sd);
4820Sstevel@tonic-gate 
4830Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
4840Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
4850Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
4860Sstevel@tonic-gate 				    "metad add drive sidenames"));
4870Sstevel@tonic-gate 			else
4880Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
4890Sstevel@tonic-gate 		} else {			/* version 2 */
4900Sstevel@tonic-gate 			rval = mdrpc_add_drv_sidenms_2(&v2_args, &res, clntp);
4910Sstevel@tonic-gate 
4920Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
4930Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
4940Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
4950Sstevel@tonic-gate 				    "metad add drive sidenames"));
4960Sstevel@tonic-gate 			else
4970Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
4980Sstevel@tonic-gate 		}
4990Sstevel@tonic-gate 
5000Sstevel@tonic-gate 		metarpcclose(clntp);
5010Sstevel@tonic-gate 	}
5020Sstevel@tonic-gate 
5030Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
5040Sstevel@tonic-gate 
5050Sstevel@tonic-gate 	if (! mdisok(ep))
5060Sstevel@tonic-gate 		return (-1);
5070Sstevel@tonic-gate 
5080Sstevel@tonic-gate 	return (0);
5090Sstevel@tonic-gate }
5100Sstevel@tonic-gate 
5110Sstevel@tonic-gate /*
512*1945Sjeanm  * Adding drives via metaimport to disksets. Some of the drives may
513*1945Sjeanm  * not be available so we need more information than the basic clnt_adddrvs
514*1945Sjeanm  * offers us.
515*1945Sjeanm  */
516*1945Sjeanm int
clnt_imp_adddrvs(char * hostname,mdsetname_t * sp,md_drive_desc * dd,md_timeval32_t timestamp,ulong_t genid,md_error_t * ep)517*1945Sjeanm clnt_imp_adddrvs(
518*1945Sjeanm 	char			*hostname,
519*1945Sjeanm 	mdsetname_t		*sp,
520*1945Sjeanm 	md_drive_desc		*dd,
521*1945Sjeanm 	md_timeval32_t		timestamp,
522*1945Sjeanm 	ulong_t			genid,
523*1945Sjeanm 	md_error_t		*ep
524*1945Sjeanm )
525*1945Sjeanm {
526*1945Sjeanm 	CLIENT			*clntp;
527*1945Sjeanm 	mdrpc_drives_2_args	v2_args;
528*1945Sjeanm 	mdrpc_drives_2_args_r1	*v21_args;
529*1945Sjeanm 	mdrpc_generic_res	res;
530*1945Sjeanm 	int			rval;
531*1945Sjeanm 	int			version;
532*1945Sjeanm 
533*1945Sjeanm 	/* initialize */
534*1945Sjeanm 	mdclrerror(ep);
535*1945Sjeanm 	(void) memset(&v2_args, 0, sizeof (v2_args));
536*1945Sjeanm 	(void) memset(&res, 0, sizeof (res));
537*1945Sjeanm 
538*1945Sjeanm 	/* build args */
539*1945Sjeanm 	v2_args.rev = MD_METAD_ARGS_REV_1;
540*1945Sjeanm 	v21_args = &v2_args.mdrpc_drives_2_args_u.rev1;
541*1945Sjeanm 	v21_args->sp = sp;
542*1945Sjeanm 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
543*1945Sjeanm 	v21_args->drivedescs = dd;
544*1945Sjeanm 	v21_args->timestamp = timestamp;
545*1945Sjeanm 	v21_args->genid = genid;
546*1945Sjeanm 
547*1945Sjeanm 	/* do it */
548*1945Sjeanm 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
549*1945Sjeanm 		int	bool;
550*1945Sjeanm 
551*1945Sjeanm 		/*
552*1945Sjeanm 		 * If the server is local, we call the v1 procedure
553*1945Sjeanm 		 */
554*1945Sjeanm 		bool = mdrpc_imp_adddrvs_2(&v2_args, &res, NULL);
555*1945Sjeanm 		assert(bool == TRUE);
556*1945Sjeanm 		(void) mdstealerror(ep, &res.status);
557*1945Sjeanm 	} else {
558*1945Sjeanm 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
559*1945Sjeanm 			return (-1);
560*1945Sjeanm 
561*1945Sjeanm 		/*
562*1945Sjeanm 		 * Check the client handle for the version
563*1945Sjeanm 		 * and invoke the appropriate version of the
564*1945Sjeanm 		 * remote procedure
565*1945Sjeanm 		 */
566*1945Sjeanm 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
567*1945Sjeanm 
568*1945Sjeanm 		/*
569*1945Sjeanm 		 * If the client is version 1, return error
570*1945Sjeanm 		 * otherwise, make the remote procedure call.
571*1945Sjeanm 		 */
572*1945Sjeanm 		if (version == METAD_VERSION) { /* version 1 */
573*1945Sjeanm 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
574*1945Sjeanm 			    sp->setno, hostname, NULL, NULL);
575*1945Sjeanm 			metarpcclose(clntp);
576*1945Sjeanm 			return (-1);
577*1945Sjeanm 		} else {
578*1945Sjeanm 			rval = mdrpc_imp_adddrvs_2(&v2_args, &res, clntp);
579*1945Sjeanm 			if (rval != RPC_SUCCESS)
580*1945Sjeanm 				(void) mdrpcerror(ep, clntp, hostname,
581*1945Sjeanm 				    dgettext(TEXT_DOMAIN,
582*1945Sjeanm 				    "metad imp add drives"));
583*1945Sjeanm 			else
584*1945Sjeanm 				(void) mdstealerror(ep, &res.status);
585*1945Sjeanm 		}
586*1945Sjeanm 
587*1945Sjeanm 		metarpcclose(clntp);
588*1945Sjeanm 	}
589*1945Sjeanm 
590*1945Sjeanm 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
591*1945Sjeanm 
592*1945Sjeanm 	if (! mdisok(ep))
593*1945Sjeanm 		return (-1);
594*1945Sjeanm 
595*1945Sjeanm 	return (0);
596*1945Sjeanm }
597*1945Sjeanm 
598*1945Sjeanm 
599*1945Sjeanm /*
6000Sstevel@tonic-gate  * Add drives to disksets.
6010Sstevel@tonic-gate  */
6020Sstevel@tonic-gate int
clnt_adddrvs(char * hostname,mdsetname_t * sp,md_drive_desc * dd,md_timeval32_t timestamp,ulong_t genid,md_error_t * ep)6030Sstevel@tonic-gate clnt_adddrvs(
6040Sstevel@tonic-gate 	char			*hostname,
6050Sstevel@tonic-gate 	mdsetname_t		*sp,
6060Sstevel@tonic-gate 	md_drive_desc		*dd,
6070Sstevel@tonic-gate 	md_timeval32_t		timestamp,
6080Sstevel@tonic-gate 	ulong_t			genid,
6090Sstevel@tonic-gate 	md_error_t		*ep
6100Sstevel@tonic-gate )
6110Sstevel@tonic-gate {
6120Sstevel@tonic-gate 	CLIENT			*clntp;
6130Sstevel@tonic-gate 	mdrpc_drives_args	v1_args;
6140Sstevel@tonic-gate 	mdrpc_drives_2_args	v2_args;
6150Sstevel@tonic-gate 	mdrpc_drives_2_args_r1	*v21_args;
6160Sstevel@tonic-gate 	mdrpc_generic_res	res;
6170Sstevel@tonic-gate 	int			rval;
6180Sstevel@tonic-gate 	int			version;
6190Sstevel@tonic-gate 
6200Sstevel@tonic-gate 	/* initialize */
6210Sstevel@tonic-gate 	mdclrerror(ep);
6220Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
6230Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
6240Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
6250Sstevel@tonic-gate 
6260Sstevel@tonic-gate 	/* build args */
6270Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
6280Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_drives_2_args_u.rev1;
6290Sstevel@tonic-gate 	v21_args->sp = sp;
6300Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
6310Sstevel@tonic-gate 	v21_args->drivedescs = dd;
6320Sstevel@tonic-gate 	v21_args->timestamp = timestamp;
6330Sstevel@tonic-gate 	v21_args->genid = genid;
6340Sstevel@tonic-gate 
6350Sstevel@tonic-gate 	/* do it */
6360Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
6370Sstevel@tonic-gate 		int	bool;
6380Sstevel@tonic-gate 
6390Sstevel@tonic-gate 		/*
6400Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
6410Sstevel@tonic-gate 		 */
6420Sstevel@tonic-gate 		bool = mdrpc_adddrvs_2_svc(&v2_args, &res, NULL);
6430Sstevel@tonic-gate 		assert(bool == TRUE);
6440Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
6450Sstevel@tonic-gate 	} else {
6460Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
6470Sstevel@tonic-gate 			return (-1);
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate 		/*
6500Sstevel@tonic-gate 		 * Check the client handle for the version
6510Sstevel@tonic-gate 		 * and invoke the appropriate version of the
6520Sstevel@tonic-gate 		 * remote procedure
6530Sstevel@tonic-gate 		 */
6540Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
6550Sstevel@tonic-gate 
6560Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
6570Sstevel@tonic-gate 
6580Sstevel@tonic-gate 			alloc_olddrvdesc(&v1_args.drivedescs, dd);
6590Sstevel@tonic-gate 
6600Sstevel@tonic-gate 			/* build args */
6610Sstevel@tonic-gate 			v1_args.sp = sp;
6620Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
6630Sstevel@tonic-gate 			meta_conv_drvdesc_new2old(v1_args.drivedescs, dd);
6640Sstevel@tonic-gate 			v1_args.timestamp = timestamp;
6650Sstevel@tonic-gate 			v1_args.genid = genid;
6660Sstevel@tonic-gate 
6670Sstevel@tonic-gate 			rval = mdrpc_adddrvs_1(&v1_args, &res, clntp);
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate 			free_olddrvdesc(v1_args.drivedescs);
6700Sstevel@tonic-gate 
6710Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
6720Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
6730Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad add drives"));
6740Sstevel@tonic-gate 			else
6750Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
6760Sstevel@tonic-gate 		} else {			/* version 2 */
6770Sstevel@tonic-gate 			rval = mdrpc_adddrvs_2(&v2_args, &res, clntp);
6780Sstevel@tonic-gate 
6790Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
6800Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
6810Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad add drives"));
6820Sstevel@tonic-gate 			else
6830Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
6840Sstevel@tonic-gate 		}
6850Sstevel@tonic-gate 
6860Sstevel@tonic-gate 		metarpcclose(clntp);
6870Sstevel@tonic-gate 	}
6880Sstevel@tonic-gate 
6890Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
6900Sstevel@tonic-gate 
6910Sstevel@tonic-gate 	if (! mdisok(ep))
6920Sstevel@tonic-gate 		return (-1);
6930Sstevel@tonic-gate 
6940Sstevel@tonic-gate 	return (0);
6950Sstevel@tonic-gate }
6960Sstevel@tonic-gate 
6970Sstevel@tonic-gate /*
6980Sstevel@tonic-gate  * Add hosts to disksets.
6990Sstevel@tonic-gate  */
7000Sstevel@tonic-gate int
clnt_addhosts(char * hostname,mdsetname_t * sp,int node_c,char ** node_v,md_error_t * ep)7010Sstevel@tonic-gate clnt_addhosts(
7020Sstevel@tonic-gate 	char			*hostname,
7030Sstevel@tonic-gate 	mdsetname_t		*sp,
7040Sstevel@tonic-gate 	int			node_c,
7050Sstevel@tonic-gate 	char			**node_v,
7060Sstevel@tonic-gate 	md_error_t		*ep
7070Sstevel@tonic-gate )
7080Sstevel@tonic-gate {
7090Sstevel@tonic-gate 	CLIENT			*clntp;
7100Sstevel@tonic-gate 	mdrpc_host_args		*args;
7110Sstevel@tonic-gate 	mdrpc_host_2_args	v2_args;
7120Sstevel@tonic-gate 	mdrpc_generic_res	res;
7130Sstevel@tonic-gate 	int			version;
7140Sstevel@tonic-gate 
7150Sstevel@tonic-gate 	/* initialize */
7160Sstevel@tonic-gate 	mdclrerror(ep);
7170Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
7180Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
7190Sstevel@tonic-gate 
7200Sstevel@tonic-gate 	/* build args */
7210Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
7220Sstevel@tonic-gate 	args = &v2_args.mdrpc_host_2_args_u.rev1;
7230Sstevel@tonic-gate 	args->sp = sp;
7240Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
7250Sstevel@tonic-gate 	args->hosts.hosts_len = node_c;
7260Sstevel@tonic-gate 	args->hosts.hosts_val = node_v;
7270Sstevel@tonic-gate 
7280Sstevel@tonic-gate 	/* do it */
7290Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
7300Sstevel@tonic-gate 		int bool;
7310Sstevel@tonic-gate 		bool = mdrpc_addhosts_2_svc(&v2_args, &res, NULL);
7320Sstevel@tonic-gate 		assert(bool == TRUE);
7330Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
7340Sstevel@tonic-gate 	} else {
7350Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
7360Sstevel@tonic-gate 			return (-1);
7370Sstevel@tonic-gate 
7380Sstevel@tonic-gate 		/*
7390Sstevel@tonic-gate 		 * Check the client handle for the version and invoke
7400Sstevel@tonic-gate 		 * the appropriate version of the remote procedure
7410Sstevel@tonic-gate 		 */
7420Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
7430Sstevel@tonic-gate 
7440Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
7450Sstevel@tonic-gate 			if (mdrpc_addhosts_1(args, &res, clntp) != RPC_SUCCESS)
7460Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
7470Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad add hosts"));
7480Sstevel@tonic-gate 			else
7490Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
7500Sstevel@tonic-gate 		} else {
7510Sstevel@tonic-gate 			if (mdrpc_addhosts_2(&v2_args, &res, clntp) !=
7520Sstevel@tonic-gate 			    RPC_SUCCESS)
7530Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
7540Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad add hosts"));
7550Sstevel@tonic-gate 			else
7560Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
7570Sstevel@tonic-gate 		}
7580Sstevel@tonic-gate 
7590Sstevel@tonic-gate 		metarpcclose(clntp);
7600Sstevel@tonic-gate 	}
7610Sstevel@tonic-gate 
7620Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
7630Sstevel@tonic-gate 
7640Sstevel@tonic-gate 	if (! mdisok(ep))
7650Sstevel@tonic-gate 		return (-1);
7660Sstevel@tonic-gate 
7670Sstevel@tonic-gate 	return (0);
7680Sstevel@tonic-gate }
7690Sstevel@tonic-gate 
7700Sstevel@tonic-gate /*
7710Sstevel@tonic-gate  * Create disksets.
7720Sstevel@tonic-gate  */
7730Sstevel@tonic-gate int
clnt_createset(char * hostname,mdsetname_t * sp,md_node_nm_arr_t nodes,md_timeval32_t timestamp,ulong_t genid,md_error_t * ep)7740Sstevel@tonic-gate clnt_createset(
7750Sstevel@tonic-gate 	char			*hostname,
7760Sstevel@tonic-gate 	mdsetname_t		*sp,
7770Sstevel@tonic-gate 	md_node_nm_arr_t	nodes,
7780Sstevel@tonic-gate 	md_timeval32_t		timestamp,
7790Sstevel@tonic-gate 	ulong_t			genid,
7800Sstevel@tonic-gate 	md_error_t		*ep
7810Sstevel@tonic-gate )
7820Sstevel@tonic-gate {
7830Sstevel@tonic-gate 	CLIENT			*clntp;
7840Sstevel@tonic-gate 	mdrpc_createset_args	*args;
7850Sstevel@tonic-gate 	mdrpc_createset_2_args	v2_args;
7860Sstevel@tonic-gate 	mdrpc_generic_res	res;
7870Sstevel@tonic-gate 	int			i;
7880Sstevel@tonic-gate 	int			version;
7890Sstevel@tonic-gate 
7900Sstevel@tonic-gate 	/* initialize */
7910Sstevel@tonic-gate 	mdclrerror(ep);
7920Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
7930Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
7940Sstevel@tonic-gate 
7950Sstevel@tonic-gate 	/* build args */
7960Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
7970Sstevel@tonic-gate 	args = &v2_args.mdrpc_createset_2_args_u.rev1;
7980Sstevel@tonic-gate 	args->sp = sp;
7990Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
8000Sstevel@tonic-gate 	args->timestamp = timestamp;
8010Sstevel@tonic-gate 	args->genid = genid;
8020Sstevel@tonic-gate 	for (i = 0; i < MD_MAXSIDES; i++)
8030Sstevel@tonic-gate 		(void) strcpy(args->nodes[i], nodes[i]);
8040Sstevel@tonic-gate 
8050Sstevel@tonic-gate 	/* do it */
8060Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
8070Sstevel@tonic-gate 		int	bool;
8080Sstevel@tonic-gate 		bool = mdrpc_createset_2_svc(&v2_args, &res, NULL);
8090Sstevel@tonic-gate 		assert(bool == TRUE);
8100Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
8110Sstevel@tonic-gate 	} else {
8120Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
8130Sstevel@tonic-gate 			return (-1);
8140Sstevel@tonic-gate 
8150Sstevel@tonic-gate 		/*
8160Sstevel@tonic-gate 		 * Check the client handle for the version and invoke
8170Sstevel@tonic-gate 		 * the appropriate version of the remote procedure
8180Sstevel@tonic-gate 		 */
8190Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
8200Sstevel@tonic-gate 
8210Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
8220Sstevel@tonic-gate 			if (mdrpc_createset_1(args, &res, clntp) !=
8230Sstevel@tonic-gate 			    RPC_SUCCESS)
8240Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
8250Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad create set"));
8260Sstevel@tonic-gate 			else
8270Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
8280Sstevel@tonic-gate 		} else {
8290Sstevel@tonic-gate 			if (mdrpc_createset_2(&v2_args, &res, clntp) !=
8300Sstevel@tonic-gate 			    RPC_SUCCESS)
8310Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
8320Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad create set"));
8330Sstevel@tonic-gate 			else
8340Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
8350Sstevel@tonic-gate 		}
8360Sstevel@tonic-gate 
8370Sstevel@tonic-gate 		metarpcclose(clntp);
8380Sstevel@tonic-gate 	}
8390Sstevel@tonic-gate 
8400Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
8410Sstevel@tonic-gate 
8420Sstevel@tonic-gate 	if (! mdisok(ep))
8430Sstevel@tonic-gate 		return (-1);
8440Sstevel@tonic-gate 
8450Sstevel@tonic-gate 	return (0);
8460Sstevel@tonic-gate }
8470Sstevel@tonic-gate 
8480Sstevel@tonic-gate /*
8490Sstevel@tonic-gate  * Create MN disksets.
8500Sstevel@tonic-gate  */
8510Sstevel@tonic-gate int
clnt_mncreateset(char * hostname,mdsetname_t * sp,md_mnnode_desc * nodelist,md_timeval32_t timestamp,ulong_t genid,md_node_nm_t master_nodenm,int master_nodeid,md_error_t * ep)8520Sstevel@tonic-gate clnt_mncreateset(
8530Sstevel@tonic-gate 	char			*hostname,
8540Sstevel@tonic-gate 	mdsetname_t		*sp,
8550Sstevel@tonic-gate 	md_mnnode_desc		*nodelist,
8560Sstevel@tonic-gate 	md_timeval32_t		timestamp,
8570Sstevel@tonic-gate 	ulong_t			genid,
8580Sstevel@tonic-gate 	md_node_nm_t		master_nodenm,
8590Sstevel@tonic-gate 	int			master_nodeid,
8600Sstevel@tonic-gate 	md_error_t		*ep
8610Sstevel@tonic-gate )
8620Sstevel@tonic-gate {
8630Sstevel@tonic-gate 	CLIENT			*clntp;
8640Sstevel@tonic-gate 	mdrpc_mncreateset_args	*args;
8650Sstevel@tonic-gate 	mdrpc_mncreateset_2_args v2_args;
8660Sstevel@tonic-gate 	mdrpc_generic_res	res;
8670Sstevel@tonic-gate 	int			version;
8680Sstevel@tonic-gate 
8690Sstevel@tonic-gate 	/* initialize */
8700Sstevel@tonic-gate 	mdclrerror(ep);
8710Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
8720Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
8730Sstevel@tonic-gate 
8740Sstevel@tonic-gate 	/* build args */
8750Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
8760Sstevel@tonic-gate 	args = &v2_args.mdrpc_mncreateset_2_args_u.rev1;
8770Sstevel@tonic-gate 	args->sp = sp;
8780Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
8790Sstevel@tonic-gate 	args->timestamp = timestamp;
8800Sstevel@tonic-gate 	args->genid = genid;
8810Sstevel@tonic-gate 	(void) strlcpy(args->master_nodenm, master_nodenm, MD_MAX_NODENAME);
8820Sstevel@tonic-gate 	args->master_nodeid = master_nodeid;
8830Sstevel@tonic-gate 	args->nodelist = nodelist;
8840Sstevel@tonic-gate 
8850Sstevel@tonic-gate 	/* do it */
8860Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
8870Sstevel@tonic-gate 		int	bool;
8880Sstevel@tonic-gate 		bool = mdrpc_mncreateset_2_svc(&v2_args, &res, NULL);
8890Sstevel@tonic-gate 		assert(bool == TRUE);
8900Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
8910Sstevel@tonic-gate 	} else {
8920Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
8930Sstevel@tonic-gate 			return (-1);
8940Sstevel@tonic-gate 
8950Sstevel@tonic-gate 		/*
8960Sstevel@tonic-gate 		 * Check the client handle for the version
8970Sstevel@tonic-gate 		 */
8980Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
8990Sstevel@tonic-gate 
9000Sstevel@tonic-gate 		/*
9010Sstevel@tonic-gate 		 * If the client is version 1, return error
9020Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
9030Sstevel@tonic-gate 		 */
9040Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
9050Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
9060Sstevel@tonic-gate 			    sp->setno, hostname, NULL, sp->setname);
9070Sstevel@tonic-gate 			metarpcclose(clntp);
9080Sstevel@tonic-gate 			return (-1);
9090Sstevel@tonic-gate 		} else {
9100Sstevel@tonic-gate 			if (mdrpc_mncreateset_2(&v2_args, &res, clntp)
9110Sstevel@tonic-gate 							!= RPC_SUCCESS)
9120Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
9130Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad mncreate set"));
9140Sstevel@tonic-gate 			else
9150Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
9160Sstevel@tonic-gate 		}
9170Sstevel@tonic-gate 
9180Sstevel@tonic-gate 		metarpcclose(clntp);
9190Sstevel@tonic-gate 	}
9200Sstevel@tonic-gate 
9210Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
9220Sstevel@tonic-gate 
9230Sstevel@tonic-gate 	if (! mdisok(ep))
9240Sstevel@tonic-gate 		return (-1);
9250Sstevel@tonic-gate 
9260Sstevel@tonic-gate 	return (0);
9270Sstevel@tonic-gate }
9280Sstevel@tonic-gate 
9290Sstevel@tonic-gate /*
9300Sstevel@tonic-gate  * Join MN set
9310Sstevel@tonic-gate  */
9320Sstevel@tonic-gate int
clnt_joinset(char * hostname,mdsetname_t * sp,int flags,md_error_t * ep)9330Sstevel@tonic-gate clnt_joinset(
9340Sstevel@tonic-gate 	char			*hostname,
9350Sstevel@tonic-gate 	mdsetname_t		*sp,
9360Sstevel@tonic-gate 	int			flags,
9370Sstevel@tonic-gate 	md_error_t		*ep
9380Sstevel@tonic-gate )
9390Sstevel@tonic-gate {
9400Sstevel@tonic-gate 	CLIENT			*clntp;
9410Sstevel@tonic-gate 	mdrpc_sp_flags_args	*args;
9420Sstevel@tonic-gate 	mdrpc_sp_flags_2_args	v2_args;
9430Sstevel@tonic-gate 	mdrpc_generic_res	res;
9440Sstevel@tonic-gate 	int			version;
9450Sstevel@tonic-gate 
9460Sstevel@tonic-gate 	/* initialize */
9470Sstevel@tonic-gate 	mdclrerror(ep);
9480Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
9490Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
9500Sstevel@tonic-gate 
9510Sstevel@tonic-gate 	/* build args */
9520Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
9530Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_flags_2_args_u.rev1;
9540Sstevel@tonic-gate 	args->sp = sp;
9550Sstevel@tonic-gate 	args->flags = flags;
9560Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
9570Sstevel@tonic-gate 
9580Sstevel@tonic-gate 	/* do it */
9590Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
9600Sstevel@tonic-gate 		int	bool;
9610Sstevel@tonic-gate 		bool = mdrpc_joinset_2_svc(&v2_args, &res, NULL);
9620Sstevel@tonic-gate 		assert(bool == TRUE);
9630Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
9640Sstevel@tonic-gate 	} else {
9650Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
9660Sstevel@tonic-gate 			return (-1);
9670Sstevel@tonic-gate 
9680Sstevel@tonic-gate 		/*
9690Sstevel@tonic-gate 		 * Check the client handle for the version
9700Sstevel@tonic-gate 		 */
9710Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
9720Sstevel@tonic-gate 
9730Sstevel@tonic-gate 		/*
9740Sstevel@tonic-gate 		 * If the client is version 1, return error
9750Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
9760Sstevel@tonic-gate 		 */
9770Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
9780Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
9790Sstevel@tonic-gate 			    sp->setno, hostname, NULL, sp->setname);
9800Sstevel@tonic-gate 			metarpcclose(clntp);
9810Sstevel@tonic-gate 			return (-1);
9820Sstevel@tonic-gate 		} else {
9830Sstevel@tonic-gate 			if (mdrpc_joinset_2(&v2_args, &res, clntp)
9840Sstevel@tonic-gate 							!= RPC_SUCCESS)
9850Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
9860Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad join set"));
9870Sstevel@tonic-gate 			else
9880Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
9890Sstevel@tonic-gate 		}
9900Sstevel@tonic-gate 
9910Sstevel@tonic-gate 		metarpcclose(clntp);
9920Sstevel@tonic-gate 	}
9930Sstevel@tonic-gate 
9940Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
9950Sstevel@tonic-gate 
9960Sstevel@tonic-gate 	if (! mdisok(ep))
9970Sstevel@tonic-gate 		return (-1);
9980Sstevel@tonic-gate 
9990Sstevel@tonic-gate 	return (0);
10000Sstevel@tonic-gate }
10010Sstevel@tonic-gate 
10020Sstevel@tonic-gate /*
10030Sstevel@tonic-gate  * Withdraw from MN set
10040Sstevel@tonic-gate  */
10050Sstevel@tonic-gate int
clnt_withdrawset(char * hostname,mdsetname_t * sp,md_error_t * ep)10060Sstevel@tonic-gate clnt_withdrawset(
10070Sstevel@tonic-gate 	char			*hostname,
10080Sstevel@tonic-gate 	mdsetname_t		*sp,
10090Sstevel@tonic-gate 	md_error_t		*ep
10100Sstevel@tonic-gate )
10110Sstevel@tonic-gate {
10120Sstevel@tonic-gate 	CLIENT			*clntp;
10130Sstevel@tonic-gate 	mdrpc_sp_args		*args;
10140Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
10150Sstevel@tonic-gate 	mdrpc_generic_res	res;
10160Sstevel@tonic-gate 	int			version;
10170Sstevel@tonic-gate 
10180Sstevel@tonic-gate 	/* initialize */
10190Sstevel@tonic-gate 	mdclrerror(ep);
10200Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
10210Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
10220Sstevel@tonic-gate 
10230Sstevel@tonic-gate 	/* build args */
10240Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
10250Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
10260Sstevel@tonic-gate 	args->sp = sp;
10270Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
10280Sstevel@tonic-gate 
10290Sstevel@tonic-gate 	/* do it */
10300Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
10310Sstevel@tonic-gate 		int	bool;
10320Sstevel@tonic-gate 		bool = mdrpc_withdrawset_2_svc(&v2_args, &res, NULL);
10330Sstevel@tonic-gate 		assert(bool == TRUE);
10340Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
10350Sstevel@tonic-gate 	} else {
10360Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
10370Sstevel@tonic-gate 			return (-1);
10380Sstevel@tonic-gate 
10390Sstevel@tonic-gate 		/*
10400Sstevel@tonic-gate 		 * Check the client handle for the version
10410Sstevel@tonic-gate 		 */
10420Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
10430Sstevel@tonic-gate 
10440Sstevel@tonic-gate 		/*
10450Sstevel@tonic-gate 		 * If the client is version 1, return error
10460Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
10470Sstevel@tonic-gate 		 */
10480Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
10490Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
10500Sstevel@tonic-gate 			    sp->setno, hostname, NULL, sp->setname);
10510Sstevel@tonic-gate 			metarpcclose(clntp);
10520Sstevel@tonic-gate 			return (-1);
10530Sstevel@tonic-gate 		} else {
10540Sstevel@tonic-gate 			if (mdrpc_withdrawset_2(&v2_args, &res, clntp)
10550Sstevel@tonic-gate 							!= RPC_SUCCESS)
10560Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
10570Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
10580Sstevel@tonic-gate 				    "metad withdraw set"));
10590Sstevel@tonic-gate 			else
10600Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
10610Sstevel@tonic-gate 		}
10620Sstevel@tonic-gate 
10630Sstevel@tonic-gate 		metarpcclose(clntp);
10640Sstevel@tonic-gate 	}
10650Sstevel@tonic-gate 
10660Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
10670Sstevel@tonic-gate 
10680Sstevel@tonic-gate 	if (! mdisok(ep))
10690Sstevel@tonic-gate 		return (-1);
10700Sstevel@tonic-gate 
10710Sstevel@tonic-gate 	return (0);
10720Sstevel@tonic-gate }
10730Sstevel@tonic-gate 
10740Sstevel@tonic-gate /*
10750Sstevel@tonic-gate  * Delete side names for the diskset drive records
10760Sstevel@tonic-gate  * NOTE: these are removed from the local set's namespace.
10770Sstevel@tonic-gate  */
10780Sstevel@tonic-gate int
clnt_del_drv_sidenms(char * hostname,mdsetname_t * sp,md_error_t * ep)10790Sstevel@tonic-gate clnt_del_drv_sidenms(
10800Sstevel@tonic-gate 	char			*hostname,
10810Sstevel@tonic-gate 	mdsetname_t		*sp,
10820Sstevel@tonic-gate 	md_error_t		*ep
10830Sstevel@tonic-gate )
10840Sstevel@tonic-gate {
10850Sstevel@tonic-gate 	CLIENT			*clntp;
10860Sstevel@tonic-gate 	mdrpc_sp_args		*args;
10870Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
10880Sstevel@tonic-gate 	mdrpc_generic_res	res;
10890Sstevel@tonic-gate 	int			version;
10900Sstevel@tonic-gate 
10910Sstevel@tonic-gate 	/* initialize */
10920Sstevel@tonic-gate 	mdclrerror(ep);
10930Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
10940Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
10950Sstevel@tonic-gate 
10960Sstevel@tonic-gate 	/* build args */
10970Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
10980Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
10990Sstevel@tonic-gate 	args->sp = sp;
11000Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
11010Sstevel@tonic-gate 
11020Sstevel@tonic-gate 	/* do it */
11030Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
11040Sstevel@tonic-gate 		int	bool;
11050Sstevel@tonic-gate 		bool = mdrpc_del_drv_sidenms_2_svc(&v2_args, &res, NULL);
11060Sstevel@tonic-gate 		assert(bool == TRUE);
11070Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
11080Sstevel@tonic-gate 	} else {
11090Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
11100Sstevel@tonic-gate 			return (-1);
11110Sstevel@tonic-gate 
11120Sstevel@tonic-gate 		if (metaget_setdesc(sp, ep) == NULL) {
11130Sstevel@tonic-gate 			if (! mdisok(ep))
11140Sstevel@tonic-gate 				return (-1);
11150Sstevel@tonic-gate 			mdclrerror(ep);
11160Sstevel@tonic-gate 		}
11170Sstevel@tonic-gate 
11180Sstevel@tonic-gate 		/*
11190Sstevel@tonic-gate 		 * Check the client handle for the version and invoke
11200Sstevel@tonic-gate 		 * the appropriate version of the remote procedure
11210Sstevel@tonic-gate 		 */
11220Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
11230Sstevel@tonic-gate 
11240Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
11250Sstevel@tonic-gate 			if (mdrpc_del_drv_sidenms_1(args, &res, clntp) !=
11260Sstevel@tonic-gate 			    RPC_SUCCESS)
11270Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
11280Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
11290Sstevel@tonic-gate 				    "metad delete drive sidenames"));
11300Sstevel@tonic-gate 			else
11310Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
11320Sstevel@tonic-gate 		} else {
11330Sstevel@tonic-gate 			if (mdrpc_del_drv_sidenms_2(&v2_args, &res, clntp) !=
11340Sstevel@tonic-gate 			    RPC_SUCCESS)
11350Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
11360Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
11370Sstevel@tonic-gate 				    "metad delete drive sidenames"));
11380Sstevel@tonic-gate 			else
11390Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
11400Sstevel@tonic-gate 		}
11410Sstevel@tonic-gate 
11420Sstevel@tonic-gate 		metarpcclose(clntp);
11430Sstevel@tonic-gate 	}
11440Sstevel@tonic-gate 
11450Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
11460Sstevel@tonic-gate 
11470Sstevel@tonic-gate 	if (! mdisok(ep))
11480Sstevel@tonic-gate 		return (-1);
11490Sstevel@tonic-gate 
11500Sstevel@tonic-gate 	return (0);
11510Sstevel@tonic-gate }
11520Sstevel@tonic-gate 
11530Sstevel@tonic-gate /*
11540Sstevel@tonic-gate  * delete drives from the set
11550Sstevel@tonic-gate  */
11560Sstevel@tonic-gate int
clnt_deldrvs(char * hostname,mdsetname_t * sp,md_drive_desc * dd,md_error_t * ep)11570Sstevel@tonic-gate clnt_deldrvs(
11580Sstevel@tonic-gate 	char			*hostname,
11590Sstevel@tonic-gate 	mdsetname_t		*sp,
11600Sstevel@tonic-gate 	md_drive_desc		*dd,
11610Sstevel@tonic-gate 	md_error_t		*ep
11620Sstevel@tonic-gate )
11630Sstevel@tonic-gate {
11640Sstevel@tonic-gate 	CLIENT			*clntp;
11650Sstevel@tonic-gate 	mdrpc_drives_args	v1_args;
11660Sstevel@tonic-gate 	mdrpc_drives_2_args	v2_args;
11670Sstevel@tonic-gate 	mdrpc_drives_2_args_r1	*v21_args;
11680Sstevel@tonic-gate 	mdrpc_generic_res	res;
11690Sstevel@tonic-gate 	int			rval;
11700Sstevel@tonic-gate 	int			version;
11710Sstevel@tonic-gate 
11720Sstevel@tonic-gate 	/* initialize */
11730Sstevel@tonic-gate 	mdclrerror(ep);
11740Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
11750Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
11760Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
11770Sstevel@tonic-gate 
11780Sstevel@tonic-gate 	/* build args */
11790Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
11800Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_drives_2_args_u.rev1;
11810Sstevel@tonic-gate 	v21_args->sp = sp;
11820Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
11830Sstevel@tonic-gate 	v21_args->drivedescs = dd;
11840Sstevel@tonic-gate 
11850Sstevel@tonic-gate 	/* do it */
11860Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
11870Sstevel@tonic-gate 		int	bool;
11880Sstevel@tonic-gate 
11890Sstevel@tonic-gate 		/*
11900Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
11910Sstevel@tonic-gate 		 */
11920Sstevel@tonic-gate 		bool = mdrpc_deldrvs_2_svc(&v2_args, &res, NULL);
11930Sstevel@tonic-gate 		assert(bool == TRUE);
11940Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
11950Sstevel@tonic-gate 	} else {
11960Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
11970Sstevel@tonic-gate 			return (-1);
11980Sstevel@tonic-gate 
11990Sstevel@tonic-gate 		/*
12000Sstevel@tonic-gate 		 * Check the client handle for the version
12010Sstevel@tonic-gate 		 * and invoke the appropriate version of the
12020Sstevel@tonic-gate 		 * remote procedure
12030Sstevel@tonic-gate 		 */
12040Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
12050Sstevel@tonic-gate 
12060Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
12070Sstevel@tonic-gate 
12080Sstevel@tonic-gate 			alloc_olddrvdesc(&v1_args.drivedescs, dd);
12090Sstevel@tonic-gate 
12100Sstevel@tonic-gate 			/* build args */
12110Sstevel@tonic-gate 			v1_args.sp = sp;
12120Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
12130Sstevel@tonic-gate 			meta_conv_drvdesc_new2old(v1_args.drivedescs, dd);
12140Sstevel@tonic-gate 
12150Sstevel@tonic-gate 			rval = mdrpc_deldrvs_1(&v1_args, &res, clntp);
12160Sstevel@tonic-gate 
12170Sstevel@tonic-gate 			free_olddrvdesc(v1_args.drivedescs);
12180Sstevel@tonic-gate 
12190Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
12200Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
12210Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
12220Sstevel@tonic-gate 				    "metad delete drives"));
12230Sstevel@tonic-gate 			else
12240Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
12250Sstevel@tonic-gate 		} else {			/* version 2 */
12260Sstevel@tonic-gate 			rval = mdrpc_deldrvs_2(&v2_args, &res, clntp);
12270Sstevel@tonic-gate 
12280Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
12290Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
12300Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
12310Sstevel@tonic-gate 				    "metad delete drives"));
12320Sstevel@tonic-gate 			else
12330Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
12340Sstevel@tonic-gate 		}
12350Sstevel@tonic-gate 
12360Sstevel@tonic-gate 		metarpcclose(clntp);
12370Sstevel@tonic-gate 	}
12380Sstevel@tonic-gate 
12390Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
12400Sstevel@tonic-gate 
12410Sstevel@tonic-gate 	if (! mdisok(ep))
12420Sstevel@tonic-gate 		return (-1);
12430Sstevel@tonic-gate 
12440Sstevel@tonic-gate 	return (0);
12450Sstevel@tonic-gate }
12460Sstevel@tonic-gate 
12470Sstevel@tonic-gate /*
12480Sstevel@tonic-gate  * delete host(s) from a set.
12490Sstevel@tonic-gate  */
12500Sstevel@tonic-gate int
clnt_delhosts(char * hostname,mdsetname_t * sp,int node_c,char ** node_v,md_error_t * ep)12510Sstevel@tonic-gate clnt_delhosts(
12520Sstevel@tonic-gate 	char			*hostname,
12530Sstevel@tonic-gate 	mdsetname_t		*sp,
12540Sstevel@tonic-gate 	int			node_c,
12550Sstevel@tonic-gate 	char			**node_v,
12560Sstevel@tonic-gate 	md_error_t		*ep
12570Sstevel@tonic-gate )
12580Sstevel@tonic-gate {
12590Sstevel@tonic-gate 	CLIENT			*clntp;
12600Sstevel@tonic-gate 	mdrpc_host_args		*args;
12610Sstevel@tonic-gate 	mdrpc_host_2_args	v2_args;
12620Sstevel@tonic-gate 	mdrpc_generic_res	res;
12630Sstevel@tonic-gate 	int			version;
12640Sstevel@tonic-gate 
12650Sstevel@tonic-gate 	/* initialize */
12660Sstevel@tonic-gate 	mdclrerror(ep);
12670Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
12680Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
12690Sstevel@tonic-gate 
12700Sstevel@tonic-gate 	/* build args */
12710Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
12720Sstevel@tonic-gate 	args = &v2_args.mdrpc_host_2_args_u.rev1;
12730Sstevel@tonic-gate 	args->sp = sp;
12740Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
12750Sstevel@tonic-gate 	args->hosts.hosts_len = node_c;
12760Sstevel@tonic-gate 	args->hosts.hosts_val = node_v;
12770Sstevel@tonic-gate 
12780Sstevel@tonic-gate 	/* do it */
12790Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
12800Sstevel@tonic-gate 		int	bool;
12810Sstevel@tonic-gate 		bool = mdrpc_delhosts_2_svc(&v2_args, &res, NULL);
12820Sstevel@tonic-gate 		assert(bool == TRUE);
12830Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
12840Sstevel@tonic-gate 	} else {
12850Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
12860Sstevel@tonic-gate 			return (-1);
12870Sstevel@tonic-gate 
12880Sstevel@tonic-gate 		/*
12890Sstevel@tonic-gate 		 * Check the client handle for the version
12900Sstevel@tonic-gate 		 * and invoke the appropriate version of the
12910Sstevel@tonic-gate 		 * remote procedure
12920Sstevel@tonic-gate 		 */
12930Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
12940Sstevel@tonic-gate 
12950Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
12960Sstevel@tonic-gate 			if (mdrpc_delhosts_1(args, &res, clntp) != RPC_SUCCESS)
12970Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
12980Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad delete hosts"));
12990Sstevel@tonic-gate 			else
13000Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
13010Sstevel@tonic-gate 		} else {
13020Sstevel@tonic-gate 			if (mdrpc_delhosts_2(&v2_args, &res, clntp) !=
13030Sstevel@tonic-gate 			    RPC_SUCCESS)
13040Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
13050Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad delete hosts"));
13060Sstevel@tonic-gate 			else
13070Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
13080Sstevel@tonic-gate 		}
13090Sstevel@tonic-gate 
13100Sstevel@tonic-gate 		metarpcclose(clntp);
13110Sstevel@tonic-gate 	}
13120Sstevel@tonic-gate 
13130Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
13140Sstevel@tonic-gate 
13150Sstevel@tonic-gate 	if (! mdisok(ep))
13160Sstevel@tonic-gate 		return (-1);
13170Sstevel@tonic-gate 
13180Sstevel@tonic-gate 	return (0);
13190Sstevel@tonic-gate }
13200Sstevel@tonic-gate 
13210Sstevel@tonic-gate /*
13220Sstevel@tonic-gate  * Delete diskset.
13230Sstevel@tonic-gate  */
13240Sstevel@tonic-gate int
clnt_delset(char * hostname,mdsetname_t * sp,md_error_t * ep)13250Sstevel@tonic-gate clnt_delset(
13260Sstevel@tonic-gate 	char			*hostname,
13270Sstevel@tonic-gate 	mdsetname_t		*sp,
13280Sstevel@tonic-gate 	md_error_t		*ep
13290Sstevel@tonic-gate )
13300Sstevel@tonic-gate {
13310Sstevel@tonic-gate 	CLIENT			*clntp;
13320Sstevel@tonic-gate 	mdrpc_sp_args		*args;
13330Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
13340Sstevel@tonic-gate 	mdrpc_generic_res	res;
13350Sstevel@tonic-gate 	int			version;
13360Sstevel@tonic-gate 
13370Sstevel@tonic-gate 	/* initialize */
13380Sstevel@tonic-gate 	mdclrerror(ep);
13390Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
13400Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
13410Sstevel@tonic-gate 
13420Sstevel@tonic-gate 	/* build args */
13430Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
13440Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
13450Sstevel@tonic-gate 	args->sp = sp;
13460Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
13470Sstevel@tonic-gate 
13480Sstevel@tonic-gate 	/* do it */
13490Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
13500Sstevel@tonic-gate 		int	bool;
13510Sstevel@tonic-gate 		bool = mdrpc_delset_2_svc(&v2_args, &res, NULL);
13520Sstevel@tonic-gate 		assert(bool == TRUE);
13530Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
13540Sstevel@tonic-gate 	} else {
13550Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
13560Sstevel@tonic-gate 			return (-1);
13570Sstevel@tonic-gate 
13580Sstevel@tonic-gate 		/*
13590Sstevel@tonic-gate 		 * Check the client handle for the version
13600Sstevel@tonic-gate 		 * and invoke the appropriate version of the
13610Sstevel@tonic-gate 		 * remote procedure
13620Sstevel@tonic-gate 		 */
13630Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
13640Sstevel@tonic-gate 
13650Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
13660Sstevel@tonic-gate 			if (mdrpc_delset_1(args, &res, clntp) != RPC_SUCCESS)
13670Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
13680Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad delete set"));
13690Sstevel@tonic-gate 			else
13700Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
13710Sstevel@tonic-gate 		} else {
13720Sstevel@tonic-gate 			if (mdrpc_delset_2(&v2_args, &res, clntp) !=
13730Sstevel@tonic-gate 			    RPC_SUCCESS)
13740Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
13750Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad delete set"));
13760Sstevel@tonic-gate 			else
13770Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
13780Sstevel@tonic-gate 		}
13790Sstevel@tonic-gate 
13800Sstevel@tonic-gate 		metarpcclose(clntp);
13810Sstevel@tonic-gate 	}
13820Sstevel@tonic-gate 
13830Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
13840Sstevel@tonic-gate 
13850Sstevel@tonic-gate 	if (! mdisok(ep))
13860Sstevel@tonic-gate 		return (-1);
13870Sstevel@tonic-gate 
13880Sstevel@tonic-gate 	return (0);
13890Sstevel@tonic-gate }
13900Sstevel@tonic-gate 
13910Sstevel@tonic-gate /*
13920Sstevel@tonic-gate  * return remote device info
13930Sstevel@tonic-gate  */
13940Sstevel@tonic-gate int
clnt_devinfo(char * hostname,mdsetname_t * sp,mddrivename_t * dp,md_dev64_t * ret_dev,time_t * ret_timestamp,md_error_t * ep)13950Sstevel@tonic-gate clnt_devinfo(
13960Sstevel@tonic-gate 	char			*hostname,
13970Sstevel@tonic-gate 	mdsetname_t		*sp,
13980Sstevel@tonic-gate 	mddrivename_t		*dp,
13990Sstevel@tonic-gate 	md_dev64_t		*ret_dev,
14000Sstevel@tonic-gate 	time_t			*ret_timestamp,
14010Sstevel@tonic-gate 	md_error_t		*ep
14020Sstevel@tonic-gate )
14030Sstevel@tonic-gate {
14040Sstevel@tonic-gate 	CLIENT			*clntp;
14050Sstevel@tonic-gate 	mdrpc_devinfo_args	v1_args;
14060Sstevel@tonic-gate 	mdrpc_devinfo_2_args	v2_args;
14070Sstevel@tonic-gate 	mdrpc_devinfo_2_args_r1	*v21_args;
14080Sstevel@tonic-gate 	mdrpc_devinfo_res	v1_res;
14090Sstevel@tonic-gate 	mdrpc_devinfo_2_res	v2_res;
14100Sstevel@tonic-gate 	int			rval, version;
14110Sstevel@tonic-gate 
14120Sstevel@tonic-gate 	/* initialize */
14130Sstevel@tonic-gate 	mdclrerror(ep);
14140Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
14150Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
14160Sstevel@tonic-gate 	(void) memset(&v1_res,  0, sizeof (v1_res));
14170Sstevel@tonic-gate 	(void) memset(&v2_res, 	0, sizeof (v2_res));
14180Sstevel@tonic-gate 
14190Sstevel@tonic-gate 	/* build args */
14200Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
14210Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_devinfo_2_args_u.rev1;
14220Sstevel@tonic-gate 	v21_args->sp = sp;
14230Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
14240Sstevel@tonic-gate 	v21_args->drivenamep = dp;
14250Sstevel@tonic-gate 
14260Sstevel@tonic-gate 	/* do it */
14270Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
14280Sstevel@tonic-gate 		int	bool;
14290Sstevel@tonic-gate 
14300Sstevel@tonic-gate 		/*
14310Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure.
14320Sstevel@tonic-gate 		 */
14330Sstevel@tonic-gate 		bool = mdrpc_devinfo_2_svc(&v2_args, &v2_res, NULL);
14340Sstevel@tonic-gate 		assert(bool == TRUE);
14350Sstevel@tonic-gate 		(void) mdstealerror(ep, &v1_res.status);
14360Sstevel@tonic-gate 	} else {
14370Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
14380Sstevel@tonic-gate 			return (-1);
14390Sstevel@tonic-gate 
14400Sstevel@tonic-gate 		/*
14410Sstevel@tonic-gate 		 * Check the client handle for the version
14420Sstevel@tonic-gate 		 * and invoke the appropriate version of
14430Sstevel@tonic-gate 		 * the remote procedure.
14440Sstevel@tonic-gate 		 */
14450Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
14460Sstevel@tonic-gate 
14470Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
14480Sstevel@tonic-gate 			v1_args.drivenamep =
14490Sstevel@tonic-gate 			    Zalloc(sizeof (o_mddrivename_t));
14500Sstevel@tonic-gate 			v1_args.drivenamep->parts.parts_val =
14510Sstevel@tonic-gate 			    Zalloc((sizeof (o_mdname_t)) *
14520Sstevel@tonic-gate 			    dp->parts.parts_len);
14530Sstevel@tonic-gate 
14540Sstevel@tonic-gate 			/* build args */
14550Sstevel@tonic-gate 			v1_args.sp = sp;
14560Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno,
14570Sstevel@tonic-gate 			    sp->setname);
14580Sstevel@tonic-gate 
14590Sstevel@tonic-gate 			/*
14600Sstevel@tonic-gate 			 * Convert v2 arguments to v1 arguments
14610Sstevel@tonic-gate 			 * before sending over the wire.
14620Sstevel@tonic-gate 			 */
14630Sstevel@tonic-gate 			meta_conv_drvname_new2old(v1_args.drivenamep,
14640Sstevel@tonic-gate 			    v21_args->drivenamep);
14650Sstevel@tonic-gate 
14660Sstevel@tonic-gate 			rval = mdrpc_devinfo_1(&v1_args, &v1_res, clntp);
14670Sstevel@tonic-gate 
14680Sstevel@tonic-gate 			free(v1_args.drivenamep->parts.parts_val);
14690Sstevel@tonic-gate 			free(v1_args.drivenamep);
14700Sstevel@tonic-gate 
14710Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
14720Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
14730Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad device info"));
14740Sstevel@tonic-gate 			else
14750Sstevel@tonic-gate 				(void) mdstealerror(ep, &v1_res.status);
14760Sstevel@tonic-gate 		} else {			/* version 2 */
14770Sstevel@tonic-gate 			rval = mdrpc_devinfo_2(&v2_args, &v2_res, clntp);
14780Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
14790Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
14800Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad device info"));
14810Sstevel@tonic-gate 			else
14820Sstevel@tonic-gate 				(void) mdstealerror(ep, &v2_res.status);
14830Sstevel@tonic-gate 		}
14840Sstevel@tonic-gate 
14850Sstevel@tonic-gate 		metarpcclose(clntp);
14860Sstevel@tonic-gate 	}
14870Sstevel@tonic-gate 
14880Sstevel@tonic-gate 	if (mdisok(ep)) {
14890Sstevel@tonic-gate 		/* do something with the results */
14900Sstevel@tonic-gate 		rval = 0;
14910Sstevel@tonic-gate 
14920Sstevel@tonic-gate 		if (ret_dev != NULL) {
14930Sstevel@tonic-gate 			if (version == METAD_VERSION)
14940Sstevel@tonic-gate 				*ret_dev = meta_expldev(v1_res.dev);
14950Sstevel@tonic-gate 			else
14960Sstevel@tonic-gate 				*ret_dev = v2_res.dev;
14970Sstevel@tonic-gate 		}
14980Sstevel@tonic-gate 
14990Sstevel@tonic-gate 		if (ret_timestamp != NULL) {
15000Sstevel@tonic-gate 			if (version == METAD_VERSION)
15010Sstevel@tonic-gate 				*ret_timestamp = v1_res.vtime;
15020Sstevel@tonic-gate 			else
15030Sstevel@tonic-gate 				*ret_timestamp = v2_res.vtime;
15040Sstevel@tonic-gate 		}
15050Sstevel@tonic-gate 	}
15060Sstevel@tonic-gate 
15070Sstevel@tonic-gate 	if (version == METAD_VERSION)
15080Sstevel@tonic-gate 		xdr_free(xdr_mdrpc_devinfo_res, (char *)&v1_res);
15090Sstevel@tonic-gate 	else
15100Sstevel@tonic-gate 		xdr_free(xdr_mdrpc_devinfo_2_res, (char *)&v2_res);
15110Sstevel@tonic-gate 
15120Sstevel@tonic-gate 	return (rval);
15130Sstevel@tonic-gate }
15140Sstevel@tonic-gate 
15150Sstevel@tonic-gate /*
15160Sstevel@tonic-gate  * return remote device info
15170Sstevel@tonic-gate  */
15180Sstevel@tonic-gate int
clnt_devid(char * hostname,mdsetname_t * sp,mddrivename_t * dp,char ** ret_encdevid,md_error_t * ep)15190Sstevel@tonic-gate clnt_devid(
15200Sstevel@tonic-gate 	char			*hostname,
15210Sstevel@tonic-gate 	mdsetname_t		*sp,
15220Sstevel@tonic-gate 	mddrivename_t		*dp,
15230Sstevel@tonic-gate 	char			**ret_encdevid,
15240Sstevel@tonic-gate 	md_error_t		*ep
15250Sstevel@tonic-gate )
15260Sstevel@tonic-gate {
15270Sstevel@tonic-gate 	CLIENT			*clntp;
15280Sstevel@tonic-gate 	mdrpc_devid_args	*args;
15290Sstevel@tonic-gate 	mdrpc_devid_2_args	v2_args;
15300Sstevel@tonic-gate 	mdrpc_devid_res		res;
15310Sstevel@tonic-gate 	int			rval;
15320Sstevel@tonic-gate 	int			version;
15330Sstevel@tonic-gate 
15340Sstevel@tonic-gate 	/* initialize */
15350Sstevel@tonic-gate 	mdclrerror(ep);
15360Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
15370Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
15380Sstevel@tonic-gate 
15390Sstevel@tonic-gate 	/* build args */
15400Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
15410Sstevel@tonic-gate 	args = &v2_args.mdrpc_devid_2_args_u.rev1;
15420Sstevel@tonic-gate 	args->sp = sp;
15430Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
15440Sstevel@tonic-gate 	args->drivenamep = dp;
15450Sstevel@tonic-gate 
15460Sstevel@tonic-gate 	/* do it */
15470Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
15480Sstevel@tonic-gate 		int	bool;
15490Sstevel@tonic-gate 
15500Sstevel@tonic-gate 		/*
15510Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure.
15520Sstevel@tonic-gate 		 */
15530Sstevel@tonic-gate 		bool = mdrpc_devid_2_svc(&v2_args, &res, NULL);
15540Sstevel@tonic-gate 		assert(bool == TRUE);
15550Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
15560Sstevel@tonic-gate 	} else {
15570Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
15580Sstevel@tonic-gate 			return (-1);
15590Sstevel@tonic-gate 
15600Sstevel@tonic-gate 		/*
15610Sstevel@tonic-gate 		 * Check the client handle for the version
15620Sstevel@tonic-gate 		 */
15630Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
15640Sstevel@tonic-gate 
15650Sstevel@tonic-gate 		/*
15660Sstevel@tonic-gate 		 * If the client is version 1, return error
15670Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
15680Sstevel@tonic-gate 		 */
15690Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
15700Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_DRIVENOTONHOST, sp->setno,
15710Sstevel@tonic-gate 			    hostname, dp->cname, sp->setname);
15720Sstevel@tonic-gate 		} else {			/* version 2 */
15730Sstevel@tonic-gate 			rval = mdrpc_devid_2(&v2_args, &res, clntp);
15740Sstevel@tonic-gate 
15750Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
15760Sstevel@tonic-gate 			    (void) mdrpcerror(ep, clntp, hostname,
15770Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad devid info"));
15780Sstevel@tonic-gate 			else
15790Sstevel@tonic-gate 			    (void) mdstealerror(ep, &res.status);
15800Sstevel@tonic-gate 		}
15810Sstevel@tonic-gate 
15820Sstevel@tonic-gate 		metarpcclose(clntp);
15830Sstevel@tonic-gate 	}
15840Sstevel@tonic-gate 
15850Sstevel@tonic-gate 	if (mdisok(ep)) {
15860Sstevel@tonic-gate 		/* do something with the results */
15870Sstevel@tonic-gate 		rval = 0;
15880Sstevel@tonic-gate 
15890Sstevel@tonic-gate 		if (ret_encdevid != NULL)
15900Sstevel@tonic-gate 			*ret_encdevid = strdup(res.enc_devid);
15910Sstevel@tonic-gate 
15920Sstevel@tonic-gate 	}
15930Sstevel@tonic-gate 
15940Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_devid_res, (char *)&res);
15950Sstevel@tonic-gate 
15960Sstevel@tonic-gate 	return (rval);
15970Sstevel@tonic-gate }
15980Sstevel@tonic-gate 
15990Sstevel@tonic-gate /*
16000Sstevel@tonic-gate  * Get the device information of a disk on a remote host. The information
16010Sstevel@tonic-gate  * retrieved is the device's name, the associated driver and the dev_t.
16020Sstevel@tonic-gate  * The lookup is performed by using the devid of the disk as this is
16030Sstevel@tonic-gate  * unique to the disk.  The device name on the originating node is passed
16040Sstevel@tonic-gate  * in.  If that devname is found when doing the devid to namelist translation
16050Sstevel@tonic-gate  * then that value is used to make the device names as consistent as possible
16060Sstevel@tonic-gate  * across the nodes.
16070Sstevel@tonic-gate  *
16080Sstevel@tonic-gate  * An attempt is made to retrieve this information by calling
16090Sstevel@tonic-gate  * mdrpc_devinfo_by_devid_name_2_svc.  Locally this call should always
16100Sstevel@tonic-gate  * succeed.  In the case where a call is made through a CLIENT handle,
16110Sstevel@tonic-gate  * it is possible that the function hasn't been implemented on the called
16120Sstevel@tonic-gate  * node.  If this is the case fall back to mdrpc_devinfo_by_devidstr_2_svc.
16130Sstevel@tonic-gate  *
16140Sstevel@tonic-gate  * Returns:
16150Sstevel@tonic-gate  * 	-1 	Error
16160Sstevel@tonic-gate  * 	ENOTSUP Operation not supported i.e. procedure not supported on
16170Sstevel@tonic-gate  * 		the remote node
16180Sstevel@tonic-gate  * 	0	Success
16190Sstevel@tonic-gate  */
16200Sstevel@tonic-gate int
clnt_devinfo_by_devid(char * hostname,mdsetname_t * sp,char * devidstr,md_dev64_t * ret_dev,char * orig_devname,char ** ret_devname,char ** ret_driver,md_error_t * ep)16210Sstevel@tonic-gate clnt_devinfo_by_devid(
16220Sstevel@tonic-gate 	char		*hostname,
16230Sstevel@tonic-gate 	mdsetname_t	*sp,
16240Sstevel@tonic-gate 	char		*devidstr,
16250Sstevel@tonic-gate 	md_dev64_t	*ret_dev,
16260Sstevel@tonic-gate 	char		*orig_devname,
16270Sstevel@tonic-gate 	char		**ret_devname,
16280Sstevel@tonic-gate 	char		**ret_driver,
16290Sstevel@tonic-gate 	md_error_t	*ep
16300Sstevel@tonic-gate )
16310Sstevel@tonic-gate {
16320Sstevel@tonic-gate 	CLIENT			*clntp;
16330Sstevel@tonic-gate 	mdrpc_devidstr_args	devid_args;
16340Sstevel@tonic-gate 	mdrpc_devid_name_args	*args;
16350Sstevel@tonic-gate 	mdrpc_devid_name_2_args	v2_args;
16360Sstevel@tonic-gate 	mdrpc_devinfo_2_res	res;
16370Sstevel@tonic-gate 	int			rval;
16380Sstevel@tonic-gate 	int			version;
16390Sstevel@tonic-gate 
16400Sstevel@tonic-gate 	/* initialize */
16410Sstevel@tonic-gate 	mdclrerror(ep);
16420Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
16430Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
16440Sstevel@tonic-gate 
16450Sstevel@tonic-gate 	/* build args */
16460Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
16470Sstevel@tonic-gate 	args = &v2_args.mdrpc_devid_name_2_args_u.rev1;
16480Sstevel@tonic-gate 	args->enc_devid = devidstr;
16490Sstevel@tonic-gate 	args->orig_devname = orig_devname;
16500Sstevel@tonic-gate 	args->sp = sp;
16510Sstevel@tonic-gate 
16520Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
16530Sstevel@tonic-gate 		int	bool;
16540Sstevel@tonic-gate 
16550Sstevel@tonic-gate 		/*
16560Sstevel@tonic-gate 		 * We are calling this locally so call the function
16570Sstevel@tonic-gate 		 * directly.
16580Sstevel@tonic-gate 		 */
16590Sstevel@tonic-gate 		bool = mdrpc_devinfo_by_devid_name_2_svc(&v2_args, &res, NULL);
16600Sstevel@tonic-gate 		assert(bool == TRUE);
16610Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
16620Sstevel@tonic-gate 	} else {
16630Sstevel@tonic-gate 
16640Sstevel@tonic-gate 		/* open connection */
16650Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL) {
16660Sstevel@tonic-gate 			return (-1);
16670Sstevel@tonic-gate 		}
16680Sstevel@tonic-gate 
16690Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
16700Sstevel@tonic-gate 
16710Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* Version 1 */
16720Sstevel@tonic-gate 			metarpcclose(clntp);
16730Sstevel@tonic-gate 			return (ENOTSUP);
16740Sstevel@tonic-gate 		}
16750Sstevel@tonic-gate 
16760Sstevel@tonic-gate 		rval = mdrpc_devinfo_by_devid_name_2(&v2_args, &res, clntp);
16770Sstevel@tonic-gate 
16780Sstevel@tonic-gate 		if (rval != RPC_SUCCESS) {
16790Sstevel@tonic-gate 			/* try falling back to devidstr_2_svc */
16800Sstevel@tonic-gate 			(void) memset(&devid_args, 0, sizeof (devid_args));
16810Sstevel@tonic-gate 			(void) memset(&res, 0, sizeof (res));
16820Sstevel@tonic-gate 
16830Sstevel@tonic-gate 			devid_args.enc_devid = devidstr;
16840Sstevel@tonic-gate 			devid_args.sp = sp;
16850Sstevel@tonic-gate 
16860Sstevel@tonic-gate 			rval = mdrpc_devinfo_by_devid_2(
16870Sstevel@tonic-gate 					&devid_args, &res, clntp);
16880Sstevel@tonic-gate 
16890Sstevel@tonic-gate 			if (rval != RPC_SUCCESS) {
16900Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
16910Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
16920Sstevel@tonic-gate 				    "metad devinfo by devid"));
16930Sstevel@tonic-gate 			} else {
16940Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
16950Sstevel@tonic-gate 			}
16960Sstevel@tonic-gate 		} else {
16970Sstevel@tonic-gate 			(void) mdstealerror(ep, &res.status);
16980Sstevel@tonic-gate 		}
16990Sstevel@tonic-gate 		metarpcclose(clntp);
17000Sstevel@tonic-gate 	}
17010Sstevel@tonic-gate 
17020Sstevel@tonic-gate 	if (mdisok(ep)) {
17030Sstevel@tonic-gate 		rval = 0;
17040Sstevel@tonic-gate 		if (ret_dev != NULL)
17050Sstevel@tonic-gate 			*ret_dev = res.dev;
17060Sstevel@tonic-gate 
17070Sstevel@tonic-gate 		if (ret_devname != NULL && res.devname != NULL)
17080Sstevel@tonic-gate 			*ret_devname = Strdup(res.devname);
17090Sstevel@tonic-gate 
17100Sstevel@tonic-gate 		if (ret_driver != NULL && res.drivername != NULL)
17110Sstevel@tonic-gate 			*ret_driver = Strdup(res.drivername);
17120Sstevel@tonic-gate 	}
17130Sstevel@tonic-gate 
17140Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_devinfo_2_res, (char *)&res);
17150Sstevel@tonic-gate 
17160Sstevel@tonic-gate 	if (! mdisok(ep))
17170Sstevel@tonic-gate 		return (-1);
17180Sstevel@tonic-gate 
17190Sstevel@tonic-gate 	return (0);
17200Sstevel@tonic-gate 
17210Sstevel@tonic-gate }
17220Sstevel@tonic-gate 
17230Sstevel@tonic-gate 
17240Sstevel@tonic-gate /*
17250Sstevel@tonic-gate  * return status of whether driver is used, mount
17260Sstevel@tonic-gate  */
17270Sstevel@tonic-gate int
clnt_drvused(char * hostname,mdsetname_t * sp,mddrivename_t * dp,md_error_t * ep)17280Sstevel@tonic-gate clnt_drvused(
17290Sstevel@tonic-gate 	char			*hostname,
17300Sstevel@tonic-gate 	mdsetname_t		*sp,
17310Sstevel@tonic-gate 	mddrivename_t		*dp,
17320Sstevel@tonic-gate 	md_error_t		*ep
17330Sstevel@tonic-gate )
17340Sstevel@tonic-gate {
17350Sstevel@tonic-gate 	CLIENT			*clntp;
17360Sstevel@tonic-gate 	mdrpc_drvused_args	v1_args;
17370Sstevel@tonic-gate 	mdrpc_drvused_2_args	v2_args;
17380Sstevel@tonic-gate 	mdrpc_drvused_2_args_r1	*v21_args;
17390Sstevel@tonic-gate 	mdrpc_generic_res	res;
17400Sstevel@tonic-gate 	int			rval;
17410Sstevel@tonic-gate 	int			version;
17420Sstevel@tonic-gate 
17430Sstevel@tonic-gate 	/* initialize */
17440Sstevel@tonic-gate 	mdclrerror(ep);
17450Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
17460Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
17470Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
17480Sstevel@tonic-gate 
17490Sstevel@tonic-gate 	/* build args */
17500Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
17510Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_drvused_2_args_u.rev1;
17520Sstevel@tonic-gate 	v21_args->sp = sp;
17530Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
17540Sstevel@tonic-gate 	v21_args->drivenamep = dp;
17550Sstevel@tonic-gate 
17560Sstevel@tonic-gate 	/* do it */
17570Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
17580Sstevel@tonic-gate 		int	bool;
17590Sstevel@tonic-gate 
17600Sstevel@tonic-gate 		/*
17610Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
17620Sstevel@tonic-gate 		 */
17630Sstevel@tonic-gate 		bool = mdrpc_drvused_2_svc(&v2_args, &res, NULL);
17640Sstevel@tonic-gate 		assert(bool == TRUE);
17650Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
17660Sstevel@tonic-gate 	} else {
17670Sstevel@tonic-gate 		/* open connection */
17680Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
17690Sstevel@tonic-gate 			return (-1);
17700Sstevel@tonic-gate 
17710Sstevel@tonic-gate 		/*
17720Sstevel@tonic-gate 		 * Check the client handle for the version
17730Sstevel@tonic-gate 		 * and invoke the appropriate version of the
17740Sstevel@tonic-gate 		 * remote procedure
17750Sstevel@tonic-gate 		 */
17760Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
17770Sstevel@tonic-gate 
17780Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
17790Sstevel@tonic-gate 			v1_args.drivenamep =
17800Sstevel@tonic-gate 			    Zalloc(sizeof (o_mddrivename_t));
17810Sstevel@tonic-gate 			v1_args.drivenamep->parts.parts_val =
17820Sstevel@tonic-gate 			    Zalloc((sizeof (o_mdname_t)) *
17830Sstevel@tonic-gate 			    dp->parts.parts_len);
17840Sstevel@tonic-gate 
17850Sstevel@tonic-gate 			/* build args */
17860Sstevel@tonic-gate 			v1_args.sp = sp;
17870Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
17880Sstevel@tonic-gate 
17890Sstevel@tonic-gate 			/* Convert v2 args to v1 args */
17900Sstevel@tonic-gate 			meta_conv_drvname_new2old(v1_args.drivenamep,
17910Sstevel@tonic-gate 			    v21_args->drivenamep);
17920Sstevel@tonic-gate 
17930Sstevel@tonic-gate 			rval = mdrpc_drvused_1(&v1_args, &res, clntp);
17940Sstevel@tonic-gate 
17950Sstevel@tonic-gate 			free(v1_args.drivenamep->parts.parts_val);
17960Sstevel@tonic-gate 			free(v1_args.drivenamep);
17970Sstevel@tonic-gate 
17980Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
17990Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
18000Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad drive used"));
18010Sstevel@tonic-gate 			else
18020Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
18030Sstevel@tonic-gate 		} else {			/* version 2 */
18040Sstevel@tonic-gate 			rval = mdrpc_drvused_2(&v2_args, &res, clntp);
18050Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
18060Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
18070Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad drive used"));
18080Sstevel@tonic-gate 			else
18090Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
18100Sstevel@tonic-gate 		}
18110Sstevel@tonic-gate 
18120Sstevel@tonic-gate 		metarpcclose(clntp);
18130Sstevel@tonic-gate 	}
18140Sstevel@tonic-gate 
18150Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
18160Sstevel@tonic-gate 
18170Sstevel@tonic-gate 	if (! mdisok(ep))
18180Sstevel@tonic-gate 		return (-1);
18190Sstevel@tonic-gate 
18200Sstevel@tonic-gate 	return (0);
18210Sstevel@tonic-gate }
18220Sstevel@tonic-gate 
18230Sstevel@tonic-gate void
free_sr(md_set_record * sr)18240Sstevel@tonic-gate free_sr(md_set_record *sr)
18250Sstevel@tonic-gate {
18260Sstevel@tonic-gate 	mdrpc_getset_res	res;
18270Sstevel@tonic-gate 	mdrpc_mngetset_res	mnres;
18280Sstevel@tonic-gate 
18290Sstevel@tonic-gate 	if (md_in_daemon)
18300Sstevel@tonic-gate 		return;
18310Sstevel@tonic-gate 
18320Sstevel@tonic-gate 	/*
18330Sstevel@tonic-gate 	 * dummy up a result struct, to do a deep free of the (mn)sr.
18340Sstevel@tonic-gate 	 * (A deep free means that the xdr_free code will free the
18350Sstevel@tonic-gate 	 * linked list of drive records for the sr and will also free
18360Sstevel@tonic-gate 	 * the linked list of node records for the mnsr.)
18370Sstevel@tonic-gate 	 */
18380Sstevel@tonic-gate 	if (MD_MNSET_REC(sr)) {
18390Sstevel@tonic-gate 		(void) memset(&mnres, 0, sizeof (mnres));
18400Sstevel@tonic-gate 		mnres.mnsr = (struct md_mnset_record *)sr;
18410Sstevel@tonic-gate 		xdr_free(xdr_mdrpc_mngetset_res, (char *)&mnres);
18420Sstevel@tonic-gate 	} else {
18430Sstevel@tonic-gate 		(void) memset(&res, 0, sizeof (res));
18440Sstevel@tonic-gate 		res.sr = sr;
18450Sstevel@tonic-gate 		xdr_free(xdr_mdrpc_getset_res, (char *)&res);
18460Sstevel@tonic-gate 	}
18470Sstevel@tonic-gate }
18480Sstevel@tonic-gate 
18490Sstevel@tonic-gate void
short_circuit_getset(mdrpc_getset_args * args,mdrpc_getset_res * res)18500Sstevel@tonic-gate short_circuit_getset(
18510Sstevel@tonic-gate 	mdrpc_getset_args	*args,
18520Sstevel@tonic-gate 	mdrpc_getset_res	*res
18530Sstevel@tonic-gate )
18540Sstevel@tonic-gate {
18550Sstevel@tonic-gate 	if (args->setname != NULL)
18560Sstevel@tonic-gate 		res->sr = metad_getsetbyname(args->setname, &res->status);
18570Sstevel@tonic-gate 	else
18580Sstevel@tonic-gate 		res->sr = metad_getsetbynum(args->setno, &res->status);
18590Sstevel@tonic-gate }
18600Sstevel@tonic-gate 
18610Sstevel@tonic-gate void
short_circuit_mngetset(mdrpc_getset_args * args,mdrpc_mngetset_res * res)18620Sstevel@tonic-gate short_circuit_mngetset(
18630Sstevel@tonic-gate 	mdrpc_getset_args	*args,
18640Sstevel@tonic-gate 	mdrpc_mngetset_res	*res
18650Sstevel@tonic-gate )
18660Sstevel@tonic-gate {
18670Sstevel@tonic-gate 	md_set_record		*sr;
18680Sstevel@tonic-gate 	if (args->setname != NULL)
18690Sstevel@tonic-gate 		sr = metad_getsetbyname(args->setname, &res->status);
18700Sstevel@tonic-gate 	else
18710Sstevel@tonic-gate 		sr = metad_getsetbynum(args->setno, &res->status);
18720Sstevel@tonic-gate 
18730Sstevel@tonic-gate 	if (MD_MNSET_REC(sr)) {
18740Sstevel@tonic-gate 		res->mnsr = (struct md_mnset_record *)sr;
18750Sstevel@tonic-gate 	} else {
18760Sstevel@tonic-gate 		res->mnsr = NULL;
18770Sstevel@tonic-gate 	}
18780Sstevel@tonic-gate }
18790Sstevel@tonic-gate 
18800Sstevel@tonic-gate static int
is_auto_take_set(char * setname,set_t setno)18810Sstevel@tonic-gate is_auto_take_set(char *setname, set_t setno)
18820Sstevel@tonic-gate {
18830Sstevel@tonic-gate 	if (setname != NULL)
18840Sstevel@tonic-gate 	    return (metad_isautotakebyname(setname));
18850Sstevel@tonic-gate 	else
18860Sstevel@tonic-gate 	    return (metad_isautotakebynum(setno));
18870Sstevel@tonic-gate }
18880Sstevel@tonic-gate 
18890Sstevel@tonic-gate /*
18900Sstevel@tonic-gate  * return the diskset record, and drive records.
18910Sstevel@tonic-gate  * If record is a MNdiskset record, then only the first md_set_record
18920Sstevel@tonic-gate  * bytes were copied from the daemon.
18930Sstevel@tonic-gate  */
18940Sstevel@tonic-gate int
clnt_getset(char * hostname,char * setname,set_t setno,md_set_record ** ret_sr,md_error_t * ep)18950Sstevel@tonic-gate clnt_getset(
18960Sstevel@tonic-gate 	char			*hostname,
18970Sstevel@tonic-gate 	char			*setname,
18980Sstevel@tonic-gate 	set_t			setno,
18990Sstevel@tonic-gate 	md_set_record		**ret_sr,
19000Sstevel@tonic-gate 	md_error_t		*ep
19010Sstevel@tonic-gate )
19020Sstevel@tonic-gate {
19030Sstevel@tonic-gate 	CLIENT			*clntp;
19040Sstevel@tonic-gate 	mdrpc_getset_args	*args;
19050Sstevel@tonic-gate 	mdrpc_getset_2_args	v2_args;
19060Sstevel@tonic-gate 	mdrpc_getset_res	res;
19070Sstevel@tonic-gate 	int			rval = -1;
19080Sstevel@tonic-gate 	int			version;
19090Sstevel@tonic-gate 
19100Sstevel@tonic-gate 	/* initialize */
19110Sstevel@tonic-gate 	mdclrerror(ep);
19120Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
19130Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
19140Sstevel@tonic-gate 
19150Sstevel@tonic-gate 	/* build args */
19160Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
19170Sstevel@tonic-gate 	args = &v2_args.mdrpc_getset_2_args_u.rev1;
19180Sstevel@tonic-gate 	args->setname = setname;
19190Sstevel@tonic-gate 	args->setno   = setno;
19200Sstevel@tonic-gate 
19210Sstevel@tonic-gate 	/* do it */
19220Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
19230Sstevel@tonic-gate 		short_circuit_getset(args, &res);
19240Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
19250Sstevel@tonic-gate 	} else {
19260Sstevel@tonic-gate 	    if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL) {
19270Sstevel@tonic-gate 		/*
19280Sstevel@tonic-gate 		 * This has to work during the boot up before the rpc.metad can
19290Sstevel@tonic-gate 		 * run.  Check to see if we can handle this as a strictly local
19300Sstevel@tonic-gate 		 * diskset.
19310Sstevel@tonic-gate 		 */
19320Sstevel@tonic-gate 		if (is_auto_take_set(setname, setno)) {
19330Sstevel@tonic-gate 		    mdclrerror(ep);
19340Sstevel@tonic-gate 		    short_circuit_getset(args, &res);
19350Sstevel@tonic-gate 		    res.sr = setdup(res.sr);
19360Sstevel@tonic-gate 		    (void) mdstealerror(ep, &res.status);
19370Sstevel@tonic-gate 		} else {
19380Sstevel@tonic-gate 		    return (-1);
19390Sstevel@tonic-gate 		}
19400Sstevel@tonic-gate 	    } else {
19410Sstevel@tonic-gate 
19420Sstevel@tonic-gate 		/*
19430Sstevel@tonic-gate 		 * Check the client handle for the version
19440Sstevel@tonic-gate 		 * and invoke the appropriate version of the
19450Sstevel@tonic-gate 		 * remote procedure
19460Sstevel@tonic-gate 		 */
19470Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
19480Sstevel@tonic-gate 
19490Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
19500Sstevel@tonic-gate 			if (mdrpc_getset_1(args, &res, clntp) != RPC_SUCCESS)
19510Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
19520Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad get set"));
19530Sstevel@tonic-gate 			else
19540Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
19550Sstevel@tonic-gate 		} else {
19560Sstevel@tonic-gate 			if (mdrpc_getset_2(&v2_args, &res, clntp) !=
19570Sstevel@tonic-gate 			    RPC_SUCCESS)
19580Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
19590Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad get set"));
19600Sstevel@tonic-gate 			else
19610Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
19620Sstevel@tonic-gate 		}
19630Sstevel@tonic-gate 
19640Sstevel@tonic-gate 		metarpcclose(clntp);
19650Sstevel@tonic-gate 	    }
19660Sstevel@tonic-gate 	}
19670Sstevel@tonic-gate 
19680Sstevel@tonic-gate 	if (mdisok(ep)) {
19690Sstevel@tonic-gate 		rval = 0;
19700Sstevel@tonic-gate 		if (ret_sr != NULL)
19710Sstevel@tonic-gate 			*ret_sr = res.sr;
19720Sstevel@tonic-gate 		else
19730Sstevel@tonic-gate 			if (! md_in_daemon)
19740Sstevel@tonic-gate 				xdr_free(xdr_mdrpc_getset_res, (char *)&res);
19750Sstevel@tonic-gate 	}
19760Sstevel@tonic-gate 
19770Sstevel@tonic-gate 	return (rval);
19780Sstevel@tonic-gate }
19790Sstevel@tonic-gate 
19800Sstevel@tonic-gate /*
19810Sstevel@tonic-gate  * return the multi-node diskset record, drive records and node records.
19820Sstevel@tonic-gate  */
198362Sjeanm int
clnt_mngetset(char * hostname,char * setname,set_t setno,md_mnset_record ** ret_mnsr,md_error_t * ep)19840Sstevel@tonic-gate clnt_mngetset(
19850Sstevel@tonic-gate 	char			*hostname,
19860Sstevel@tonic-gate 	char			*setname,
19870Sstevel@tonic-gate 	set_t			setno,
19880Sstevel@tonic-gate 	md_mnset_record		**ret_mnsr,
19890Sstevel@tonic-gate 	md_error_t		*ep
19900Sstevel@tonic-gate )
19910Sstevel@tonic-gate {
19920Sstevel@tonic-gate 	CLIENT			*clntp;
19930Sstevel@tonic-gate 	mdrpc_getset_args	*args;
19940Sstevel@tonic-gate 	mdrpc_getset_2_args	v2_args;
19950Sstevel@tonic-gate 	mdrpc_mngetset_res	res;
19960Sstevel@tonic-gate 	int			rval = -1;
19970Sstevel@tonic-gate 	int			version;
19980Sstevel@tonic-gate 
19990Sstevel@tonic-gate 	/* initialize */
20000Sstevel@tonic-gate 	mdclrerror(ep);
20010Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
20020Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
20030Sstevel@tonic-gate 
20040Sstevel@tonic-gate 	/* build args */
20050Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
20060Sstevel@tonic-gate 	args = &v2_args.mdrpc_getset_2_args_u.rev1;
20070Sstevel@tonic-gate 	args->setname = setname;
20080Sstevel@tonic-gate 	args->setno   = setno;
20090Sstevel@tonic-gate 
20100Sstevel@tonic-gate 	/* do it */
20110Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
20120Sstevel@tonic-gate 		short_circuit_mngetset(args, &res);
20130Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
20140Sstevel@tonic-gate 	} else {
20150Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
20160Sstevel@tonic-gate 			return (-1);
20170Sstevel@tonic-gate 
20180Sstevel@tonic-gate 		/*
20190Sstevel@tonic-gate 		 * Check the client handle for the version
20200Sstevel@tonic-gate 		 */
20210Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
20220Sstevel@tonic-gate 
20230Sstevel@tonic-gate 		/*
20240Sstevel@tonic-gate 		 * If the client is version 1, return error
20250Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
20260Sstevel@tonic-gate 		 */
20270Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
20280Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
20290Sstevel@tonic-gate 				setno, hostname, NULL, setname);
20300Sstevel@tonic-gate 			metarpcclose(clntp);
20310Sstevel@tonic-gate 			return (-1);
20320Sstevel@tonic-gate 		} else {
20330Sstevel@tonic-gate 			if (mdrpc_mngetset_2(&v2_args, &res, clntp)
20340Sstevel@tonic-gate 							!= RPC_SUCCESS)
20350Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
20360Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad mn get set"));
20370Sstevel@tonic-gate 			else
20380Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
20390Sstevel@tonic-gate 		}
20400Sstevel@tonic-gate 
20410Sstevel@tonic-gate 		metarpcclose(clntp);
20420Sstevel@tonic-gate 	}
20430Sstevel@tonic-gate 
20440Sstevel@tonic-gate 	/* If no ep error and no version mismatch - rpc call worked ok */
20450Sstevel@tonic-gate 	if (mdisok(ep)) {
20460Sstevel@tonic-gate 		rval = 0;
20470Sstevel@tonic-gate 		if (ret_mnsr != NULL)
20480Sstevel@tonic-gate 			*ret_mnsr = res.mnsr;
20490Sstevel@tonic-gate 		else
20500Sstevel@tonic-gate 			if (! md_in_daemon)
20510Sstevel@tonic-gate 				xdr_free(xdr_mdrpc_mngetset_res, (char *)&res);
20520Sstevel@tonic-gate 	}
20530Sstevel@tonic-gate 
20540Sstevel@tonic-gate 	return (rval);
20550Sstevel@tonic-gate }
20560Sstevel@tonic-gate 
20570Sstevel@tonic-gate /*
20580Sstevel@tonic-gate  * Set master nodeid and nodename in multi-node set record.
20590Sstevel@tonic-gate  */
206062Sjeanm int
clnt_mnsetmaster(char * hostname,mdsetname_t * sp,md_node_nm_t master_nodenm,int master_nodeid,md_error_t * ep)20610Sstevel@tonic-gate clnt_mnsetmaster(
20620Sstevel@tonic-gate 	char			*hostname,
20630Sstevel@tonic-gate 	mdsetname_t		*sp,
20640Sstevel@tonic-gate 	md_node_nm_t		master_nodenm,
20650Sstevel@tonic-gate 	int			master_nodeid,
20660Sstevel@tonic-gate 	md_error_t		*ep
20670Sstevel@tonic-gate )
20680Sstevel@tonic-gate {
20690Sstevel@tonic-gate 	CLIENT			*clntp;
20700Sstevel@tonic-gate 	mdrpc_mnsetmaster_args	*args;
20710Sstevel@tonic-gate 	mdrpc_mnsetmaster_2_args	v2_args;
20720Sstevel@tonic-gate 	mdrpc_generic_res	res;
20730Sstevel@tonic-gate 	int			version;
20740Sstevel@tonic-gate 
20750Sstevel@tonic-gate 	/* initialize */
20760Sstevel@tonic-gate 	mdclrerror(ep);
20770Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
20780Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
20790Sstevel@tonic-gate 
20800Sstevel@tonic-gate 	/* build args */
20810Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
20820Sstevel@tonic-gate 	args = &v2_args.mdrpc_mnsetmaster_2_args_u.rev1;
20830Sstevel@tonic-gate 	args->sp = sp;
20840Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
20850Sstevel@tonic-gate 	(void) strlcpy(args->master_nodenm, master_nodenm, MD_MAX_NODENAME);
20860Sstevel@tonic-gate 	args->master_nodeid = master_nodeid;
20870Sstevel@tonic-gate 
20880Sstevel@tonic-gate 	/* do it */
20890Sstevel@tonic-gate 	if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
20900Sstevel@tonic-gate 		return (-1);
20910Sstevel@tonic-gate 
20920Sstevel@tonic-gate 	/*
20930Sstevel@tonic-gate 	 * Check the client handle for the version
20940Sstevel@tonic-gate 	 */
20950Sstevel@tonic-gate 	CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
20960Sstevel@tonic-gate 
20970Sstevel@tonic-gate 	/*
20980Sstevel@tonic-gate 	 * If the client is version 1, return error
20990Sstevel@tonic-gate 	 * otherwise, make the remote procedure call.
21000Sstevel@tonic-gate 	 */
21010Sstevel@tonic-gate 	if (version == METAD_VERSION) { /* version 1 */
21020Sstevel@tonic-gate 		(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
21030Sstevel@tonic-gate 			sp->setno, hostname, NULL, sp->setname);
21040Sstevel@tonic-gate 		metarpcclose(clntp);
21050Sstevel@tonic-gate 		return (-1);
21060Sstevel@tonic-gate 	} else {
21070Sstevel@tonic-gate 		if (mdrpc_mnsetmaster_2(&v2_args, &res, clntp) != RPC_SUCCESS)
21080Sstevel@tonic-gate 			(void) mdrpcerror(ep, clntp, hostname,
21090Sstevel@tonic-gate 			dgettext(TEXT_DOMAIN, "metad multi-owner set master"));
21100Sstevel@tonic-gate 		else
21110Sstevel@tonic-gate 			(void) mdstealerror(ep, &res.status);
21120Sstevel@tonic-gate 	}
21130Sstevel@tonic-gate 
21140Sstevel@tonic-gate 	metarpcclose(clntp);
21150Sstevel@tonic-gate 
21160Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
21170Sstevel@tonic-gate 
21180Sstevel@tonic-gate 	if (! mdisok(ep))
21190Sstevel@tonic-gate 		return (-1);
21200Sstevel@tonic-gate 
21210Sstevel@tonic-gate 	return (0);
21220Sstevel@tonic-gate }
21230Sstevel@tonic-gate 
21240Sstevel@tonic-gate /*
21250Sstevel@tonic-gate  * Get the MH timeout values.
21260Sstevel@tonic-gate  */
21270Sstevel@tonic-gate int
clnt_gtimeout(char * hostname,mdsetname_t * sp,mhd_mhiargs_t * ret_mhiargs,md_error_t * ep)21280Sstevel@tonic-gate clnt_gtimeout(
21290Sstevel@tonic-gate 	char			*hostname,
21300Sstevel@tonic-gate 	mdsetname_t		*sp,
21310Sstevel@tonic-gate 	mhd_mhiargs_t		*ret_mhiargs,
21320Sstevel@tonic-gate 	md_error_t		*ep
21330Sstevel@tonic-gate )
21340Sstevel@tonic-gate {
21350Sstevel@tonic-gate 	CLIENT			*clntp;
21360Sstevel@tonic-gate 	mdrpc_sp_args		*args;
21370Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
21380Sstevel@tonic-gate 	mdrpc_gtimeout_res	res;
21390Sstevel@tonic-gate 	int			rval = -1;
21400Sstevel@tonic-gate 	int			version;
21410Sstevel@tonic-gate 
21420Sstevel@tonic-gate 	/* initialize */
21430Sstevel@tonic-gate 	mdclrerror(ep);
21440Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
21450Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
21460Sstevel@tonic-gate 
21470Sstevel@tonic-gate 	/* build args */
21480Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
21490Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
21500Sstevel@tonic-gate 	args->sp = sp;
21510Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
21520Sstevel@tonic-gate 
21530Sstevel@tonic-gate 	/* do it */
21540Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
21550Sstevel@tonic-gate 		int	bool;
21560Sstevel@tonic-gate 		bool = mdrpc_gtimeout_2_svc(&v2_args, &res, NULL);
21570Sstevel@tonic-gate 		assert(bool == TRUE);
21580Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
21590Sstevel@tonic-gate 	} else {
21600Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
21610Sstevel@tonic-gate 			return (-1);
21620Sstevel@tonic-gate 
21630Sstevel@tonic-gate 		/*
21640Sstevel@tonic-gate 		 * Check the client handle for the version
21650Sstevel@tonic-gate 		 * and invoke the appropriate version of the
21660Sstevel@tonic-gate 		 * remote procedure
21670Sstevel@tonic-gate 		 */
21680Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
21690Sstevel@tonic-gate 
21700Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
21710Sstevel@tonic-gate 			if (mdrpc_gtimeout_1(args, &res, clntp) != RPC_SUCCESS)
21720Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
21730Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad get timeout"));
21740Sstevel@tonic-gate 			else
21750Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
21760Sstevel@tonic-gate 		} else {
21770Sstevel@tonic-gate 			if (mdrpc_gtimeout_2(&v2_args, &res, clntp) !=
21780Sstevel@tonic-gate 			    RPC_SUCCESS)
21790Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
21800Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad get timeout"));
21810Sstevel@tonic-gate 			else
21820Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
21830Sstevel@tonic-gate 		}
21840Sstevel@tonic-gate 
21850Sstevel@tonic-gate 		metarpcclose(clntp);
21860Sstevel@tonic-gate 	}
21870Sstevel@tonic-gate 
21880Sstevel@tonic-gate 	if (mdisok(ep)) {
21890Sstevel@tonic-gate 
21900Sstevel@tonic-gate 		/* do something with the results */
21910Sstevel@tonic-gate 		rval = 0;
21920Sstevel@tonic-gate 
21930Sstevel@tonic-gate 		/* copy md_mhiargs_t */
21940Sstevel@tonic-gate 		if (ret_mhiargs != NULL)
21950Sstevel@tonic-gate 			*ret_mhiargs = *res.mhiargsp;
21960Sstevel@tonic-gate 	}
21970Sstevel@tonic-gate 
21980Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_gtimeout_res, (char *)&res);
21990Sstevel@tonic-gate 
22000Sstevel@tonic-gate 	return (rval);
22010Sstevel@tonic-gate }
22020Sstevel@tonic-gate 
22030Sstevel@tonic-gate /*
22040Sstevel@tonic-gate  * get real hostname from remote host
22050Sstevel@tonic-gate  */
22060Sstevel@tonic-gate int
clnt_hostname(char * hostname,char ** ret_hostname,md_error_t * ep)22070Sstevel@tonic-gate clnt_hostname(
22080Sstevel@tonic-gate 	char			*hostname,
22090Sstevel@tonic-gate 	char			**ret_hostname,
22100Sstevel@tonic-gate 	md_error_t		*ep
22110Sstevel@tonic-gate )
22120Sstevel@tonic-gate {
22130Sstevel@tonic-gate 	CLIENT			*clntp;
22140Sstevel@tonic-gate 	mdrpc_null_args		args;
22150Sstevel@tonic-gate 	mdrpc_hostname_res	res;
22160Sstevel@tonic-gate 	int			rval = -1;
22170Sstevel@tonic-gate 
22180Sstevel@tonic-gate 	/* initialize */
22190Sstevel@tonic-gate 	mdclrerror(ep);
22200Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
22210Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
22220Sstevel@tonic-gate 
22230Sstevel@tonic-gate 	/* build args */
22240Sstevel@tonic-gate 	args.cl_sk = NULL;
22250Sstevel@tonic-gate 
22260Sstevel@tonic-gate 	/* do it */
22270Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
22280Sstevel@tonic-gate 		int	bool;
22290Sstevel@tonic-gate 		bool = mdrpc_hostname_1_svc(&args, &res, NULL);
22300Sstevel@tonic-gate 		assert(bool == TRUE);
22310Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
22320Sstevel@tonic-gate 	} else {
22330Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
22340Sstevel@tonic-gate 			return (-1);
22350Sstevel@tonic-gate 
22360Sstevel@tonic-gate 		if (mdrpc_hostname_1(&args, &res, clntp) != RPC_SUCCESS)
22370Sstevel@tonic-gate 			(void) mdrpcerror(ep, clntp, hostname,
22380Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad hostname"));
22390Sstevel@tonic-gate 		else
22400Sstevel@tonic-gate 			(void) mdstealerror(ep, &res.status);
22410Sstevel@tonic-gate 
22420Sstevel@tonic-gate 		metarpcclose(clntp);
22430Sstevel@tonic-gate 	}
22440Sstevel@tonic-gate 
22450Sstevel@tonic-gate 	if (mdisok(ep)) {
22460Sstevel@tonic-gate 		/* do something with the results */
22470Sstevel@tonic-gate 		rval = 0;
22480Sstevel@tonic-gate 
22490Sstevel@tonic-gate 		if (ret_hostname != NULL)
22500Sstevel@tonic-gate 			*ret_hostname = Strdup(res.hostname);
22510Sstevel@tonic-gate 	}
22520Sstevel@tonic-gate 
22530Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_hostname_res, (char *)&res);
22540Sstevel@tonic-gate 
22550Sstevel@tonic-gate 	return (rval);
22560Sstevel@tonic-gate }
22570Sstevel@tonic-gate 
22580Sstevel@tonic-gate /*
22590Sstevel@tonic-gate  * NULLPROC - just returns a response
22600Sstevel@tonic-gate  */
22610Sstevel@tonic-gate int
clnt_nullproc(char * hostname,md_error_t * ep)22620Sstevel@tonic-gate clnt_nullproc(
22630Sstevel@tonic-gate 	char			*hostname,
22640Sstevel@tonic-gate 	md_error_t		*ep
22650Sstevel@tonic-gate )
22660Sstevel@tonic-gate {
22670Sstevel@tonic-gate 	CLIENT			*clntp;
22680Sstevel@tonic-gate 
22690Sstevel@tonic-gate 	/* initialize */
22700Sstevel@tonic-gate 	mdclrerror(ep);
22710Sstevel@tonic-gate 
22720Sstevel@tonic-gate 	/* do it */
22730Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
22740Sstevel@tonic-gate 		int	bool;
22750Sstevel@tonic-gate 		bool = mdrpc_nullproc_1_svc(NULL, ep, NULL);
22760Sstevel@tonic-gate 		assert(bool == TRUE);
22770Sstevel@tonic-gate 	} else {
22780Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_DEF_TMO, ep)) == NULL)
22790Sstevel@tonic-gate 			return (-1);
22800Sstevel@tonic-gate 
22810Sstevel@tonic-gate 		if (mdrpc_nullproc_1(NULL, ep, clntp) != RPC_SUCCESS)
22820Sstevel@tonic-gate 			(void) mdrpcerror(ep, clntp, hostname,
22830Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad nullproc"));
22840Sstevel@tonic-gate 
22850Sstevel@tonic-gate 		metarpcclose(clntp);
22860Sstevel@tonic-gate 	}
22870Sstevel@tonic-gate 
22880Sstevel@tonic-gate 	if (! mdisok(ep))
22890Sstevel@tonic-gate 		return (-1);
22900Sstevel@tonic-gate 
22910Sstevel@tonic-gate 	return (0);
22920Sstevel@tonic-gate }
22930Sstevel@tonic-gate 
22940Sstevel@tonic-gate /*
22950Sstevel@tonic-gate  * does host own the set?
22960Sstevel@tonic-gate  */
22970Sstevel@tonic-gate int
clnt_ownset(char * hostname,mdsetname_t * sp,int * ret_bool,md_error_t * ep)22980Sstevel@tonic-gate clnt_ownset(
22990Sstevel@tonic-gate 	char			*hostname,
23000Sstevel@tonic-gate 	mdsetname_t		*sp,
23010Sstevel@tonic-gate 	int			*ret_bool,
23020Sstevel@tonic-gate 	md_error_t		*ep
23030Sstevel@tonic-gate )
23040Sstevel@tonic-gate {
23050Sstevel@tonic-gate 	CLIENT			*clntp;
23060Sstevel@tonic-gate 	mdrpc_sp_args		*args;
23070Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
23080Sstevel@tonic-gate 	mdrpc_bool_res		res;
23090Sstevel@tonic-gate 	int			rval = -1;
23100Sstevel@tonic-gate 	int			version;
23110Sstevel@tonic-gate 
23120Sstevel@tonic-gate 	/* initialize */
23130Sstevel@tonic-gate 	mdclrerror(ep);
23140Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
23150Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
23160Sstevel@tonic-gate 
23170Sstevel@tonic-gate 	/* build args */
23180Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
23190Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
23200Sstevel@tonic-gate 	args->sp = sp;
23210Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
23220Sstevel@tonic-gate 
23230Sstevel@tonic-gate 	/* do it */
23240Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
23250Sstevel@tonic-gate 		int	bool;
23260Sstevel@tonic-gate 		bool = mdrpc_ownset_2_svc(&v2_args, &res, NULL);
23270Sstevel@tonic-gate 		assert(bool == TRUE);
23280Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
23290Sstevel@tonic-gate 	} else {
23300Sstevel@tonic-gate 	    if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL) {
23310Sstevel@tonic-gate 		/*
23320Sstevel@tonic-gate 		 * This has to work in the code path from libpreen which is
23330Sstevel@tonic-gate 		 * running within fsck before the rpc.metad can run.  Check
23340Sstevel@tonic-gate 		 * to see if we should handle this as an auto-take diskset.
23350Sstevel@tonic-gate 		 */
23360Sstevel@tonic-gate 		if (is_auto_take_set(sp->setname, sp->setno)) {
23370Sstevel@tonic-gate 		    /* Can't call mdrpc_ownset_2_svc since not in daemon */
23380Sstevel@tonic-gate 		    mdclrerror(ep);
23390Sstevel@tonic-gate 		    if (s_ownset(sp->setno, ep))
23400Sstevel@tonic-gate 			res.value = TRUE;
23410Sstevel@tonic-gate 		    else
23420Sstevel@tonic-gate 			res.value = FALSE;
23430Sstevel@tonic-gate 		} else {
23440Sstevel@tonic-gate 		    return (-1);
23450Sstevel@tonic-gate 		}
23460Sstevel@tonic-gate 
23470Sstevel@tonic-gate 	    } else {
23480Sstevel@tonic-gate 
23490Sstevel@tonic-gate 		/*
23500Sstevel@tonic-gate 		 * Check the client handle for the version
23510Sstevel@tonic-gate 		 * and invoke the appropriate version of the
23520Sstevel@tonic-gate 		 * remote procedure
23530Sstevel@tonic-gate 		 */
23540Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
23550Sstevel@tonic-gate 
23560Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
23570Sstevel@tonic-gate 			if (mdrpc_ownset_1(args, &res, clntp) != RPC_SUCCESS)
23580Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
23590Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad own set"));
23600Sstevel@tonic-gate 			else
23610Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
23620Sstevel@tonic-gate 		} else {
23630Sstevel@tonic-gate 			if (mdrpc_ownset_2(&v2_args, &res, clntp) !=
23640Sstevel@tonic-gate 			    RPC_SUCCESS)
23650Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
23660Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad own set"));
23670Sstevel@tonic-gate 			else
23680Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
23690Sstevel@tonic-gate 		}
23700Sstevel@tonic-gate 
23710Sstevel@tonic-gate 		metarpcclose(clntp);
23720Sstevel@tonic-gate 	    }
23730Sstevel@tonic-gate 	}
23740Sstevel@tonic-gate 
23750Sstevel@tonic-gate 	if (mdisok(ep)) {
23760Sstevel@tonic-gate 		/* do something with the results */
23770Sstevel@tonic-gate 		rval = 0;
23780Sstevel@tonic-gate 
23790Sstevel@tonic-gate 		if (ret_bool != NULL)
23800Sstevel@tonic-gate 			*ret_bool = res.value;
23810Sstevel@tonic-gate 	}
23820Sstevel@tonic-gate 
23830Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_bool_res, (char *)&res);
23840Sstevel@tonic-gate 
23850Sstevel@tonic-gate 	return (rval);
23860Sstevel@tonic-gate }
23870Sstevel@tonic-gate 
23880Sstevel@tonic-gate /*
23890Sstevel@tonic-gate  * Valid set name.
23900Sstevel@tonic-gate  */
23910Sstevel@tonic-gate int
clnt_setnameok(char * hostname,mdsetname_t * sp,int * ret_bool,md_error_t * ep)23920Sstevel@tonic-gate clnt_setnameok(
23930Sstevel@tonic-gate 	char			*hostname,
23940Sstevel@tonic-gate 	mdsetname_t		*sp,
23950Sstevel@tonic-gate 	int			*ret_bool,
23960Sstevel@tonic-gate 	md_error_t		*ep
23970Sstevel@tonic-gate )
23980Sstevel@tonic-gate {
23990Sstevel@tonic-gate 	CLIENT			*clntp;
24000Sstevel@tonic-gate 	mdrpc_sp_args		*args;
24010Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
24020Sstevel@tonic-gate 	mdrpc_bool_res		res;
24030Sstevel@tonic-gate 	int			rval = -1;
24040Sstevel@tonic-gate 	int			version;
24050Sstevel@tonic-gate 
24060Sstevel@tonic-gate 	/* initialize */
24070Sstevel@tonic-gate 	mdclrerror(ep);
24080Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
24090Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
24100Sstevel@tonic-gate 
24110Sstevel@tonic-gate 	/* build args */
24120Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
24130Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
24140Sstevel@tonic-gate 	args->sp = sp;
24150Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
24160Sstevel@tonic-gate 
24170Sstevel@tonic-gate 	/* do it */
24180Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
24190Sstevel@tonic-gate 		int	bool;
24200Sstevel@tonic-gate 		bool = mdrpc_setnameok_2_svc(&v2_args, &res, NULL);
24210Sstevel@tonic-gate 		assert(bool == TRUE);
24220Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
24230Sstevel@tonic-gate 	} else {
24240Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
24250Sstevel@tonic-gate 			return (-1);
24260Sstevel@tonic-gate 
24270Sstevel@tonic-gate 		/*
24280Sstevel@tonic-gate 		 * Check the client handle for the version
24290Sstevel@tonic-gate 		 * and invoke the appropriate version of the
24300Sstevel@tonic-gate 		 * remote procedure
24310Sstevel@tonic-gate 		 */
24320Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
24330Sstevel@tonic-gate 
24340Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
24350Sstevel@tonic-gate 			if (mdrpc_setnameok_1(args, &res, clntp) != RPC_SUCCESS)
24360Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
24370Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad setname ok"));
24380Sstevel@tonic-gate 			else
24390Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
24400Sstevel@tonic-gate 		} else {
24410Sstevel@tonic-gate 			if (mdrpc_setnameok_2(&v2_args, &res, clntp) !=
24420Sstevel@tonic-gate 			    RPC_SUCCESS)
24430Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
24440Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad setname ok"));
24450Sstevel@tonic-gate 			else
24460Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
24470Sstevel@tonic-gate 		}
24480Sstevel@tonic-gate 
24490Sstevel@tonic-gate 		metarpcclose(clntp);
24500Sstevel@tonic-gate 	}
24510Sstevel@tonic-gate 
24520Sstevel@tonic-gate 	if (mdisok(ep)) {
24530Sstevel@tonic-gate 		/* do something with the results */
24540Sstevel@tonic-gate 		rval = 0;
24550Sstevel@tonic-gate 
24560Sstevel@tonic-gate 		if (ret_bool != NULL)
24570Sstevel@tonic-gate 			*ret_bool = res.value;
24580Sstevel@tonic-gate 	}
24590Sstevel@tonic-gate 
24600Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_bool_res, (char *)&res);
24610Sstevel@tonic-gate 
24620Sstevel@tonic-gate 	return (rval);
24630Sstevel@tonic-gate }
24640Sstevel@tonic-gate 
24650Sstevel@tonic-gate /*
24660Sstevel@tonic-gate  * Is set number in-use?
24670Sstevel@tonic-gate  */
24680Sstevel@tonic-gate int
clnt_setnumbusy(char * hostname,set_t setno,int * ret_bool,md_error_t * ep)24690Sstevel@tonic-gate clnt_setnumbusy(
24700Sstevel@tonic-gate 	char			*hostname,
24710Sstevel@tonic-gate 	set_t			setno,
24720Sstevel@tonic-gate 	int			*ret_bool,
24730Sstevel@tonic-gate 	md_error_t		*ep
24740Sstevel@tonic-gate )
24750Sstevel@tonic-gate {
24760Sstevel@tonic-gate 	CLIENT			*clntp;
24770Sstevel@tonic-gate 	mdrpc_setno_args	*args;
24780Sstevel@tonic-gate 	mdrpc_setno_2_args	v2_args;
24790Sstevel@tonic-gate 	mdrpc_bool_res		res;
24800Sstevel@tonic-gate 	int			rval = -1;
24810Sstevel@tonic-gate 	int			version;
24820Sstevel@tonic-gate 
24830Sstevel@tonic-gate 	/* initialize */
24840Sstevel@tonic-gate 	mdclrerror(ep);
24850Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
24860Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
24870Sstevel@tonic-gate 
24880Sstevel@tonic-gate 	/* build args */
24890Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
24900Sstevel@tonic-gate 	args = &v2_args.mdrpc_setno_2_args_u.rev1;
24910Sstevel@tonic-gate 	args->setno = setno;
24920Sstevel@tonic-gate 	args->cl_sk = NULL;
24930Sstevel@tonic-gate 
24940Sstevel@tonic-gate 	/* do it */
24950Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
24960Sstevel@tonic-gate 		int	bool;
24970Sstevel@tonic-gate 		bool = mdrpc_setnumbusy_2_svc(&v2_args, &res, NULL);
24980Sstevel@tonic-gate 		assert(bool == TRUE);
24990Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
25000Sstevel@tonic-gate 	} else {
25010Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
25020Sstevel@tonic-gate 			return (-1);
25030Sstevel@tonic-gate 
25040Sstevel@tonic-gate 		/*
25050Sstevel@tonic-gate 		 * Check the client handle for the version
25060Sstevel@tonic-gate 		 * and invoke the appropriate version of the
25070Sstevel@tonic-gate 		 * remote procedure
25080Sstevel@tonic-gate 		 */
25090Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
25100Sstevel@tonic-gate 
25110Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
25120Sstevel@tonic-gate 			if (mdrpc_setnumbusy_1(args, &res, clntp) !=
25130Sstevel@tonic-gate 			    RPC_SUCCESS)
25140Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
25150Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad setnumber busy"));
25160Sstevel@tonic-gate 			else
25170Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
25180Sstevel@tonic-gate 		} else {
25190Sstevel@tonic-gate 			if (mdrpc_setnumbusy_2(&v2_args, &res, clntp) !=
25200Sstevel@tonic-gate 			    RPC_SUCCESS)
25210Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
25220Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad setnumber busy"));
25230Sstevel@tonic-gate 			else
25240Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
25250Sstevel@tonic-gate 		}
25260Sstevel@tonic-gate 
25270Sstevel@tonic-gate 		metarpcclose(clntp);
25280Sstevel@tonic-gate 	}
25290Sstevel@tonic-gate 
25300Sstevel@tonic-gate 	if (mdisok(ep)) {
25310Sstevel@tonic-gate 		/* do something with the results */
25320Sstevel@tonic-gate 		rval = 0;
25330Sstevel@tonic-gate 
25340Sstevel@tonic-gate 		if (ret_bool != NULL)
25350Sstevel@tonic-gate 			*ret_bool = res.value;
25360Sstevel@tonic-gate 	}
25370Sstevel@tonic-gate 
25380Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_bool_res, (char *)&res);
25390Sstevel@tonic-gate 
25400Sstevel@tonic-gate 	return (rval);
25410Sstevel@tonic-gate }
25420Sstevel@tonic-gate 
25430Sstevel@tonic-gate /*
25440Sstevel@tonic-gate  * Set the timeout values used into the drive records.
25450Sstevel@tonic-gate  */
25460Sstevel@tonic-gate int
clnt_stimeout(char * hostname,mdsetname_t * sp,mhd_mhiargs_t * mhiargsp,md_error_t * ep)25470Sstevel@tonic-gate clnt_stimeout(
25480Sstevel@tonic-gate 	char			*hostname,
25490Sstevel@tonic-gate 	mdsetname_t		*sp,
25500Sstevel@tonic-gate 	mhd_mhiargs_t		*mhiargsp,
25510Sstevel@tonic-gate 	md_error_t		*ep
25520Sstevel@tonic-gate )
25530Sstevel@tonic-gate {
25540Sstevel@tonic-gate 	CLIENT			*clntp;
25550Sstevel@tonic-gate 	mdrpc_stimeout_args	*args;
25560Sstevel@tonic-gate 	mdrpc_stimeout_2_args	v2_args;
25570Sstevel@tonic-gate 	mdrpc_generic_res	res;
25580Sstevel@tonic-gate 	int			version;
25590Sstevel@tonic-gate 
25600Sstevel@tonic-gate 	/* initialize */
25610Sstevel@tonic-gate 	mdclrerror(ep);
25620Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
25630Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
25640Sstevel@tonic-gate 
25650Sstevel@tonic-gate 	/* build args */
25660Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
25670Sstevel@tonic-gate 	args = &v2_args.mdrpc_stimeout_2_args_u.rev1;
25680Sstevel@tonic-gate 	args->sp = sp;
25690Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
25700Sstevel@tonic-gate 	args->mhiargsp = mhiargsp;
25710Sstevel@tonic-gate 
25720Sstevel@tonic-gate 	/* do it */
25730Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
25740Sstevel@tonic-gate 		int	bool;
25750Sstevel@tonic-gate 		bool = mdrpc_stimeout_2_svc(&v2_args, &res, NULL);
25760Sstevel@tonic-gate 		assert(bool == TRUE);
25770Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
25780Sstevel@tonic-gate 	} else {
25790Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
25800Sstevel@tonic-gate 			return (-1);
25810Sstevel@tonic-gate 
25820Sstevel@tonic-gate 		/*
25830Sstevel@tonic-gate 		 * Check the client handle for the version
25840Sstevel@tonic-gate 		 * and invoke the appropriate version of the
25850Sstevel@tonic-gate 		 * remote procedure
25860Sstevel@tonic-gate 		 */
25870Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
25880Sstevel@tonic-gate 
25890Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
25900Sstevel@tonic-gate 			if (mdrpc_stimeout_1(args, &res, clntp) != RPC_SUCCESS)
25910Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
25920Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad set timeout"));
25930Sstevel@tonic-gate 			else
25940Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
25950Sstevel@tonic-gate 		} else {
25960Sstevel@tonic-gate 			if (mdrpc_stimeout_2(&v2_args, &res, clntp) !=
25970Sstevel@tonic-gate 			    RPC_SUCCESS)
25980Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
25990Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad set timeout"));
26000Sstevel@tonic-gate 			else
26010Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
26020Sstevel@tonic-gate 		}
26030Sstevel@tonic-gate 
26040Sstevel@tonic-gate 		metarpcclose(clntp);
26050Sstevel@tonic-gate 	}
26060Sstevel@tonic-gate 
26070Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
26080Sstevel@tonic-gate 
26090Sstevel@tonic-gate 	if (! mdisok(ep))
26100Sstevel@tonic-gate 		return (-1);
26110Sstevel@tonic-gate 
26120Sstevel@tonic-gate 	return (0);
26130Sstevel@tonic-gate }
26140Sstevel@tonic-gate 
26150Sstevel@tonic-gate /*
26160Sstevel@tonic-gate  * update drive records
26170Sstevel@tonic-gate  */
26180Sstevel@tonic-gate int
clnt_upd_dr_dbinfo(char * hostname,mdsetname_t * sp,md_drive_desc * dd,md_error_t * ep)26190Sstevel@tonic-gate clnt_upd_dr_dbinfo(
26200Sstevel@tonic-gate 	char			*hostname,
26210Sstevel@tonic-gate 	mdsetname_t		*sp,
26220Sstevel@tonic-gate 	md_drive_desc		*dd,
26230Sstevel@tonic-gate 	md_error_t		*ep
26240Sstevel@tonic-gate )
26250Sstevel@tonic-gate {
26260Sstevel@tonic-gate 	CLIENT			*clntp;
26270Sstevel@tonic-gate 	mdrpc_drives_args	v1_args;
26280Sstevel@tonic-gate 	mdrpc_drives_2_args	v2_args;
26290Sstevel@tonic-gate 	mdrpc_drives_2_args_r1	*v21_args;
26300Sstevel@tonic-gate 	mdrpc_generic_res	res;
26310Sstevel@tonic-gate 	int			rval;
26320Sstevel@tonic-gate 	int			version;
26330Sstevel@tonic-gate 
26340Sstevel@tonic-gate 	/* initialize */
26350Sstevel@tonic-gate 	mdclrerror(ep);
26360Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
26370Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
26380Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
26390Sstevel@tonic-gate 
26400Sstevel@tonic-gate 	/* build args */
26410Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
26420Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_drives_2_args_u.rev1;
26430Sstevel@tonic-gate 	v21_args->sp = sp;
26440Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
26450Sstevel@tonic-gate 	v21_args->drivedescs = dd;
26460Sstevel@tonic-gate 
26470Sstevel@tonic-gate 	/* do it */
26480Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
26490Sstevel@tonic-gate 		int	bool;
26500Sstevel@tonic-gate 
26510Sstevel@tonic-gate 		/*
26520Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
26530Sstevel@tonic-gate 		 */
26540Sstevel@tonic-gate 		bool = mdrpc_upd_dr_dbinfo_2_svc(&v2_args, &res, NULL);
26550Sstevel@tonic-gate 		assert(bool == TRUE);
26560Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
26570Sstevel@tonic-gate 	} else {
26580Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
26590Sstevel@tonic-gate 			return (-1);
26600Sstevel@tonic-gate 
26610Sstevel@tonic-gate 		/*
26620Sstevel@tonic-gate 		 * Check the client handle for the version
26630Sstevel@tonic-gate 		 * and invoke the appropriate version of the
26640Sstevel@tonic-gate 		 * remote procedure
26650Sstevel@tonic-gate 		 */
26660Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
26670Sstevel@tonic-gate 
26680Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
26690Sstevel@tonic-gate 
26700Sstevel@tonic-gate 			alloc_olddrvdesc(&v1_args.drivedescs, dd);
26710Sstevel@tonic-gate 
26720Sstevel@tonic-gate 			/* build args */
26730Sstevel@tonic-gate 			v1_args.sp = sp;
26740Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
26750Sstevel@tonic-gate 			meta_conv_drvdesc_new2old(v1_args.drivedescs, dd);
26760Sstevel@tonic-gate 
26770Sstevel@tonic-gate 			rval = mdrpc_upd_dr_dbinfo_1(&v1_args, &res, clntp);
26780Sstevel@tonic-gate 
26790Sstevel@tonic-gate 			free_olddrvdesc(v1_args.drivedescs);
26800Sstevel@tonic-gate 
26810Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
26820Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
26830Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
26840Sstevel@tonic-gate 				    "metad update drive dbinfo"));
26850Sstevel@tonic-gate 			else
26860Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
26870Sstevel@tonic-gate 		} else {			/* version 2 */
26880Sstevel@tonic-gate 			rval = mdrpc_upd_dr_dbinfo_2(&v2_args, &res, clntp);
26890Sstevel@tonic-gate 
26900Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
26910Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
26920Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
26930Sstevel@tonic-gate 				    "metad update drive dbinfo"));
26940Sstevel@tonic-gate 			else
26950Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
26960Sstevel@tonic-gate 		}
26970Sstevel@tonic-gate 
26980Sstevel@tonic-gate 		metarpcclose(clntp);
26990Sstevel@tonic-gate 	}
27000Sstevel@tonic-gate 
27010Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
27020Sstevel@tonic-gate 
27030Sstevel@tonic-gate 	if (! mdisok(ep))
27040Sstevel@tonic-gate 		return (-1);
27050Sstevel@tonic-gate 
27060Sstevel@tonic-gate 	return (0);
27070Sstevel@tonic-gate }
27080Sstevel@tonic-gate 
27090Sstevel@tonic-gate /*
27100Sstevel@tonic-gate  * update dr_flags field of drive record.
27110Sstevel@tonic-gate  */
27120Sstevel@tonic-gate int
clnt_upd_dr_flags(char * hostname,mdsetname_t * sp,md_drive_desc * dd,uint_t new_flags,md_error_t * ep)27130Sstevel@tonic-gate clnt_upd_dr_flags(
27140Sstevel@tonic-gate 	char			*hostname,
27150Sstevel@tonic-gate 	mdsetname_t		*sp,
27160Sstevel@tonic-gate 	md_drive_desc		*dd,
27170Sstevel@tonic-gate 	uint_t			new_flags,
27180Sstevel@tonic-gate 	md_error_t		*ep
27190Sstevel@tonic-gate )
27200Sstevel@tonic-gate {
27210Sstevel@tonic-gate 	CLIENT				*clntp;
27220Sstevel@tonic-gate 	mdrpc_upd_dr_flags_args		v1_args;
27230Sstevel@tonic-gate 	mdrpc_upd_dr_flags_2_args	v2_args;
27240Sstevel@tonic-gate 	mdrpc_upd_dr_flags_2_args_r1	*v21_args;
27250Sstevel@tonic-gate 	mdrpc_generic_res		res;
27260Sstevel@tonic-gate 	int				rval;
27270Sstevel@tonic-gate 	int				version;
27280Sstevel@tonic-gate 
27290Sstevel@tonic-gate 	/* initialize */
27300Sstevel@tonic-gate 	mdclrerror(ep);
27310Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
27320Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
27330Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
27340Sstevel@tonic-gate 
27350Sstevel@tonic-gate 	/* build args */
27360Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
27370Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_upd_dr_flags_2_args_u.rev1;
27380Sstevel@tonic-gate 	v21_args->sp = sp;
27390Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
27400Sstevel@tonic-gate 	v21_args->drivedescs = dd;
27410Sstevel@tonic-gate 	v21_args->new_flags = new_flags;
27420Sstevel@tonic-gate 
27430Sstevel@tonic-gate 	/* do it */
27440Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
27450Sstevel@tonic-gate 		int	bool;
27460Sstevel@tonic-gate 
27470Sstevel@tonic-gate 		/*
27480Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
27490Sstevel@tonic-gate 		 */
27500Sstevel@tonic-gate 		bool = mdrpc_upd_dr_flags_2_svc(&v2_args, &res, NULL);
27510Sstevel@tonic-gate 		assert(bool == TRUE);
27520Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
27530Sstevel@tonic-gate 	} else {
27540Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
27550Sstevel@tonic-gate 			return (-1);
27560Sstevel@tonic-gate 
27570Sstevel@tonic-gate 		/*
27580Sstevel@tonic-gate 		 * Check the client handle for the version
27590Sstevel@tonic-gate 		 * and invoke the appropriate version of the
27600Sstevel@tonic-gate 		 * remote procedure
27610Sstevel@tonic-gate 		 */
27620Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
27630Sstevel@tonic-gate 
27640Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
27650Sstevel@tonic-gate 
27660Sstevel@tonic-gate 			alloc_olddrvdesc(&v1_args.drivedescs, dd);
27670Sstevel@tonic-gate 
27680Sstevel@tonic-gate 			/* build args */
27690Sstevel@tonic-gate 			v1_args.sp = sp;
27700Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
27710Sstevel@tonic-gate 			meta_conv_drvdesc_new2old(v1_args.drivedescs, dd);
27720Sstevel@tonic-gate 			v1_args.new_flags = new_flags;
27730Sstevel@tonic-gate 
27740Sstevel@tonic-gate 			rval = mdrpc_upd_dr_flags_1(&v1_args, &res, clntp);
27750Sstevel@tonic-gate 
27760Sstevel@tonic-gate 			free_olddrvdesc(v1_args.drivedescs);
27770Sstevel@tonic-gate 
27780Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
27790Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
27800Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
27810Sstevel@tonic-gate 				    "metad update drive flags"));
27820Sstevel@tonic-gate 			else
27830Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
27840Sstevel@tonic-gate 		} else {			/* version 2 */
27850Sstevel@tonic-gate 			rval = mdrpc_upd_dr_flags_2(&v2_args, &res, clntp);
27860Sstevel@tonic-gate 
27870Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
27880Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
27890Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
27900Sstevel@tonic-gate 				    "metad update drive flags"));
27910Sstevel@tonic-gate 			else
27920Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
27930Sstevel@tonic-gate 		}
27940Sstevel@tonic-gate 
27950Sstevel@tonic-gate 		metarpcclose(clntp);
27960Sstevel@tonic-gate 	}
27970Sstevel@tonic-gate 
27980Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
27990Sstevel@tonic-gate 
28000Sstevel@tonic-gate 	if (! mdisok(ep)) {
28010Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
28020Sstevel@tonic-gate 			return (-1);
28030Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
28040Sstevel@tonic-gate 			return (-1);
28050Sstevel@tonic-gate 		mdclrerror(ep);
28060Sstevel@tonic-gate 	}
28070Sstevel@tonic-gate 
28080Sstevel@tonic-gate 	return (0);
28090Sstevel@tonic-gate }
28100Sstevel@tonic-gate 
28110Sstevel@tonic-gate /*
28120Sstevel@tonic-gate  * update set record flags
28130Sstevel@tonic-gate  * This replaces all of the sr_flags with the new_flags.  It relies on the
28140Sstevel@tonic-gate  * caller to "do the right thing" to preserve the existing flags that should
28150Sstevel@tonic-gate  * not be reset.
28160Sstevel@tonic-gate  */
28170Sstevel@tonic-gate static int
upd_sr_flags_common(char * hostname,mdsetname_t * sp,uint_t new_flags,md_error_t * ep)28180Sstevel@tonic-gate upd_sr_flags_common(
28190Sstevel@tonic-gate 	char			*hostname,
28200Sstevel@tonic-gate 	mdsetname_t		*sp,
28210Sstevel@tonic-gate 	uint_t			new_flags,
28220Sstevel@tonic-gate 	md_error_t		*ep
28230Sstevel@tonic-gate )
28240Sstevel@tonic-gate {
28250Sstevel@tonic-gate 	CLIENT				*clntp;
28260Sstevel@tonic-gate 	mdrpc_upd_sr_flags_args		*args;
28270Sstevel@tonic-gate 	mdrpc_upd_sr_flags_2_args	v2_args;
28280Sstevel@tonic-gate 	mdrpc_generic_res		res;
28290Sstevel@tonic-gate 	int				version;
28300Sstevel@tonic-gate 
28310Sstevel@tonic-gate 	/* initialize */
28320Sstevel@tonic-gate 	mdclrerror(ep);
28330Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
28340Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
28350Sstevel@tonic-gate 
28360Sstevel@tonic-gate 	/* build args */
28370Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
28380Sstevel@tonic-gate 	args = &v2_args.mdrpc_upd_sr_flags_2_args_u.rev1;
28390Sstevel@tonic-gate 	args->sp = sp;
28400Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
28410Sstevel@tonic-gate 
28420Sstevel@tonic-gate 	args->new_flags = new_flags;
28430Sstevel@tonic-gate 
28440Sstevel@tonic-gate 	/* do it */
28450Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
28460Sstevel@tonic-gate 		int	bool;
28470Sstevel@tonic-gate 		bool = mdrpc_upd_sr_flags_2_svc(&v2_args, &res, NULL);
28480Sstevel@tonic-gate 		assert(bool == TRUE);
28490Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
28500Sstevel@tonic-gate 	} else {
28510Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
28520Sstevel@tonic-gate 			return (-1);
28530Sstevel@tonic-gate 
28540Sstevel@tonic-gate 		/*
28550Sstevel@tonic-gate 		 * Check the client handle for the version
28560Sstevel@tonic-gate 		 * and invoke the appropriate version of the
28570Sstevel@tonic-gate 		 * remote procedure
28580Sstevel@tonic-gate 		 */
28590Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
28600Sstevel@tonic-gate 
28610Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
28620Sstevel@tonic-gate 			if (mdrpc_upd_sr_flags_1(args, &res, clntp) !=
28630Sstevel@tonic-gate 			    RPC_SUCCESS)
28640Sstevel@tonic-gate 			    (void) mdrpcerror(ep, clntp, hostname,
28650Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad update set flags"));
28660Sstevel@tonic-gate 			else
28670Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
28680Sstevel@tonic-gate 		} else {
28690Sstevel@tonic-gate 			if (mdrpc_upd_sr_flags_2(&v2_args, &res, clntp) !=
28700Sstevel@tonic-gate 			    RPC_SUCCESS)
28710Sstevel@tonic-gate 			    (void) mdrpcerror(ep, clntp, hostname,
28720Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad update set flags"));
28730Sstevel@tonic-gate 			else
28740Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
28750Sstevel@tonic-gate 		}
28760Sstevel@tonic-gate 
28770Sstevel@tonic-gate 		metarpcclose(clntp);
28780Sstevel@tonic-gate 	}
28790Sstevel@tonic-gate 
28800Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
28810Sstevel@tonic-gate 
28820Sstevel@tonic-gate 	if (! mdisok(ep)) {
28830Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
28840Sstevel@tonic-gate 			return (-1);
28850Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
28860Sstevel@tonic-gate 			return (-1);
28870Sstevel@tonic-gate 		mdclrerror(ep);
28880Sstevel@tonic-gate 	}
28890Sstevel@tonic-gate 
28900Sstevel@tonic-gate 	return (0);
28910Sstevel@tonic-gate }
28920Sstevel@tonic-gate 
28930Sstevel@tonic-gate /*
28940Sstevel@tonic-gate  * Enable bits in the set record flags field.  This just turns on the specified
28950Sstevel@tonic-gate  * bits and leaves the other bits alone.
28960Sstevel@tonic-gate  */
28970Sstevel@tonic-gate int
clnt_enable_sr_flags(char * hostname,mdsetname_t * sp,uint_t flags,md_error_t * ep)28980Sstevel@tonic-gate clnt_enable_sr_flags(
28990Sstevel@tonic-gate 	char			*hostname,
29000Sstevel@tonic-gate 	mdsetname_t		*sp,
29010Sstevel@tonic-gate 	uint_t			flags,
29020Sstevel@tonic-gate 	md_error_t		*ep
29030Sstevel@tonic-gate )
29040Sstevel@tonic-gate {
29050Sstevel@tonic-gate 	uint_t		new_flags;
29060Sstevel@tonic-gate 	md_set_desc	*sd;
29070Sstevel@tonic-gate 
29080Sstevel@tonic-gate 	mdclrerror(ep);
29090Sstevel@tonic-gate 
29100Sstevel@tonic-gate 	/* Get the flags from the current set */
29110Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
29120Sstevel@tonic-gate 		return (-1);
29130Sstevel@tonic-gate 
29140Sstevel@tonic-gate 	/* Turn on the specified bits */
29150Sstevel@tonic-gate 	new_flags = (sd->sd_flags | flags);
29160Sstevel@tonic-gate 
29170Sstevel@tonic-gate 	/* do it */
29180Sstevel@tonic-gate 	return (upd_sr_flags_common(hostname, sp, new_flags, ep));
29190Sstevel@tonic-gate }
29200Sstevel@tonic-gate 
29210Sstevel@tonic-gate /*
29220Sstevel@tonic-gate  * Disable bits in the set record flags field.  This just turns off the
29230Sstevel@tonic-gate  * specified bits and leaves the other bits alone.
29240Sstevel@tonic-gate  */
29250Sstevel@tonic-gate int
clnt_disable_sr_flags(char * hostname,mdsetname_t * sp,uint_t flags,md_error_t * ep)29260Sstevel@tonic-gate clnt_disable_sr_flags(
29270Sstevel@tonic-gate 	char			*hostname,
29280Sstevel@tonic-gate 	mdsetname_t		*sp,
29290Sstevel@tonic-gate 	uint_t			flags,
29300Sstevel@tonic-gate 	md_error_t		*ep
29310Sstevel@tonic-gate )
29320Sstevel@tonic-gate {
29330Sstevel@tonic-gate 	uint_t		new_flags;
29340Sstevel@tonic-gate 	md_set_desc	*sd;
29350Sstevel@tonic-gate 
29360Sstevel@tonic-gate 	mdclrerror(ep);
29370Sstevel@tonic-gate 
29380Sstevel@tonic-gate 	/* Get the flags from the current set */
29390Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
29400Sstevel@tonic-gate 		return (-1);
29410Sstevel@tonic-gate 
29420Sstevel@tonic-gate 	/* Turn off the specified bits */
29430Sstevel@tonic-gate 	new_flags = (sd->sd_flags & ~flags);
29440Sstevel@tonic-gate 
29450Sstevel@tonic-gate 	/* do it */
29460Sstevel@tonic-gate 	return (upd_sr_flags_common(hostname, sp, new_flags, ep));
29470Sstevel@tonic-gate }
29480Sstevel@tonic-gate 
29490Sstevel@tonic-gate /*
29500Sstevel@tonic-gate  * Assign the flags as the new value(s) for the MD_SR_STATE_FLAGS within the
29510Sstevel@tonic-gate  * set record flags field.  This actually can set any bits but only clears
29520Sstevel@tonic-gate  * the bits within the MD_SR_STATE_FLAGS subfield and leaves any other
29530Sstevel@tonic-gate  * bits turned on.  It can be used to clear (state) and set bits all in one
29540Sstevel@tonic-gate  * rpc call.
29550Sstevel@tonic-gate  */
29560Sstevel@tonic-gate int
clnt_upd_sr_flags(char * hostname,mdsetname_t * sp,uint_t flags,md_error_t * ep)29570Sstevel@tonic-gate clnt_upd_sr_flags(
29580Sstevel@tonic-gate 	char			*hostname,
29590Sstevel@tonic-gate 	mdsetname_t		*sp,
29600Sstevel@tonic-gate 	uint_t			flags,
29610Sstevel@tonic-gate 	md_error_t		*ep
29620Sstevel@tonic-gate )
29630Sstevel@tonic-gate {
29640Sstevel@tonic-gate 	uint_t		new_flags;
29650Sstevel@tonic-gate 	md_set_desc	*sd;
29660Sstevel@tonic-gate 
29670Sstevel@tonic-gate 	mdclrerror(ep);
29680Sstevel@tonic-gate 
29690Sstevel@tonic-gate 	/* Get the flags from the current set */
29700Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
29710Sstevel@tonic-gate 		return (-1);
29720Sstevel@tonic-gate 
29730Sstevel@tonic-gate 	/* clear the existing state flags */
29740Sstevel@tonic-gate 	sd->sd_flags &= ~MD_SR_STATE_FLAGS;
29750Sstevel@tonic-gate 
29760Sstevel@tonic-gate 	/* Or in the new value */
29770Sstevel@tonic-gate 	new_flags = (sd->sd_flags | flags);
29780Sstevel@tonic-gate 
29790Sstevel@tonic-gate 	/* do it */
29800Sstevel@tonic-gate 	return (upd_sr_flags_common(hostname, sp, new_flags, ep));
29810Sstevel@tonic-gate }
29820Sstevel@tonic-gate 
29830Sstevel@tonic-gate md_setkey_t *
cl_get_setkey(set_t setno,char * setname)29840Sstevel@tonic-gate cl_get_setkey(set_t setno, char *setname)
29850Sstevel@tonic-gate {
29860Sstevel@tonic-gate 
29870Sstevel@tonic-gate 	if (my_cl_sk == NULL) {
29880Sstevel@tonic-gate 		my_cl_sk = Zalloc(sizeof (md_setkey_t));
29890Sstevel@tonic-gate 		my_cl_sk->sk_setno = setno;
29900Sstevel@tonic-gate 		my_cl_sk->sk_setname = Strdup(setname);
29910Sstevel@tonic-gate 		my_cl_sk->sk_host = Strdup(mynode());
29920Sstevel@tonic-gate 	} else {
29930Sstevel@tonic-gate 		my_cl_sk->sk_setno = setno;
29940Sstevel@tonic-gate 		if (my_cl_sk->sk_setname != NULL)
29950Sstevel@tonic-gate 			Free(my_cl_sk->sk_setname);
29960Sstevel@tonic-gate 		my_cl_sk->sk_setname = Strdup(setname);
29970Sstevel@tonic-gate 	}
29980Sstevel@tonic-gate 
29990Sstevel@tonic-gate 	return (my_cl_sk);
30000Sstevel@tonic-gate }
30010Sstevel@tonic-gate 
30020Sstevel@tonic-gate void
cl_set_setkey(md_setkey_t * cl_sk)30030Sstevel@tonic-gate cl_set_setkey(md_setkey_t *cl_sk)
30040Sstevel@tonic-gate {
30050Sstevel@tonic-gate 	if ((cl_sk != NULL) && (my_cl_sk != NULL)) {
30060Sstevel@tonic-gate 		assert(my_cl_sk->sk_setno == cl_sk->sk_setno);
30070Sstevel@tonic-gate 		assert(strcmp(my_cl_sk->sk_setname, cl_sk->sk_setname) == 0);
30080Sstevel@tonic-gate 		assert(strcmp(my_cl_sk->sk_host, cl_sk->sk_host) == 0);
30090Sstevel@tonic-gate 		my_cl_sk->sk_key = cl_sk->sk_key;
30100Sstevel@tonic-gate 		return;
30110Sstevel@tonic-gate 	}
30120Sstevel@tonic-gate 
30130Sstevel@tonic-gate 	if (my_cl_sk != NULL) {
30140Sstevel@tonic-gate 		if (my_cl_sk->sk_setname != NULL)
30150Sstevel@tonic-gate 			Free(my_cl_sk->sk_setname);
30160Sstevel@tonic-gate 		if (my_cl_sk->sk_host != NULL)
30170Sstevel@tonic-gate 			Free(my_cl_sk->sk_host);
30180Sstevel@tonic-gate 		Free(my_cl_sk);
30190Sstevel@tonic-gate 	}
30200Sstevel@tonic-gate 
30210Sstevel@tonic-gate 	my_cl_sk = NULL;
30220Sstevel@tonic-gate 
30230Sstevel@tonic-gate 	/* get here, if set called before get */
30240Sstevel@tonic-gate 	if (cl_sk != NULL) {
30250Sstevel@tonic-gate 		my_cl_sk = Zalloc(sizeof (md_setkey_t));
30260Sstevel@tonic-gate 		my_cl_sk->sk_host = Strdup(cl_sk->sk_host);
30270Sstevel@tonic-gate 		my_cl_sk->sk_setno = cl_sk->sk_setno;
30280Sstevel@tonic-gate 		my_cl_sk->sk_setname = Strdup(cl_sk->sk_setname);
30290Sstevel@tonic-gate 		my_cl_sk->sk_key = cl_sk->sk_key;
30300Sstevel@tonic-gate 	}
30310Sstevel@tonic-gate }
30320Sstevel@tonic-gate 
30330Sstevel@tonic-gate /*
30340Sstevel@tonic-gate  * Unlock the set after operation is complete.
30350Sstevel@tonic-gate  */
30360Sstevel@tonic-gate int
clnt_unlock_set(char * hostname,md_setkey_t * cl_sk,md_error_t * ep)30370Sstevel@tonic-gate clnt_unlock_set(
30380Sstevel@tonic-gate 	char			*hostname,
30390Sstevel@tonic-gate 	md_setkey_t		*cl_sk,
30400Sstevel@tonic-gate 	md_error_t		*ep
30410Sstevel@tonic-gate )
30420Sstevel@tonic-gate {
30430Sstevel@tonic-gate 	CLIENT			*clntp;
30440Sstevel@tonic-gate 	mdrpc_null_args		args;
30450Sstevel@tonic-gate 	mdrpc_setlock_res	res;
30460Sstevel@tonic-gate 
30470Sstevel@tonic-gate 	/* initialize */
30480Sstevel@tonic-gate 	mdclrerror(ep);
30490Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
30500Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
30510Sstevel@tonic-gate 
30520Sstevel@tonic-gate 	/* build args */
30530Sstevel@tonic-gate 	args.cl_sk = cl_sk;
30540Sstevel@tonic-gate 
30550Sstevel@tonic-gate 	/* do it */
30560Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
30570Sstevel@tonic-gate 		int	bool;
30580Sstevel@tonic-gate 		bool = mdrpc_unlock_set_1_svc(&args, &res, NULL);
30590Sstevel@tonic-gate 		assert(bool == TRUE);
30600Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
30610Sstevel@tonic-gate 	} else {
30620Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
30630Sstevel@tonic-gate 			return (-1);
30640Sstevel@tonic-gate 
30650Sstevel@tonic-gate 		if (mdrpc_unlock_set_1(&args, &res, clntp) != RPC_SUCCESS)
30660Sstevel@tonic-gate 			(void) mdrpcerror(ep, clntp, hostname,
30670Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad unlock set"));
30680Sstevel@tonic-gate 		else
30690Sstevel@tonic-gate 			(void) mdstealerror(ep, &res.status);
30700Sstevel@tonic-gate 
30710Sstevel@tonic-gate 		metarpcclose(clntp);
30720Sstevel@tonic-gate 	}
30730Sstevel@tonic-gate 
30740Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_setlock_res, (char *)&res);
30750Sstevel@tonic-gate 
30760Sstevel@tonic-gate 	if (! mdisok(ep)) {
30770Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
30780Sstevel@tonic-gate 			return (-1);
30790Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
30800Sstevel@tonic-gate 			return (-1);
30810Sstevel@tonic-gate 		mdclrerror(ep);
30820Sstevel@tonic-gate 	}
30830Sstevel@tonic-gate 
30840Sstevel@tonic-gate 	return (0);
30850Sstevel@tonic-gate }
30860Sstevel@tonic-gate 
30870Sstevel@tonic-gate /*
30880Sstevel@tonic-gate  * Lock set so that only operators with valid keys are allowed in the daemon.
30890Sstevel@tonic-gate  */
30900Sstevel@tonic-gate int
clnt_lock_set(char * hostname,mdsetname_t * sp,md_error_t * ep)30910Sstevel@tonic-gate clnt_lock_set(
30920Sstevel@tonic-gate 	char			*hostname,
30930Sstevel@tonic-gate 	mdsetname_t		*sp,
30940Sstevel@tonic-gate 	md_error_t		*ep
30950Sstevel@tonic-gate )
30960Sstevel@tonic-gate {
30970Sstevel@tonic-gate 	CLIENT			*clntp;
30980Sstevel@tonic-gate 	mdrpc_null_args		args;
30990Sstevel@tonic-gate 	mdrpc_setlock_res	res;
31000Sstevel@tonic-gate 
31010Sstevel@tonic-gate 	/* initialize */
31020Sstevel@tonic-gate 	mdclrerror(ep);
31030Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
31040Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
31050Sstevel@tonic-gate 
31060Sstevel@tonic-gate 	/* build args */
31070Sstevel@tonic-gate 	args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
31080Sstevel@tonic-gate 
31090Sstevel@tonic-gate 	/* do it */
31100Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
31110Sstevel@tonic-gate 		int	bool;
31120Sstevel@tonic-gate 		bool = mdrpc_lock_set_1_svc(&args, &res, NULL);
31130Sstevel@tonic-gate 		assert(bool == TRUE);
31140Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
31150Sstevel@tonic-gate 	} else {
31160Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
31170Sstevel@tonic-gate 			return (-1);
31180Sstevel@tonic-gate 
31190Sstevel@tonic-gate 		if (mdrpc_lock_set_1(&args, &res, clntp) != RPC_SUCCESS)
31200Sstevel@tonic-gate 			(void) mdrpcerror(ep, clntp, hostname,
31210Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad lock set"));
31220Sstevel@tonic-gate 		else
31230Sstevel@tonic-gate 			(void) mdstealerror(ep, &res.status);
31240Sstevel@tonic-gate 
31250Sstevel@tonic-gate 		metarpcclose(clntp);
31260Sstevel@tonic-gate 	}
31270Sstevel@tonic-gate 
31280Sstevel@tonic-gate 	if (mdisok(ep))
31290Sstevel@tonic-gate 		cl_set_setkey(res.cl_sk);
31300Sstevel@tonic-gate 
31310Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_setlock_res, (char *)&res);
31320Sstevel@tonic-gate 
31330Sstevel@tonic-gate 	if (! mdisok(ep)) {
31340Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
31350Sstevel@tonic-gate 			return (-1);
31360Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
31370Sstevel@tonic-gate 			return (-1);
31380Sstevel@tonic-gate 		mdclrerror(ep);
31390Sstevel@tonic-gate 	}
31400Sstevel@tonic-gate 
31410Sstevel@tonic-gate 	return (0);
31420Sstevel@tonic-gate }
31430Sstevel@tonic-gate 
31440Sstevel@tonic-gate /*
31450Sstevel@tonic-gate  * Add mediator hosts to disksets.
31460Sstevel@tonic-gate  */
31470Sstevel@tonic-gate int
clnt_updmeds(char * hostname,mdsetname_t * sp,md_h_arr_t * medp,md_error_t * ep)31480Sstevel@tonic-gate clnt_updmeds(
31490Sstevel@tonic-gate 	char			*hostname,
31500Sstevel@tonic-gate 	mdsetname_t		*sp,
31510Sstevel@tonic-gate 	md_h_arr_t		*medp,
31520Sstevel@tonic-gate 	md_error_t		*ep
31530Sstevel@tonic-gate )
31540Sstevel@tonic-gate {
31550Sstevel@tonic-gate 	CLIENT			*clntp;
31560Sstevel@tonic-gate 	mdrpc_updmeds_args	*args;
31570Sstevel@tonic-gate 	mdrpc_updmeds_2_args	v2_args;
31580Sstevel@tonic-gate 	mdrpc_generic_res	res;
31590Sstevel@tonic-gate 	int			version;
31600Sstevel@tonic-gate 
31610Sstevel@tonic-gate 	/* initialize */
31620Sstevel@tonic-gate 	mdclrerror(ep);
31630Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
31640Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
31650Sstevel@tonic-gate 
31660Sstevel@tonic-gate 	/* build args */
31670Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
31680Sstevel@tonic-gate 	args = &v2_args.mdrpc_updmeds_2_args_u.rev1;
31690Sstevel@tonic-gate 	args->sp = sp;
31700Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
31710Sstevel@tonic-gate 	args->meds = *medp;			/* structure assignment */
31720Sstevel@tonic-gate 
31730Sstevel@tonic-gate 	/* do it */
31740Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
31750Sstevel@tonic-gate 		int bool;
31760Sstevel@tonic-gate 		bool = mdrpc_updmeds_2_svc(&v2_args, &res, NULL);
31770Sstevel@tonic-gate 		assert(bool == TRUE);
31780Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
31790Sstevel@tonic-gate 	} else {
31800Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
31810Sstevel@tonic-gate 			return (-1);
31820Sstevel@tonic-gate 
31830Sstevel@tonic-gate 		/*
31840Sstevel@tonic-gate 		 * Check the client handle for the version
31850Sstevel@tonic-gate 		 * and invoke the appropriate version of the
31860Sstevel@tonic-gate 		 * remote procedure
31870Sstevel@tonic-gate 		 */
31880Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
31890Sstevel@tonic-gate 
31900Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
31910Sstevel@tonic-gate 			if (mdrpc_updmeds_1(args, &res, clntp) != RPC_SUCCESS)
31920Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
31930Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad add hosts"));
31940Sstevel@tonic-gate 			else
31950Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
31960Sstevel@tonic-gate 		} else {
31970Sstevel@tonic-gate 			if (mdrpc_updmeds_2(&v2_args, &res, clntp) !=
31980Sstevel@tonic-gate 			    RPC_SUCCESS)
31990Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
32000Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad add hosts"));
32010Sstevel@tonic-gate 			else
32020Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
32030Sstevel@tonic-gate 		}
32040Sstevel@tonic-gate 
32050Sstevel@tonic-gate 		metarpcclose(clntp);
32060Sstevel@tonic-gate 	}
32070Sstevel@tonic-gate 
32080Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
32090Sstevel@tonic-gate 
32100Sstevel@tonic-gate 	if (! mdisok(ep))
32110Sstevel@tonic-gate 		return (-1);
32120Sstevel@tonic-gate 
32130Sstevel@tonic-gate 	return (0);
32140Sstevel@tonic-gate }
32150Sstevel@tonic-gate 
32160Sstevel@tonic-gate /*
32170Sstevel@tonic-gate  * update nr_flags field of node records based
32180Sstevel@tonic-gate  * on given action.
32190Sstevel@tonic-gate  */
32200Sstevel@tonic-gate int
clnt_upd_nr_flags(char * hostname,mdsetname_t * sp,md_mnnode_desc * nd,uint_t flag_action,uint_t flags,md_error_t * ep)32210Sstevel@tonic-gate clnt_upd_nr_flags(
32220Sstevel@tonic-gate 	char			*hostname,
32230Sstevel@tonic-gate 	mdsetname_t		*sp,
32240Sstevel@tonic-gate 	md_mnnode_desc		*nd,
32250Sstevel@tonic-gate 	uint_t			flag_action,
32260Sstevel@tonic-gate 	uint_t			flags,
32270Sstevel@tonic-gate 	md_error_t		*ep
32280Sstevel@tonic-gate )
32290Sstevel@tonic-gate {
32300Sstevel@tonic-gate 	CLIENT				*clntp;
32310Sstevel@tonic-gate 	mdrpc_upd_nr_flags_args		*args;
32320Sstevel@tonic-gate 	mdrpc_upd_nr_flags_2_args	v2_args;
32330Sstevel@tonic-gate 	mdrpc_generic_res		res;
32340Sstevel@tonic-gate 	int				version;
32350Sstevel@tonic-gate 
32360Sstevel@tonic-gate 	/* initialize */
32370Sstevel@tonic-gate 	mdclrerror(ep);
32380Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
32390Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
32400Sstevel@tonic-gate 
32410Sstevel@tonic-gate 	/* build args */
32420Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
32430Sstevel@tonic-gate 	args = &v2_args.mdrpc_upd_nr_flags_2_args_u.rev1;
32440Sstevel@tonic-gate 	args->sp = sp;
32450Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
32460Sstevel@tonic-gate 	args->nodedescs = nd;
32470Sstevel@tonic-gate 	args->flag_action = flag_action;
32480Sstevel@tonic-gate 	args->flags = flags;
32490Sstevel@tonic-gate 
32500Sstevel@tonic-gate 	/* do it */
32510Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
32520Sstevel@tonic-gate 		int	bool;
32530Sstevel@tonic-gate 		bool = mdrpc_upd_nr_flags_2_svc(&v2_args, &res, NULL);
32540Sstevel@tonic-gate 		assert(bool == TRUE);
32550Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
32560Sstevel@tonic-gate 	} else {
32570Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
32580Sstevel@tonic-gate 			return (-1);
32590Sstevel@tonic-gate 
32600Sstevel@tonic-gate 		/*
32610Sstevel@tonic-gate 		 * Check the client handle for the version
32620Sstevel@tonic-gate 		 */
32630Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
32640Sstevel@tonic-gate 
32650Sstevel@tonic-gate 		/*
32660Sstevel@tonic-gate 		 * If the client is version 1, return error
32670Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
32680Sstevel@tonic-gate 		 */
32690Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
32700Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
32710Sstevel@tonic-gate 				sp->setno, hostname, NULL, sp->setname);
32720Sstevel@tonic-gate 			metarpcclose(clntp);
32730Sstevel@tonic-gate 			return (-1);
32740Sstevel@tonic-gate 		} else {
32750Sstevel@tonic-gate 			if (mdrpc_upd_nr_flags_2(&v2_args, &res, clntp)
32760Sstevel@tonic-gate 							!= RPC_SUCCESS)
32770Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
32780Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
32790Sstevel@tonic-gate 				    "metad set node flags"));
32800Sstevel@tonic-gate 			else
32810Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
32820Sstevel@tonic-gate 		}
32830Sstevel@tonic-gate 
32840Sstevel@tonic-gate 		metarpcclose(clntp);
32850Sstevel@tonic-gate 	}
32860Sstevel@tonic-gate 
32870Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
32880Sstevel@tonic-gate 
32890Sstevel@tonic-gate 	if (! mdisok(ep)) {
32900Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
32910Sstevel@tonic-gate 			return (-1);
32920Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
32930Sstevel@tonic-gate 			return (-1);
32940Sstevel@tonic-gate 		mdclrerror(ep);
32950Sstevel@tonic-gate 	}
32960Sstevel@tonic-gate 
32970Sstevel@tonic-gate 	return (0);
32980Sstevel@tonic-gate }
32990Sstevel@tonic-gate 
33000Sstevel@tonic-gate /*
33010Sstevel@tonic-gate  * Clear set locks for all MN disksets.
33020Sstevel@tonic-gate  * Used during reconfig cycle to recover from failed nodes.
33030Sstevel@tonic-gate  */
33040Sstevel@tonic-gate int
clnt_clr_mnsetlock(char * hostname,md_error_t * ep)33050Sstevel@tonic-gate clnt_clr_mnsetlock(
33060Sstevel@tonic-gate 	char			*hostname,
33070Sstevel@tonic-gate 	md_error_t		*ep
33080Sstevel@tonic-gate )
33090Sstevel@tonic-gate {
33100Sstevel@tonic-gate 	CLIENT			*clntp;
33110Sstevel@tonic-gate 	mdrpc_null_args		args;
33120Sstevel@tonic-gate 	mdrpc_generic_res	res;
33130Sstevel@tonic-gate 	int			version;
33140Sstevel@tonic-gate 
33150Sstevel@tonic-gate 	/* initialize */
33160Sstevel@tonic-gate 	mdclrerror(ep);
33170Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
33180Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
33190Sstevel@tonic-gate 
33200Sstevel@tonic-gate 	/* do it */
33210Sstevel@tonic-gate 	if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
33220Sstevel@tonic-gate 		return (-1);
33230Sstevel@tonic-gate 
33240Sstevel@tonic-gate 	/*
33250Sstevel@tonic-gate 	 * Check the client handle for the version
33260Sstevel@tonic-gate 	 */
33270Sstevel@tonic-gate 	CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
33280Sstevel@tonic-gate 
33290Sstevel@tonic-gate 	/*
33300Sstevel@tonic-gate 	 * If the client is version 1, return error
33310Sstevel@tonic-gate 	 * otherwise, make the remote procedure call.
33320Sstevel@tonic-gate 	 */
33330Sstevel@tonic-gate 	if (version == METAD_VERSION) { /* version 1 */
33340Sstevel@tonic-gate 		(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
33350Sstevel@tonic-gate 			NULL, hostname, NULL, NULL);
33360Sstevel@tonic-gate 		metarpcclose(clntp);
33370Sstevel@tonic-gate 		return (-1);
33380Sstevel@tonic-gate 	} else {
33390Sstevel@tonic-gate 		if (mdrpc_clr_mnsetlock_2(&args, &res, clntp) != RPC_SUCCESS)
33400Sstevel@tonic-gate 			(void) mdrpcerror(ep, clntp, hostname,
33410Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad clr mnsetlock"));
33420Sstevel@tonic-gate 		else
33430Sstevel@tonic-gate 			(void) mdstealerror(ep, &res.status);
33440Sstevel@tonic-gate 	}
33450Sstevel@tonic-gate 
33460Sstevel@tonic-gate 	metarpcclose(clntp);
33470Sstevel@tonic-gate 
33480Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
33490Sstevel@tonic-gate 
33500Sstevel@tonic-gate 	if (! mdisok(ep))
33510Sstevel@tonic-gate 		return (-1);
33520Sstevel@tonic-gate 
33530Sstevel@tonic-gate 	return (0);
33540Sstevel@tonic-gate }
33550Sstevel@tonic-gate 
33560Sstevel@tonic-gate /*
33570Sstevel@tonic-gate  * Calls to suspend, resume or reinit the rpc.mdcommd daemon.
33580Sstevel@tonic-gate  * This allows a node to remotely suspend, reinit and resume the
33590Sstevel@tonic-gate  * rpc.mdcommd daemon on the given hostname node.  Used by libmeta
33600Sstevel@tonic-gate  * to lock out class 1 messages (metainit, etc) on all nodes when running
33610Sstevel@tonic-gate  * metaset and metadb commands on this node.
33620Sstevel@tonic-gate  *
33630Sstevel@tonic-gate  * When suspending the commd, the suspend request will fail until all
33640Sstevel@tonic-gate  * messages have been drained from the rpc.mdcommd.  This routine will
33650Sstevel@tonic-gate  * spin sending the suspend request until the rpc.mdcommd is drained
33660Sstevel@tonic-gate  * or until rpc.mdcommd returns a failure other than MDMNE_SET_NOT_DRAINED.
33670Sstevel@tonic-gate  *
33680Sstevel@tonic-gate  * Also used to send the rpc.mdcommd daemon a new nodelist by draining all
33690Sstevel@tonic-gate  * messages from the mdcommd and sending a reinit command to have mdcommd
33700Sstevel@tonic-gate  * get the new nodelist from rpc.metad.  Used when nodelist is changed
33710Sstevel@tonic-gate  * during:
33720Sstevel@tonic-gate  *	- addition or deletion of host from diskset
33730Sstevel@tonic-gate  *	- join or withdrawal of host from diskset
33740Sstevel@tonic-gate  *	- addition of first disk to diskset (joins all nodes)
33750Sstevel@tonic-gate  *	- removal of last disk from diskset (withdraws all nodes)
33760Sstevel@tonic-gate  */
33770Sstevel@tonic-gate int
clnt_mdcommdctl(char * hostname,int flag_action,mdsetname_t * sp,md_mn_msgclass_t class,uint_t flags,md_error_t * ep)33780Sstevel@tonic-gate clnt_mdcommdctl(
33790Sstevel@tonic-gate 	char			*hostname,
33800Sstevel@tonic-gate 	int			flag_action,
33810Sstevel@tonic-gate 	mdsetname_t		*sp,
33820Sstevel@tonic-gate 	md_mn_msgclass_t	class,
33830Sstevel@tonic-gate 	uint_t			flags,
33840Sstevel@tonic-gate 	md_error_t		*ep
33850Sstevel@tonic-gate )
33860Sstevel@tonic-gate {
33870Sstevel@tonic-gate 	CLIENT				*clntp;
33880Sstevel@tonic-gate 	mdrpc_mdcommdctl_args		*args;
33890Sstevel@tonic-gate 	mdrpc_mdcommdctl_2_args		v2_args;
33900Sstevel@tonic-gate 	mdrpc_generic_res		res;
33910Sstevel@tonic-gate 	int				version;
33920Sstevel@tonic-gate 	int				suspend_spin = 0;
33930Sstevel@tonic-gate 
33940Sstevel@tonic-gate 	/* initialize */
33950Sstevel@tonic-gate 	mdclrerror(ep);
33960Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
33970Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
33980Sstevel@tonic-gate 
33990Sstevel@tonic-gate 	/* build args */
34000Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
34010Sstevel@tonic-gate 	args = &v2_args.mdrpc_mdcommdctl_2_args_u.rev1;
34020Sstevel@tonic-gate 	args->flag_action = flag_action;
34030Sstevel@tonic-gate 	args->setno = sp->setno;
34040Sstevel@tonic-gate 	args->class = class;
34050Sstevel@tonic-gate 	args->flags = flags;
34060Sstevel@tonic-gate 
34070Sstevel@tonic-gate 	/* do it */
34080Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
34090Sstevel@tonic-gate 		int	bool;
34100Sstevel@tonic-gate 		/*
34110Sstevel@tonic-gate 		 * Call v2 procedure directly if rpc.metad on this node is
34120Sstevel@tonic-gate 		 * sending message to itself.
34130Sstevel@tonic-gate 		 */
34140Sstevel@tonic-gate 		if (flag_action == COMMDCTL_SUSPEND) {
34150Sstevel@tonic-gate 			suspend_spin = 1;
34160Sstevel@tonic-gate 			while (suspend_spin) {
34170Sstevel@tonic-gate 				suspend_spin = 0;
34180Sstevel@tonic-gate 				bool = mdrpc_mdcommdctl_2_svc(&v2_args, &res,
34190Sstevel@tonic-gate 					NULL);
34200Sstevel@tonic-gate 				assert(bool == TRUE);
34210Sstevel@tonic-gate 				/*
34220Sstevel@tonic-gate 				 * If set not yet drained, wait a second
34230Sstevel@tonic-gate 				 * and try again.
34240Sstevel@tonic-gate 				 */
34250Sstevel@tonic-gate 				if (mdisdserror(&(res.status),
34260Sstevel@tonic-gate 				    MDE_DS_COMMDCTL_SUSPEND_NYD)) {
34270Sstevel@tonic-gate 					/* Wait a second and try again */
34280Sstevel@tonic-gate 					mdclrerror(&(res.status));
34290Sstevel@tonic-gate 					(void) sleep(1);
34300Sstevel@tonic-gate 					suspend_spin = 1;
34310Sstevel@tonic-gate 				}
34320Sstevel@tonic-gate 			}
34330Sstevel@tonic-gate 		} else {
34340Sstevel@tonic-gate 			bool = mdrpc_mdcommdctl_2_svc(&v2_args, &res, NULL);
34350Sstevel@tonic-gate 			assert(bool == TRUE);
34360Sstevel@tonic-gate 		}
34370Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
34380Sstevel@tonic-gate 	} else {
34390Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
34400Sstevel@tonic-gate 			return (-1);
34410Sstevel@tonic-gate 
34420Sstevel@tonic-gate 		/*
34430Sstevel@tonic-gate 		 * Check the client handle for the version
34440Sstevel@tonic-gate 		 */
34450Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
34460Sstevel@tonic-gate 
34470Sstevel@tonic-gate 		/*
34480Sstevel@tonic-gate 		 * If the client is version 1, return error
34490Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
34500Sstevel@tonic-gate 		 */
34510Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
34520Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
34530Sstevel@tonic-gate 				sp->setno, hostname, NULL, sp->setname);
34540Sstevel@tonic-gate 			metarpcclose(clntp);
34550Sstevel@tonic-gate 			return (-1);
34560Sstevel@tonic-gate 		}
34570Sstevel@tonic-gate 
34580Sstevel@tonic-gate 		if (flag_action == COMMDCTL_SUSPEND) {
34590Sstevel@tonic-gate 			suspend_spin = 1;
34600Sstevel@tonic-gate 			while (suspend_spin) {
34610Sstevel@tonic-gate 				suspend_spin = 0;
34620Sstevel@tonic-gate 				if (mdrpc_mdcommdctl_2(&v2_args, &res,
34630Sstevel@tonic-gate 				    clntp) != RPC_SUCCESS) {
34640Sstevel@tonic-gate 					(void) mdrpcerror(ep, clntp,
34650Sstevel@tonic-gate 					    hostname,
34660Sstevel@tonic-gate 					    dgettext(TEXT_DOMAIN,
34670Sstevel@tonic-gate 					    "metad commd control"));
34680Sstevel@tonic-gate 				} else {
34690Sstevel@tonic-gate 					/*
34700Sstevel@tonic-gate 					 * If set not yet drained,
34710Sstevel@tonic-gate 					 * wait a second and
34720Sstevel@tonic-gate 					 * and try again.
34730Sstevel@tonic-gate 					 */
34740Sstevel@tonic-gate 					if (mdisdserror(&(res.status),
34750Sstevel@tonic-gate 					    MDE_DS_COMMDCTL_SUSPEND_NYD)) {
34760Sstevel@tonic-gate 						mdclrerror(&(res.status));
34770Sstevel@tonic-gate 						(void) sleep(1);
34780Sstevel@tonic-gate 						suspend_spin = 1;
34790Sstevel@tonic-gate 					} else {
34800Sstevel@tonic-gate 						(void) mdstealerror(ep,
34810Sstevel@tonic-gate 						    &res.status);
34820Sstevel@tonic-gate 					}
34830Sstevel@tonic-gate 				}
34840Sstevel@tonic-gate 			}
34850Sstevel@tonic-gate 		} else {
34860Sstevel@tonic-gate 			if (mdrpc_mdcommdctl_2(&v2_args, &res, clntp)
34870Sstevel@tonic-gate 			    != RPC_SUCCESS)
34880Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
34890Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
34900Sstevel@tonic-gate 				    "metad commd control"));
34910Sstevel@tonic-gate 			else
34920Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
34930Sstevel@tonic-gate 		}
34940Sstevel@tonic-gate 		metarpcclose(clntp);
34950Sstevel@tonic-gate 	}
34960Sstevel@tonic-gate 
34970Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
34980Sstevel@tonic-gate 
34990Sstevel@tonic-gate 	if (! mdisok(ep)) {
35000Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
35010Sstevel@tonic-gate 			return (-1);
35020Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
35030Sstevel@tonic-gate 			return (-1);
35040Sstevel@tonic-gate 		mdclrerror(ep);
35050Sstevel@tonic-gate 	}
35060Sstevel@tonic-gate 
35070Sstevel@tonic-gate 	return (0);
35080Sstevel@tonic-gate }
35090Sstevel@tonic-gate 
35100Sstevel@tonic-gate /*
35110Sstevel@tonic-gate  * Is owner node stale?
35120Sstevel@tonic-gate  */
35130Sstevel@tonic-gate int
clnt_mn_is_stale(char * hostname,mdsetname_t * sp,int * ret_bool,md_error_t * ep)35140Sstevel@tonic-gate clnt_mn_is_stale(
35150Sstevel@tonic-gate 	char			*hostname,
35160Sstevel@tonic-gate 	mdsetname_t		*sp,
35170Sstevel@tonic-gate 	int			*ret_bool,
35180Sstevel@tonic-gate 	md_error_t		*ep
35190Sstevel@tonic-gate )
35200Sstevel@tonic-gate {
35210Sstevel@tonic-gate 	CLIENT			*clntp;
35220Sstevel@tonic-gate 	mdrpc_setno_args	*args;
35230Sstevel@tonic-gate 	mdrpc_setno_2_args	v2_args;
35240Sstevel@tonic-gate 	mdrpc_bool_res		res;
35250Sstevel@tonic-gate 	int			rval = -1;
35260Sstevel@tonic-gate 	int			version;
35270Sstevel@tonic-gate 
35280Sstevel@tonic-gate 	/* initialize */
35290Sstevel@tonic-gate 	mdclrerror(ep);
35300Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
35310Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
35320Sstevel@tonic-gate 
35330Sstevel@tonic-gate 	/* build args */
35340Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
35350Sstevel@tonic-gate 	args = &v2_args.mdrpc_setno_2_args_u.rev1;
35360Sstevel@tonic-gate 	args->setno = sp->setno;
35370Sstevel@tonic-gate 
35380Sstevel@tonic-gate 	/* do it */
35390Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
35400Sstevel@tonic-gate 		int	bool;
35410Sstevel@tonic-gate 		/*
35420Sstevel@tonic-gate 		 * Call v2 procedure directly if rpc.metad on this node is
35430Sstevel@tonic-gate 		 * sending message to itself.
35440Sstevel@tonic-gate 		 */
35450Sstevel@tonic-gate 		bool = mdrpc_mn_is_stale_2_svc(&v2_args, &res, NULL);
35460Sstevel@tonic-gate 		assert(bool == TRUE);
35470Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
35480Sstevel@tonic-gate 	} else {
35490Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
35500Sstevel@tonic-gate 			return (-1);
35510Sstevel@tonic-gate 
35520Sstevel@tonic-gate 		/*
35530Sstevel@tonic-gate 		 * Check the client handle for the version
35540Sstevel@tonic-gate 		 * and invoke the appropriate version of the
35550Sstevel@tonic-gate 		 * remote procedure
35560Sstevel@tonic-gate 		 */
35570Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
35580Sstevel@tonic-gate 
35590Sstevel@tonic-gate 		/*
35600Sstevel@tonic-gate 		 * If the client is version 1, return error
35610Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
35620Sstevel@tonic-gate 		 */
35630Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
35640Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
35650Sstevel@tonic-gate 			    sp->setno, hostname, NULL, sp->setname);
35660Sstevel@tonic-gate 			metarpcclose(clntp);
35670Sstevel@tonic-gate 			return (-1);
35680Sstevel@tonic-gate 		} else {
35690Sstevel@tonic-gate 			if (mdrpc_mn_is_stale_2(&v2_args, &res, clntp) !=
35700Sstevel@tonic-gate 			    RPC_SUCCESS)
35710Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
35720Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad mn is stale"));
35730Sstevel@tonic-gate 			else
35740Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
35750Sstevel@tonic-gate 		}
35760Sstevel@tonic-gate 
35770Sstevel@tonic-gate 		metarpcclose(clntp);
35780Sstevel@tonic-gate 	}
35790Sstevel@tonic-gate 
35800Sstevel@tonic-gate 	if (mdisok(ep)) {
35810Sstevel@tonic-gate 		/* do something with the results */
35820Sstevel@tonic-gate 		rval = 0;
35830Sstevel@tonic-gate 
35840Sstevel@tonic-gate 		if (ret_bool != NULL)
35850Sstevel@tonic-gate 			*ret_bool = res.value;
35860Sstevel@tonic-gate 	}
35870Sstevel@tonic-gate 
35880Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_bool_res, (char *)&res);
35890Sstevel@tonic-gate 
35900Sstevel@tonic-gate 	return (rval);
35910Sstevel@tonic-gate }
35920Sstevel@tonic-gate 
35930Sstevel@tonic-gate /*
35940Sstevel@tonic-gate  * Free md_drive_desc linked list of drive descriptors that was alloc'd
35950Sstevel@tonic-gate  * from a call to the RPC routine clnt_getdrivedesc.  Drive descriptors
35960Sstevel@tonic-gate  * are from another node.
35970Sstevel@tonic-gate  */
35980Sstevel@tonic-gate void
free_rem_dd(md_drive_desc * dd)35990Sstevel@tonic-gate free_rem_dd(md_drive_desc *dd)
36000Sstevel@tonic-gate {
36010Sstevel@tonic-gate 	mdrpc_getdrivedesc_res	res;
36020Sstevel@tonic-gate 
36030Sstevel@tonic-gate 	/*
36040Sstevel@tonic-gate 	 * dummy up a result struct, to do a deep free of the dd.
36050Sstevel@tonic-gate 	 * (A deep free means that the xdr_free code will free the
36060Sstevel@tonic-gate 	 * linked list of drive descs.)
36070Sstevel@tonic-gate 	 */
36080Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
36090Sstevel@tonic-gate 	res.dd = (struct md_drive_desc *)dd;
36100Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_getdrivedesc_res, (char *)&res);
36110Sstevel@tonic-gate }
36120Sstevel@tonic-gate 
36130Sstevel@tonic-gate /*
36140Sstevel@tonic-gate  * Get a partially filled in drive desc from remote node.  Used in MN
36150Sstevel@tonic-gate  * disksets during the reconfig cycle to get the diskset drive
36160Sstevel@tonic-gate  * information from another host in order to sync up all nodes.
36170Sstevel@tonic-gate  * Used when the drive record information isn't good enough
36180Sstevel@tonic-gate  * since the drive record doesn't give the name of
36190Sstevel@tonic-gate  * the drive, but just a key into that other node's nodespace.
36200Sstevel@tonic-gate  * Returned drive desc has the drive name filled in but no other strings
36210Sstevel@tonic-gate  * in the drivename structure.
36220Sstevel@tonic-gate  *
36230Sstevel@tonic-gate  * Returns a 0 if RPC was successful, 1 otherwise.
36240Sstevel@tonic-gate  */
36250Sstevel@tonic-gate int
clnt_getdrivedesc(char * hostname,mdsetname_t * sp,md_drive_desc ** ret_dd,md_error_t * ep)36260Sstevel@tonic-gate clnt_getdrivedesc(
36270Sstevel@tonic-gate 	char			*hostname,
36280Sstevel@tonic-gate 	mdsetname_t		*sp,
36290Sstevel@tonic-gate 	md_drive_desc		**ret_dd,
36300Sstevel@tonic-gate 	md_error_t		*ep
36310Sstevel@tonic-gate )
36320Sstevel@tonic-gate {
36330Sstevel@tonic-gate 	CLIENT			*clntp;
36340Sstevel@tonic-gate 	mdrpc_sp_args		*args;
36350Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
36360Sstevel@tonic-gate 	mdrpc_getdrivedesc_res	res;
36370Sstevel@tonic-gate 	int			version;
36380Sstevel@tonic-gate 	int			rval = -1;
36390Sstevel@tonic-gate 
36400Sstevel@tonic-gate 	/* initialize */
36410Sstevel@tonic-gate 	mdclrerror(ep);
36420Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
36430Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
36440Sstevel@tonic-gate 
36450Sstevel@tonic-gate 	/* build args */
36460Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
36470Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
36480Sstevel@tonic-gate 	args->sp = sp;
36490Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
36500Sstevel@tonic-gate 
36510Sstevel@tonic-gate 	/* do it */
36520Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
36530Sstevel@tonic-gate 		int	bool;
36540Sstevel@tonic-gate 		bool = mdrpc_getdrivedesc_2_svc(&v2_args, &res, NULL);
36550Sstevel@tonic-gate 		assert(bool == TRUE);
36560Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
36570Sstevel@tonic-gate 	} else {
36580Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
36590Sstevel@tonic-gate 			return (-1);
36600Sstevel@tonic-gate 
36610Sstevel@tonic-gate 		/*
36620Sstevel@tonic-gate 		 * Check the client handle for the version
36630Sstevel@tonic-gate 		 */
36640Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
36650Sstevel@tonic-gate 
36660Sstevel@tonic-gate 		/*
36670Sstevel@tonic-gate 		 * If the client is version 1, return error
36680Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
36690Sstevel@tonic-gate 		 */
36700Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
36710Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
36720Sstevel@tonic-gate 			    sp->setno, hostname, NULL, sp->setname);
36730Sstevel@tonic-gate 			metarpcclose(clntp);
36740Sstevel@tonic-gate 			return (-1);
36750Sstevel@tonic-gate 		} else {
36760Sstevel@tonic-gate 			if (mdrpc_getdrivedesc_2(&v2_args, &res, clntp)
36770Sstevel@tonic-gate 							!= RPC_SUCCESS)
36780Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
36790Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
36800Sstevel@tonic-gate 				    "metad get drive desc set"));
36810Sstevel@tonic-gate 			else
36820Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
36830Sstevel@tonic-gate 		}
36840Sstevel@tonic-gate 
36850Sstevel@tonic-gate 		metarpcclose(clntp);
36860Sstevel@tonic-gate 	}
36870Sstevel@tonic-gate 
36880Sstevel@tonic-gate 	/* If no ep error and no version mismatch - rpc call worked ok */
36890Sstevel@tonic-gate 	if (mdisok(ep)) {
36900Sstevel@tonic-gate 		rval = 0;
36910Sstevel@tonic-gate 		if (ret_dd != NULL)
36920Sstevel@tonic-gate 			*ret_dd = res.dd;
36930Sstevel@tonic-gate 		else
36940Sstevel@tonic-gate 			xdr_free(xdr_mdrpc_getdrivedesc_res, (char *)&res);
36950Sstevel@tonic-gate 	}
36960Sstevel@tonic-gate 
36970Sstevel@tonic-gate 	return (rval);
36980Sstevel@tonic-gate }
36990Sstevel@tonic-gate 
37000Sstevel@tonic-gate /*
37010Sstevel@tonic-gate  * update dr_flags field of drive record.
37020Sstevel@tonic-gate  * Also sync up genid of drive descriptors and make set
37030Sstevel@tonic-gate  * record and node records match the genid.
37040Sstevel@tonic-gate  *
37050Sstevel@tonic-gate  * Returns a 0 if RPC was successful, 1 otherwise.
37060Sstevel@tonic-gate  */
37070Sstevel@tonic-gate int
clnt_upd_dr_reconfig(char * hostname,mdsetname_t * sp,md_drive_desc * dd,md_error_t * ep)37080Sstevel@tonic-gate clnt_upd_dr_reconfig(
37090Sstevel@tonic-gate 	char			*hostname,
37100Sstevel@tonic-gate 	mdsetname_t		*sp,
37110Sstevel@tonic-gate 	md_drive_desc		*dd,
37120Sstevel@tonic-gate 	md_error_t		*ep
37130Sstevel@tonic-gate )
37140Sstevel@tonic-gate {
37150Sstevel@tonic-gate 	CLIENT				*clntp;
37160Sstevel@tonic-gate 	mdrpc_upd_dr_flags_2_args	v2_args;
37170Sstevel@tonic-gate 	mdrpc_upd_dr_flags_2_args_r1	*v21_args;
37180Sstevel@tonic-gate 	mdrpc_generic_res		res;
37190Sstevel@tonic-gate 	int				rval;
37200Sstevel@tonic-gate 	int				version;
37210Sstevel@tonic-gate 
37220Sstevel@tonic-gate 	/* initialize */
37230Sstevel@tonic-gate 	mdclrerror(ep);
37240Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
37250Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
37260Sstevel@tonic-gate 
37270Sstevel@tonic-gate 	/* build args */
37280Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
37290Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_upd_dr_flags_2_args_u.rev1;
37300Sstevel@tonic-gate 	v21_args->sp = sp;
37310Sstevel@tonic-gate 	v21_args->drivedescs = dd;
37320Sstevel@tonic-gate 
37330Sstevel@tonic-gate 	/* do it */
37340Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
37350Sstevel@tonic-gate 		int	bool;
37360Sstevel@tonic-gate 
37370Sstevel@tonic-gate 		/*
37380Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
37390Sstevel@tonic-gate 		 */
37400Sstevel@tonic-gate 		bool = mdrpc_upd_dr_reconfig_2_svc(&v2_args, &res, NULL);
37410Sstevel@tonic-gate 		assert(bool == TRUE);
37420Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
37430Sstevel@tonic-gate 	} else {
37440Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
37450Sstevel@tonic-gate 			return (-1);
37460Sstevel@tonic-gate 
37470Sstevel@tonic-gate 		/*
37480Sstevel@tonic-gate 		 * Check the client handle for the version
37490Sstevel@tonic-gate 		 */
37500Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
37510Sstevel@tonic-gate 		/*
37520Sstevel@tonic-gate 		 * If the client is version 1, return error
37530Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
37540Sstevel@tonic-gate 		 */
37550Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
37560Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
37570Sstevel@tonic-gate 				sp->setno, hostname, NULL, sp->setname);
37580Sstevel@tonic-gate 			metarpcclose(clntp);
37590Sstevel@tonic-gate 			return (-1);
37600Sstevel@tonic-gate 		} else {
37610Sstevel@tonic-gate 			rval = mdrpc_upd_dr_reconfig_2(&v2_args, &res, clntp);
37620Sstevel@tonic-gate 
37630Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
37640Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
37650Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
37660Sstevel@tonic-gate 				    "metad update drive reconfig"));
37670Sstevel@tonic-gate 			else
37680Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
37690Sstevel@tonic-gate 		}
37700Sstevel@tonic-gate 
37710Sstevel@tonic-gate 		metarpcclose(clntp);
37720Sstevel@tonic-gate 	}
37730Sstevel@tonic-gate 
37740Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
37750Sstevel@tonic-gate 
37760Sstevel@tonic-gate 	if (! mdisok(ep)) {
37770Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
37780Sstevel@tonic-gate 			return (-1);
37790Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
37800Sstevel@tonic-gate 			return (-1);
37810Sstevel@tonic-gate 		mdclrerror(ep);
37820Sstevel@tonic-gate 	}
37830Sstevel@tonic-gate 
37840Sstevel@tonic-gate 	return (0);
37850Sstevel@tonic-gate }
37860Sstevel@tonic-gate 
37870Sstevel@tonic-gate /*
37880Sstevel@tonic-gate  * Reset mirror owner(s) if mirror owner(s) is in the list of
37890Sstevel@tonic-gate  * node's specified in the array of nodeids.
37900Sstevel@tonic-gate  * This is called when a node has been deleted or withdrawn
37910Sstevel@tonic-gate  * from the diskset.
37920Sstevel@tonic-gate  */
37930Sstevel@tonic-gate int
clnt_reset_mirror_owner(char * hostname,mdsetname_t * sp,int node_c,int node_id[],md_error_t * ep)37940Sstevel@tonic-gate clnt_reset_mirror_owner(
37950Sstevel@tonic-gate 	char			*hostname,
37960Sstevel@tonic-gate 	mdsetname_t		*sp,
37970Sstevel@tonic-gate 	int			node_c,
37980Sstevel@tonic-gate 	int			node_id[],
37990Sstevel@tonic-gate 	md_error_t		*ep
38000Sstevel@tonic-gate )
38010Sstevel@tonic-gate {
38020Sstevel@tonic-gate 	CLIENT			*clntp;
38030Sstevel@tonic-gate 	mdrpc_nodeid_args	*args;
38040Sstevel@tonic-gate 	mdrpc_nodeid_2_args	v2_args;
38050Sstevel@tonic-gate 	mdrpc_generic_res	res;
38060Sstevel@tonic-gate 	int			version;
38070Sstevel@tonic-gate 
38080Sstevel@tonic-gate 	/* initialize */
38090Sstevel@tonic-gate 	mdclrerror(ep);
38100Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
38110Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
38120Sstevel@tonic-gate 
38130Sstevel@tonic-gate 	/* build args */
38140Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
38150Sstevel@tonic-gate 	args = &v2_args.mdrpc_nodeid_2_args_u.rev1;
38160Sstevel@tonic-gate 	args->sp = sp;
38170Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
38180Sstevel@tonic-gate 	args->nodeid.nodeid_len = node_c;
38190Sstevel@tonic-gate 	args->nodeid.nodeid_val = &node_id[0];
38200Sstevel@tonic-gate 
38210Sstevel@tonic-gate 	/* do it */
38220Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
38230Sstevel@tonic-gate 		int	bool;
38240Sstevel@tonic-gate 		bool = mdrpc_reset_mirror_owner_2_svc(&v2_args, &res, NULL);
38250Sstevel@tonic-gate 		assert(bool == TRUE);
38260Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
38270Sstevel@tonic-gate 	} else {
38280Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
38290Sstevel@tonic-gate 			return (-1);
38300Sstevel@tonic-gate 
38310Sstevel@tonic-gate 		/*
38320Sstevel@tonic-gate 		 * Check the client handle for the version
38330Sstevel@tonic-gate 		 * and invoke the appropriate version of the
38340Sstevel@tonic-gate 		 * remote procedure
38350Sstevel@tonic-gate 		 */
38360Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
38370Sstevel@tonic-gate 
38380Sstevel@tonic-gate 		/*
38390Sstevel@tonic-gate 		 * If the client is version 1, return error
38400Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
38410Sstevel@tonic-gate 		 */
38420Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
38430Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
38440Sstevel@tonic-gate 			    sp->setno, hostname, NULL, sp->setname);
38450Sstevel@tonic-gate 			metarpcclose(clntp);
38460Sstevel@tonic-gate 			return (-1);
38470Sstevel@tonic-gate 		} else {
38480Sstevel@tonic-gate 			if (mdrpc_reset_mirror_owner_2(&v2_args, &res, clntp)
38490Sstevel@tonic-gate 			    != RPC_SUCCESS)
38500Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
38510Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
38520Sstevel@tonic-gate 					"metad reset mirror owner"));
38530Sstevel@tonic-gate 			else
38540Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
38550Sstevel@tonic-gate 		}
38560Sstevel@tonic-gate 
38570Sstevel@tonic-gate 		metarpcclose(clntp);
38580Sstevel@tonic-gate 	}
38590Sstevel@tonic-gate 
38600Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
38610Sstevel@tonic-gate 
38620Sstevel@tonic-gate 	if (! mdisok(ep))
38630Sstevel@tonic-gate 		return (-1);
38640Sstevel@tonic-gate 
38650Sstevel@tonic-gate 	return (0);
38660Sstevel@tonic-gate }
38670Sstevel@tonic-gate 
38680Sstevel@tonic-gate /*
38690Sstevel@tonic-gate  * Call to suspend and resume I/O for given diskset(s).
38700Sstevel@tonic-gate  * This allows a node to remotely suspend and resume I/O on
38710Sstevel@tonic-gate  * a MN diskset.  A diskset number of 0 represents all MN disksets.
38720Sstevel@tonic-gate  */
38730Sstevel@tonic-gate int
clnt_mn_susp_res_io(char * hostname,set_t setno,int cmd,md_error_t * ep)38740Sstevel@tonic-gate clnt_mn_susp_res_io(
38750Sstevel@tonic-gate 	char			*hostname,
38760Sstevel@tonic-gate 	set_t			setno,
38770Sstevel@tonic-gate 	int			cmd,
38780Sstevel@tonic-gate 	md_error_t		*ep
38790Sstevel@tonic-gate )
38800Sstevel@tonic-gate {
38810Sstevel@tonic-gate 	CLIENT					*clntp;
38820Sstevel@tonic-gate 	mdrpc_mn_susp_res_io_args		*args;
38830Sstevel@tonic-gate 	mdrpc_mn_susp_res_io_2_args		v2_args;
38840Sstevel@tonic-gate 	mdrpc_generic_res			res;
38850Sstevel@tonic-gate 	int					version;
38860Sstevel@tonic-gate 
38870Sstevel@tonic-gate 	/* initialize */
38880Sstevel@tonic-gate 	mdclrerror(ep);
38890Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
38900Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
38910Sstevel@tonic-gate 
38920Sstevel@tonic-gate 	/* build args */
38930Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
38940Sstevel@tonic-gate 	args = &v2_args.mdrpc_mn_susp_res_io_2_args_u.rev1;
38950Sstevel@tonic-gate 	args->susp_res_cmd = cmd;
38960Sstevel@tonic-gate 	args->susp_res_setno = setno;
38970Sstevel@tonic-gate 
38980Sstevel@tonic-gate 	/* do it */
38990Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
39000Sstevel@tonic-gate 		int	bool;
39010Sstevel@tonic-gate 		/*
39020Sstevel@tonic-gate 		 * Call v2 procedure directly if rpc.metad on this node is
39030Sstevel@tonic-gate 		 * sending message to itself.
39040Sstevel@tonic-gate 		 */
39050Sstevel@tonic-gate 		bool = mdrpc_mn_susp_res_io_2_svc(&v2_args, &res, NULL);
39060Sstevel@tonic-gate 		assert(bool == TRUE);
39070Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
39080Sstevel@tonic-gate 	} else {
39090Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
39100Sstevel@tonic-gate 			return (-1);
39110Sstevel@tonic-gate 
39120Sstevel@tonic-gate 		/*
39130Sstevel@tonic-gate 		 * Check the client handle for the version
39140Sstevel@tonic-gate 		 */
39150Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
39160Sstevel@tonic-gate 
39170Sstevel@tonic-gate 		/*
39180Sstevel@tonic-gate 		 * If the client is version 1, return error
39190Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
39200Sstevel@tonic-gate 		 */
39210Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
39220Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
39230Sstevel@tonic-gate 			    setno, hostname, NULL, NULL);
39240Sstevel@tonic-gate 			metarpcclose(clntp);
39250Sstevel@tonic-gate 			return (-1);
39260Sstevel@tonic-gate 		} else {
39270Sstevel@tonic-gate 			if (mdrpc_mn_susp_res_io_2(&v2_args, &res, clntp)
39280Sstevel@tonic-gate 							!= RPC_SUCCESS)
39290Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
39300Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
39310Sstevel@tonic-gate 				    "metad mn_susp_res_io control"));
39320Sstevel@tonic-gate 			else
39330Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
39340Sstevel@tonic-gate 		}
39350Sstevel@tonic-gate 
39360Sstevel@tonic-gate 		metarpcclose(clntp);
39370Sstevel@tonic-gate 	}
39380Sstevel@tonic-gate 
39390Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
39400Sstevel@tonic-gate 
39410Sstevel@tonic-gate 	if (! mdisok(ep)) {
39420Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
39430Sstevel@tonic-gate 			return (-1);
39440Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
39450Sstevel@tonic-gate 			return (-1);
39460Sstevel@tonic-gate 		mdclrerror(ep);
39470Sstevel@tonic-gate 	}
39480Sstevel@tonic-gate 
39490Sstevel@tonic-gate 	return (0);
39500Sstevel@tonic-gate }
39510Sstevel@tonic-gate 
39520Sstevel@tonic-gate /*
39530Sstevel@tonic-gate  * Resnarf the set after the set has been imported
39540Sstevel@tonic-gate  *
39550Sstevel@tonic-gate  * We should never be making this procedure call
39560Sstevel@tonic-gate  * over the wire, it's sole purpose is to snarf
39570Sstevel@tonic-gate  * the imported set on the localhost.
39580Sstevel@tonic-gate  */
39590Sstevel@tonic-gate int
clnt_resnarf_set(char * hostname,set_t setno,md_error_t * ep)39600Sstevel@tonic-gate clnt_resnarf_set(
39610Sstevel@tonic-gate 	char		*hostname,
39620Sstevel@tonic-gate 	set_t		setno,
39630Sstevel@tonic-gate 	md_error_t	*ep
39640Sstevel@tonic-gate )
39650Sstevel@tonic-gate {
39660Sstevel@tonic-gate 	CLIENT			*clntp;
39670Sstevel@tonic-gate 	mdrpc_setno_2_args	args;
39680Sstevel@tonic-gate 	mdrpc_generic_res	res;
39690Sstevel@tonic-gate 	int			rval = -1;
39700Sstevel@tonic-gate 	int			version;
39710Sstevel@tonic-gate 
39720Sstevel@tonic-gate 	/* initialize */
39730Sstevel@tonic-gate 	mdclrerror(ep);
39740Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
39750Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
39760Sstevel@tonic-gate 
39770Sstevel@tonic-gate 	/* build args */
39780Sstevel@tonic-gate 	args.rev = MD_METAD_ARGS_REV_1;
39790Sstevel@tonic-gate 	args.mdrpc_setno_2_args_u.rev1.setno = setno;
39800Sstevel@tonic-gate 	args.mdrpc_setno_2_args_u.rev1.cl_sk = NULL;
39810Sstevel@tonic-gate 
39820Sstevel@tonic-gate 	/* do it */
39830Sstevel@tonic-gate 	if (strcmp(mynode(), hostname) == 0) {
39840Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
39850Sstevel@tonic-gate 			return (-1);
39860Sstevel@tonic-gate 
39870Sstevel@tonic-gate 		/* Check the client handle for the version */
39880Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
39890Sstevel@tonic-gate 
39900Sstevel@tonic-gate 		/* If the client is version 1, return error */
39910Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
39920Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_CANTRESNARF, MD_SET_BAD,
39930Sstevel@tonic-gate 			    mynode(), NULL, NULL);
39940Sstevel@tonic-gate 		} else {
39950Sstevel@tonic-gate 			rval = mdrpc_resnarf_set_2(&args, &res, clntp);
39960Sstevel@tonic-gate 
39970Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
39980Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
39990Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad resnarf set"));
40000Sstevel@tonic-gate 			else
40010Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
40020Sstevel@tonic-gate 		}
40030Sstevel@tonic-gate 
40040Sstevel@tonic-gate 		metarpcclose(clntp);
40050Sstevel@tonic-gate 
40060Sstevel@tonic-gate 	} else {
40070Sstevel@tonic-gate 		(void) mddserror(ep, MDE_DS_CANTRESNARF, MD_SET_BAD,
40080Sstevel@tonic-gate 		    mynode(), NULL, NULL);
40090Sstevel@tonic-gate 	}
40100Sstevel@tonic-gate 
40110Sstevel@tonic-gate 	if (mdisok(ep))
40120Sstevel@tonic-gate 		rval = 0;
40130Sstevel@tonic-gate 
40140Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
40150Sstevel@tonic-gate 
40160Sstevel@tonic-gate 	return (rval);
40170Sstevel@tonic-gate }
40180Sstevel@tonic-gate 
40190Sstevel@tonic-gate /*
40200Sstevel@tonic-gate  * Call to start a resync for a given diskset.
40210Sstevel@tonic-gate  * Used when a node has been added to a diskset.
40220Sstevel@tonic-gate  * Should be called after rpc.mdcommd is resumed.
40230Sstevel@tonic-gate  */
40240Sstevel@tonic-gate int
clnt_mn_mirror_resync_all(char * hostname,set_t setno,md_error_t * ep)40250Sstevel@tonic-gate clnt_mn_mirror_resync_all(
40260Sstevel@tonic-gate 	char			*hostname,
40270Sstevel@tonic-gate 	set_t			setno,
40280Sstevel@tonic-gate 	md_error_t		*ep
40290Sstevel@tonic-gate )
40300Sstevel@tonic-gate {
40310Sstevel@tonic-gate 	CLIENT					*clntp;
40320Sstevel@tonic-gate 	mdrpc_setno_2_args			args;
40330Sstevel@tonic-gate 	mdrpc_generic_res			res;
40340Sstevel@tonic-gate 	int					version;
40350Sstevel@tonic-gate 
40360Sstevel@tonic-gate 	/* initialize */
40370Sstevel@tonic-gate 	mdclrerror(ep);
40380Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
40390Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
40400Sstevel@tonic-gate 
40410Sstevel@tonic-gate 	/* build args */
40420Sstevel@tonic-gate 	args.rev = MD_METAD_ARGS_REV_1;
40430Sstevel@tonic-gate 	args.mdrpc_setno_2_args_u.rev1.setno = setno;
40440Sstevel@tonic-gate 	args.mdrpc_setno_2_args_u.rev1.cl_sk = NULL;
40450Sstevel@tonic-gate 
40460Sstevel@tonic-gate 	/* do it */
40470Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
40480Sstevel@tonic-gate 		int	bool;
40490Sstevel@tonic-gate 		/*
40500Sstevel@tonic-gate 		 * Call v2 procedure directly if rpc.metad on this node is
40510Sstevel@tonic-gate 		 * sending message to itself.
40520Sstevel@tonic-gate 		 */
40530Sstevel@tonic-gate 		bool = mdrpc_mn_mirror_resync_all_2_svc(&args, &res, NULL);
40540Sstevel@tonic-gate 		assert(bool == TRUE);
40550Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
40560Sstevel@tonic-gate 	} else {
40570Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
40580Sstevel@tonic-gate 			return (-1);
40590Sstevel@tonic-gate 
40600Sstevel@tonic-gate 		/*
40610Sstevel@tonic-gate 		 * Check the client handle for the version
40620Sstevel@tonic-gate 		 */
40630Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
40640Sstevel@tonic-gate 
40650Sstevel@tonic-gate 		/*
40660Sstevel@tonic-gate 		 * If the client is version 1, return error
40670Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
40680Sstevel@tonic-gate 		 */
40690Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
40700Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
40710Sstevel@tonic-gate 			    setno, hostname, NULL, NULL);
40720Sstevel@tonic-gate 			metarpcclose(clntp);
40730Sstevel@tonic-gate 			return (-1);
40740Sstevel@tonic-gate 		} else {
40750Sstevel@tonic-gate 			if (mdrpc_mn_mirror_resync_all_2(&args, &res, clntp)
40760Sstevel@tonic-gate 							!= RPC_SUCCESS)
40770Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
40780Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
40790Sstevel@tonic-gate 				    "metad mn_mirror_resync_all"));
40800Sstevel@tonic-gate 			else
40810Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
40820Sstevel@tonic-gate 		}
40830Sstevel@tonic-gate 
40840Sstevel@tonic-gate 		metarpcclose(clntp);
40850Sstevel@tonic-gate 	}
40860Sstevel@tonic-gate 
40870Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
40880Sstevel@tonic-gate 
40890Sstevel@tonic-gate 	if (! mdisok(ep)) {
40900Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
40910Sstevel@tonic-gate 			return (-1);
40920Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
40930Sstevel@tonic-gate 			return (-1);
40940Sstevel@tonic-gate 		mdclrerror(ep);
40950Sstevel@tonic-gate 	}
40960Sstevel@tonic-gate 
40970Sstevel@tonic-gate 	return (0);
40980Sstevel@tonic-gate }
40990Sstevel@tonic-gate 
41000Sstevel@tonic-gate /*
41010Sstevel@tonic-gate  * Call to update the ABR state for all soft partitions.
41020Sstevel@tonic-gate  * Used when a node has been added to a diskset.
41030Sstevel@tonic-gate  * Should be called after rpc.mdcommd is resumed.
41040Sstevel@tonic-gate  */
41050Sstevel@tonic-gate int
clnt_mn_sp_update_abr(char * hostname,set_t setno,md_error_t * ep)41060Sstevel@tonic-gate clnt_mn_sp_update_abr(
41070Sstevel@tonic-gate 	char			*hostname,
41080Sstevel@tonic-gate 	set_t			setno,
41090Sstevel@tonic-gate 	md_error_t		*ep
41100Sstevel@tonic-gate )
41110Sstevel@tonic-gate {
41120Sstevel@tonic-gate 	CLIENT					*clntp;
41130Sstevel@tonic-gate 	mdrpc_setno_2_args			args;
41140Sstevel@tonic-gate 	mdrpc_generic_res			res;
41150Sstevel@tonic-gate 	int					version;
41160Sstevel@tonic-gate 
41170Sstevel@tonic-gate 	/* initialize */
41180Sstevel@tonic-gate 	mdclrerror(ep);
41190Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
41200Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
41210Sstevel@tonic-gate 
41220Sstevel@tonic-gate 	/* build args */
41230Sstevel@tonic-gate 	args.rev = MD_METAD_ARGS_REV_1;
41240Sstevel@tonic-gate 	args.mdrpc_setno_2_args_u.rev1.setno = setno;
41250Sstevel@tonic-gate 	args.mdrpc_setno_2_args_u.rev1.cl_sk = NULL;
41260Sstevel@tonic-gate 
41270Sstevel@tonic-gate 	/*
41280Sstevel@tonic-gate 	 * No need to call function if adding local node as ABR cannot
41290Sstevel@tonic-gate 	 * be set.
41300Sstevel@tonic-gate 	 */
41310Sstevel@tonic-gate 	if (strcmp(mynode(), hostname) != 0) {
41320Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
41330Sstevel@tonic-gate 			return (-1);
41340Sstevel@tonic-gate 
41350Sstevel@tonic-gate 		/*
41360Sstevel@tonic-gate 		 * Check the client handle for the version
41370Sstevel@tonic-gate 		 */
41380Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
41390Sstevel@tonic-gate 
41400Sstevel@tonic-gate 		/*
41410Sstevel@tonic-gate 		 * If the client is version 1, return error
41420Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
41430Sstevel@tonic-gate 		 */
41440Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
41450Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
41460Sstevel@tonic-gate 			    setno, hostname, NULL, NULL);
41470Sstevel@tonic-gate 			metarpcclose(clntp);
41480Sstevel@tonic-gate 			return (-1);
41490Sstevel@tonic-gate 		} else {
41500Sstevel@tonic-gate 			if (mdrpc_mn_sp_update_abr_2(&args, &res, clntp)
41510Sstevel@tonic-gate 							!= RPC_SUCCESS)
41520Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
41530Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
41540Sstevel@tonic-gate 				    "metad mn_sp_update_abr"));
41550Sstevel@tonic-gate 			else
41560Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
41570Sstevel@tonic-gate 		}
41580Sstevel@tonic-gate 
41590Sstevel@tonic-gate 		metarpcclose(clntp);
41600Sstevel@tonic-gate 	}
41610Sstevel@tonic-gate 
41620Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
41630Sstevel@tonic-gate 
41640Sstevel@tonic-gate 	if (! mdisok(ep)) {
41650Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
41660Sstevel@tonic-gate 			return (-1);
41670Sstevel@tonic-gate 		mdclrerror(ep);
41680Sstevel@tonic-gate 	}
41690Sstevel@tonic-gate 
41700Sstevel@tonic-gate 	return (0);
41710Sstevel@tonic-gate }
4172