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