1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * Just in case we're not in a build environment, make sure that
31*0Sstevel@tonic-gate  * TEXT_DOMAIN gets set to something.
32*0Sstevel@tonic-gate  */
33*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
34*0Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
35*0Sstevel@tonic-gate #endif
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate #include <meta.h>
38*0Sstevel@tonic-gate #include <metad.h>
39*0Sstevel@tonic-gate #include <devid.h>
40*0Sstevel@tonic-gate 
41*0Sstevel@tonic-gate static md_setkey_t	*my_cl_sk = NULL;
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate #define	CL_DEF_TMO	30L
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate /*
46*0Sstevel@tonic-gate  * Convert an old style mddrivename_t into a new style
47*0Sstevel@tonic-gate  * mddrivename_t. Meant to be used *ONLY* by rpc.metad
48*0Sstevel@tonic-gate  */
49*0Sstevel@tonic-gate void
50*0Sstevel@tonic-gate meta_conv_drvname_old2new(
51*0Sstevel@tonic-gate 	o_mddrivename_t		*v1_dp,
52*0Sstevel@tonic-gate 	mddrivename_t		*v2_dp
53*0Sstevel@tonic-gate )
54*0Sstevel@tonic-gate {
55*0Sstevel@tonic-gate 	int 		sliceno;
56*0Sstevel@tonic-gate 	o_mdname_t	*v1_np;
57*0Sstevel@tonic-gate 	mdname_t	*v2_np;
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate 	/* fields that haven't changed */
60*0Sstevel@tonic-gate 	v2_dp->cname   = v1_dp->cname;
61*0Sstevel@tonic-gate 	v2_dp->rname   = v1_dp->rname;
62*0Sstevel@tonic-gate 	v2_dp->type    = v1_dp->type;
63*0Sstevel@tonic-gate 	v2_dp->errnum  = v1_dp->errnum;
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate 	/* geometry information */
66*0Sstevel@tonic-gate 	v2_dp->geom.ncyl  = v1_dp->geom.ncyl;
67*0Sstevel@tonic-gate 	v2_dp->geom.nhead = v1_dp->geom.nhead;
68*0Sstevel@tonic-gate 	v2_dp->geom.nsect = v1_dp->geom.nsect;
69*0Sstevel@tonic-gate 	v2_dp->geom.rpm   = v1_dp->geom.rpm;
70*0Sstevel@tonic-gate 	v2_dp->geom.write_reinstruct = v1_dp->geom.write_reinstruct;
71*0Sstevel@tonic-gate 	v2_dp->geom.read_reinstruct  = v1_dp->geom.read_reinstruct;
72*0Sstevel@tonic-gate 	v2_dp->geom.blk_sz = 0;
73*0Sstevel@tonic-gate 
74*0Sstevel@tonic-gate 	/* controller information */
75*0Sstevel@tonic-gate 	v2_dp->cinfo = v1_dp->cinfo;
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate 	/* vtoc information */
78*0Sstevel@tonic-gate 	v2_dp->vtoc.nparts    = v1_dp->vtoc.nparts;
79*0Sstevel@tonic-gate 	v2_dp->vtoc.first_lba = 0;
80*0Sstevel@tonic-gate 	v2_dp->vtoc.last_lba  = 0;
81*0Sstevel@tonic-gate 	v2_dp->vtoc.lbasize   = 0;
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate 	for (sliceno = 0; sliceno < (MD_MAX_PARTS - 1); sliceno++) {
84*0Sstevel@tonic-gate 		v2_dp->vtoc.parts[sliceno].start =
85*0Sstevel@tonic-gate 		    (diskaddr_t)v1_dp->vtoc.parts[sliceno].start;
86*0Sstevel@tonic-gate 		v2_dp->vtoc.parts[sliceno].size =
87*0Sstevel@tonic-gate 		    (diskaddr_t)v1_dp->vtoc.parts[sliceno].size;
88*0Sstevel@tonic-gate 		v2_dp->vtoc.parts[sliceno].tag =
89*0Sstevel@tonic-gate 		    v1_dp->vtoc.parts[sliceno].tag;
90*0Sstevel@tonic-gate 		v2_dp->vtoc.parts[sliceno].flag =
91*0Sstevel@tonic-gate 		    v1_dp->vtoc.parts[sliceno].flag;
92*0Sstevel@tonic-gate 		v2_dp->vtoc.parts[sliceno].label =
93*0Sstevel@tonic-gate 		    (diskaddr_t)v1_dp->vtoc.parts[sliceno].label;
94*0Sstevel@tonic-gate 	}
95*0Sstevel@tonic-gate 
96*0Sstevel@tonic-gate 	/* The new style vtoc has 17 partitions */
97*0Sstevel@tonic-gate 	v2_dp->vtoc.parts[MD_MAX_PARTS - 1].start = 0;
98*0Sstevel@tonic-gate 	v2_dp->vtoc.parts[MD_MAX_PARTS - 1].size  = 0;
99*0Sstevel@tonic-gate 	v2_dp->vtoc.parts[MD_MAX_PARTS - 1].tag   = 0;
100*0Sstevel@tonic-gate 	v2_dp->vtoc.parts[MD_MAX_PARTS - 1].flag  = 0;
101*0Sstevel@tonic-gate 	v2_dp->vtoc.parts[MD_MAX_PARTS - 1].label = 0;
102*0Sstevel@tonic-gate 
103*0Sstevel@tonic-gate 	v2_dp->vtoc.typename = v1_dp->vtoc.typename;
104*0Sstevel@tonic-gate 
105*0Sstevel@tonic-gate 	/* partition information */
106*0Sstevel@tonic-gate 	v2_dp->parts.parts_len = v1_dp->parts.parts_len;
107*0Sstevel@tonic-gate 	for (sliceno = 0; sliceno < v1_dp->parts.parts_len; sliceno++) {
108*0Sstevel@tonic-gate 		v1_np = &v1_dp->parts.parts_val[sliceno];
109*0Sstevel@tonic-gate 		v2_np = &v2_dp->parts.parts_val[sliceno];
110*0Sstevel@tonic-gate 
111*0Sstevel@tonic-gate 		/*
112*0Sstevel@tonic-gate 		 * We speculate that if cname for a particular
113*0Sstevel@tonic-gate 		 * partition does not exist, the other fields
114*0Sstevel@tonic-gate 		 * don't exist either. In such a case, we don't
115*0Sstevel@tonic-gate 		 * need to do anything for that partition.
116*0Sstevel@tonic-gate 		 */
117*0Sstevel@tonic-gate 		if (v1_np->cname != NULL) {
118*0Sstevel@tonic-gate 			v2_np->cname = v1_np->cname;
119*0Sstevel@tonic-gate 			v2_np->bname = v1_np->bname;
120*0Sstevel@tonic-gate 			v2_np->rname = v1_np->rname;
121*0Sstevel@tonic-gate 			v2_np->devicesname = v1_np->devicesname;
122*0Sstevel@tonic-gate 			v2_np->dev = meta_expldev(v1_np->dev);
123*0Sstevel@tonic-gate 			v2_np->key = v1_np->key;
124*0Sstevel@tonic-gate 			v2_np->end_blk = (diskaddr_t)v1_np->end_blk;
125*0Sstevel@tonic-gate 			v2_np->start_blk = (diskaddr_t)v1_np->start_blk;
126*0Sstevel@tonic-gate 		}
127*0Sstevel@tonic-gate 		v2_np->drivenamep = v2_dp;
128*0Sstevel@tonic-gate 	}
129*0Sstevel@tonic-gate 
130*0Sstevel@tonic-gate 	/* We don't care about the rest of the fields */
131*0Sstevel@tonic-gate 	v2_dp->side_names = v1_dp->side_names;
132*0Sstevel@tonic-gate 	v2_dp->side_names_key = v1_dp->side_names_key;
133*0Sstevel@tonic-gate 	v2_dp->miscname = v1_dp->miscname;
134*0Sstevel@tonic-gate }
135*0Sstevel@tonic-gate 
136*0Sstevel@tonic-gate /*
137*0Sstevel@tonic-gate  * Convert a new style mddrivename_t into an old style
138*0Sstevel@tonic-gate  * mddrivename_t. Meant to be used *ONLY* by rpc.metad
139*0Sstevel@tonic-gate  */
140*0Sstevel@tonic-gate void
141*0Sstevel@tonic-gate meta_conv_drvname_new2old(
142*0Sstevel@tonic-gate 	o_mddrivename_t		*v1_dp,
143*0Sstevel@tonic-gate 	mddrivename_t		*v2_dp
144*0Sstevel@tonic-gate )
145*0Sstevel@tonic-gate {
146*0Sstevel@tonic-gate 	int 		sliceno;
147*0Sstevel@tonic-gate 	o_mdname_t	*v1_np;
148*0Sstevel@tonic-gate 	mdname_t	*v2_np;
149*0Sstevel@tonic-gate 
150*0Sstevel@tonic-gate 	/* fields that haven't changed */
151*0Sstevel@tonic-gate 	v1_dp->cname   = v2_dp->cname;
152*0Sstevel@tonic-gate 	v1_dp->rname   = v2_dp->rname;
153*0Sstevel@tonic-gate 	v1_dp->type    = v2_dp->type;
154*0Sstevel@tonic-gate 	v1_dp->errnum  = v2_dp->errnum;
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate 	/* geometry information */
157*0Sstevel@tonic-gate 	v1_dp->geom.ncyl  = v2_dp->geom.ncyl;
158*0Sstevel@tonic-gate 	v1_dp->geom.nhead = v2_dp->geom.nhead;
159*0Sstevel@tonic-gate 	v1_dp->geom.nsect = v2_dp->geom.nsect;
160*0Sstevel@tonic-gate 	v1_dp->geom.rpm   = v2_dp->geom.rpm;
161*0Sstevel@tonic-gate 	v1_dp->geom.write_reinstruct = v2_dp->geom.write_reinstruct;
162*0Sstevel@tonic-gate 	v1_dp->geom.read_reinstruct  = v2_dp->geom.read_reinstruct;
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 	/* controller information */
165*0Sstevel@tonic-gate 	v1_dp->cinfo = v2_dp->cinfo;
166*0Sstevel@tonic-gate 
167*0Sstevel@tonic-gate 	/* vtoc information */
168*0Sstevel@tonic-gate 	v1_dp->vtoc.typename = v2_dp->vtoc.typename;
169*0Sstevel@tonic-gate 	v1_dp->vtoc.nparts   = v2_dp->vtoc.nparts;
170*0Sstevel@tonic-gate 
171*0Sstevel@tonic-gate 	for (sliceno = 0; sliceno < (MD_MAX_PARTS - 1); sliceno++) {
172*0Sstevel@tonic-gate 		v1_dp->vtoc.parts[sliceno].start =
173*0Sstevel@tonic-gate 		    (daddr_t)v2_dp->vtoc.parts[sliceno].start;
174*0Sstevel@tonic-gate 		v1_dp->vtoc.parts[sliceno].size  =
175*0Sstevel@tonic-gate 		    (daddr_t)v2_dp->vtoc.parts[sliceno].size;
176*0Sstevel@tonic-gate 		v1_dp->vtoc.parts[sliceno].tag   =
177*0Sstevel@tonic-gate 		    v2_dp->vtoc.parts[sliceno].tag;
178*0Sstevel@tonic-gate 		v1_dp->vtoc.parts[sliceno].flag  =
179*0Sstevel@tonic-gate 		    v2_dp->vtoc.parts[sliceno].flag;
180*0Sstevel@tonic-gate 		v1_dp->vtoc.parts[sliceno].label =
181*0Sstevel@tonic-gate 		    (daddr_t)v2_dp->vtoc.parts[sliceno].label;
182*0Sstevel@tonic-gate 	}
183*0Sstevel@tonic-gate 
184*0Sstevel@tonic-gate 	/* partition information */
185*0Sstevel@tonic-gate 	v1_dp->parts.parts_len = v2_dp->parts.parts_len;
186*0Sstevel@tonic-gate 
187*0Sstevel@tonic-gate 	for (sliceno = 0; sliceno < v2_dp->parts.parts_len; sliceno++) {
188*0Sstevel@tonic-gate 		v1_np = &v1_dp->parts.parts_val[sliceno];
189*0Sstevel@tonic-gate 		v2_np = &v2_dp->parts.parts_val[sliceno];
190*0Sstevel@tonic-gate 
191*0Sstevel@tonic-gate 		/*
192*0Sstevel@tonic-gate 		 * We speculate that if cname for a particular
193*0Sstevel@tonic-gate 		 * partition does not exist then the rest of
194*0Sstevel@tonic-gate 		 * the fields a partition don't exist either.
195*0Sstevel@tonic-gate 		 * In such a case, we don't need to do anything
196*0Sstevel@tonic-gate 		 * for that partition.
197*0Sstevel@tonic-gate 		 */
198*0Sstevel@tonic-gate 		if (v2_np->cname != NULL) {
199*0Sstevel@tonic-gate 			v1_np->cname = v2_np->cname;
200*0Sstevel@tonic-gate 			v1_np->bname = v2_np->bname;
201*0Sstevel@tonic-gate 			v1_np->rname = v2_np->rname;
202*0Sstevel@tonic-gate 			v1_np->devicesname = v2_np->devicesname;
203*0Sstevel@tonic-gate 			v1_np->dev = meta_cmpldev(v2_np->dev);
204*0Sstevel@tonic-gate 			v1_np->key = v2_np->key;
205*0Sstevel@tonic-gate 			v1_np->end_blk = (daddr_t)v2_np->end_blk;
206*0Sstevel@tonic-gate 			v1_np->start_blk = (daddr_t)v2_np->start_blk;
207*0Sstevel@tonic-gate 		}
208*0Sstevel@tonic-gate 		v1_np->drivenamep = v1_dp;
209*0Sstevel@tonic-gate 	}
210*0Sstevel@tonic-gate 
211*0Sstevel@tonic-gate 	/* We don't care about the rest of the fields */
212*0Sstevel@tonic-gate 	v1_dp->side_names = v2_dp->side_names;
213*0Sstevel@tonic-gate 	v1_dp->side_names_key = v2_dp->side_names_key;
214*0Sstevel@tonic-gate 	v1_dp->miscname = v2_dp->miscname;
215*0Sstevel@tonic-gate }
216*0Sstevel@tonic-gate 
217*0Sstevel@tonic-gate /*
218*0Sstevel@tonic-gate  * Convert an old style md_drive_desc_t into a new style
219*0Sstevel@tonic-gate  * md_drive_desc_t. Meant to be used *ONLY* by rpc.metad
220*0Sstevel@tonic-gate  */
221*0Sstevel@tonic-gate void
222*0Sstevel@tonic-gate meta_conv_drvdesc_old2new(
223*0Sstevel@tonic-gate 	o_md_drive_desc		*v1_dd,
224*0Sstevel@tonic-gate 	md_drive_desc		*v2_dd
225*0Sstevel@tonic-gate )
226*0Sstevel@tonic-gate {
227*0Sstevel@tonic-gate 	md_drive_desc	*dd;
228*0Sstevel@tonic-gate 	o_md_drive_desc	*o_dd;
229*0Sstevel@tonic-gate 
230*0Sstevel@tonic-gate 	dd = v2_dd;
231*0Sstevel@tonic-gate 
232*0Sstevel@tonic-gate 	for (o_dd = v1_dd; o_dd != NULL; o_dd = o_dd->dd_next) {
233*0Sstevel@tonic-gate 		dd->dd_ctime = o_dd->dd_ctime;
234*0Sstevel@tonic-gate 		dd->dd_genid = o_dd->dd_genid;
235*0Sstevel@tonic-gate 		dd->dd_flags = o_dd->dd_flags;
236*0Sstevel@tonic-gate 		meta_conv_drvname_old2new(o_dd->dd_dnp, dd->dd_dnp);
237*0Sstevel@tonic-gate 		dd->dd_dbcnt = o_dd->dd_dbcnt;
238*0Sstevel@tonic-gate 		dd->dd_dbsize = o_dd->dd_dbsize;
239*0Sstevel@tonic-gate 		dd = dd->dd_next;
240*0Sstevel@tonic-gate 	}
241*0Sstevel@tonic-gate }
242*0Sstevel@tonic-gate 
243*0Sstevel@tonic-gate /*
244*0Sstevel@tonic-gate  * Convert an new style md_drive_desc_t into a old style
245*0Sstevel@tonic-gate  * md_drive_desc_t. Meant to be used *ONLY* by rpc.metad
246*0Sstevel@tonic-gate  */
247*0Sstevel@tonic-gate void
248*0Sstevel@tonic-gate meta_conv_drvdesc_new2old(
249*0Sstevel@tonic-gate 	o_md_drive_desc		*v1_dd,
250*0Sstevel@tonic-gate 	md_drive_desc		*v2_dd
251*0Sstevel@tonic-gate )
252*0Sstevel@tonic-gate {
253*0Sstevel@tonic-gate 	md_drive_desc	*dd;
254*0Sstevel@tonic-gate 	o_md_drive_desc	*o_dd;
255*0Sstevel@tonic-gate 
256*0Sstevel@tonic-gate 	o_dd = v1_dd;
257*0Sstevel@tonic-gate 
258*0Sstevel@tonic-gate 	for (dd = v2_dd; dd != NULL; dd = dd->dd_next) {
259*0Sstevel@tonic-gate 		o_dd->dd_ctime = dd->dd_ctime;
260*0Sstevel@tonic-gate 		o_dd->dd_genid = dd->dd_genid;
261*0Sstevel@tonic-gate 		o_dd->dd_flags = dd->dd_flags;
262*0Sstevel@tonic-gate 		meta_conv_drvname_new2old(o_dd->dd_dnp, dd->dd_dnp);
263*0Sstevel@tonic-gate 		o_dd->dd_dbcnt = dd->dd_dbcnt;
264*0Sstevel@tonic-gate 		o_dd->dd_dbsize = dd->dd_dbsize;
265*0Sstevel@tonic-gate 		o_dd = o_dd->dd_next;
266*0Sstevel@tonic-gate 	}
267*0Sstevel@tonic-gate }
268*0Sstevel@tonic-gate 
269*0Sstevel@tonic-gate /*
270*0Sstevel@tonic-gate  * Allocate memory for v1 drive descriptor
271*0Sstevel@tonic-gate  * depending upon the number of drives in the
272*0Sstevel@tonic-gate  * v2 drive descriptor
273*0Sstevel@tonic-gate  */
274*0Sstevel@tonic-gate void
275*0Sstevel@tonic-gate alloc_olddrvdesc(
276*0Sstevel@tonic-gate 	o_md_drive_desc		**v1_dd,
277*0Sstevel@tonic-gate 	md_drive_desc		*v2_dd
278*0Sstevel@tonic-gate )
279*0Sstevel@tonic-gate {
280*0Sstevel@tonic-gate 	md_drive_desc	*dd;
281*0Sstevel@tonic-gate 	o_md_drive_desc *new, *head;
282*0Sstevel@tonic-gate 
283*0Sstevel@tonic-gate 	head = NULL;
284*0Sstevel@tonic-gate 
285*0Sstevel@tonic-gate 	for (dd = v2_dd; dd != NULL; dd = dd->dd_next) {
286*0Sstevel@tonic-gate 		new = Zalloc(sizeof (o_md_drive_desc));
287*0Sstevel@tonic-gate 		new->dd_dnp = Zalloc(sizeof (o_mddrivename_t));
288*0Sstevel@tonic-gate 		new->dd_dnp->parts.parts_val = Zalloc(sizeof (o_mdname_t) *
289*0Sstevel@tonic-gate 		    dd->dd_dnp->parts.parts_len);
290*0Sstevel@tonic-gate 		new->dd_next = head;
291*0Sstevel@tonic-gate 		head = new;
292*0Sstevel@tonic-gate 	}
293*0Sstevel@tonic-gate 	*v1_dd = head;
294*0Sstevel@tonic-gate }
295*0Sstevel@tonic-gate 
296*0Sstevel@tonic-gate /*
297*0Sstevel@tonic-gate  * Allocate memory for v2 drive descriptor
298*0Sstevel@tonic-gate  * depending upon the number of drives in the
299*0Sstevel@tonic-gate  * v1 drive descriptor
300*0Sstevel@tonic-gate  */
301*0Sstevel@tonic-gate void
302*0Sstevel@tonic-gate alloc_newdrvdesc(
303*0Sstevel@tonic-gate 	o_md_drive_desc		*v1_dd,
304*0Sstevel@tonic-gate 	md_drive_desc		**v2_dd
305*0Sstevel@tonic-gate )
306*0Sstevel@tonic-gate {
307*0Sstevel@tonic-gate 	md_drive_desc	*new, *head;
308*0Sstevel@tonic-gate 	o_md_drive_desc	*o_dd;
309*0Sstevel@tonic-gate 
310*0Sstevel@tonic-gate 	head = NULL;
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate 	for (o_dd = v1_dd; o_dd != NULL; o_dd = o_dd->dd_next) {
313*0Sstevel@tonic-gate 		new = Zalloc(sizeof (md_drive_desc));
314*0Sstevel@tonic-gate 		new->dd_dnp = Zalloc(sizeof (mddrivename_t));
315*0Sstevel@tonic-gate 		new->dd_dnp->parts.parts_val = Zalloc(sizeof (mdname_t) *
316*0Sstevel@tonic-gate 		    o_dd->dd_dnp->parts.parts_len);
317*0Sstevel@tonic-gate 		new->dd_next = head;
318*0Sstevel@tonic-gate 		head = new;
319*0Sstevel@tonic-gate 	}
320*0Sstevel@tonic-gate 	*v2_dd = head;
321*0Sstevel@tonic-gate }
322*0Sstevel@tonic-gate 
323*0Sstevel@tonic-gate void
324*0Sstevel@tonic-gate free_olddrvdesc(
325*0Sstevel@tonic-gate 	o_md_drive_desc		*v1_dd
326*0Sstevel@tonic-gate )
327*0Sstevel@tonic-gate {
328*0Sstevel@tonic-gate 	o_md_drive_desc	*o_dd, *head;
329*0Sstevel@tonic-gate 
330*0Sstevel@tonic-gate 	head = v1_dd;
331*0Sstevel@tonic-gate 
332*0Sstevel@tonic-gate 	while (head != NULL) {
333*0Sstevel@tonic-gate 		o_dd = head;
334*0Sstevel@tonic-gate 		head = head->dd_next;
335*0Sstevel@tonic-gate 		free(o_dd->dd_dnp->parts.parts_val);
336*0Sstevel@tonic-gate 		free(o_dd->dd_dnp);
337*0Sstevel@tonic-gate 		free(o_dd);
338*0Sstevel@tonic-gate 	}
339*0Sstevel@tonic-gate }
340*0Sstevel@tonic-gate 
341*0Sstevel@tonic-gate void
342*0Sstevel@tonic-gate free_newdrvdesc(
343*0Sstevel@tonic-gate 	md_drive_desc		*v2_dd
344*0Sstevel@tonic-gate )
345*0Sstevel@tonic-gate {
346*0Sstevel@tonic-gate 	md_drive_desc	*dd, *head;
347*0Sstevel@tonic-gate 
348*0Sstevel@tonic-gate 	head = v2_dd;
349*0Sstevel@tonic-gate 
350*0Sstevel@tonic-gate 	while (head != NULL) {
351*0Sstevel@tonic-gate 		dd = head;
352*0Sstevel@tonic-gate 		head = head->dd_next;
353*0Sstevel@tonic-gate 		free(dd->dd_dnp->parts.parts_val);
354*0Sstevel@tonic-gate 		free(dd->dd_dnp);
355*0Sstevel@tonic-gate 		free(dd);
356*0Sstevel@tonic-gate 	}
357*0Sstevel@tonic-gate }
358*0Sstevel@tonic-gate 
359*0Sstevel@tonic-gate /*
360*0Sstevel@tonic-gate  * Return the device id for a given device
361*0Sstevel@tonic-gate  */
362*0Sstevel@tonic-gate char *
363*0Sstevel@tonic-gate meta_get_devid(
364*0Sstevel@tonic-gate 	char	*rname
365*0Sstevel@tonic-gate )
366*0Sstevel@tonic-gate {
367*0Sstevel@tonic-gate 	ddi_devid_t	devid;
368*0Sstevel@tonic-gate 	int		fd;
369*0Sstevel@tonic-gate 	char		*enc_devid, *dup_enc_devid = NULL;
370*0Sstevel@tonic-gate 
371*0Sstevel@tonic-gate 	if ((fd = open(rname, O_RDWR | O_NDELAY, 0)) < 0)
372*0Sstevel@tonic-gate 		return (NULL);
373*0Sstevel@tonic-gate 
374*0Sstevel@tonic-gate 	if (devid_get(fd, &devid) == -1) {
375*0Sstevel@tonic-gate 		(void) close(fd);
376*0Sstevel@tonic-gate 		return (NULL);
377*0Sstevel@tonic-gate 	}
378*0Sstevel@tonic-gate 	(void) close(fd);
379*0Sstevel@tonic-gate 
380*0Sstevel@tonic-gate 	enc_devid = devid_str_encode(devid, NULL);
381*0Sstevel@tonic-gate 	devid_free(devid);
382*0Sstevel@tonic-gate 
383*0Sstevel@tonic-gate 	if (enc_devid != NULL) {
384*0Sstevel@tonic-gate 		dup_enc_devid = strdup(enc_devid);
385*0Sstevel@tonic-gate 		devid_str_free(enc_devid);
386*0Sstevel@tonic-gate 	}
387*0Sstevel@tonic-gate 
388*0Sstevel@tonic-gate 	return (dup_enc_devid);
389*0Sstevel@tonic-gate }
390*0Sstevel@tonic-gate 
391*0Sstevel@tonic-gate /*
392*0Sstevel@tonic-gate  * Add side names for the diskset drive records
393*0Sstevel@tonic-gate  * NOTE: these go into the local set's namespace.
394*0Sstevel@tonic-gate  */
395*0Sstevel@tonic-gate int
396*0Sstevel@tonic-gate clnt_add_drv_sidenms(
397*0Sstevel@tonic-gate 	char			*hostname,
398*0Sstevel@tonic-gate 	char			*this_host,
399*0Sstevel@tonic-gate 	mdsetname_t		*sp,
400*0Sstevel@tonic-gate 	md_set_desc		*sd,
401*0Sstevel@tonic-gate 	int			node_c,
402*0Sstevel@tonic-gate 	char			**node_v,
403*0Sstevel@tonic-gate 	md_error_t		*ep
404*0Sstevel@tonic-gate )
405*0Sstevel@tonic-gate {
406*0Sstevel@tonic-gate 	CLIENT				*clntp;
407*0Sstevel@tonic-gate 	mdrpc_drv_sidenm_args		v1_args;
408*0Sstevel@tonic-gate 	mdrpc_drv_sidenm_2_args		v2_args;
409*0Sstevel@tonic-gate 	mdrpc_drv_sidenm_2_args_r1	*v21_args;
410*0Sstevel@tonic-gate 	mdrpc_generic_res		res;
411*0Sstevel@tonic-gate 	int				rval;
412*0Sstevel@tonic-gate 	int				version;
413*0Sstevel@tonic-gate 	int				i, j;
414*0Sstevel@tonic-gate 
415*0Sstevel@tonic-gate 	/* initialize */
416*0Sstevel@tonic-gate 	mdclrerror(ep);
417*0Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
418*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
419*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
420*0Sstevel@tonic-gate 
421*0Sstevel@tonic-gate 	/* build args */
422*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
423*0Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_drv_sidenm_2_args_u.rev1;
424*0Sstevel@tonic-gate 	v21_args->hostname = this_host;
425*0Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
426*0Sstevel@tonic-gate 	v21_args->sp = sp;
427*0Sstevel@tonic-gate 	v21_args->sd = sd;
428*0Sstevel@tonic-gate 	v21_args->node_v.node_v_len = node_c;
429*0Sstevel@tonic-gate 	v21_args->node_v.node_v_val = node_v;
430*0Sstevel@tonic-gate 
431*0Sstevel@tonic-gate 	/* do it */
432*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
433*0Sstevel@tonic-gate 		int	bool;
434*0Sstevel@tonic-gate 
435*0Sstevel@tonic-gate 		/*
436*0Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
437*0Sstevel@tonic-gate 		 */
438*0Sstevel@tonic-gate 		bool = mdrpc_add_drv_sidenms_2_svc(&v2_args, &res, NULL);
439*0Sstevel@tonic-gate 		assert(bool == TRUE);
440*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
441*0Sstevel@tonic-gate 	} else {
442*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
443*0Sstevel@tonic-gate 			return (-1);
444*0Sstevel@tonic-gate 
445*0Sstevel@tonic-gate 		/*
446*0Sstevel@tonic-gate 		 * Check the client handle for the version
447*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
448*0Sstevel@tonic-gate 		 * remote procedure
449*0Sstevel@tonic-gate 		 */
450*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
451*0Sstevel@tonic-gate 
452*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
453*0Sstevel@tonic-gate 
454*0Sstevel@tonic-gate 			v1_args.sd = Zalloc(sizeof (o_md_set_desc));
455*0Sstevel@tonic-gate 			alloc_olddrvdesc(&v1_args.sd->sd_drvs, sd->sd_drvs);
456*0Sstevel@tonic-gate 
457*0Sstevel@tonic-gate 			/* build args */
458*0Sstevel@tonic-gate 			v1_args.hostname = this_host;
459*0Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
460*0Sstevel@tonic-gate 			v1_args.sp = sp;
461*0Sstevel@tonic-gate 			/* set descriptor */
462*0Sstevel@tonic-gate 			v1_args.sd->sd_ctime = sd->sd_ctime;
463*0Sstevel@tonic-gate 			v1_args.sd->sd_genid = sd->sd_genid;
464*0Sstevel@tonic-gate 			v1_args.sd->sd_setno = sd->sd_setno;
465*0Sstevel@tonic-gate 			v1_args.sd->sd_flags = sd->sd_flags;
466*0Sstevel@tonic-gate 			for (i = 0; i < MD_MAXSIDES; i++) {
467*0Sstevel@tonic-gate 				v1_args.sd->sd_isown[i] = sd->sd_isown[i];
468*0Sstevel@tonic-gate 
469*0Sstevel@tonic-gate 				for (j = 0; j < MD_MAX_NODENAME_PLUS_1; j ++)
470*0Sstevel@tonic-gate 					v1_args.sd->sd_nodes[i][j] =
471*0Sstevel@tonic-gate 					    sd->sd_nodes[i][j];
472*0Sstevel@tonic-gate 			}
473*0Sstevel@tonic-gate 			v1_args.sd->sd_med = sd->sd_med;
474*0Sstevel@tonic-gate 			meta_conv_drvdesc_new2old(v1_args.sd->sd_drvs,
475*0Sstevel@tonic-gate 			    sd->sd_drvs);
476*0Sstevel@tonic-gate 			v1_args.node_v.node_v_len = node_c;
477*0Sstevel@tonic-gate 			v1_args.node_v.node_v_val = node_v;
478*0Sstevel@tonic-gate 
479*0Sstevel@tonic-gate 			rval = mdrpc_add_drv_sidenms_1(&v1_args, &res, clntp);
480*0Sstevel@tonic-gate 
481*0Sstevel@tonic-gate 			free_olddrvdesc(v1_args.sd->sd_drvs);
482*0Sstevel@tonic-gate 			free(v1_args.sd);
483*0Sstevel@tonic-gate 
484*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
485*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
486*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
487*0Sstevel@tonic-gate 				    "metad add drive sidenames"));
488*0Sstevel@tonic-gate 			else
489*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
490*0Sstevel@tonic-gate 		} else {			/* version 2 */
491*0Sstevel@tonic-gate 			rval = mdrpc_add_drv_sidenms_2(&v2_args, &res, clntp);
492*0Sstevel@tonic-gate 
493*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
494*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
495*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
496*0Sstevel@tonic-gate 				    "metad add drive sidenames"));
497*0Sstevel@tonic-gate 			else
498*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
499*0Sstevel@tonic-gate 		}
500*0Sstevel@tonic-gate 
501*0Sstevel@tonic-gate 		metarpcclose(clntp);
502*0Sstevel@tonic-gate 	}
503*0Sstevel@tonic-gate 
504*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
505*0Sstevel@tonic-gate 
506*0Sstevel@tonic-gate 	if (! mdisok(ep))
507*0Sstevel@tonic-gate 		return (-1);
508*0Sstevel@tonic-gate 
509*0Sstevel@tonic-gate 	return (0);
510*0Sstevel@tonic-gate }
511*0Sstevel@tonic-gate 
512*0Sstevel@tonic-gate /*
513*0Sstevel@tonic-gate  * Add drives to disksets.
514*0Sstevel@tonic-gate  */
515*0Sstevel@tonic-gate int
516*0Sstevel@tonic-gate clnt_adddrvs(
517*0Sstevel@tonic-gate 	char			*hostname,
518*0Sstevel@tonic-gate 	mdsetname_t		*sp,
519*0Sstevel@tonic-gate 	md_drive_desc		*dd,
520*0Sstevel@tonic-gate 	md_timeval32_t		timestamp,
521*0Sstevel@tonic-gate 	ulong_t			genid,
522*0Sstevel@tonic-gate 	md_error_t		*ep
523*0Sstevel@tonic-gate )
524*0Sstevel@tonic-gate {
525*0Sstevel@tonic-gate 	CLIENT			*clntp;
526*0Sstevel@tonic-gate 	mdrpc_drives_args	v1_args;
527*0Sstevel@tonic-gate 	mdrpc_drives_2_args	v2_args;
528*0Sstevel@tonic-gate 	mdrpc_drives_2_args_r1	*v21_args;
529*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
530*0Sstevel@tonic-gate 	int			rval;
531*0Sstevel@tonic-gate 	int			version;
532*0Sstevel@tonic-gate 
533*0Sstevel@tonic-gate 	/* initialize */
534*0Sstevel@tonic-gate 	mdclrerror(ep);
535*0Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
536*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
537*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
538*0Sstevel@tonic-gate 
539*0Sstevel@tonic-gate 	/* build args */
540*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
541*0Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_drives_2_args_u.rev1;
542*0Sstevel@tonic-gate 	v21_args->sp = sp;
543*0Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
544*0Sstevel@tonic-gate 	v21_args->drivedescs = dd;
545*0Sstevel@tonic-gate 	v21_args->timestamp = timestamp;
546*0Sstevel@tonic-gate 	v21_args->genid = genid;
547*0Sstevel@tonic-gate 
548*0Sstevel@tonic-gate 	/* do it */
549*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
550*0Sstevel@tonic-gate 		int	bool;
551*0Sstevel@tonic-gate 
552*0Sstevel@tonic-gate 		/*
553*0Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
554*0Sstevel@tonic-gate 		 */
555*0Sstevel@tonic-gate 		bool = mdrpc_adddrvs_2_svc(&v2_args, &res, NULL);
556*0Sstevel@tonic-gate 		assert(bool == TRUE);
557*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
558*0Sstevel@tonic-gate 	} else {
559*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
560*0Sstevel@tonic-gate 			return (-1);
561*0Sstevel@tonic-gate 
562*0Sstevel@tonic-gate 		/*
563*0Sstevel@tonic-gate 		 * Check the client handle for the version
564*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
565*0Sstevel@tonic-gate 		 * remote procedure
566*0Sstevel@tonic-gate 		 */
567*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
568*0Sstevel@tonic-gate 
569*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
570*0Sstevel@tonic-gate 
571*0Sstevel@tonic-gate 			alloc_olddrvdesc(&v1_args.drivedescs, dd);
572*0Sstevel@tonic-gate 
573*0Sstevel@tonic-gate 			/* build args */
574*0Sstevel@tonic-gate 			v1_args.sp = sp;
575*0Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
576*0Sstevel@tonic-gate 			meta_conv_drvdesc_new2old(v1_args.drivedescs, dd);
577*0Sstevel@tonic-gate 			v1_args.timestamp = timestamp;
578*0Sstevel@tonic-gate 			v1_args.genid = genid;
579*0Sstevel@tonic-gate 
580*0Sstevel@tonic-gate 			rval = mdrpc_adddrvs_1(&v1_args, &res, clntp);
581*0Sstevel@tonic-gate 
582*0Sstevel@tonic-gate 			free_olddrvdesc(v1_args.drivedescs);
583*0Sstevel@tonic-gate 
584*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
585*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
586*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad add drives"));
587*0Sstevel@tonic-gate 			else
588*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
589*0Sstevel@tonic-gate 		} else {			/* version 2 */
590*0Sstevel@tonic-gate 			rval = mdrpc_adddrvs_2(&v2_args, &res, clntp);
591*0Sstevel@tonic-gate 
592*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
593*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
594*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad add drives"));
595*0Sstevel@tonic-gate 			else
596*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
597*0Sstevel@tonic-gate 		}
598*0Sstevel@tonic-gate 
599*0Sstevel@tonic-gate 		metarpcclose(clntp);
600*0Sstevel@tonic-gate 	}
601*0Sstevel@tonic-gate 
602*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
603*0Sstevel@tonic-gate 
604*0Sstevel@tonic-gate 	if (! mdisok(ep))
605*0Sstevel@tonic-gate 		return (-1);
606*0Sstevel@tonic-gate 
607*0Sstevel@tonic-gate 	return (0);
608*0Sstevel@tonic-gate }
609*0Sstevel@tonic-gate 
610*0Sstevel@tonic-gate /*
611*0Sstevel@tonic-gate  * Add hosts to disksets.
612*0Sstevel@tonic-gate  */
613*0Sstevel@tonic-gate int
614*0Sstevel@tonic-gate clnt_addhosts(
615*0Sstevel@tonic-gate 	char			*hostname,
616*0Sstevel@tonic-gate 	mdsetname_t		*sp,
617*0Sstevel@tonic-gate 	int			node_c,
618*0Sstevel@tonic-gate 	char			**node_v,
619*0Sstevel@tonic-gate 	md_error_t		*ep
620*0Sstevel@tonic-gate )
621*0Sstevel@tonic-gate {
622*0Sstevel@tonic-gate 	CLIENT			*clntp;
623*0Sstevel@tonic-gate 	mdrpc_host_args		*args;
624*0Sstevel@tonic-gate 	mdrpc_host_2_args	v2_args;
625*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
626*0Sstevel@tonic-gate 	int			version;
627*0Sstevel@tonic-gate 
628*0Sstevel@tonic-gate 	/* initialize */
629*0Sstevel@tonic-gate 	mdclrerror(ep);
630*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
631*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
632*0Sstevel@tonic-gate 
633*0Sstevel@tonic-gate 	/* build args */
634*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
635*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_host_2_args_u.rev1;
636*0Sstevel@tonic-gate 	args->sp = sp;
637*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
638*0Sstevel@tonic-gate 	args->hosts.hosts_len = node_c;
639*0Sstevel@tonic-gate 	args->hosts.hosts_val = node_v;
640*0Sstevel@tonic-gate 
641*0Sstevel@tonic-gate 	/* do it */
642*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
643*0Sstevel@tonic-gate 		int bool;
644*0Sstevel@tonic-gate 		bool = mdrpc_addhosts_2_svc(&v2_args, &res, NULL);
645*0Sstevel@tonic-gate 		assert(bool == TRUE);
646*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
647*0Sstevel@tonic-gate 	} else {
648*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
649*0Sstevel@tonic-gate 			return (-1);
650*0Sstevel@tonic-gate 
651*0Sstevel@tonic-gate 		/*
652*0Sstevel@tonic-gate 		 * Check the client handle for the version and invoke
653*0Sstevel@tonic-gate 		 * the appropriate version of the remote procedure
654*0Sstevel@tonic-gate 		 */
655*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
656*0Sstevel@tonic-gate 
657*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
658*0Sstevel@tonic-gate 			if (mdrpc_addhosts_1(args, &res, clntp) != RPC_SUCCESS)
659*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
660*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad add hosts"));
661*0Sstevel@tonic-gate 			else
662*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
663*0Sstevel@tonic-gate 		} else {
664*0Sstevel@tonic-gate 			if (mdrpc_addhosts_2(&v2_args, &res, clntp) !=
665*0Sstevel@tonic-gate 			    RPC_SUCCESS)
666*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
667*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad add hosts"));
668*0Sstevel@tonic-gate 			else
669*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
670*0Sstevel@tonic-gate 		}
671*0Sstevel@tonic-gate 
672*0Sstevel@tonic-gate 		metarpcclose(clntp);
673*0Sstevel@tonic-gate 	}
674*0Sstevel@tonic-gate 
675*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
676*0Sstevel@tonic-gate 
677*0Sstevel@tonic-gate 	if (! mdisok(ep))
678*0Sstevel@tonic-gate 		return (-1);
679*0Sstevel@tonic-gate 
680*0Sstevel@tonic-gate 	return (0);
681*0Sstevel@tonic-gate }
682*0Sstevel@tonic-gate 
683*0Sstevel@tonic-gate /*
684*0Sstevel@tonic-gate  * Create disksets.
685*0Sstevel@tonic-gate  */
686*0Sstevel@tonic-gate int
687*0Sstevel@tonic-gate clnt_createset(
688*0Sstevel@tonic-gate 	char			*hostname,
689*0Sstevel@tonic-gate 	mdsetname_t		*sp,
690*0Sstevel@tonic-gate 	md_node_nm_arr_t	nodes,
691*0Sstevel@tonic-gate 	md_timeval32_t		timestamp,
692*0Sstevel@tonic-gate 	ulong_t			genid,
693*0Sstevel@tonic-gate 	md_error_t		*ep
694*0Sstevel@tonic-gate )
695*0Sstevel@tonic-gate {
696*0Sstevel@tonic-gate 	CLIENT			*clntp;
697*0Sstevel@tonic-gate 	mdrpc_createset_args	*args;
698*0Sstevel@tonic-gate 	mdrpc_createset_2_args	v2_args;
699*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
700*0Sstevel@tonic-gate 	int			i;
701*0Sstevel@tonic-gate 	int			version;
702*0Sstevel@tonic-gate 
703*0Sstevel@tonic-gate 	/* initialize */
704*0Sstevel@tonic-gate 	mdclrerror(ep);
705*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
706*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
707*0Sstevel@tonic-gate 
708*0Sstevel@tonic-gate 	/* build args */
709*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
710*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_createset_2_args_u.rev1;
711*0Sstevel@tonic-gate 	args->sp = sp;
712*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
713*0Sstevel@tonic-gate 	args->timestamp = timestamp;
714*0Sstevel@tonic-gate 	args->genid = genid;
715*0Sstevel@tonic-gate 	for (i = 0; i < MD_MAXSIDES; i++)
716*0Sstevel@tonic-gate 		(void) strcpy(args->nodes[i], nodes[i]);
717*0Sstevel@tonic-gate 
718*0Sstevel@tonic-gate 	/* do it */
719*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
720*0Sstevel@tonic-gate 		int	bool;
721*0Sstevel@tonic-gate 		bool = mdrpc_createset_2_svc(&v2_args, &res, NULL);
722*0Sstevel@tonic-gate 		assert(bool == TRUE);
723*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
724*0Sstevel@tonic-gate 	} else {
725*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
726*0Sstevel@tonic-gate 			return (-1);
727*0Sstevel@tonic-gate 
728*0Sstevel@tonic-gate 		/*
729*0Sstevel@tonic-gate 		 * Check the client handle for the version and invoke
730*0Sstevel@tonic-gate 		 * the appropriate version of the remote procedure
731*0Sstevel@tonic-gate 		 */
732*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
733*0Sstevel@tonic-gate 
734*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
735*0Sstevel@tonic-gate 			if (mdrpc_createset_1(args, &res, clntp) !=
736*0Sstevel@tonic-gate 			    RPC_SUCCESS)
737*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
738*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad create set"));
739*0Sstevel@tonic-gate 			else
740*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
741*0Sstevel@tonic-gate 		} else {
742*0Sstevel@tonic-gate 			if (mdrpc_createset_2(&v2_args, &res, clntp) !=
743*0Sstevel@tonic-gate 			    RPC_SUCCESS)
744*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
745*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad create set"));
746*0Sstevel@tonic-gate 			else
747*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
748*0Sstevel@tonic-gate 		}
749*0Sstevel@tonic-gate 
750*0Sstevel@tonic-gate 		metarpcclose(clntp);
751*0Sstevel@tonic-gate 	}
752*0Sstevel@tonic-gate 
753*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
754*0Sstevel@tonic-gate 
755*0Sstevel@tonic-gate 	if (! mdisok(ep))
756*0Sstevel@tonic-gate 		return (-1);
757*0Sstevel@tonic-gate 
758*0Sstevel@tonic-gate 	return (0);
759*0Sstevel@tonic-gate }
760*0Sstevel@tonic-gate 
761*0Sstevel@tonic-gate /*
762*0Sstevel@tonic-gate  * Create MN disksets.
763*0Sstevel@tonic-gate  */
764*0Sstevel@tonic-gate int
765*0Sstevel@tonic-gate clnt_mncreateset(
766*0Sstevel@tonic-gate 	char			*hostname,
767*0Sstevel@tonic-gate 	mdsetname_t		*sp,
768*0Sstevel@tonic-gate 	md_mnnode_desc		*nodelist,
769*0Sstevel@tonic-gate 	md_timeval32_t		timestamp,
770*0Sstevel@tonic-gate 	ulong_t			genid,
771*0Sstevel@tonic-gate 	md_node_nm_t		master_nodenm,
772*0Sstevel@tonic-gate 	int			master_nodeid,
773*0Sstevel@tonic-gate 	md_error_t		*ep
774*0Sstevel@tonic-gate )
775*0Sstevel@tonic-gate {
776*0Sstevel@tonic-gate 	CLIENT			*clntp;
777*0Sstevel@tonic-gate 	mdrpc_mncreateset_args	*args;
778*0Sstevel@tonic-gate 	mdrpc_mncreateset_2_args v2_args;
779*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
780*0Sstevel@tonic-gate 	int			version;
781*0Sstevel@tonic-gate 
782*0Sstevel@tonic-gate 	/* initialize */
783*0Sstevel@tonic-gate 	mdclrerror(ep);
784*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
785*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
786*0Sstevel@tonic-gate 
787*0Sstevel@tonic-gate 	/* build args */
788*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
789*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_mncreateset_2_args_u.rev1;
790*0Sstevel@tonic-gate 	args->sp = sp;
791*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
792*0Sstevel@tonic-gate 	args->timestamp = timestamp;
793*0Sstevel@tonic-gate 	args->genid = genid;
794*0Sstevel@tonic-gate 	(void) strlcpy(args->master_nodenm, master_nodenm, MD_MAX_NODENAME);
795*0Sstevel@tonic-gate 	args->master_nodeid = master_nodeid;
796*0Sstevel@tonic-gate 	args->nodelist = nodelist;
797*0Sstevel@tonic-gate 
798*0Sstevel@tonic-gate 	/* do it */
799*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
800*0Sstevel@tonic-gate 		int	bool;
801*0Sstevel@tonic-gate 		bool = mdrpc_mncreateset_2_svc(&v2_args, &res, NULL);
802*0Sstevel@tonic-gate 		assert(bool == TRUE);
803*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
804*0Sstevel@tonic-gate 	} else {
805*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
806*0Sstevel@tonic-gate 			return (-1);
807*0Sstevel@tonic-gate 
808*0Sstevel@tonic-gate 		/*
809*0Sstevel@tonic-gate 		 * Check the client handle for the version
810*0Sstevel@tonic-gate 		 */
811*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
812*0Sstevel@tonic-gate 
813*0Sstevel@tonic-gate 		/*
814*0Sstevel@tonic-gate 		 * If the client is version 1, return error
815*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
816*0Sstevel@tonic-gate 		 */
817*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
818*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
819*0Sstevel@tonic-gate 			    sp->setno, hostname, NULL, sp->setname);
820*0Sstevel@tonic-gate 			metarpcclose(clntp);
821*0Sstevel@tonic-gate 			return (-1);
822*0Sstevel@tonic-gate 		} else {
823*0Sstevel@tonic-gate 			if (mdrpc_mncreateset_2(&v2_args, &res, clntp)
824*0Sstevel@tonic-gate 							!= RPC_SUCCESS)
825*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
826*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad mncreate set"));
827*0Sstevel@tonic-gate 			else
828*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
829*0Sstevel@tonic-gate 		}
830*0Sstevel@tonic-gate 
831*0Sstevel@tonic-gate 		metarpcclose(clntp);
832*0Sstevel@tonic-gate 	}
833*0Sstevel@tonic-gate 
834*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
835*0Sstevel@tonic-gate 
836*0Sstevel@tonic-gate 	if (! mdisok(ep))
837*0Sstevel@tonic-gate 		return (-1);
838*0Sstevel@tonic-gate 
839*0Sstevel@tonic-gate 	return (0);
840*0Sstevel@tonic-gate }
841*0Sstevel@tonic-gate 
842*0Sstevel@tonic-gate /*
843*0Sstevel@tonic-gate  * Join MN set
844*0Sstevel@tonic-gate  */
845*0Sstevel@tonic-gate int
846*0Sstevel@tonic-gate clnt_joinset(
847*0Sstevel@tonic-gate 	char			*hostname,
848*0Sstevel@tonic-gate 	mdsetname_t		*sp,
849*0Sstevel@tonic-gate 	int			flags,
850*0Sstevel@tonic-gate 	md_error_t		*ep
851*0Sstevel@tonic-gate )
852*0Sstevel@tonic-gate {
853*0Sstevel@tonic-gate 	CLIENT			*clntp;
854*0Sstevel@tonic-gate 	mdrpc_sp_flags_args	*args;
855*0Sstevel@tonic-gate 	mdrpc_sp_flags_2_args	v2_args;
856*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
857*0Sstevel@tonic-gate 	int			version;
858*0Sstevel@tonic-gate 
859*0Sstevel@tonic-gate 	/* initialize */
860*0Sstevel@tonic-gate 	mdclrerror(ep);
861*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
862*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
863*0Sstevel@tonic-gate 
864*0Sstevel@tonic-gate 	/* build args */
865*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
866*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_flags_2_args_u.rev1;
867*0Sstevel@tonic-gate 	args->sp = sp;
868*0Sstevel@tonic-gate 	args->flags = flags;
869*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
870*0Sstevel@tonic-gate 
871*0Sstevel@tonic-gate 	/* do it */
872*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
873*0Sstevel@tonic-gate 		int	bool;
874*0Sstevel@tonic-gate 		bool = mdrpc_joinset_2_svc(&v2_args, &res, NULL);
875*0Sstevel@tonic-gate 		assert(bool == TRUE);
876*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
877*0Sstevel@tonic-gate 	} else {
878*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
879*0Sstevel@tonic-gate 			return (-1);
880*0Sstevel@tonic-gate 
881*0Sstevel@tonic-gate 		/*
882*0Sstevel@tonic-gate 		 * Check the client handle for the version
883*0Sstevel@tonic-gate 		 */
884*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
885*0Sstevel@tonic-gate 
886*0Sstevel@tonic-gate 		/*
887*0Sstevel@tonic-gate 		 * If the client is version 1, return error
888*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
889*0Sstevel@tonic-gate 		 */
890*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
891*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
892*0Sstevel@tonic-gate 			    sp->setno, hostname, NULL, sp->setname);
893*0Sstevel@tonic-gate 			metarpcclose(clntp);
894*0Sstevel@tonic-gate 			return (-1);
895*0Sstevel@tonic-gate 		} else {
896*0Sstevel@tonic-gate 			if (mdrpc_joinset_2(&v2_args, &res, clntp)
897*0Sstevel@tonic-gate 							!= RPC_SUCCESS)
898*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
899*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad join set"));
900*0Sstevel@tonic-gate 			else
901*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
902*0Sstevel@tonic-gate 		}
903*0Sstevel@tonic-gate 
904*0Sstevel@tonic-gate 		metarpcclose(clntp);
905*0Sstevel@tonic-gate 	}
906*0Sstevel@tonic-gate 
907*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
908*0Sstevel@tonic-gate 
909*0Sstevel@tonic-gate 	if (! mdisok(ep))
910*0Sstevel@tonic-gate 		return (-1);
911*0Sstevel@tonic-gate 
912*0Sstevel@tonic-gate 	return (0);
913*0Sstevel@tonic-gate }
914*0Sstevel@tonic-gate 
915*0Sstevel@tonic-gate /*
916*0Sstevel@tonic-gate  * Withdraw from MN set
917*0Sstevel@tonic-gate  */
918*0Sstevel@tonic-gate int
919*0Sstevel@tonic-gate clnt_withdrawset(
920*0Sstevel@tonic-gate 	char			*hostname,
921*0Sstevel@tonic-gate 	mdsetname_t		*sp,
922*0Sstevel@tonic-gate 	md_error_t		*ep
923*0Sstevel@tonic-gate )
924*0Sstevel@tonic-gate {
925*0Sstevel@tonic-gate 	CLIENT			*clntp;
926*0Sstevel@tonic-gate 	mdrpc_sp_args		*args;
927*0Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
928*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
929*0Sstevel@tonic-gate 	int			version;
930*0Sstevel@tonic-gate 
931*0Sstevel@tonic-gate 	/* initialize */
932*0Sstevel@tonic-gate 	mdclrerror(ep);
933*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
934*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
935*0Sstevel@tonic-gate 
936*0Sstevel@tonic-gate 	/* build args */
937*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
938*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
939*0Sstevel@tonic-gate 	args->sp = sp;
940*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
941*0Sstevel@tonic-gate 
942*0Sstevel@tonic-gate 	/* do it */
943*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
944*0Sstevel@tonic-gate 		int	bool;
945*0Sstevel@tonic-gate 		bool = mdrpc_withdrawset_2_svc(&v2_args, &res, NULL);
946*0Sstevel@tonic-gate 		assert(bool == TRUE);
947*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
948*0Sstevel@tonic-gate 	} else {
949*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
950*0Sstevel@tonic-gate 			return (-1);
951*0Sstevel@tonic-gate 
952*0Sstevel@tonic-gate 		/*
953*0Sstevel@tonic-gate 		 * Check the client handle for the version
954*0Sstevel@tonic-gate 		 */
955*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
956*0Sstevel@tonic-gate 
957*0Sstevel@tonic-gate 		/*
958*0Sstevel@tonic-gate 		 * If the client is version 1, return error
959*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
960*0Sstevel@tonic-gate 		 */
961*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
962*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
963*0Sstevel@tonic-gate 			    sp->setno, hostname, NULL, sp->setname);
964*0Sstevel@tonic-gate 			metarpcclose(clntp);
965*0Sstevel@tonic-gate 			return (-1);
966*0Sstevel@tonic-gate 		} else {
967*0Sstevel@tonic-gate 			if (mdrpc_withdrawset_2(&v2_args, &res, clntp)
968*0Sstevel@tonic-gate 							!= RPC_SUCCESS)
969*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
970*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
971*0Sstevel@tonic-gate 				    "metad withdraw set"));
972*0Sstevel@tonic-gate 			else
973*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
974*0Sstevel@tonic-gate 		}
975*0Sstevel@tonic-gate 
976*0Sstevel@tonic-gate 		metarpcclose(clntp);
977*0Sstevel@tonic-gate 	}
978*0Sstevel@tonic-gate 
979*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
980*0Sstevel@tonic-gate 
981*0Sstevel@tonic-gate 	if (! mdisok(ep))
982*0Sstevel@tonic-gate 		return (-1);
983*0Sstevel@tonic-gate 
984*0Sstevel@tonic-gate 	return (0);
985*0Sstevel@tonic-gate }
986*0Sstevel@tonic-gate 
987*0Sstevel@tonic-gate /*
988*0Sstevel@tonic-gate  * Delete side names for the diskset drive records
989*0Sstevel@tonic-gate  * NOTE: these are removed from the local set's namespace.
990*0Sstevel@tonic-gate  */
991*0Sstevel@tonic-gate int
992*0Sstevel@tonic-gate clnt_del_drv_sidenms(
993*0Sstevel@tonic-gate 	char			*hostname,
994*0Sstevel@tonic-gate 	mdsetname_t		*sp,
995*0Sstevel@tonic-gate 	md_error_t		*ep
996*0Sstevel@tonic-gate )
997*0Sstevel@tonic-gate {
998*0Sstevel@tonic-gate 	CLIENT			*clntp;
999*0Sstevel@tonic-gate 	mdrpc_sp_args		*args;
1000*0Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
1001*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
1002*0Sstevel@tonic-gate 	int			version;
1003*0Sstevel@tonic-gate 
1004*0Sstevel@tonic-gate 	/* initialize */
1005*0Sstevel@tonic-gate 	mdclrerror(ep);
1006*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
1007*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
1008*0Sstevel@tonic-gate 
1009*0Sstevel@tonic-gate 	/* build args */
1010*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
1011*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
1012*0Sstevel@tonic-gate 	args->sp = sp;
1013*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
1014*0Sstevel@tonic-gate 
1015*0Sstevel@tonic-gate 	/* do it */
1016*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
1017*0Sstevel@tonic-gate 		int	bool;
1018*0Sstevel@tonic-gate 		bool = mdrpc_del_drv_sidenms_2_svc(&v2_args, &res, NULL);
1019*0Sstevel@tonic-gate 		assert(bool == TRUE);
1020*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
1021*0Sstevel@tonic-gate 	} else {
1022*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
1023*0Sstevel@tonic-gate 			return (-1);
1024*0Sstevel@tonic-gate 
1025*0Sstevel@tonic-gate 		if (metaget_setdesc(sp, ep) == NULL) {
1026*0Sstevel@tonic-gate 			if (! mdisok(ep))
1027*0Sstevel@tonic-gate 				return (-1);
1028*0Sstevel@tonic-gate 			mdclrerror(ep);
1029*0Sstevel@tonic-gate 		}
1030*0Sstevel@tonic-gate 
1031*0Sstevel@tonic-gate 		/*
1032*0Sstevel@tonic-gate 		 * Check the client handle for the version and invoke
1033*0Sstevel@tonic-gate 		 * the appropriate version of the remote procedure
1034*0Sstevel@tonic-gate 		 */
1035*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
1036*0Sstevel@tonic-gate 
1037*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
1038*0Sstevel@tonic-gate 			if (mdrpc_del_drv_sidenms_1(args, &res, clntp) !=
1039*0Sstevel@tonic-gate 			    RPC_SUCCESS)
1040*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1041*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
1042*0Sstevel@tonic-gate 				    "metad delete drive sidenames"));
1043*0Sstevel@tonic-gate 			else
1044*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1045*0Sstevel@tonic-gate 		} else {
1046*0Sstevel@tonic-gate 			if (mdrpc_del_drv_sidenms_2(&v2_args, &res, clntp) !=
1047*0Sstevel@tonic-gate 			    RPC_SUCCESS)
1048*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1049*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
1050*0Sstevel@tonic-gate 				    "metad delete drive sidenames"));
1051*0Sstevel@tonic-gate 			else
1052*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1053*0Sstevel@tonic-gate 		}
1054*0Sstevel@tonic-gate 
1055*0Sstevel@tonic-gate 		metarpcclose(clntp);
1056*0Sstevel@tonic-gate 	}
1057*0Sstevel@tonic-gate 
1058*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
1059*0Sstevel@tonic-gate 
1060*0Sstevel@tonic-gate 	if (! mdisok(ep))
1061*0Sstevel@tonic-gate 		return (-1);
1062*0Sstevel@tonic-gate 
1063*0Sstevel@tonic-gate 	return (0);
1064*0Sstevel@tonic-gate }
1065*0Sstevel@tonic-gate 
1066*0Sstevel@tonic-gate /*
1067*0Sstevel@tonic-gate  * delete drives from the set
1068*0Sstevel@tonic-gate  */
1069*0Sstevel@tonic-gate int
1070*0Sstevel@tonic-gate clnt_deldrvs(
1071*0Sstevel@tonic-gate 	char			*hostname,
1072*0Sstevel@tonic-gate 	mdsetname_t		*sp,
1073*0Sstevel@tonic-gate 	md_drive_desc		*dd,
1074*0Sstevel@tonic-gate 	md_error_t		*ep
1075*0Sstevel@tonic-gate )
1076*0Sstevel@tonic-gate {
1077*0Sstevel@tonic-gate 	CLIENT			*clntp;
1078*0Sstevel@tonic-gate 	mdrpc_drives_args	v1_args;
1079*0Sstevel@tonic-gate 	mdrpc_drives_2_args	v2_args;
1080*0Sstevel@tonic-gate 	mdrpc_drives_2_args_r1	*v21_args;
1081*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
1082*0Sstevel@tonic-gate 	int			rval;
1083*0Sstevel@tonic-gate 	int			version;
1084*0Sstevel@tonic-gate 
1085*0Sstevel@tonic-gate 	/* initialize */
1086*0Sstevel@tonic-gate 	mdclrerror(ep);
1087*0Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
1088*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
1089*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
1090*0Sstevel@tonic-gate 
1091*0Sstevel@tonic-gate 	/* build args */
1092*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
1093*0Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_drives_2_args_u.rev1;
1094*0Sstevel@tonic-gate 	v21_args->sp = sp;
1095*0Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
1096*0Sstevel@tonic-gate 	v21_args->drivedescs = dd;
1097*0Sstevel@tonic-gate 
1098*0Sstevel@tonic-gate 	/* do it */
1099*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
1100*0Sstevel@tonic-gate 		int	bool;
1101*0Sstevel@tonic-gate 
1102*0Sstevel@tonic-gate 		/*
1103*0Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
1104*0Sstevel@tonic-gate 		 */
1105*0Sstevel@tonic-gate 		bool = mdrpc_deldrvs_2_svc(&v2_args, &res, NULL);
1106*0Sstevel@tonic-gate 		assert(bool == TRUE);
1107*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
1108*0Sstevel@tonic-gate 	} else {
1109*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
1110*0Sstevel@tonic-gate 			return (-1);
1111*0Sstevel@tonic-gate 
1112*0Sstevel@tonic-gate 		/*
1113*0Sstevel@tonic-gate 		 * Check the client handle for the version
1114*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
1115*0Sstevel@tonic-gate 		 * remote procedure
1116*0Sstevel@tonic-gate 		 */
1117*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
1118*0Sstevel@tonic-gate 
1119*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
1120*0Sstevel@tonic-gate 
1121*0Sstevel@tonic-gate 			alloc_olddrvdesc(&v1_args.drivedescs, dd);
1122*0Sstevel@tonic-gate 
1123*0Sstevel@tonic-gate 			/* build args */
1124*0Sstevel@tonic-gate 			v1_args.sp = sp;
1125*0Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
1126*0Sstevel@tonic-gate 			meta_conv_drvdesc_new2old(v1_args.drivedescs, dd);
1127*0Sstevel@tonic-gate 
1128*0Sstevel@tonic-gate 			rval = mdrpc_deldrvs_1(&v1_args, &res, clntp);
1129*0Sstevel@tonic-gate 
1130*0Sstevel@tonic-gate 			free_olddrvdesc(v1_args.drivedescs);
1131*0Sstevel@tonic-gate 
1132*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
1133*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1134*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
1135*0Sstevel@tonic-gate 				    "metad delete drives"));
1136*0Sstevel@tonic-gate 			else
1137*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1138*0Sstevel@tonic-gate 		} else {			/* version 2 */
1139*0Sstevel@tonic-gate 			rval = mdrpc_deldrvs_2(&v2_args, &res, clntp);
1140*0Sstevel@tonic-gate 
1141*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
1142*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1143*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
1144*0Sstevel@tonic-gate 				    "metad delete drives"));
1145*0Sstevel@tonic-gate 			else
1146*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1147*0Sstevel@tonic-gate 		}
1148*0Sstevel@tonic-gate 
1149*0Sstevel@tonic-gate 		metarpcclose(clntp);
1150*0Sstevel@tonic-gate 	}
1151*0Sstevel@tonic-gate 
1152*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
1153*0Sstevel@tonic-gate 
1154*0Sstevel@tonic-gate 	if (! mdisok(ep))
1155*0Sstevel@tonic-gate 		return (-1);
1156*0Sstevel@tonic-gate 
1157*0Sstevel@tonic-gate 	return (0);
1158*0Sstevel@tonic-gate }
1159*0Sstevel@tonic-gate 
1160*0Sstevel@tonic-gate /*
1161*0Sstevel@tonic-gate  * delete host(s) from a set.
1162*0Sstevel@tonic-gate  */
1163*0Sstevel@tonic-gate int
1164*0Sstevel@tonic-gate clnt_delhosts(
1165*0Sstevel@tonic-gate 	char			*hostname,
1166*0Sstevel@tonic-gate 	mdsetname_t		*sp,
1167*0Sstevel@tonic-gate 	int			node_c,
1168*0Sstevel@tonic-gate 	char			**node_v,
1169*0Sstevel@tonic-gate 	md_error_t		*ep
1170*0Sstevel@tonic-gate )
1171*0Sstevel@tonic-gate {
1172*0Sstevel@tonic-gate 	CLIENT			*clntp;
1173*0Sstevel@tonic-gate 	mdrpc_host_args		*args;
1174*0Sstevel@tonic-gate 	mdrpc_host_2_args	v2_args;
1175*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
1176*0Sstevel@tonic-gate 	int			version;
1177*0Sstevel@tonic-gate 
1178*0Sstevel@tonic-gate 	/* initialize */
1179*0Sstevel@tonic-gate 	mdclrerror(ep);
1180*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
1181*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
1182*0Sstevel@tonic-gate 
1183*0Sstevel@tonic-gate 	/* build args */
1184*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
1185*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_host_2_args_u.rev1;
1186*0Sstevel@tonic-gate 	args->sp = sp;
1187*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
1188*0Sstevel@tonic-gate 	args->hosts.hosts_len = node_c;
1189*0Sstevel@tonic-gate 	args->hosts.hosts_val = node_v;
1190*0Sstevel@tonic-gate 
1191*0Sstevel@tonic-gate 	/* do it */
1192*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
1193*0Sstevel@tonic-gate 		int	bool;
1194*0Sstevel@tonic-gate 		bool = mdrpc_delhosts_2_svc(&v2_args, &res, NULL);
1195*0Sstevel@tonic-gate 		assert(bool == TRUE);
1196*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
1197*0Sstevel@tonic-gate 	} else {
1198*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
1199*0Sstevel@tonic-gate 			return (-1);
1200*0Sstevel@tonic-gate 
1201*0Sstevel@tonic-gate 		/*
1202*0Sstevel@tonic-gate 		 * Check the client handle for the version
1203*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
1204*0Sstevel@tonic-gate 		 * remote procedure
1205*0Sstevel@tonic-gate 		 */
1206*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
1207*0Sstevel@tonic-gate 
1208*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
1209*0Sstevel@tonic-gate 			if (mdrpc_delhosts_1(args, &res, clntp) != RPC_SUCCESS)
1210*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1211*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad delete hosts"));
1212*0Sstevel@tonic-gate 			else
1213*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1214*0Sstevel@tonic-gate 		} else {
1215*0Sstevel@tonic-gate 			if (mdrpc_delhosts_2(&v2_args, &res, clntp) !=
1216*0Sstevel@tonic-gate 			    RPC_SUCCESS)
1217*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1218*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad delete hosts"));
1219*0Sstevel@tonic-gate 			else
1220*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1221*0Sstevel@tonic-gate 		}
1222*0Sstevel@tonic-gate 
1223*0Sstevel@tonic-gate 		metarpcclose(clntp);
1224*0Sstevel@tonic-gate 	}
1225*0Sstevel@tonic-gate 
1226*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
1227*0Sstevel@tonic-gate 
1228*0Sstevel@tonic-gate 	if (! mdisok(ep))
1229*0Sstevel@tonic-gate 		return (-1);
1230*0Sstevel@tonic-gate 
1231*0Sstevel@tonic-gate 	return (0);
1232*0Sstevel@tonic-gate }
1233*0Sstevel@tonic-gate 
1234*0Sstevel@tonic-gate /*
1235*0Sstevel@tonic-gate  * Delete diskset.
1236*0Sstevel@tonic-gate  */
1237*0Sstevel@tonic-gate int
1238*0Sstevel@tonic-gate clnt_delset(
1239*0Sstevel@tonic-gate 	char			*hostname,
1240*0Sstevel@tonic-gate 	mdsetname_t		*sp,
1241*0Sstevel@tonic-gate 	md_error_t		*ep
1242*0Sstevel@tonic-gate )
1243*0Sstevel@tonic-gate {
1244*0Sstevel@tonic-gate 	CLIENT			*clntp;
1245*0Sstevel@tonic-gate 	mdrpc_sp_args		*args;
1246*0Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
1247*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
1248*0Sstevel@tonic-gate 	int			version;
1249*0Sstevel@tonic-gate 
1250*0Sstevel@tonic-gate 	/* initialize */
1251*0Sstevel@tonic-gate 	mdclrerror(ep);
1252*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
1253*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
1254*0Sstevel@tonic-gate 
1255*0Sstevel@tonic-gate 	/* build args */
1256*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
1257*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
1258*0Sstevel@tonic-gate 	args->sp = sp;
1259*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
1260*0Sstevel@tonic-gate 
1261*0Sstevel@tonic-gate 	/* do it */
1262*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
1263*0Sstevel@tonic-gate 		int	bool;
1264*0Sstevel@tonic-gate 		bool = mdrpc_delset_2_svc(&v2_args, &res, NULL);
1265*0Sstevel@tonic-gate 		assert(bool == TRUE);
1266*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
1267*0Sstevel@tonic-gate 	} else {
1268*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
1269*0Sstevel@tonic-gate 			return (-1);
1270*0Sstevel@tonic-gate 
1271*0Sstevel@tonic-gate 		/*
1272*0Sstevel@tonic-gate 		 * Check the client handle for the version
1273*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
1274*0Sstevel@tonic-gate 		 * remote procedure
1275*0Sstevel@tonic-gate 		 */
1276*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
1277*0Sstevel@tonic-gate 
1278*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
1279*0Sstevel@tonic-gate 			if (mdrpc_delset_1(args, &res, clntp) != RPC_SUCCESS)
1280*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1281*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad delete set"));
1282*0Sstevel@tonic-gate 			else
1283*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1284*0Sstevel@tonic-gate 		} else {
1285*0Sstevel@tonic-gate 			if (mdrpc_delset_2(&v2_args, &res, clntp) !=
1286*0Sstevel@tonic-gate 			    RPC_SUCCESS)
1287*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1288*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad delete set"));
1289*0Sstevel@tonic-gate 			else
1290*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1291*0Sstevel@tonic-gate 		}
1292*0Sstevel@tonic-gate 
1293*0Sstevel@tonic-gate 		metarpcclose(clntp);
1294*0Sstevel@tonic-gate 	}
1295*0Sstevel@tonic-gate 
1296*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
1297*0Sstevel@tonic-gate 
1298*0Sstevel@tonic-gate 	if (! mdisok(ep))
1299*0Sstevel@tonic-gate 		return (-1);
1300*0Sstevel@tonic-gate 
1301*0Sstevel@tonic-gate 	return (0);
1302*0Sstevel@tonic-gate }
1303*0Sstevel@tonic-gate 
1304*0Sstevel@tonic-gate /*
1305*0Sstevel@tonic-gate  * return remote device info
1306*0Sstevel@tonic-gate  */
1307*0Sstevel@tonic-gate int
1308*0Sstevel@tonic-gate clnt_devinfo(
1309*0Sstevel@tonic-gate 	char			*hostname,
1310*0Sstevel@tonic-gate 	mdsetname_t		*sp,
1311*0Sstevel@tonic-gate 	mddrivename_t		*dp,
1312*0Sstevel@tonic-gate 	md_dev64_t		*ret_dev,
1313*0Sstevel@tonic-gate 	time_t			*ret_timestamp,
1314*0Sstevel@tonic-gate 	md_error_t		*ep
1315*0Sstevel@tonic-gate )
1316*0Sstevel@tonic-gate {
1317*0Sstevel@tonic-gate 	CLIENT			*clntp;
1318*0Sstevel@tonic-gate 	mdrpc_devinfo_args	v1_args;
1319*0Sstevel@tonic-gate 	mdrpc_devinfo_2_args	v2_args;
1320*0Sstevel@tonic-gate 	mdrpc_devinfo_2_args_r1	*v21_args;
1321*0Sstevel@tonic-gate 	mdrpc_devinfo_res	v1_res;
1322*0Sstevel@tonic-gate 	mdrpc_devinfo_2_res	v2_res;
1323*0Sstevel@tonic-gate 	int			rval, version;
1324*0Sstevel@tonic-gate 
1325*0Sstevel@tonic-gate 	/* initialize */
1326*0Sstevel@tonic-gate 	mdclrerror(ep);
1327*0Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
1328*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
1329*0Sstevel@tonic-gate 	(void) memset(&v1_res,  0, sizeof (v1_res));
1330*0Sstevel@tonic-gate 	(void) memset(&v2_res, 	0, sizeof (v2_res));
1331*0Sstevel@tonic-gate 
1332*0Sstevel@tonic-gate 	/* build args */
1333*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
1334*0Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_devinfo_2_args_u.rev1;
1335*0Sstevel@tonic-gate 	v21_args->sp = sp;
1336*0Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
1337*0Sstevel@tonic-gate 	v21_args->drivenamep = dp;
1338*0Sstevel@tonic-gate 
1339*0Sstevel@tonic-gate 	/* do it */
1340*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
1341*0Sstevel@tonic-gate 		int	bool;
1342*0Sstevel@tonic-gate 
1343*0Sstevel@tonic-gate 		/*
1344*0Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure.
1345*0Sstevel@tonic-gate 		 */
1346*0Sstevel@tonic-gate 		bool = mdrpc_devinfo_2_svc(&v2_args, &v2_res, NULL);
1347*0Sstevel@tonic-gate 		assert(bool == TRUE);
1348*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &v1_res.status);
1349*0Sstevel@tonic-gate 	} else {
1350*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
1351*0Sstevel@tonic-gate 			return (-1);
1352*0Sstevel@tonic-gate 
1353*0Sstevel@tonic-gate 		/*
1354*0Sstevel@tonic-gate 		 * Check the client handle for the version
1355*0Sstevel@tonic-gate 		 * and invoke the appropriate version of
1356*0Sstevel@tonic-gate 		 * the remote procedure.
1357*0Sstevel@tonic-gate 		 */
1358*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
1359*0Sstevel@tonic-gate 
1360*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
1361*0Sstevel@tonic-gate 			v1_args.drivenamep =
1362*0Sstevel@tonic-gate 			    Zalloc(sizeof (o_mddrivename_t));
1363*0Sstevel@tonic-gate 			v1_args.drivenamep->parts.parts_val =
1364*0Sstevel@tonic-gate 			    Zalloc((sizeof (o_mdname_t)) *
1365*0Sstevel@tonic-gate 			    dp->parts.parts_len);
1366*0Sstevel@tonic-gate 
1367*0Sstevel@tonic-gate 			/* build args */
1368*0Sstevel@tonic-gate 			v1_args.sp = sp;
1369*0Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno,
1370*0Sstevel@tonic-gate 			    sp->setname);
1371*0Sstevel@tonic-gate 
1372*0Sstevel@tonic-gate 			/*
1373*0Sstevel@tonic-gate 			 * Convert v2 arguments to v1 arguments
1374*0Sstevel@tonic-gate 			 * before sending over the wire.
1375*0Sstevel@tonic-gate 			 */
1376*0Sstevel@tonic-gate 			meta_conv_drvname_new2old(v1_args.drivenamep,
1377*0Sstevel@tonic-gate 			    v21_args->drivenamep);
1378*0Sstevel@tonic-gate 
1379*0Sstevel@tonic-gate 			rval = mdrpc_devinfo_1(&v1_args, &v1_res, clntp);
1380*0Sstevel@tonic-gate 
1381*0Sstevel@tonic-gate 			free(v1_args.drivenamep->parts.parts_val);
1382*0Sstevel@tonic-gate 			free(v1_args.drivenamep);
1383*0Sstevel@tonic-gate 
1384*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
1385*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1386*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad device info"));
1387*0Sstevel@tonic-gate 			else
1388*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &v1_res.status);
1389*0Sstevel@tonic-gate 		} else {			/* version 2 */
1390*0Sstevel@tonic-gate 			rval = mdrpc_devinfo_2(&v2_args, &v2_res, clntp);
1391*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
1392*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1393*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad device info"));
1394*0Sstevel@tonic-gate 			else
1395*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &v2_res.status);
1396*0Sstevel@tonic-gate 		}
1397*0Sstevel@tonic-gate 
1398*0Sstevel@tonic-gate 		metarpcclose(clntp);
1399*0Sstevel@tonic-gate 	}
1400*0Sstevel@tonic-gate 
1401*0Sstevel@tonic-gate 	if (mdisok(ep)) {
1402*0Sstevel@tonic-gate 		/* do something with the results */
1403*0Sstevel@tonic-gate 		rval = 0;
1404*0Sstevel@tonic-gate 
1405*0Sstevel@tonic-gate 		if (ret_dev != NULL) {
1406*0Sstevel@tonic-gate 			if (version == METAD_VERSION)
1407*0Sstevel@tonic-gate 				*ret_dev = meta_expldev(v1_res.dev);
1408*0Sstevel@tonic-gate 			else
1409*0Sstevel@tonic-gate 				*ret_dev = v2_res.dev;
1410*0Sstevel@tonic-gate 		}
1411*0Sstevel@tonic-gate 
1412*0Sstevel@tonic-gate 		if (ret_timestamp != NULL) {
1413*0Sstevel@tonic-gate 			if (version == METAD_VERSION)
1414*0Sstevel@tonic-gate 				*ret_timestamp = v1_res.vtime;
1415*0Sstevel@tonic-gate 			else
1416*0Sstevel@tonic-gate 				*ret_timestamp = v2_res.vtime;
1417*0Sstevel@tonic-gate 		}
1418*0Sstevel@tonic-gate 	}
1419*0Sstevel@tonic-gate 
1420*0Sstevel@tonic-gate 	if (version == METAD_VERSION)
1421*0Sstevel@tonic-gate 		xdr_free(xdr_mdrpc_devinfo_res, (char *)&v1_res);
1422*0Sstevel@tonic-gate 	else
1423*0Sstevel@tonic-gate 		xdr_free(xdr_mdrpc_devinfo_2_res, (char *)&v2_res);
1424*0Sstevel@tonic-gate 
1425*0Sstevel@tonic-gate 	return (rval);
1426*0Sstevel@tonic-gate }
1427*0Sstevel@tonic-gate 
1428*0Sstevel@tonic-gate /*
1429*0Sstevel@tonic-gate  * return remote device info
1430*0Sstevel@tonic-gate  */
1431*0Sstevel@tonic-gate int
1432*0Sstevel@tonic-gate clnt_devid(
1433*0Sstevel@tonic-gate 	char			*hostname,
1434*0Sstevel@tonic-gate 	mdsetname_t		*sp,
1435*0Sstevel@tonic-gate 	mddrivename_t		*dp,
1436*0Sstevel@tonic-gate 	char			**ret_encdevid,
1437*0Sstevel@tonic-gate 	md_error_t		*ep
1438*0Sstevel@tonic-gate )
1439*0Sstevel@tonic-gate {
1440*0Sstevel@tonic-gate 	CLIENT			*clntp;
1441*0Sstevel@tonic-gate 	mdrpc_devid_args	*args;
1442*0Sstevel@tonic-gate 	mdrpc_devid_2_args	v2_args;
1443*0Sstevel@tonic-gate 	mdrpc_devid_res		res;
1444*0Sstevel@tonic-gate 	int			rval;
1445*0Sstevel@tonic-gate 	int			version;
1446*0Sstevel@tonic-gate 
1447*0Sstevel@tonic-gate 	/* initialize */
1448*0Sstevel@tonic-gate 	mdclrerror(ep);
1449*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
1450*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
1451*0Sstevel@tonic-gate 
1452*0Sstevel@tonic-gate 	/* build args */
1453*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
1454*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_devid_2_args_u.rev1;
1455*0Sstevel@tonic-gate 	args->sp = sp;
1456*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
1457*0Sstevel@tonic-gate 	args->drivenamep = dp;
1458*0Sstevel@tonic-gate 
1459*0Sstevel@tonic-gate 	/* do it */
1460*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
1461*0Sstevel@tonic-gate 		int	bool;
1462*0Sstevel@tonic-gate 
1463*0Sstevel@tonic-gate 		/*
1464*0Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure.
1465*0Sstevel@tonic-gate 		 */
1466*0Sstevel@tonic-gate 		bool = mdrpc_devid_2_svc(&v2_args, &res, NULL);
1467*0Sstevel@tonic-gate 		assert(bool == TRUE);
1468*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
1469*0Sstevel@tonic-gate 	} else {
1470*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
1471*0Sstevel@tonic-gate 			return (-1);
1472*0Sstevel@tonic-gate 
1473*0Sstevel@tonic-gate 		/*
1474*0Sstevel@tonic-gate 		 * Check the client handle for the version
1475*0Sstevel@tonic-gate 		 */
1476*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
1477*0Sstevel@tonic-gate 
1478*0Sstevel@tonic-gate 		/*
1479*0Sstevel@tonic-gate 		 * If the client is version 1, return error
1480*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
1481*0Sstevel@tonic-gate 		 */
1482*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
1483*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_DRIVENOTONHOST, sp->setno,
1484*0Sstevel@tonic-gate 			    hostname, dp->cname, sp->setname);
1485*0Sstevel@tonic-gate 		} else {			/* version 2 */
1486*0Sstevel@tonic-gate 			rval = mdrpc_devid_2(&v2_args, &res, clntp);
1487*0Sstevel@tonic-gate 
1488*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
1489*0Sstevel@tonic-gate 			    (void) mdrpcerror(ep, clntp, hostname,
1490*0Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad devid info"));
1491*0Sstevel@tonic-gate 			else
1492*0Sstevel@tonic-gate 			    (void) mdstealerror(ep, &res.status);
1493*0Sstevel@tonic-gate 		}
1494*0Sstevel@tonic-gate 
1495*0Sstevel@tonic-gate 		metarpcclose(clntp);
1496*0Sstevel@tonic-gate 	}
1497*0Sstevel@tonic-gate 
1498*0Sstevel@tonic-gate 	if (mdisok(ep)) {
1499*0Sstevel@tonic-gate 		/* do something with the results */
1500*0Sstevel@tonic-gate 		rval = 0;
1501*0Sstevel@tonic-gate 
1502*0Sstevel@tonic-gate 		if (ret_encdevid != NULL)
1503*0Sstevel@tonic-gate 			*ret_encdevid = strdup(res.enc_devid);
1504*0Sstevel@tonic-gate 
1505*0Sstevel@tonic-gate 	}
1506*0Sstevel@tonic-gate 
1507*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_devid_res, (char *)&res);
1508*0Sstevel@tonic-gate 
1509*0Sstevel@tonic-gate 	return (rval);
1510*0Sstevel@tonic-gate }
1511*0Sstevel@tonic-gate 
1512*0Sstevel@tonic-gate /*
1513*0Sstevel@tonic-gate  * Get the device information of a disk on a remote host. The information
1514*0Sstevel@tonic-gate  * retrieved is the device's name, the associated driver and the dev_t.
1515*0Sstevel@tonic-gate  * The lookup is performed by using the devid of the disk as this is
1516*0Sstevel@tonic-gate  * unique to the disk.  The device name on the originating node is passed
1517*0Sstevel@tonic-gate  * in.  If that devname is found when doing the devid to namelist translation
1518*0Sstevel@tonic-gate  * then that value is used to make the device names as consistent as possible
1519*0Sstevel@tonic-gate  * across the nodes.
1520*0Sstevel@tonic-gate  *
1521*0Sstevel@tonic-gate  * An attempt is made to retrieve this information by calling
1522*0Sstevel@tonic-gate  * mdrpc_devinfo_by_devid_name_2_svc.  Locally this call should always
1523*0Sstevel@tonic-gate  * succeed.  In the case where a call is made through a CLIENT handle,
1524*0Sstevel@tonic-gate  * it is possible that the function hasn't been implemented on the called
1525*0Sstevel@tonic-gate  * node.  If this is the case fall back to mdrpc_devinfo_by_devidstr_2_svc.
1526*0Sstevel@tonic-gate  *
1527*0Sstevel@tonic-gate  * Returns:
1528*0Sstevel@tonic-gate  * 	-1 	Error
1529*0Sstevel@tonic-gate  * 	ENOTSUP Operation not supported i.e. procedure not supported on
1530*0Sstevel@tonic-gate  * 		the remote node
1531*0Sstevel@tonic-gate  * 	0	Success
1532*0Sstevel@tonic-gate  */
1533*0Sstevel@tonic-gate int
1534*0Sstevel@tonic-gate clnt_devinfo_by_devid(
1535*0Sstevel@tonic-gate 	char		*hostname,
1536*0Sstevel@tonic-gate 	mdsetname_t	*sp,
1537*0Sstevel@tonic-gate 	char		*devidstr,
1538*0Sstevel@tonic-gate 	md_dev64_t	*ret_dev,
1539*0Sstevel@tonic-gate 	char		*orig_devname,
1540*0Sstevel@tonic-gate 	char		**ret_devname,
1541*0Sstevel@tonic-gate 	char		**ret_driver,
1542*0Sstevel@tonic-gate 	md_error_t	*ep
1543*0Sstevel@tonic-gate )
1544*0Sstevel@tonic-gate {
1545*0Sstevel@tonic-gate 	CLIENT			*clntp;
1546*0Sstevel@tonic-gate 	mdrpc_devidstr_args	devid_args;
1547*0Sstevel@tonic-gate 	mdrpc_devid_name_args	*args;
1548*0Sstevel@tonic-gate 	mdrpc_devid_name_2_args	v2_args;
1549*0Sstevel@tonic-gate 	mdrpc_devinfo_2_res	res;
1550*0Sstevel@tonic-gate 	int			rval;
1551*0Sstevel@tonic-gate 	int			version;
1552*0Sstevel@tonic-gate 
1553*0Sstevel@tonic-gate 	/* initialize */
1554*0Sstevel@tonic-gate 	mdclrerror(ep);
1555*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
1556*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
1557*0Sstevel@tonic-gate 
1558*0Sstevel@tonic-gate 	/* build args */
1559*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
1560*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_devid_name_2_args_u.rev1;
1561*0Sstevel@tonic-gate 	args->enc_devid = devidstr;
1562*0Sstevel@tonic-gate 	args->orig_devname = orig_devname;
1563*0Sstevel@tonic-gate 	args->sp = sp;
1564*0Sstevel@tonic-gate 
1565*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
1566*0Sstevel@tonic-gate 		int	bool;
1567*0Sstevel@tonic-gate 
1568*0Sstevel@tonic-gate 		/*
1569*0Sstevel@tonic-gate 		 * We are calling this locally so call the function
1570*0Sstevel@tonic-gate 		 * directly.
1571*0Sstevel@tonic-gate 		 */
1572*0Sstevel@tonic-gate 		bool = mdrpc_devinfo_by_devid_name_2_svc(&v2_args, &res, NULL);
1573*0Sstevel@tonic-gate 		assert(bool == TRUE);
1574*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
1575*0Sstevel@tonic-gate 	} else {
1576*0Sstevel@tonic-gate 
1577*0Sstevel@tonic-gate 		/* open connection */
1578*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL) {
1579*0Sstevel@tonic-gate 			return (-1);
1580*0Sstevel@tonic-gate 		}
1581*0Sstevel@tonic-gate 
1582*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
1583*0Sstevel@tonic-gate 
1584*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* Version 1 */
1585*0Sstevel@tonic-gate 			metarpcclose(clntp);
1586*0Sstevel@tonic-gate 			return (ENOTSUP);
1587*0Sstevel@tonic-gate 		}
1588*0Sstevel@tonic-gate 
1589*0Sstevel@tonic-gate 		rval = mdrpc_devinfo_by_devid_name_2(&v2_args, &res, clntp);
1590*0Sstevel@tonic-gate 
1591*0Sstevel@tonic-gate 		if (rval != RPC_SUCCESS) {
1592*0Sstevel@tonic-gate 			/* try falling back to devidstr_2_svc */
1593*0Sstevel@tonic-gate 			(void) memset(&devid_args, 0, sizeof (devid_args));
1594*0Sstevel@tonic-gate 			(void) memset(&res, 0, sizeof (res));
1595*0Sstevel@tonic-gate 
1596*0Sstevel@tonic-gate 			devid_args.enc_devid = devidstr;
1597*0Sstevel@tonic-gate 			devid_args.sp = sp;
1598*0Sstevel@tonic-gate 
1599*0Sstevel@tonic-gate 			rval = mdrpc_devinfo_by_devid_2(
1600*0Sstevel@tonic-gate 					&devid_args, &res, clntp);
1601*0Sstevel@tonic-gate 
1602*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS) {
1603*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1604*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
1605*0Sstevel@tonic-gate 				    "metad devinfo by devid"));
1606*0Sstevel@tonic-gate 			} else {
1607*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1608*0Sstevel@tonic-gate 			}
1609*0Sstevel@tonic-gate 		} else {
1610*0Sstevel@tonic-gate 			(void) mdstealerror(ep, &res.status);
1611*0Sstevel@tonic-gate 		}
1612*0Sstevel@tonic-gate 		metarpcclose(clntp);
1613*0Sstevel@tonic-gate 	}
1614*0Sstevel@tonic-gate 
1615*0Sstevel@tonic-gate 	if (mdisok(ep)) {
1616*0Sstevel@tonic-gate 		rval = 0;
1617*0Sstevel@tonic-gate 		if (ret_dev != NULL)
1618*0Sstevel@tonic-gate 			*ret_dev = res.dev;
1619*0Sstevel@tonic-gate 
1620*0Sstevel@tonic-gate 		if (ret_devname != NULL && res.devname != NULL)
1621*0Sstevel@tonic-gate 			*ret_devname = Strdup(res.devname);
1622*0Sstevel@tonic-gate 
1623*0Sstevel@tonic-gate 		if (ret_driver != NULL && res.drivername != NULL)
1624*0Sstevel@tonic-gate 			*ret_driver = Strdup(res.drivername);
1625*0Sstevel@tonic-gate 	}
1626*0Sstevel@tonic-gate 
1627*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_devinfo_2_res, (char *)&res);
1628*0Sstevel@tonic-gate 
1629*0Sstevel@tonic-gate 	if (! mdisok(ep))
1630*0Sstevel@tonic-gate 		return (-1);
1631*0Sstevel@tonic-gate 
1632*0Sstevel@tonic-gate 	return (0);
1633*0Sstevel@tonic-gate 
1634*0Sstevel@tonic-gate }
1635*0Sstevel@tonic-gate 
1636*0Sstevel@tonic-gate 
1637*0Sstevel@tonic-gate /*
1638*0Sstevel@tonic-gate  * return status of whether driver is used, mount
1639*0Sstevel@tonic-gate  */
1640*0Sstevel@tonic-gate int
1641*0Sstevel@tonic-gate clnt_drvused(
1642*0Sstevel@tonic-gate 	char			*hostname,
1643*0Sstevel@tonic-gate 	mdsetname_t		*sp,
1644*0Sstevel@tonic-gate 	mddrivename_t		*dp,
1645*0Sstevel@tonic-gate 	md_error_t		*ep
1646*0Sstevel@tonic-gate )
1647*0Sstevel@tonic-gate {
1648*0Sstevel@tonic-gate 	CLIENT			*clntp;
1649*0Sstevel@tonic-gate 	mdrpc_drvused_args	v1_args;
1650*0Sstevel@tonic-gate 	mdrpc_drvused_2_args	v2_args;
1651*0Sstevel@tonic-gate 	mdrpc_drvused_2_args_r1	*v21_args;
1652*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
1653*0Sstevel@tonic-gate 	int			rval;
1654*0Sstevel@tonic-gate 	int			version;
1655*0Sstevel@tonic-gate 
1656*0Sstevel@tonic-gate 	/* initialize */
1657*0Sstevel@tonic-gate 	mdclrerror(ep);
1658*0Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
1659*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
1660*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
1661*0Sstevel@tonic-gate 
1662*0Sstevel@tonic-gate 	/* build args */
1663*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
1664*0Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_drvused_2_args_u.rev1;
1665*0Sstevel@tonic-gate 	v21_args->sp = sp;
1666*0Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
1667*0Sstevel@tonic-gate 	v21_args->drivenamep = dp;
1668*0Sstevel@tonic-gate 
1669*0Sstevel@tonic-gate 	/* do it */
1670*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
1671*0Sstevel@tonic-gate 		int	bool;
1672*0Sstevel@tonic-gate 
1673*0Sstevel@tonic-gate 		/*
1674*0Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
1675*0Sstevel@tonic-gate 		 */
1676*0Sstevel@tonic-gate 		bool = mdrpc_drvused_2_svc(&v2_args, &res, NULL);
1677*0Sstevel@tonic-gate 		assert(bool == TRUE);
1678*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
1679*0Sstevel@tonic-gate 	} else {
1680*0Sstevel@tonic-gate 		/* open connection */
1681*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
1682*0Sstevel@tonic-gate 			return (-1);
1683*0Sstevel@tonic-gate 
1684*0Sstevel@tonic-gate 		/*
1685*0Sstevel@tonic-gate 		 * Check the client handle for the version
1686*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
1687*0Sstevel@tonic-gate 		 * remote procedure
1688*0Sstevel@tonic-gate 		 */
1689*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
1690*0Sstevel@tonic-gate 
1691*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
1692*0Sstevel@tonic-gate 			v1_args.drivenamep =
1693*0Sstevel@tonic-gate 			    Zalloc(sizeof (o_mddrivename_t));
1694*0Sstevel@tonic-gate 			v1_args.drivenamep->parts.parts_val =
1695*0Sstevel@tonic-gate 			    Zalloc((sizeof (o_mdname_t)) *
1696*0Sstevel@tonic-gate 			    dp->parts.parts_len);
1697*0Sstevel@tonic-gate 
1698*0Sstevel@tonic-gate 			/* build args */
1699*0Sstevel@tonic-gate 			v1_args.sp = sp;
1700*0Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
1701*0Sstevel@tonic-gate 
1702*0Sstevel@tonic-gate 			/* Convert v2 args to v1 args */
1703*0Sstevel@tonic-gate 			meta_conv_drvname_new2old(v1_args.drivenamep,
1704*0Sstevel@tonic-gate 			    v21_args->drivenamep);
1705*0Sstevel@tonic-gate 
1706*0Sstevel@tonic-gate 			rval = mdrpc_drvused_1(&v1_args, &res, clntp);
1707*0Sstevel@tonic-gate 
1708*0Sstevel@tonic-gate 			free(v1_args.drivenamep->parts.parts_val);
1709*0Sstevel@tonic-gate 			free(v1_args.drivenamep);
1710*0Sstevel@tonic-gate 
1711*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
1712*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1713*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad drive used"));
1714*0Sstevel@tonic-gate 			else
1715*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1716*0Sstevel@tonic-gate 		} else {			/* version 2 */
1717*0Sstevel@tonic-gate 			rval = mdrpc_drvused_2(&v2_args, &res, clntp);
1718*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
1719*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1720*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad drive used"));
1721*0Sstevel@tonic-gate 			else
1722*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1723*0Sstevel@tonic-gate 		}
1724*0Sstevel@tonic-gate 
1725*0Sstevel@tonic-gate 		metarpcclose(clntp);
1726*0Sstevel@tonic-gate 	}
1727*0Sstevel@tonic-gate 
1728*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
1729*0Sstevel@tonic-gate 
1730*0Sstevel@tonic-gate 	if (! mdisok(ep))
1731*0Sstevel@tonic-gate 		return (-1);
1732*0Sstevel@tonic-gate 
1733*0Sstevel@tonic-gate 	return (0);
1734*0Sstevel@tonic-gate }
1735*0Sstevel@tonic-gate 
1736*0Sstevel@tonic-gate void
1737*0Sstevel@tonic-gate free_sr(md_set_record *sr)
1738*0Sstevel@tonic-gate {
1739*0Sstevel@tonic-gate 	mdrpc_getset_res	res;
1740*0Sstevel@tonic-gate 	mdrpc_mngetset_res	mnres;
1741*0Sstevel@tonic-gate 
1742*0Sstevel@tonic-gate 	if (md_in_daemon)
1743*0Sstevel@tonic-gate 		return;
1744*0Sstevel@tonic-gate 
1745*0Sstevel@tonic-gate 	/*
1746*0Sstevel@tonic-gate 	 * dummy up a result struct, to do a deep free of the (mn)sr.
1747*0Sstevel@tonic-gate 	 * (A deep free means that the xdr_free code will free the
1748*0Sstevel@tonic-gate 	 * linked list of drive records for the sr and will also free
1749*0Sstevel@tonic-gate 	 * the linked list of node records for the mnsr.)
1750*0Sstevel@tonic-gate 	 */
1751*0Sstevel@tonic-gate 	if (MD_MNSET_REC(sr)) {
1752*0Sstevel@tonic-gate 		(void) memset(&mnres, 0, sizeof (mnres));
1753*0Sstevel@tonic-gate 		mnres.mnsr = (struct md_mnset_record *)sr;
1754*0Sstevel@tonic-gate 		xdr_free(xdr_mdrpc_mngetset_res, (char *)&mnres);
1755*0Sstevel@tonic-gate 	} else {
1756*0Sstevel@tonic-gate 		(void) memset(&res, 0, sizeof (res));
1757*0Sstevel@tonic-gate 		res.sr = sr;
1758*0Sstevel@tonic-gate 		xdr_free(xdr_mdrpc_getset_res, (char *)&res);
1759*0Sstevel@tonic-gate 	}
1760*0Sstevel@tonic-gate }
1761*0Sstevel@tonic-gate 
1762*0Sstevel@tonic-gate void
1763*0Sstevel@tonic-gate short_circuit_getset(
1764*0Sstevel@tonic-gate 	mdrpc_getset_args	*args,
1765*0Sstevel@tonic-gate 	mdrpc_getset_res	*res
1766*0Sstevel@tonic-gate )
1767*0Sstevel@tonic-gate {
1768*0Sstevel@tonic-gate 	if (args->setname != NULL)
1769*0Sstevel@tonic-gate 		res->sr = metad_getsetbyname(args->setname, &res->status);
1770*0Sstevel@tonic-gate 	else
1771*0Sstevel@tonic-gate 		res->sr = metad_getsetbynum(args->setno, &res->status);
1772*0Sstevel@tonic-gate }
1773*0Sstevel@tonic-gate 
1774*0Sstevel@tonic-gate void
1775*0Sstevel@tonic-gate short_circuit_mngetset(
1776*0Sstevel@tonic-gate 	mdrpc_getset_args	*args,
1777*0Sstevel@tonic-gate 	mdrpc_mngetset_res	*res
1778*0Sstevel@tonic-gate )
1779*0Sstevel@tonic-gate {
1780*0Sstevel@tonic-gate 	md_set_record		*sr;
1781*0Sstevel@tonic-gate 	if (args->setname != NULL)
1782*0Sstevel@tonic-gate 		sr = metad_getsetbyname(args->setname, &res->status);
1783*0Sstevel@tonic-gate 	else
1784*0Sstevel@tonic-gate 		sr = metad_getsetbynum(args->setno, &res->status);
1785*0Sstevel@tonic-gate 
1786*0Sstevel@tonic-gate 	if (MD_MNSET_REC(sr)) {
1787*0Sstevel@tonic-gate 		res->mnsr = (struct md_mnset_record *)sr;
1788*0Sstevel@tonic-gate 	} else {
1789*0Sstevel@tonic-gate 		res->mnsr = NULL;
1790*0Sstevel@tonic-gate 	}
1791*0Sstevel@tonic-gate }
1792*0Sstevel@tonic-gate 
1793*0Sstevel@tonic-gate static int
1794*0Sstevel@tonic-gate is_auto_take_set(char *setname, set_t setno)
1795*0Sstevel@tonic-gate {
1796*0Sstevel@tonic-gate 	if (setname != NULL)
1797*0Sstevel@tonic-gate 	    return (metad_isautotakebyname(setname));
1798*0Sstevel@tonic-gate 	else
1799*0Sstevel@tonic-gate 	    return (metad_isautotakebynum(setno));
1800*0Sstevel@tonic-gate }
1801*0Sstevel@tonic-gate 
1802*0Sstevel@tonic-gate /*
1803*0Sstevel@tonic-gate  * return the diskset record, and drive records.
1804*0Sstevel@tonic-gate  * If record is a MNdiskset record, then only the first md_set_record
1805*0Sstevel@tonic-gate  * bytes were copied from the daemon.
1806*0Sstevel@tonic-gate  */
1807*0Sstevel@tonic-gate int
1808*0Sstevel@tonic-gate clnt_getset(
1809*0Sstevel@tonic-gate 	char			*hostname,
1810*0Sstevel@tonic-gate 	char			*setname,
1811*0Sstevel@tonic-gate 	set_t			setno,
1812*0Sstevel@tonic-gate 	md_set_record		**ret_sr,
1813*0Sstevel@tonic-gate 	md_error_t		*ep
1814*0Sstevel@tonic-gate )
1815*0Sstevel@tonic-gate {
1816*0Sstevel@tonic-gate 	CLIENT			*clntp;
1817*0Sstevel@tonic-gate 	mdrpc_getset_args	*args;
1818*0Sstevel@tonic-gate 	mdrpc_getset_2_args	v2_args;
1819*0Sstevel@tonic-gate 	mdrpc_getset_res	res;
1820*0Sstevel@tonic-gate 	int			rval = -1;
1821*0Sstevel@tonic-gate 	int			version;
1822*0Sstevel@tonic-gate 
1823*0Sstevel@tonic-gate 	/* initialize */
1824*0Sstevel@tonic-gate 	mdclrerror(ep);
1825*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
1826*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
1827*0Sstevel@tonic-gate 
1828*0Sstevel@tonic-gate 	/* build args */
1829*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
1830*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_getset_2_args_u.rev1;
1831*0Sstevel@tonic-gate 	args->setname = setname;
1832*0Sstevel@tonic-gate 	args->setno   = setno;
1833*0Sstevel@tonic-gate 
1834*0Sstevel@tonic-gate 	/* do it */
1835*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
1836*0Sstevel@tonic-gate 		short_circuit_getset(args, &res);
1837*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
1838*0Sstevel@tonic-gate 	} else {
1839*0Sstevel@tonic-gate 	    if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL) {
1840*0Sstevel@tonic-gate 		/*
1841*0Sstevel@tonic-gate 		 * This has to work during the boot up before the rpc.metad can
1842*0Sstevel@tonic-gate 		 * run.  Check to see if we can handle this as a strictly local
1843*0Sstevel@tonic-gate 		 * diskset.
1844*0Sstevel@tonic-gate 		 */
1845*0Sstevel@tonic-gate 		if (is_auto_take_set(setname, setno)) {
1846*0Sstevel@tonic-gate 		    mdclrerror(ep);
1847*0Sstevel@tonic-gate 		    short_circuit_getset(args, &res);
1848*0Sstevel@tonic-gate 		    res.sr = setdup(res.sr);
1849*0Sstevel@tonic-gate 		    (void) mdstealerror(ep, &res.status);
1850*0Sstevel@tonic-gate 		} else {
1851*0Sstevel@tonic-gate 		    return (-1);
1852*0Sstevel@tonic-gate 		}
1853*0Sstevel@tonic-gate 	    } else {
1854*0Sstevel@tonic-gate 
1855*0Sstevel@tonic-gate 		/*
1856*0Sstevel@tonic-gate 		 * Check the client handle for the version
1857*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
1858*0Sstevel@tonic-gate 		 * remote procedure
1859*0Sstevel@tonic-gate 		 */
1860*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
1861*0Sstevel@tonic-gate 
1862*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
1863*0Sstevel@tonic-gate 			if (mdrpc_getset_1(args, &res, clntp) != RPC_SUCCESS)
1864*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1865*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad get set"));
1866*0Sstevel@tonic-gate 			else
1867*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1868*0Sstevel@tonic-gate 		} else {
1869*0Sstevel@tonic-gate 			if (mdrpc_getset_2(&v2_args, &res, clntp) !=
1870*0Sstevel@tonic-gate 			    RPC_SUCCESS)
1871*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1872*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad get set"));
1873*0Sstevel@tonic-gate 			else
1874*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1875*0Sstevel@tonic-gate 		}
1876*0Sstevel@tonic-gate 
1877*0Sstevel@tonic-gate 		metarpcclose(clntp);
1878*0Sstevel@tonic-gate 	    }
1879*0Sstevel@tonic-gate 	}
1880*0Sstevel@tonic-gate 
1881*0Sstevel@tonic-gate 	if (mdisok(ep)) {
1882*0Sstevel@tonic-gate 		rval = 0;
1883*0Sstevel@tonic-gate 		if (ret_sr != NULL)
1884*0Sstevel@tonic-gate 			*ret_sr = res.sr;
1885*0Sstevel@tonic-gate 		else
1886*0Sstevel@tonic-gate 			if (! md_in_daemon)
1887*0Sstevel@tonic-gate 				xdr_free(xdr_mdrpc_getset_res, (char *)&res);
1888*0Sstevel@tonic-gate 	}
1889*0Sstevel@tonic-gate 
1890*0Sstevel@tonic-gate 	return (rval);
1891*0Sstevel@tonic-gate }
1892*0Sstevel@tonic-gate 
1893*0Sstevel@tonic-gate /*
1894*0Sstevel@tonic-gate  * return the multi-node diskset record, drive records and node records.
1895*0Sstevel@tonic-gate  */
1896*0Sstevel@tonic-gate clnt_mngetset(
1897*0Sstevel@tonic-gate 	char			*hostname,
1898*0Sstevel@tonic-gate 	char			*setname,
1899*0Sstevel@tonic-gate 	set_t			setno,
1900*0Sstevel@tonic-gate 	md_mnset_record		**ret_mnsr,
1901*0Sstevel@tonic-gate 	md_error_t		*ep
1902*0Sstevel@tonic-gate )
1903*0Sstevel@tonic-gate {
1904*0Sstevel@tonic-gate 	CLIENT			*clntp;
1905*0Sstevel@tonic-gate 	mdrpc_getset_args	*args;
1906*0Sstevel@tonic-gate 	mdrpc_getset_2_args	v2_args;
1907*0Sstevel@tonic-gate 	mdrpc_mngetset_res	res;
1908*0Sstevel@tonic-gate 	int			rval = -1;
1909*0Sstevel@tonic-gate 	int			version;
1910*0Sstevel@tonic-gate 
1911*0Sstevel@tonic-gate 	/* initialize */
1912*0Sstevel@tonic-gate 	mdclrerror(ep);
1913*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
1914*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
1915*0Sstevel@tonic-gate 
1916*0Sstevel@tonic-gate 	/* build args */
1917*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
1918*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_getset_2_args_u.rev1;
1919*0Sstevel@tonic-gate 	args->setname = setname;
1920*0Sstevel@tonic-gate 	args->setno   = setno;
1921*0Sstevel@tonic-gate 
1922*0Sstevel@tonic-gate 	/* do it */
1923*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
1924*0Sstevel@tonic-gate 		short_circuit_mngetset(args, &res);
1925*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
1926*0Sstevel@tonic-gate 	} else {
1927*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
1928*0Sstevel@tonic-gate 			return (-1);
1929*0Sstevel@tonic-gate 
1930*0Sstevel@tonic-gate 		/*
1931*0Sstevel@tonic-gate 		 * Check the client handle for the version
1932*0Sstevel@tonic-gate 		 */
1933*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
1934*0Sstevel@tonic-gate 
1935*0Sstevel@tonic-gate 		/*
1936*0Sstevel@tonic-gate 		 * If the client is version 1, return error
1937*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
1938*0Sstevel@tonic-gate 		 */
1939*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
1940*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
1941*0Sstevel@tonic-gate 				setno, hostname, NULL, setname);
1942*0Sstevel@tonic-gate 			metarpcclose(clntp);
1943*0Sstevel@tonic-gate 			return (-1);
1944*0Sstevel@tonic-gate 		} else {
1945*0Sstevel@tonic-gate 			if (mdrpc_mngetset_2(&v2_args, &res, clntp)
1946*0Sstevel@tonic-gate 							!= RPC_SUCCESS)
1947*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
1948*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad mn get set"));
1949*0Sstevel@tonic-gate 			else
1950*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
1951*0Sstevel@tonic-gate 		}
1952*0Sstevel@tonic-gate 
1953*0Sstevel@tonic-gate 		metarpcclose(clntp);
1954*0Sstevel@tonic-gate 	}
1955*0Sstevel@tonic-gate 
1956*0Sstevel@tonic-gate 	/* If no ep error and no version mismatch - rpc call worked ok */
1957*0Sstevel@tonic-gate 	if (mdisok(ep)) {
1958*0Sstevel@tonic-gate 		rval = 0;
1959*0Sstevel@tonic-gate 		if (ret_mnsr != NULL)
1960*0Sstevel@tonic-gate 			*ret_mnsr = res.mnsr;
1961*0Sstevel@tonic-gate 		else
1962*0Sstevel@tonic-gate 			if (! md_in_daemon)
1963*0Sstevel@tonic-gate 				xdr_free(xdr_mdrpc_mngetset_res, (char *)&res);
1964*0Sstevel@tonic-gate 	}
1965*0Sstevel@tonic-gate 
1966*0Sstevel@tonic-gate 	return (rval);
1967*0Sstevel@tonic-gate }
1968*0Sstevel@tonic-gate 
1969*0Sstevel@tonic-gate /*
1970*0Sstevel@tonic-gate  * Set master nodeid and nodename in multi-node set record.
1971*0Sstevel@tonic-gate  */
1972*0Sstevel@tonic-gate clnt_mnsetmaster(
1973*0Sstevel@tonic-gate 	char			*hostname,
1974*0Sstevel@tonic-gate 	mdsetname_t		*sp,
1975*0Sstevel@tonic-gate 	md_node_nm_t		master_nodenm,
1976*0Sstevel@tonic-gate 	int			master_nodeid,
1977*0Sstevel@tonic-gate 	md_error_t		*ep
1978*0Sstevel@tonic-gate )
1979*0Sstevel@tonic-gate {
1980*0Sstevel@tonic-gate 	CLIENT			*clntp;
1981*0Sstevel@tonic-gate 	mdrpc_mnsetmaster_args	*args;
1982*0Sstevel@tonic-gate 	mdrpc_mnsetmaster_2_args	v2_args;
1983*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
1984*0Sstevel@tonic-gate 	int			version;
1985*0Sstevel@tonic-gate 
1986*0Sstevel@tonic-gate 	/* initialize */
1987*0Sstevel@tonic-gate 	mdclrerror(ep);
1988*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
1989*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
1990*0Sstevel@tonic-gate 
1991*0Sstevel@tonic-gate 	/* build args */
1992*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
1993*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_mnsetmaster_2_args_u.rev1;
1994*0Sstevel@tonic-gate 	args->sp = sp;
1995*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
1996*0Sstevel@tonic-gate 	(void) strlcpy(args->master_nodenm, master_nodenm, MD_MAX_NODENAME);
1997*0Sstevel@tonic-gate 	args->master_nodeid = master_nodeid;
1998*0Sstevel@tonic-gate 
1999*0Sstevel@tonic-gate 	/* do it */
2000*0Sstevel@tonic-gate 	if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
2001*0Sstevel@tonic-gate 		return (-1);
2002*0Sstevel@tonic-gate 
2003*0Sstevel@tonic-gate 	/*
2004*0Sstevel@tonic-gate 	 * Check the client handle for the version
2005*0Sstevel@tonic-gate 	 */
2006*0Sstevel@tonic-gate 	CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
2007*0Sstevel@tonic-gate 
2008*0Sstevel@tonic-gate 	/*
2009*0Sstevel@tonic-gate 	 * If the client is version 1, return error
2010*0Sstevel@tonic-gate 	 * otherwise, make the remote procedure call.
2011*0Sstevel@tonic-gate 	 */
2012*0Sstevel@tonic-gate 	if (version == METAD_VERSION) { /* version 1 */
2013*0Sstevel@tonic-gate 		(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
2014*0Sstevel@tonic-gate 			sp->setno, hostname, NULL, sp->setname);
2015*0Sstevel@tonic-gate 		metarpcclose(clntp);
2016*0Sstevel@tonic-gate 		return (-1);
2017*0Sstevel@tonic-gate 	} else {
2018*0Sstevel@tonic-gate 		if (mdrpc_mnsetmaster_2(&v2_args, &res, clntp) != RPC_SUCCESS)
2019*0Sstevel@tonic-gate 			(void) mdrpcerror(ep, clntp, hostname,
2020*0Sstevel@tonic-gate 			dgettext(TEXT_DOMAIN, "metad multi-owner set master"));
2021*0Sstevel@tonic-gate 		else
2022*0Sstevel@tonic-gate 			(void) mdstealerror(ep, &res.status);
2023*0Sstevel@tonic-gate 	}
2024*0Sstevel@tonic-gate 
2025*0Sstevel@tonic-gate 	metarpcclose(clntp);
2026*0Sstevel@tonic-gate 
2027*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
2028*0Sstevel@tonic-gate 
2029*0Sstevel@tonic-gate 	if (! mdisok(ep))
2030*0Sstevel@tonic-gate 		return (-1);
2031*0Sstevel@tonic-gate 
2032*0Sstevel@tonic-gate 	return (0);
2033*0Sstevel@tonic-gate }
2034*0Sstevel@tonic-gate 
2035*0Sstevel@tonic-gate /*
2036*0Sstevel@tonic-gate  * Get the MH timeout values.
2037*0Sstevel@tonic-gate  */
2038*0Sstevel@tonic-gate int
2039*0Sstevel@tonic-gate clnt_gtimeout(
2040*0Sstevel@tonic-gate 	char			*hostname,
2041*0Sstevel@tonic-gate 	mdsetname_t		*sp,
2042*0Sstevel@tonic-gate 	mhd_mhiargs_t		*ret_mhiargs,
2043*0Sstevel@tonic-gate 	md_error_t		*ep
2044*0Sstevel@tonic-gate )
2045*0Sstevel@tonic-gate {
2046*0Sstevel@tonic-gate 	CLIENT			*clntp;
2047*0Sstevel@tonic-gate 	mdrpc_sp_args		*args;
2048*0Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
2049*0Sstevel@tonic-gate 	mdrpc_gtimeout_res	res;
2050*0Sstevel@tonic-gate 	int			rval = -1;
2051*0Sstevel@tonic-gate 	int			version;
2052*0Sstevel@tonic-gate 
2053*0Sstevel@tonic-gate 	/* initialize */
2054*0Sstevel@tonic-gate 	mdclrerror(ep);
2055*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
2056*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
2057*0Sstevel@tonic-gate 
2058*0Sstevel@tonic-gate 	/* build args */
2059*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
2060*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
2061*0Sstevel@tonic-gate 	args->sp = sp;
2062*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
2063*0Sstevel@tonic-gate 
2064*0Sstevel@tonic-gate 	/* do it */
2065*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
2066*0Sstevel@tonic-gate 		int	bool;
2067*0Sstevel@tonic-gate 		bool = mdrpc_gtimeout_2_svc(&v2_args, &res, NULL);
2068*0Sstevel@tonic-gate 		assert(bool == TRUE);
2069*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
2070*0Sstevel@tonic-gate 	} else {
2071*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
2072*0Sstevel@tonic-gate 			return (-1);
2073*0Sstevel@tonic-gate 
2074*0Sstevel@tonic-gate 		/*
2075*0Sstevel@tonic-gate 		 * Check the client handle for the version
2076*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
2077*0Sstevel@tonic-gate 		 * remote procedure
2078*0Sstevel@tonic-gate 		 */
2079*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
2080*0Sstevel@tonic-gate 
2081*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
2082*0Sstevel@tonic-gate 			if (mdrpc_gtimeout_1(args, &res, clntp) != RPC_SUCCESS)
2083*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2084*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad get timeout"));
2085*0Sstevel@tonic-gate 			else
2086*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2087*0Sstevel@tonic-gate 		} else {
2088*0Sstevel@tonic-gate 			if (mdrpc_gtimeout_2(&v2_args, &res, clntp) !=
2089*0Sstevel@tonic-gate 			    RPC_SUCCESS)
2090*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2091*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad get timeout"));
2092*0Sstevel@tonic-gate 			else
2093*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2094*0Sstevel@tonic-gate 		}
2095*0Sstevel@tonic-gate 
2096*0Sstevel@tonic-gate 		metarpcclose(clntp);
2097*0Sstevel@tonic-gate 	}
2098*0Sstevel@tonic-gate 
2099*0Sstevel@tonic-gate 	if (mdisok(ep)) {
2100*0Sstevel@tonic-gate 
2101*0Sstevel@tonic-gate 		/* do something with the results */
2102*0Sstevel@tonic-gate 		rval = 0;
2103*0Sstevel@tonic-gate 
2104*0Sstevel@tonic-gate 		/* copy md_mhiargs_t */
2105*0Sstevel@tonic-gate 		if (ret_mhiargs != NULL)
2106*0Sstevel@tonic-gate 			*ret_mhiargs = *res.mhiargsp;
2107*0Sstevel@tonic-gate 	}
2108*0Sstevel@tonic-gate 
2109*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_gtimeout_res, (char *)&res);
2110*0Sstevel@tonic-gate 
2111*0Sstevel@tonic-gate 	return (rval);
2112*0Sstevel@tonic-gate }
2113*0Sstevel@tonic-gate 
2114*0Sstevel@tonic-gate /*
2115*0Sstevel@tonic-gate  * get real hostname from remote host
2116*0Sstevel@tonic-gate  */
2117*0Sstevel@tonic-gate int
2118*0Sstevel@tonic-gate clnt_hostname(
2119*0Sstevel@tonic-gate 	char			*hostname,
2120*0Sstevel@tonic-gate 	char			**ret_hostname,
2121*0Sstevel@tonic-gate 	md_error_t		*ep
2122*0Sstevel@tonic-gate )
2123*0Sstevel@tonic-gate {
2124*0Sstevel@tonic-gate 	CLIENT			*clntp;
2125*0Sstevel@tonic-gate 	mdrpc_null_args		args;
2126*0Sstevel@tonic-gate 	mdrpc_hostname_res	res;
2127*0Sstevel@tonic-gate 	int			rval = -1;
2128*0Sstevel@tonic-gate 
2129*0Sstevel@tonic-gate 	/* initialize */
2130*0Sstevel@tonic-gate 	mdclrerror(ep);
2131*0Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
2132*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
2133*0Sstevel@tonic-gate 
2134*0Sstevel@tonic-gate 	/* build args */
2135*0Sstevel@tonic-gate 	args.cl_sk = NULL;
2136*0Sstevel@tonic-gate 
2137*0Sstevel@tonic-gate 	/* do it */
2138*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
2139*0Sstevel@tonic-gate 		int	bool;
2140*0Sstevel@tonic-gate 		bool = mdrpc_hostname_1_svc(&args, &res, NULL);
2141*0Sstevel@tonic-gate 		assert(bool == TRUE);
2142*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
2143*0Sstevel@tonic-gate 	} else {
2144*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
2145*0Sstevel@tonic-gate 			return (-1);
2146*0Sstevel@tonic-gate 
2147*0Sstevel@tonic-gate 		if (mdrpc_hostname_1(&args, &res, clntp) != RPC_SUCCESS)
2148*0Sstevel@tonic-gate 			(void) mdrpcerror(ep, clntp, hostname,
2149*0Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad hostname"));
2150*0Sstevel@tonic-gate 		else
2151*0Sstevel@tonic-gate 			(void) mdstealerror(ep, &res.status);
2152*0Sstevel@tonic-gate 
2153*0Sstevel@tonic-gate 		metarpcclose(clntp);
2154*0Sstevel@tonic-gate 	}
2155*0Sstevel@tonic-gate 
2156*0Sstevel@tonic-gate 	if (mdisok(ep)) {
2157*0Sstevel@tonic-gate 		/* do something with the results */
2158*0Sstevel@tonic-gate 		rval = 0;
2159*0Sstevel@tonic-gate 
2160*0Sstevel@tonic-gate 		if (ret_hostname != NULL)
2161*0Sstevel@tonic-gate 			*ret_hostname = Strdup(res.hostname);
2162*0Sstevel@tonic-gate 	}
2163*0Sstevel@tonic-gate 
2164*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_hostname_res, (char *)&res);
2165*0Sstevel@tonic-gate 
2166*0Sstevel@tonic-gate 	return (rval);
2167*0Sstevel@tonic-gate }
2168*0Sstevel@tonic-gate 
2169*0Sstevel@tonic-gate /*
2170*0Sstevel@tonic-gate  * NULLPROC - just returns a response
2171*0Sstevel@tonic-gate  */
2172*0Sstevel@tonic-gate int
2173*0Sstevel@tonic-gate clnt_nullproc(
2174*0Sstevel@tonic-gate 	char			*hostname,
2175*0Sstevel@tonic-gate 	md_error_t		*ep
2176*0Sstevel@tonic-gate )
2177*0Sstevel@tonic-gate {
2178*0Sstevel@tonic-gate 	CLIENT			*clntp;
2179*0Sstevel@tonic-gate 
2180*0Sstevel@tonic-gate 	/* initialize */
2181*0Sstevel@tonic-gate 	mdclrerror(ep);
2182*0Sstevel@tonic-gate 
2183*0Sstevel@tonic-gate 	/* do it */
2184*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
2185*0Sstevel@tonic-gate 		int	bool;
2186*0Sstevel@tonic-gate 		bool = mdrpc_nullproc_1_svc(NULL, ep, NULL);
2187*0Sstevel@tonic-gate 		assert(bool == TRUE);
2188*0Sstevel@tonic-gate 	} else {
2189*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_DEF_TMO, ep)) == NULL)
2190*0Sstevel@tonic-gate 			return (-1);
2191*0Sstevel@tonic-gate 
2192*0Sstevel@tonic-gate 		if (mdrpc_nullproc_1(NULL, ep, clntp) != RPC_SUCCESS)
2193*0Sstevel@tonic-gate 			(void) mdrpcerror(ep, clntp, hostname,
2194*0Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad nullproc"));
2195*0Sstevel@tonic-gate 
2196*0Sstevel@tonic-gate 		metarpcclose(clntp);
2197*0Sstevel@tonic-gate 	}
2198*0Sstevel@tonic-gate 
2199*0Sstevel@tonic-gate 	if (! mdisok(ep))
2200*0Sstevel@tonic-gate 		return (-1);
2201*0Sstevel@tonic-gate 
2202*0Sstevel@tonic-gate 	return (0);
2203*0Sstevel@tonic-gate }
2204*0Sstevel@tonic-gate 
2205*0Sstevel@tonic-gate /*
2206*0Sstevel@tonic-gate  * does host own the set?
2207*0Sstevel@tonic-gate  */
2208*0Sstevel@tonic-gate int
2209*0Sstevel@tonic-gate clnt_ownset(
2210*0Sstevel@tonic-gate 	char			*hostname,
2211*0Sstevel@tonic-gate 	mdsetname_t		*sp,
2212*0Sstevel@tonic-gate 	int			*ret_bool,
2213*0Sstevel@tonic-gate 	md_error_t		*ep
2214*0Sstevel@tonic-gate )
2215*0Sstevel@tonic-gate {
2216*0Sstevel@tonic-gate 	CLIENT			*clntp;
2217*0Sstevel@tonic-gate 	mdrpc_sp_args		*args;
2218*0Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
2219*0Sstevel@tonic-gate 	mdrpc_bool_res		res;
2220*0Sstevel@tonic-gate 	int			rval = -1;
2221*0Sstevel@tonic-gate 	int			version;
2222*0Sstevel@tonic-gate 
2223*0Sstevel@tonic-gate 	/* initialize */
2224*0Sstevel@tonic-gate 	mdclrerror(ep);
2225*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
2226*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
2227*0Sstevel@tonic-gate 
2228*0Sstevel@tonic-gate 	/* build args */
2229*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
2230*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
2231*0Sstevel@tonic-gate 	args->sp = sp;
2232*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
2233*0Sstevel@tonic-gate 
2234*0Sstevel@tonic-gate 	/* do it */
2235*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
2236*0Sstevel@tonic-gate 		int	bool;
2237*0Sstevel@tonic-gate 		bool = mdrpc_ownset_2_svc(&v2_args, &res, NULL);
2238*0Sstevel@tonic-gate 		assert(bool == TRUE);
2239*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
2240*0Sstevel@tonic-gate 	} else {
2241*0Sstevel@tonic-gate 	    if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL) {
2242*0Sstevel@tonic-gate 		/*
2243*0Sstevel@tonic-gate 		 * This has to work in the code path from libpreen which is
2244*0Sstevel@tonic-gate 		 * running within fsck before the rpc.metad can run.  Check
2245*0Sstevel@tonic-gate 		 * to see if we should handle this as an auto-take diskset.
2246*0Sstevel@tonic-gate 		 */
2247*0Sstevel@tonic-gate 		if (is_auto_take_set(sp->setname, sp->setno)) {
2248*0Sstevel@tonic-gate 		    /* Can't call mdrpc_ownset_2_svc since not in daemon */
2249*0Sstevel@tonic-gate 		    mdclrerror(ep);
2250*0Sstevel@tonic-gate 		    if (s_ownset(sp->setno, ep))
2251*0Sstevel@tonic-gate 			res.value = TRUE;
2252*0Sstevel@tonic-gate 		    else
2253*0Sstevel@tonic-gate 			res.value = FALSE;
2254*0Sstevel@tonic-gate 		} else {
2255*0Sstevel@tonic-gate 		    return (-1);
2256*0Sstevel@tonic-gate 		}
2257*0Sstevel@tonic-gate 
2258*0Sstevel@tonic-gate 	    } else {
2259*0Sstevel@tonic-gate 
2260*0Sstevel@tonic-gate 		/*
2261*0Sstevel@tonic-gate 		 * Check the client handle for the version
2262*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
2263*0Sstevel@tonic-gate 		 * remote procedure
2264*0Sstevel@tonic-gate 		 */
2265*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
2266*0Sstevel@tonic-gate 
2267*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
2268*0Sstevel@tonic-gate 			if (mdrpc_ownset_1(args, &res, clntp) != RPC_SUCCESS)
2269*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2270*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad own set"));
2271*0Sstevel@tonic-gate 			else
2272*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2273*0Sstevel@tonic-gate 		} else {
2274*0Sstevel@tonic-gate 			if (mdrpc_ownset_2(&v2_args, &res, clntp) !=
2275*0Sstevel@tonic-gate 			    RPC_SUCCESS)
2276*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2277*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad own set"));
2278*0Sstevel@tonic-gate 			else
2279*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2280*0Sstevel@tonic-gate 		}
2281*0Sstevel@tonic-gate 
2282*0Sstevel@tonic-gate 		metarpcclose(clntp);
2283*0Sstevel@tonic-gate 	    }
2284*0Sstevel@tonic-gate 	}
2285*0Sstevel@tonic-gate 
2286*0Sstevel@tonic-gate 	if (mdisok(ep)) {
2287*0Sstevel@tonic-gate 		/* do something with the results */
2288*0Sstevel@tonic-gate 		rval = 0;
2289*0Sstevel@tonic-gate 
2290*0Sstevel@tonic-gate 		if (ret_bool != NULL)
2291*0Sstevel@tonic-gate 			*ret_bool = res.value;
2292*0Sstevel@tonic-gate 	}
2293*0Sstevel@tonic-gate 
2294*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_bool_res, (char *)&res);
2295*0Sstevel@tonic-gate 
2296*0Sstevel@tonic-gate 	return (rval);
2297*0Sstevel@tonic-gate }
2298*0Sstevel@tonic-gate 
2299*0Sstevel@tonic-gate /*
2300*0Sstevel@tonic-gate  * Valid set name.
2301*0Sstevel@tonic-gate  */
2302*0Sstevel@tonic-gate int
2303*0Sstevel@tonic-gate clnt_setnameok(
2304*0Sstevel@tonic-gate 	char			*hostname,
2305*0Sstevel@tonic-gate 	mdsetname_t		*sp,
2306*0Sstevel@tonic-gate 	int			*ret_bool,
2307*0Sstevel@tonic-gate 	md_error_t		*ep
2308*0Sstevel@tonic-gate )
2309*0Sstevel@tonic-gate {
2310*0Sstevel@tonic-gate 	CLIENT			*clntp;
2311*0Sstevel@tonic-gate 	mdrpc_sp_args		*args;
2312*0Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
2313*0Sstevel@tonic-gate 	mdrpc_bool_res		res;
2314*0Sstevel@tonic-gate 	int			rval = -1;
2315*0Sstevel@tonic-gate 	int			version;
2316*0Sstevel@tonic-gate 
2317*0Sstevel@tonic-gate 	/* initialize */
2318*0Sstevel@tonic-gate 	mdclrerror(ep);
2319*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
2320*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
2321*0Sstevel@tonic-gate 
2322*0Sstevel@tonic-gate 	/* build args */
2323*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
2324*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
2325*0Sstevel@tonic-gate 	args->sp = sp;
2326*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
2327*0Sstevel@tonic-gate 
2328*0Sstevel@tonic-gate 	/* do it */
2329*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
2330*0Sstevel@tonic-gate 		int	bool;
2331*0Sstevel@tonic-gate 		bool = mdrpc_setnameok_2_svc(&v2_args, &res, NULL);
2332*0Sstevel@tonic-gate 		assert(bool == TRUE);
2333*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
2334*0Sstevel@tonic-gate 	} else {
2335*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
2336*0Sstevel@tonic-gate 			return (-1);
2337*0Sstevel@tonic-gate 
2338*0Sstevel@tonic-gate 		/*
2339*0Sstevel@tonic-gate 		 * Check the client handle for the version
2340*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
2341*0Sstevel@tonic-gate 		 * remote procedure
2342*0Sstevel@tonic-gate 		 */
2343*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
2344*0Sstevel@tonic-gate 
2345*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
2346*0Sstevel@tonic-gate 			if (mdrpc_setnameok_1(args, &res, clntp) != RPC_SUCCESS)
2347*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2348*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad setname ok"));
2349*0Sstevel@tonic-gate 			else
2350*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2351*0Sstevel@tonic-gate 		} else {
2352*0Sstevel@tonic-gate 			if (mdrpc_setnameok_2(&v2_args, &res, clntp) !=
2353*0Sstevel@tonic-gate 			    RPC_SUCCESS)
2354*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2355*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad setname ok"));
2356*0Sstevel@tonic-gate 			else
2357*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2358*0Sstevel@tonic-gate 		}
2359*0Sstevel@tonic-gate 
2360*0Sstevel@tonic-gate 		metarpcclose(clntp);
2361*0Sstevel@tonic-gate 	}
2362*0Sstevel@tonic-gate 
2363*0Sstevel@tonic-gate 	if (mdisok(ep)) {
2364*0Sstevel@tonic-gate 		/* do something with the results */
2365*0Sstevel@tonic-gate 		rval = 0;
2366*0Sstevel@tonic-gate 
2367*0Sstevel@tonic-gate 		if (ret_bool != NULL)
2368*0Sstevel@tonic-gate 			*ret_bool = res.value;
2369*0Sstevel@tonic-gate 	}
2370*0Sstevel@tonic-gate 
2371*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_bool_res, (char *)&res);
2372*0Sstevel@tonic-gate 
2373*0Sstevel@tonic-gate 	return (rval);
2374*0Sstevel@tonic-gate }
2375*0Sstevel@tonic-gate 
2376*0Sstevel@tonic-gate /*
2377*0Sstevel@tonic-gate  * Is set number in-use?
2378*0Sstevel@tonic-gate  */
2379*0Sstevel@tonic-gate int
2380*0Sstevel@tonic-gate clnt_setnumbusy(
2381*0Sstevel@tonic-gate 	char			*hostname,
2382*0Sstevel@tonic-gate 	set_t			setno,
2383*0Sstevel@tonic-gate 	int			*ret_bool,
2384*0Sstevel@tonic-gate 	md_error_t		*ep
2385*0Sstevel@tonic-gate )
2386*0Sstevel@tonic-gate {
2387*0Sstevel@tonic-gate 	CLIENT			*clntp;
2388*0Sstevel@tonic-gate 	mdrpc_setno_args	*args;
2389*0Sstevel@tonic-gate 	mdrpc_setno_2_args	v2_args;
2390*0Sstevel@tonic-gate 	mdrpc_bool_res		res;
2391*0Sstevel@tonic-gate 	int			rval = -1;
2392*0Sstevel@tonic-gate 	int			version;
2393*0Sstevel@tonic-gate 
2394*0Sstevel@tonic-gate 	/* initialize */
2395*0Sstevel@tonic-gate 	mdclrerror(ep);
2396*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
2397*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
2398*0Sstevel@tonic-gate 
2399*0Sstevel@tonic-gate 	/* build args */
2400*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
2401*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_setno_2_args_u.rev1;
2402*0Sstevel@tonic-gate 	args->setno = setno;
2403*0Sstevel@tonic-gate 	args->cl_sk = NULL;
2404*0Sstevel@tonic-gate 
2405*0Sstevel@tonic-gate 	/* do it */
2406*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
2407*0Sstevel@tonic-gate 		int	bool;
2408*0Sstevel@tonic-gate 		bool = mdrpc_setnumbusy_2_svc(&v2_args, &res, NULL);
2409*0Sstevel@tonic-gate 		assert(bool == TRUE);
2410*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
2411*0Sstevel@tonic-gate 	} else {
2412*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
2413*0Sstevel@tonic-gate 			return (-1);
2414*0Sstevel@tonic-gate 
2415*0Sstevel@tonic-gate 		/*
2416*0Sstevel@tonic-gate 		 * Check the client handle for the version
2417*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
2418*0Sstevel@tonic-gate 		 * remote procedure
2419*0Sstevel@tonic-gate 		 */
2420*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
2421*0Sstevel@tonic-gate 
2422*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
2423*0Sstevel@tonic-gate 			if (mdrpc_setnumbusy_1(args, &res, clntp) !=
2424*0Sstevel@tonic-gate 			    RPC_SUCCESS)
2425*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2426*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad setnumber busy"));
2427*0Sstevel@tonic-gate 			else
2428*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2429*0Sstevel@tonic-gate 		} else {
2430*0Sstevel@tonic-gate 			if (mdrpc_setnumbusy_2(&v2_args, &res, clntp) !=
2431*0Sstevel@tonic-gate 			    RPC_SUCCESS)
2432*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2433*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad setnumber busy"));
2434*0Sstevel@tonic-gate 			else
2435*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2436*0Sstevel@tonic-gate 		}
2437*0Sstevel@tonic-gate 
2438*0Sstevel@tonic-gate 		metarpcclose(clntp);
2439*0Sstevel@tonic-gate 	}
2440*0Sstevel@tonic-gate 
2441*0Sstevel@tonic-gate 	if (mdisok(ep)) {
2442*0Sstevel@tonic-gate 		/* do something with the results */
2443*0Sstevel@tonic-gate 		rval = 0;
2444*0Sstevel@tonic-gate 
2445*0Sstevel@tonic-gate 		if (ret_bool != NULL)
2446*0Sstevel@tonic-gate 			*ret_bool = res.value;
2447*0Sstevel@tonic-gate 	}
2448*0Sstevel@tonic-gate 
2449*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_bool_res, (char *)&res);
2450*0Sstevel@tonic-gate 
2451*0Sstevel@tonic-gate 	return (rval);
2452*0Sstevel@tonic-gate }
2453*0Sstevel@tonic-gate 
2454*0Sstevel@tonic-gate /*
2455*0Sstevel@tonic-gate  * Set the timeout values used into the drive records.
2456*0Sstevel@tonic-gate  */
2457*0Sstevel@tonic-gate int
2458*0Sstevel@tonic-gate clnt_stimeout(
2459*0Sstevel@tonic-gate 	char			*hostname,
2460*0Sstevel@tonic-gate 	mdsetname_t		*sp,
2461*0Sstevel@tonic-gate 	mhd_mhiargs_t		*mhiargsp,
2462*0Sstevel@tonic-gate 	md_error_t		*ep
2463*0Sstevel@tonic-gate )
2464*0Sstevel@tonic-gate {
2465*0Sstevel@tonic-gate 	CLIENT			*clntp;
2466*0Sstevel@tonic-gate 	mdrpc_stimeout_args	*args;
2467*0Sstevel@tonic-gate 	mdrpc_stimeout_2_args	v2_args;
2468*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
2469*0Sstevel@tonic-gate 	int			version;
2470*0Sstevel@tonic-gate 
2471*0Sstevel@tonic-gate 	/* initialize */
2472*0Sstevel@tonic-gate 	mdclrerror(ep);
2473*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
2474*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
2475*0Sstevel@tonic-gate 
2476*0Sstevel@tonic-gate 	/* build args */
2477*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
2478*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_stimeout_2_args_u.rev1;
2479*0Sstevel@tonic-gate 	args->sp = sp;
2480*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
2481*0Sstevel@tonic-gate 	args->mhiargsp = mhiargsp;
2482*0Sstevel@tonic-gate 
2483*0Sstevel@tonic-gate 	/* do it */
2484*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
2485*0Sstevel@tonic-gate 		int	bool;
2486*0Sstevel@tonic-gate 		bool = mdrpc_stimeout_2_svc(&v2_args, &res, NULL);
2487*0Sstevel@tonic-gate 		assert(bool == TRUE);
2488*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
2489*0Sstevel@tonic-gate 	} else {
2490*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
2491*0Sstevel@tonic-gate 			return (-1);
2492*0Sstevel@tonic-gate 
2493*0Sstevel@tonic-gate 		/*
2494*0Sstevel@tonic-gate 		 * Check the client handle for the version
2495*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
2496*0Sstevel@tonic-gate 		 * remote procedure
2497*0Sstevel@tonic-gate 		 */
2498*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
2499*0Sstevel@tonic-gate 
2500*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
2501*0Sstevel@tonic-gate 			if (mdrpc_stimeout_1(args, &res, clntp) != RPC_SUCCESS)
2502*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2503*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad set timeout"));
2504*0Sstevel@tonic-gate 			else
2505*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2506*0Sstevel@tonic-gate 		} else {
2507*0Sstevel@tonic-gate 			if (mdrpc_stimeout_2(&v2_args, &res, clntp) !=
2508*0Sstevel@tonic-gate 			    RPC_SUCCESS)
2509*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2510*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad set timeout"));
2511*0Sstevel@tonic-gate 			else
2512*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2513*0Sstevel@tonic-gate 		}
2514*0Sstevel@tonic-gate 
2515*0Sstevel@tonic-gate 		metarpcclose(clntp);
2516*0Sstevel@tonic-gate 	}
2517*0Sstevel@tonic-gate 
2518*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
2519*0Sstevel@tonic-gate 
2520*0Sstevel@tonic-gate 	if (! mdisok(ep))
2521*0Sstevel@tonic-gate 		return (-1);
2522*0Sstevel@tonic-gate 
2523*0Sstevel@tonic-gate 	return (0);
2524*0Sstevel@tonic-gate }
2525*0Sstevel@tonic-gate 
2526*0Sstevel@tonic-gate /*
2527*0Sstevel@tonic-gate  * update drive records
2528*0Sstevel@tonic-gate  */
2529*0Sstevel@tonic-gate int
2530*0Sstevel@tonic-gate clnt_upd_dr_dbinfo(
2531*0Sstevel@tonic-gate 	char			*hostname,
2532*0Sstevel@tonic-gate 	mdsetname_t		*sp,
2533*0Sstevel@tonic-gate 	md_drive_desc		*dd,
2534*0Sstevel@tonic-gate 	md_error_t		*ep
2535*0Sstevel@tonic-gate )
2536*0Sstevel@tonic-gate {
2537*0Sstevel@tonic-gate 	CLIENT			*clntp;
2538*0Sstevel@tonic-gate 	mdrpc_drives_args	v1_args;
2539*0Sstevel@tonic-gate 	mdrpc_drives_2_args	v2_args;
2540*0Sstevel@tonic-gate 	mdrpc_drives_2_args_r1	*v21_args;
2541*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
2542*0Sstevel@tonic-gate 	int			rval;
2543*0Sstevel@tonic-gate 	int			version;
2544*0Sstevel@tonic-gate 
2545*0Sstevel@tonic-gate 	/* initialize */
2546*0Sstevel@tonic-gate 	mdclrerror(ep);
2547*0Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
2548*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
2549*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
2550*0Sstevel@tonic-gate 
2551*0Sstevel@tonic-gate 	/* build args */
2552*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
2553*0Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_drives_2_args_u.rev1;
2554*0Sstevel@tonic-gate 	v21_args->sp = sp;
2555*0Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
2556*0Sstevel@tonic-gate 	v21_args->drivedescs = dd;
2557*0Sstevel@tonic-gate 
2558*0Sstevel@tonic-gate 	/* do it */
2559*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
2560*0Sstevel@tonic-gate 		int	bool;
2561*0Sstevel@tonic-gate 
2562*0Sstevel@tonic-gate 		/*
2563*0Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
2564*0Sstevel@tonic-gate 		 */
2565*0Sstevel@tonic-gate 		bool = mdrpc_upd_dr_dbinfo_2_svc(&v2_args, &res, NULL);
2566*0Sstevel@tonic-gate 		assert(bool == TRUE);
2567*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
2568*0Sstevel@tonic-gate 	} else {
2569*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
2570*0Sstevel@tonic-gate 			return (-1);
2571*0Sstevel@tonic-gate 
2572*0Sstevel@tonic-gate 		/*
2573*0Sstevel@tonic-gate 		 * Check the client handle for the version
2574*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
2575*0Sstevel@tonic-gate 		 * remote procedure
2576*0Sstevel@tonic-gate 		 */
2577*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
2578*0Sstevel@tonic-gate 
2579*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
2580*0Sstevel@tonic-gate 
2581*0Sstevel@tonic-gate 			alloc_olddrvdesc(&v1_args.drivedescs, dd);
2582*0Sstevel@tonic-gate 
2583*0Sstevel@tonic-gate 			/* build args */
2584*0Sstevel@tonic-gate 			v1_args.sp = sp;
2585*0Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
2586*0Sstevel@tonic-gate 			meta_conv_drvdesc_new2old(v1_args.drivedescs, dd);
2587*0Sstevel@tonic-gate 
2588*0Sstevel@tonic-gate 			rval = mdrpc_upd_dr_dbinfo_1(&v1_args, &res, clntp);
2589*0Sstevel@tonic-gate 
2590*0Sstevel@tonic-gate 			free_olddrvdesc(v1_args.drivedescs);
2591*0Sstevel@tonic-gate 
2592*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
2593*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2594*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
2595*0Sstevel@tonic-gate 				    "metad update drive dbinfo"));
2596*0Sstevel@tonic-gate 			else
2597*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2598*0Sstevel@tonic-gate 		} else {			/* version 2 */
2599*0Sstevel@tonic-gate 			rval = mdrpc_upd_dr_dbinfo_2(&v2_args, &res, clntp);
2600*0Sstevel@tonic-gate 
2601*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
2602*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2603*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
2604*0Sstevel@tonic-gate 				    "metad update drive dbinfo"));
2605*0Sstevel@tonic-gate 			else
2606*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2607*0Sstevel@tonic-gate 		}
2608*0Sstevel@tonic-gate 
2609*0Sstevel@tonic-gate 		metarpcclose(clntp);
2610*0Sstevel@tonic-gate 	}
2611*0Sstevel@tonic-gate 
2612*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
2613*0Sstevel@tonic-gate 
2614*0Sstevel@tonic-gate 	if (! mdisok(ep))
2615*0Sstevel@tonic-gate 		return (-1);
2616*0Sstevel@tonic-gate 
2617*0Sstevel@tonic-gate 	return (0);
2618*0Sstevel@tonic-gate }
2619*0Sstevel@tonic-gate 
2620*0Sstevel@tonic-gate /*
2621*0Sstevel@tonic-gate  * update dr_flags field of drive record.
2622*0Sstevel@tonic-gate  */
2623*0Sstevel@tonic-gate int
2624*0Sstevel@tonic-gate clnt_upd_dr_flags(
2625*0Sstevel@tonic-gate 	char			*hostname,
2626*0Sstevel@tonic-gate 	mdsetname_t		*sp,
2627*0Sstevel@tonic-gate 	md_drive_desc		*dd,
2628*0Sstevel@tonic-gate 	uint_t			new_flags,
2629*0Sstevel@tonic-gate 	md_error_t		*ep
2630*0Sstevel@tonic-gate )
2631*0Sstevel@tonic-gate {
2632*0Sstevel@tonic-gate 	CLIENT				*clntp;
2633*0Sstevel@tonic-gate 	mdrpc_upd_dr_flags_args		v1_args;
2634*0Sstevel@tonic-gate 	mdrpc_upd_dr_flags_2_args	v2_args;
2635*0Sstevel@tonic-gate 	mdrpc_upd_dr_flags_2_args_r1	*v21_args;
2636*0Sstevel@tonic-gate 	mdrpc_generic_res		res;
2637*0Sstevel@tonic-gate 	int				rval;
2638*0Sstevel@tonic-gate 	int				version;
2639*0Sstevel@tonic-gate 
2640*0Sstevel@tonic-gate 	/* initialize */
2641*0Sstevel@tonic-gate 	mdclrerror(ep);
2642*0Sstevel@tonic-gate 	(void) memset(&v1_args, 0, sizeof (v1_args));
2643*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
2644*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
2645*0Sstevel@tonic-gate 
2646*0Sstevel@tonic-gate 	/* build args */
2647*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
2648*0Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_upd_dr_flags_2_args_u.rev1;
2649*0Sstevel@tonic-gate 	v21_args->sp = sp;
2650*0Sstevel@tonic-gate 	v21_args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
2651*0Sstevel@tonic-gate 	v21_args->drivedescs = dd;
2652*0Sstevel@tonic-gate 	v21_args->new_flags = new_flags;
2653*0Sstevel@tonic-gate 
2654*0Sstevel@tonic-gate 	/* do it */
2655*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
2656*0Sstevel@tonic-gate 		int	bool;
2657*0Sstevel@tonic-gate 
2658*0Sstevel@tonic-gate 		/*
2659*0Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
2660*0Sstevel@tonic-gate 		 */
2661*0Sstevel@tonic-gate 		bool = mdrpc_upd_dr_flags_2_svc(&v2_args, &res, NULL);
2662*0Sstevel@tonic-gate 		assert(bool == TRUE);
2663*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
2664*0Sstevel@tonic-gate 	} else {
2665*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
2666*0Sstevel@tonic-gate 			return (-1);
2667*0Sstevel@tonic-gate 
2668*0Sstevel@tonic-gate 		/*
2669*0Sstevel@tonic-gate 		 * Check the client handle for the version
2670*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
2671*0Sstevel@tonic-gate 		 * remote procedure
2672*0Sstevel@tonic-gate 		 */
2673*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
2674*0Sstevel@tonic-gate 
2675*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
2676*0Sstevel@tonic-gate 
2677*0Sstevel@tonic-gate 			alloc_olddrvdesc(&v1_args.drivedescs, dd);
2678*0Sstevel@tonic-gate 
2679*0Sstevel@tonic-gate 			/* build args */
2680*0Sstevel@tonic-gate 			v1_args.sp = sp;
2681*0Sstevel@tonic-gate 			v1_args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
2682*0Sstevel@tonic-gate 			meta_conv_drvdesc_new2old(v1_args.drivedescs, dd);
2683*0Sstevel@tonic-gate 			v1_args.new_flags = new_flags;
2684*0Sstevel@tonic-gate 
2685*0Sstevel@tonic-gate 			rval = mdrpc_upd_dr_flags_1(&v1_args, &res, clntp);
2686*0Sstevel@tonic-gate 
2687*0Sstevel@tonic-gate 			free_olddrvdesc(v1_args.drivedescs);
2688*0Sstevel@tonic-gate 
2689*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
2690*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2691*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
2692*0Sstevel@tonic-gate 				    "metad update drive flags"));
2693*0Sstevel@tonic-gate 			else
2694*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2695*0Sstevel@tonic-gate 		} else {			/* version 2 */
2696*0Sstevel@tonic-gate 			rval = mdrpc_upd_dr_flags_2(&v2_args, &res, clntp);
2697*0Sstevel@tonic-gate 
2698*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
2699*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
2700*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
2701*0Sstevel@tonic-gate 				    "metad update drive flags"));
2702*0Sstevel@tonic-gate 			else
2703*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2704*0Sstevel@tonic-gate 		}
2705*0Sstevel@tonic-gate 
2706*0Sstevel@tonic-gate 		metarpcclose(clntp);
2707*0Sstevel@tonic-gate 	}
2708*0Sstevel@tonic-gate 
2709*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
2710*0Sstevel@tonic-gate 
2711*0Sstevel@tonic-gate 	if (! mdisok(ep)) {
2712*0Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
2713*0Sstevel@tonic-gate 			return (-1);
2714*0Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
2715*0Sstevel@tonic-gate 			return (-1);
2716*0Sstevel@tonic-gate 		mdclrerror(ep);
2717*0Sstevel@tonic-gate 	}
2718*0Sstevel@tonic-gate 
2719*0Sstevel@tonic-gate 	return (0);
2720*0Sstevel@tonic-gate }
2721*0Sstevel@tonic-gate 
2722*0Sstevel@tonic-gate /*
2723*0Sstevel@tonic-gate  * update set record flags
2724*0Sstevel@tonic-gate  * This replaces all of the sr_flags with the new_flags.  It relies on the
2725*0Sstevel@tonic-gate  * caller to "do the right thing" to preserve the existing flags that should
2726*0Sstevel@tonic-gate  * not be reset.
2727*0Sstevel@tonic-gate  */
2728*0Sstevel@tonic-gate static int
2729*0Sstevel@tonic-gate upd_sr_flags_common(
2730*0Sstevel@tonic-gate 	char			*hostname,
2731*0Sstevel@tonic-gate 	mdsetname_t		*sp,
2732*0Sstevel@tonic-gate 	uint_t			new_flags,
2733*0Sstevel@tonic-gate 	md_error_t		*ep
2734*0Sstevel@tonic-gate )
2735*0Sstevel@tonic-gate {
2736*0Sstevel@tonic-gate 	CLIENT				*clntp;
2737*0Sstevel@tonic-gate 	mdrpc_upd_sr_flags_args		*args;
2738*0Sstevel@tonic-gate 	mdrpc_upd_sr_flags_2_args	v2_args;
2739*0Sstevel@tonic-gate 	mdrpc_generic_res		res;
2740*0Sstevel@tonic-gate 	int				version;
2741*0Sstevel@tonic-gate 
2742*0Sstevel@tonic-gate 	/* initialize */
2743*0Sstevel@tonic-gate 	mdclrerror(ep);
2744*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
2745*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
2746*0Sstevel@tonic-gate 
2747*0Sstevel@tonic-gate 	/* build args */
2748*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
2749*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_upd_sr_flags_2_args_u.rev1;
2750*0Sstevel@tonic-gate 	args->sp = sp;
2751*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
2752*0Sstevel@tonic-gate 
2753*0Sstevel@tonic-gate 	args->new_flags = new_flags;
2754*0Sstevel@tonic-gate 
2755*0Sstevel@tonic-gate 	/* do it */
2756*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
2757*0Sstevel@tonic-gate 		int	bool;
2758*0Sstevel@tonic-gate 		bool = mdrpc_upd_sr_flags_2_svc(&v2_args, &res, NULL);
2759*0Sstevel@tonic-gate 		assert(bool == TRUE);
2760*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
2761*0Sstevel@tonic-gate 	} else {
2762*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
2763*0Sstevel@tonic-gate 			return (-1);
2764*0Sstevel@tonic-gate 
2765*0Sstevel@tonic-gate 		/*
2766*0Sstevel@tonic-gate 		 * Check the client handle for the version
2767*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
2768*0Sstevel@tonic-gate 		 * remote procedure
2769*0Sstevel@tonic-gate 		 */
2770*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
2771*0Sstevel@tonic-gate 
2772*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
2773*0Sstevel@tonic-gate 			if (mdrpc_upd_sr_flags_1(args, &res, clntp) !=
2774*0Sstevel@tonic-gate 			    RPC_SUCCESS)
2775*0Sstevel@tonic-gate 			    (void) mdrpcerror(ep, clntp, hostname,
2776*0Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad update set flags"));
2777*0Sstevel@tonic-gate 			else
2778*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2779*0Sstevel@tonic-gate 		} else {
2780*0Sstevel@tonic-gate 			if (mdrpc_upd_sr_flags_2(&v2_args, &res, clntp) !=
2781*0Sstevel@tonic-gate 			    RPC_SUCCESS)
2782*0Sstevel@tonic-gate 			    (void) mdrpcerror(ep, clntp, hostname,
2783*0Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad update set flags"));
2784*0Sstevel@tonic-gate 			else
2785*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
2786*0Sstevel@tonic-gate 		}
2787*0Sstevel@tonic-gate 
2788*0Sstevel@tonic-gate 		metarpcclose(clntp);
2789*0Sstevel@tonic-gate 	}
2790*0Sstevel@tonic-gate 
2791*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
2792*0Sstevel@tonic-gate 
2793*0Sstevel@tonic-gate 	if (! mdisok(ep)) {
2794*0Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
2795*0Sstevel@tonic-gate 			return (-1);
2796*0Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
2797*0Sstevel@tonic-gate 			return (-1);
2798*0Sstevel@tonic-gate 		mdclrerror(ep);
2799*0Sstevel@tonic-gate 	}
2800*0Sstevel@tonic-gate 
2801*0Sstevel@tonic-gate 	return (0);
2802*0Sstevel@tonic-gate }
2803*0Sstevel@tonic-gate 
2804*0Sstevel@tonic-gate /*
2805*0Sstevel@tonic-gate  * Enable bits in the set record flags field.  This just turns on the specified
2806*0Sstevel@tonic-gate  * bits and leaves the other bits alone.
2807*0Sstevel@tonic-gate  */
2808*0Sstevel@tonic-gate int
2809*0Sstevel@tonic-gate clnt_enable_sr_flags(
2810*0Sstevel@tonic-gate 	char			*hostname,
2811*0Sstevel@tonic-gate 	mdsetname_t		*sp,
2812*0Sstevel@tonic-gate 	uint_t			flags,
2813*0Sstevel@tonic-gate 	md_error_t		*ep
2814*0Sstevel@tonic-gate )
2815*0Sstevel@tonic-gate {
2816*0Sstevel@tonic-gate 	uint_t		new_flags;
2817*0Sstevel@tonic-gate 	md_set_desc	*sd;
2818*0Sstevel@tonic-gate 
2819*0Sstevel@tonic-gate 	mdclrerror(ep);
2820*0Sstevel@tonic-gate 
2821*0Sstevel@tonic-gate 	/* Get the flags from the current set */
2822*0Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
2823*0Sstevel@tonic-gate 		return (-1);
2824*0Sstevel@tonic-gate 
2825*0Sstevel@tonic-gate 	/* Turn on the specified bits */
2826*0Sstevel@tonic-gate 	new_flags = (sd->sd_flags | flags);
2827*0Sstevel@tonic-gate 
2828*0Sstevel@tonic-gate 	/* do it */
2829*0Sstevel@tonic-gate 	return (upd_sr_flags_common(hostname, sp, new_flags, ep));
2830*0Sstevel@tonic-gate }
2831*0Sstevel@tonic-gate 
2832*0Sstevel@tonic-gate /*
2833*0Sstevel@tonic-gate  * Disable bits in the set record flags field.  This just turns off the
2834*0Sstevel@tonic-gate  * specified bits and leaves the other bits alone.
2835*0Sstevel@tonic-gate  */
2836*0Sstevel@tonic-gate int
2837*0Sstevel@tonic-gate clnt_disable_sr_flags(
2838*0Sstevel@tonic-gate 	char			*hostname,
2839*0Sstevel@tonic-gate 	mdsetname_t		*sp,
2840*0Sstevel@tonic-gate 	uint_t			flags,
2841*0Sstevel@tonic-gate 	md_error_t		*ep
2842*0Sstevel@tonic-gate )
2843*0Sstevel@tonic-gate {
2844*0Sstevel@tonic-gate 	uint_t		new_flags;
2845*0Sstevel@tonic-gate 	md_set_desc	*sd;
2846*0Sstevel@tonic-gate 
2847*0Sstevel@tonic-gate 	mdclrerror(ep);
2848*0Sstevel@tonic-gate 
2849*0Sstevel@tonic-gate 	/* Get the flags from the current set */
2850*0Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
2851*0Sstevel@tonic-gate 		return (-1);
2852*0Sstevel@tonic-gate 
2853*0Sstevel@tonic-gate 	/* Turn off the specified bits */
2854*0Sstevel@tonic-gate 	new_flags = (sd->sd_flags & ~flags);
2855*0Sstevel@tonic-gate 
2856*0Sstevel@tonic-gate 	/* do it */
2857*0Sstevel@tonic-gate 	return (upd_sr_flags_common(hostname, sp, new_flags, ep));
2858*0Sstevel@tonic-gate }
2859*0Sstevel@tonic-gate 
2860*0Sstevel@tonic-gate /*
2861*0Sstevel@tonic-gate  * Assign the flags as the new value(s) for the MD_SR_STATE_FLAGS within the
2862*0Sstevel@tonic-gate  * set record flags field.  This actually can set any bits but only clears
2863*0Sstevel@tonic-gate  * the bits within the MD_SR_STATE_FLAGS subfield and leaves any other
2864*0Sstevel@tonic-gate  * bits turned on.  It can be used to clear (state) and set bits all in one
2865*0Sstevel@tonic-gate  * rpc call.
2866*0Sstevel@tonic-gate  */
2867*0Sstevel@tonic-gate int
2868*0Sstevel@tonic-gate clnt_upd_sr_flags(
2869*0Sstevel@tonic-gate 	char			*hostname,
2870*0Sstevel@tonic-gate 	mdsetname_t		*sp,
2871*0Sstevel@tonic-gate 	uint_t			flags,
2872*0Sstevel@tonic-gate 	md_error_t		*ep
2873*0Sstevel@tonic-gate )
2874*0Sstevel@tonic-gate {
2875*0Sstevel@tonic-gate 	uint_t		new_flags;
2876*0Sstevel@tonic-gate 	md_set_desc	*sd;
2877*0Sstevel@tonic-gate 
2878*0Sstevel@tonic-gate 	mdclrerror(ep);
2879*0Sstevel@tonic-gate 
2880*0Sstevel@tonic-gate 	/* Get the flags from the current set */
2881*0Sstevel@tonic-gate 	if ((sd = metaget_setdesc(sp, ep)) == NULL)
2882*0Sstevel@tonic-gate 		return (-1);
2883*0Sstevel@tonic-gate 
2884*0Sstevel@tonic-gate 	/* clear the existing state flags */
2885*0Sstevel@tonic-gate 	sd->sd_flags &= ~MD_SR_STATE_FLAGS;
2886*0Sstevel@tonic-gate 
2887*0Sstevel@tonic-gate 	/* Or in the new value */
2888*0Sstevel@tonic-gate 	new_flags = (sd->sd_flags | flags);
2889*0Sstevel@tonic-gate 
2890*0Sstevel@tonic-gate 	/* do it */
2891*0Sstevel@tonic-gate 	return (upd_sr_flags_common(hostname, sp, new_flags, ep));
2892*0Sstevel@tonic-gate }
2893*0Sstevel@tonic-gate 
2894*0Sstevel@tonic-gate md_setkey_t *
2895*0Sstevel@tonic-gate cl_get_setkey(set_t setno, char *setname)
2896*0Sstevel@tonic-gate {
2897*0Sstevel@tonic-gate 
2898*0Sstevel@tonic-gate 	if (my_cl_sk == NULL) {
2899*0Sstevel@tonic-gate 		my_cl_sk = Zalloc(sizeof (md_setkey_t));
2900*0Sstevel@tonic-gate 		my_cl_sk->sk_setno = setno;
2901*0Sstevel@tonic-gate 		my_cl_sk->sk_setname = Strdup(setname);
2902*0Sstevel@tonic-gate 		my_cl_sk->sk_host = Strdup(mynode());
2903*0Sstevel@tonic-gate 	} else {
2904*0Sstevel@tonic-gate 		my_cl_sk->sk_setno = setno;
2905*0Sstevel@tonic-gate 		if (my_cl_sk->sk_setname != NULL)
2906*0Sstevel@tonic-gate 			Free(my_cl_sk->sk_setname);
2907*0Sstevel@tonic-gate 		my_cl_sk->sk_setname = Strdup(setname);
2908*0Sstevel@tonic-gate 	}
2909*0Sstevel@tonic-gate 
2910*0Sstevel@tonic-gate 	return (my_cl_sk);
2911*0Sstevel@tonic-gate }
2912*0Sstevel@tonic-gate 
2913*0Sstevel@tonic-gate void
2914*0Sstevel@tonic-gate cl_set_setkey(md_setkey_t *cl_sk)
2915*0Sstevel@tonic-gate {
2916*0Sstevel@tonic-gate 	if ((cl_sk != NULL) && (my_cl_sk != NULL)) {
2917*0Sstevel@tonic-gate 		assert(my_cl_sk->sk_setno == cl_sk->sk_setno);
2918*0Sstevel@tonic-gate 		assert(strcmp(my_cl_sk->sk_setname, cl_sk->sk_setname) == 0);
2919*0Sstevel@tonic-gate 		assert(strcmp(my_cl_sk->sk_host, cl_sk->sk_host) == 0);
2920*0Sstevel@tonic-gate 		my_cl_sk->sk_key = cl_sk->sk_key;
2921*0Sstevel@tonic-gate 		return;
2922*0Sstevel@tonic-gate 	}
2923*0Sstevel@tonic-gate 
2924*0Sstevel@tonic-gate 	if (my_cl_sk != NULL) {
2925*0Sstevel@tonic-gate 		if (my_cl_sk->sk_setname != NULL)
2926*0Sstevel@tonic-gate 			Free(my_cl_sk->sk_setname);
2927*0Sstevel@tonic-gate 		if (my_cl_sk->sk_host != NULL)
2928*0Sstevel@tonic-gate 			Free(my_cl_sk->sk_host);
2929*0Sstevel@tonic-gate 		Free(my_cl_sk);
2930*0Sstevel@tonic-gate 	}
2931*0Sstevel@tonic-gate 
2932*0Sstevel@tonic-gate 	my_cl_sk = NULL;
2933*0Sstevel@tonic-gate 
2934*0Sstevel@tonic-gate 	/* get here, if set called before get */
2935*0Sstevel@tonic-gate 	if (cl_sk != NULL) {
2936*0Sstevel@tonic-gate 		my_cl_sk = Zalloc(sizeof (md_setkey_t));
2937*0Sstevel@tonic-gate 		my_cl_sk->sk_host = Strdup(cl_sk->sk_host);
2938*0Sstevel@tonic-gate 		my_cl_sk->sk_setno = cl_sk->sk_setno;
2939*0Sstevel@tonic-gate 		my_cl_sk->sk_setname = Strdup(cl_sk->sk_setname);
2940*0Sstevel@tonic-gate 		my_cl_sk->sk_key = cl_sk->sk_key;
2941*0Sstevel@tonic-gate 	}
2942*0Sstevel@tonic-gate }
2943*0Sstevel@tonic-gate 
2944*0Sstevel@tonic-gate /*
2945*0Sstevel@tonic-gate  * Unlock the set after operation is complete.
2946*0Sstevel@tonic-gate  */
2947*0Sstevel@tonic-gate int
2948*0Sstevel@tonic-gate clnt_unlock_set(
2949*0Sstevel@tonic-gate 	char			*hostname,
2950*0Sstevel@tonic-gate 	md_setkey_t		*cl_sk,
2951*0Sstevel@tonic-gate 	md_error_t		*ep
2952*0Sstevel@tonic-gate )
2953*0Sstevel@tonic-gate {
2954*0Sstevel@tonic-gate 	CLIENT			*clntp;
2955*0Sstevel@tonic-gate 	mdrpc_null_args		args;
2956*0Sstevel@tonic-gate 	mdrpc_setlock_res	res;
2957*0Sstevel@tonic-gate 
2958*0Sstevel@tonic-gate 	/* initialize */
2959*0Sstevel@tonic-gate 	mdclrerror(ep);
2960*0Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
2961*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
2962*0Sstevel@tonic-gate 
2963*0Sstevel@tonic-gate 	/* build args */
2964*0Sstevel@tonic-gate 	args.cl_sk = cl_sk;
2965*0Sstevel@tonic-gate 
2966*0Sstevel@tonic-gate 	/* do it */
2967*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
2968*0Sstevel@tonic-gate 		int	bool;
2969*0Sstevel@tonic-gate 		bool = mdrpc_unlock_set_1_svc(&args, &res, NULL);
2970*0Sstevel@tonic-gate 		assert(bool == TRUE);
2971*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
2972*0Sstevel@tonic-gate 	} else {
2973*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
2974*0Sstevel@tonic-gate 			return (-1);
2975*0Sstevel@tonic-gate 
2976*0Sstevel@tonic-gate 		if (mdrpc_unlock_set_1(&args, &res, clntp) != RPC_SUCCESS)
2977*0Sstevel@tonic-gate 			(void) mdrpcerror(ep, clntp, hostname,
2978*0Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad unlock set"));
2979*0Sstevel@tonic-gate 		else
2980*0Sstevel@tonic-gate 			(void) mdstealerror(ep, &res.status);
2981*0Sstevel@tonic-gate 
2982*0Sstevel@tonic-gate 		metarpcclose(clntp);
2983*0Sstevel@tonic-gate 	}
2984*0Sstevel@tonic-gate 
2985*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_setlock_res, (char *)&res);
2986*0Sstevel@tonic-gate 
2987*0Sstevel@tonic-gate 	if (! mdisok(ep)) {
2988*0Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
2989*0Sstevel@tonic-gate 			return (-1);
2990*0Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
2991*0Sstevel@tonic-gate 			return (-1);
2992*0Sstevel@tonic-gate 		mdclrerror(ep);
2993*0Sstevel@tonic-gate 	}
2994*0Sstevel@tonic-gate 
2995*0Sstevel@tonic-gate 	return (0);
2996*0Sstevel@tonic-gate }
2997*0Sstevel@tonic-gate 
2998*0Sstevel@tonic-gate /*
2999*0Sstevel@tonic-gate  * Lock set so that only operators with valid keys are allowed in the daemon.
3000*0Sstevel@tonic-gate  */
3001*0Sstevel@tonic-gate int
3002*0Sstevel@tonic-gate clnt_lock_set(
3003*0Sstevel@tonic-gate 	char			*hostname,
3004*0Sstevel@tonic-gate 	mdsetname_t		*sp,
3005*0Sstevel@tonic-gate 	md_error_t		*ep
3006*0Sstevel@tonic-gate )
3007*0Sstevel@tonic-gate {
3008*0Sstevel@tonic-gate 	CLIENT			*clntp;
3009*0Sstevel@tonic-gate 	mdrpc_null_args		args;
3010*0Sstevel@tonic-gate 	mdrpc_setlock_res	res;
3011*0Sstevel@tonic-gate 
3012*0Sstevel@tonic-gate 	/* initialize */
3013*0Sstevel@tonic-gate 	mdclrerror(ep);
3014*0Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
3015*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
3016*0Sstevel@tonic-gate 
3017*0Sstevel@tonic-gate 	/* build args */
3018*0Sstevel@tonic-gate 	args.cl_sk = cl_get_setkey(sp->setno, sp->setname);
3019*0Sstevel@tonic-gate 
3020*0Sstevel@tonic-gate 	/* do it */
3021*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
3022*0Sstevel@tonic-gate 		int	bool;
3023*0Sstevel@tonic-gate 		bool = mdrpc_lock_set_1_svc(&args, &res, NULL);
3024*0Sstevel@tonic-gate 		assert(bool == TRUE);
3025*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
3026*0Sstevel@tonic-gate 	} else {
3027*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
3028*0Sstevel@tonic-gate 			return (-1);
3029*0Sstevel@tonic-gate 
3030*0Sstevel@tonic-gate 		if (mdrpc_lock_set_1(&args, &res, clntp) != RPC_SUCCESS)
3031*0Sstevel@tonic-gate 			(void) mdrpcerror(ep, clntp, hostname,
3032*0Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad lock set"));
3033*0Sstevel@tonic-gate 		else
3034*0Sstevel@tonic-gate 			(void) mdstealerror(ep, &res.status);
3035*0Sstevel@tonic-gate 
3036*0Sstevel@tonic-gate 		metarpcclose(clntp);
3037*0Sstevel@tonic-gate 	}
3038*0Sstevel@tonic-gate 
3039*0Sstevel@tonic-gate 	if (mdisok(ep))
3040*0Sstevel@tonic-gate 		cl_set_setkey(res.cl_sk);
3041*0Sstevel@tonic-gate 
3042*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_setlock_res, (char *)&res);
3043*0Sstevel@tonic-gate 
3044*0Sstevel@tonic-gate 	if (! mdisok(ep)) {
3045*0Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
3046*0Sstevel@tonic-gate 			return (-1);
3047*0Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
3048*0Sstevel@tonic-gate 			return (-1);
3049*0Sstevel@tonic-gate 		mdclrerror(ep);
3050*0Sstevel@tonic-gate 	}
3051*0Sstevel@tonic-gate 
3052*0Sstevel@tonic-gate 	return (0);
3053*0Sstevel@tonic-gate }
3054*0Sstevel@tonic-gate 
3055*0Sstevel@tonic-gate /*
3056*0Sstevel@tonic-gate  * Add mediator hosts to disksets.
3057*0Sstevel@tonic-gate  */
3058*0Sstevel@tonic-gate int
3059*0Sstevel@tonic-gate clnt_updmeds(
3060*0Sstevel@tonic-gate 	char			*hostname,
3061*0Sstevel@tonic-gate 	mdsetname_t		*sp,
3062*0Sstevel@tonic-gate 	md_h_arr_t		*medp,
3063*0Sstevel@tonic-gate 	md_error_t		*ep
3064*0Sstevel@tonic-gate )
3065*0Sstevel@tonic-gate {
3066*0Sstevel@tonic-gate 	CLIENT			*clntp;
3067*0Sstevel@tonic-gate 	mdrpc_updmeds_args	*args;
3068*0Sstevel@tonic-gate 	mdrpc_updmeds_2_args	v2_args;
3069*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
3070*0Sstevel@tonic-gate 	int			version;
3071*0Sstevel@tonic-gate 
3072*0Sstevel@tonic-gate 	/* initialize */
3073*0Sstevel@tonic-gate 	mdclrerror(ep);
3074*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
3075*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
3076*0Sstevel@tonic-gate 
3077*0Sstevel@tonic-gate 	/* build args */
3078*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
3079*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_updmeds_2_args_u.rev1;
3080*0Sstevel@tonic-gate 	args->sp = sp;
3081*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
3082*0Sstevel@tonic-gate 	args->meds = *medp;			/* structure assignment */
3083*0Sstevel@tonic-gate 
3084*0Sstevel@tonic-gate 	/* do it */
3085*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
3086*0Sstevel@tonic-gate 		int bool;
3087*0Sstevel@tonic-gate 		bool = mdrpc_updmeds_2_svc(&v2_args, &res, NULL);
3088*0Sstevel@tonic-gate 		assert(bool == TRUE);
3089*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
3090*0Sstevel@tonic-gate 	} else {
3091*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
3092*0Sstevel@tonic-gate 			return (-1);
3093*0Sstevel@tonic-gate 
3094*0Sstevel@tonic-gate 		/*
3095*0Sstevel@tonic-gate 		 * Check the client handle for the version
3096*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
3097*0Sstevel@tonic-gate 		 * remote procedure
3098*0Sstevel@tonic-gate 		 */
3099*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
3100*0Sstevel@tonic-gate 
3101*0Sstevel@tonic-gate 		if (version == METAD_VERSION) {	/* version 1 */
3102*0Sstevel@tonic-gate 			if (mdrpc_updmeds_1(args, &res, clntp) != RPC_SUCCESS)
3103*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
3104*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad add hosts"));
3105*0Sstevel@tonic-gate 			else
3106*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
3107*0Sstevel@tonic-gate 		} else {
3108*0Sstevel@tonic-gate 			if (mdrpc_updmeds_2(&v2_args, &res, clntp) !=
3109*0Sstevel@tonic-gate 			    RPC_SUCCESS)
3110*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
3111*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad add hosts"));
3112*0Sstevel@tonic-gate 			else
3113*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
3114*0Sstevel@tonic-gate 		}
3115*0Sstevel@tonic-gate 
3116*0Sstevel@tonic-gate 		metarpcclose(clntp);
3117*0Sstevel@tonic-gate 	}
3118*0Sstevel@tonic-gate 
3119*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
3120*0Sstevel@tonic-gate 
3121*0Sstevel@tonic-gate 	if (! mdisok(ep))
3122*0Sstevel@tonic-gate 		return (-1);
3123*0Sstevel@tonic-gate 
3124*0Sstevel@tonic-gate 	return (0);
3125*0Sstevel@tonic-gate }
3126*0Sstevel@tonic-gate 
3127*0Sstevel@tonic-gate /*
3128*0Sstevel@tonic-gate  * update nr_flags field of node records based
3129*0Sstevel@tonic-gate  * on given action.
3130*0Sstevel@tonic-gate  */
3131*0Sstevel@tonic-gate int
3132*0Sstevel@tonic-gate clnt_upd_nr_flags(
3133*0Sstevel@tonic-gate 	char			*hostname,
3134*0Sstevel@tonic-gate 	mdsetname_t		*sp,
3135*0Sstevel@tonic-gate 	md_mnnode_desc		*nd,
3136*0Sstevel@tonic-gate 	uint_t			flag_action,
3137*0Sstevel@tonic-gate 	uint_t			flags,
3138*0Sstevel@tonic-gate 	md_error_t		*ep
3139*0Sstevel@tonic-gate )
3140*0Sstevel@tonic-gate {
3141*0Sstevel@tonic-gate 	CLIENT				*clntp;
3142*0Sstevel@tonic-gate 	mdrpc_upd_nr_flags_args		*args;
3143*0Sstevel@tonic-gate 	mdrpc_upd_nr_flags_2_args	v2_args;
3144*0Sstevel@tonic-gate 	mdrpc_generic_res		res;
3145*0Sstevel@tonic-gate 	int				version;
3146*0Sstevel@tonic-gate 
3147*0Sstevel@tonic-gate 	/* initialize */
3148*0Sstevel@tonic-gate 	mdclrerror(ep);
3149*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
3150*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
3151*0Sstevel@tonic-gate 
3152*0Sstevel@tonic-gate 	/* build args */
3153*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
3154*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_upd_nr_flags_2_args_u.rev1;
3155*0Sstevel@tonic-gate 	args->sp = sp;
3156*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
3157*0Sstevel@tonic-gate 	args->nodedescs = nd;
3158*0Sstevel@tonic-gate 	args->flag_action = flag_action;
3159*0Sstevel@tonic-gate 	args->flags = flags;
3160*0Sstevel@tonic-gate 
3161*0Sstevel@tonic-gate 	/* do it */
3162*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
3163*0Sstevel@tonic-gate 		int	bool;
3164*0Sstevel@tonic-gate 		bool = mdrpc_upd_nr_flags_2_svc(&v2_args, &res, NULL);
3165*0Sstevel@tonic-gate 		assert(bool == TRUE);
3166*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
3167*0Sstevel@tonic-gate 	} else {
3168*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
3169*0Sstevel@tonic-gate 			return (-1);
3170*0Sstevel@tonic-gate 
3171*0Sstevel@tonic-gate 		/*
3172*0Sstevel@tonic-gate 		 * Check the client handle for the version
3173*0Sstevel@tonic-gate 		 */
3174*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
3175*0Sstevel@tonic-gate 
3176*0Sstevel@tonic-gate 		/*
3177*0Sstevel@tonic-gate 		 * If the client is version 1, return error
3178*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
3179*0Sstevel@tonic-gate 		 */
3180*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
3181*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
3182*0Sstevel@tonic-gate 				sp->setno, hostname, NULL, sp->setname);
3183*0Sstevel@tonic-gate 			metarpcclose(clntp);
3184*0Sstevel@tonic-gate 			return (-1);
3185*0Sstevel@tonic-gate 		} else {
3186*0Sstevel@tonic-gate 			if (mdrpc_upd_nr_flags_2(&v2_args, &res, clntp)
3187*0Sstevel@tonic-gate 							!= RPC_SUCCESS)
3188*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
3189*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
3190*0Sstevel@tonic-gate 				    "metad set node flags"));
3191*0Sstevel@tonic-gate 			else
3192*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
3193*0Sstevel@tonic-gate 		}
3194*0Sstevel@tonic-gate 
3195*0Sstevel@tonic-gate 		metarpcclose(clntp);
3196*0Sstevel@tonic-gate 	}
3197*0Sstevel@tonic-gate 
3198*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
3199*0Sstevel@tonic-gate 
3200*0Sstevel@tonic-gate 	if (! mdisok(ep)) {
3201*0Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
3202*0Sstevel@tonic-gate 			return (-1);
3203*0Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
3204*0Sstevel@tonic-gate 			return (-1);
3205*0Sstevel@tonic-gate 		mdclrerror(ep);
3206*0Sstevel@tonic-gate 	}
3207*0Sstevel@tonic-gate 
3208*0Sstevel@tonic-gate 	return (0);
3209*0Sstevel@tonic-gate }
3210*0Sstevel@tonic-gate 
3211*0Sstevel@tonic-gate /*
3212*0Sstevel@tonic-gate  * Clear set locks for all MN disksets.
3213*0Sstevel@tonic-gate  * Used during reconfig cycle to recover from failed nodes.
3214*0Sstevel@tonic-gate  */
3215*0Sstevel@tonic-gate int
3216*0Sstevel@tonic-gate clnt_clr_mnsetlock(
3217*0Sstevel@tonic-gate 	char			*hostname,
3218*0Sstevel@tonic-gate 	md_error_t		*ep
3219*0Sstevel@tonic-gate )
3220*0Sstevel@tonic-gate {
3221*0Sstevel@tonic-gate 	CLIENT			*clntp;
3222*0Sstevel@tonic-gate 	mdrpc_null_args		args;
3223*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
3224*0Sstevel@tonic-gate 	int			version;
3225*0Sstevel@tonic-gate 
3226*0Sstevel@tonic-gate 	/* initialize */
3227*0Sstevel@tonic-gate 	mdclrerror(ep);
3228*0Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
3229*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
3230*0Sstevel@tonic-gate 
3231*0Sstevel@tonic-gate 	/* do it */
3232*0Sstevel@tonic-gate 	if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
3233*0Sstevel@tonic-gate 		return (-1);
3234*0Sstevel@tonic-gate 
3235*0Sstevel@tonic-gate 	/*
3236*0Sstevel@tonic-gate 	 * Check the client handle for the version
3237*0Sstevel@tonic-gate 	 */
3238*0Sstevel@tonic-gate 	CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
3239*0Sstevel@tonic-gate 
3240*0Sstevel@tonic-gate 	/*
3241*0Sstevel@tonic-gate 	 * If the client is version 1, return error
3242*0Sstevel@tonic-gate 	 * otherwise, make the remote procedure call.
3243*0Sstevel@tonic-gate 	 */
3244*0Sstevel@tonic-gate 	if (version == METAD_VERSION) { /* version 1 */
3245*0Sstevel@tonic-gate 		(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
3246*0Sstevel@tonic-gate 			NULL, hostname, NULL, NULL);
3247*0Sstevel@tonic-gate 		metarpcclose(clntp);
3248*0Sstevel@tonic-gate 		return (-1);
3249*0Sstevel@tonic-gate 	} else {
3250*0Sstevel@tonic-gate 		if (mdrpc_clr_mnsetlock_2(&args, &res, clntp) != RPC_SUCCESS)
3251*0Sstevel@tonic-gate 			(void) mdrpcerror(ep, clntp, hostname,
3252*0Sstevel@tonic-gate 			    dgettext(TEXT_DOMAIN, "metad clr mnsetlock"));
3253*0Sstevel@tonic-gate 		else
3254*0Sstevel@tonic-gate 			(void) mdstealerror(ep, &res.status);
3255*0Sstevel@tonic-gate 	}
3256*0Sstevel@tonic-gate 
3257*0Sstevel@tonic-gate 	metarpcclose(clntp);
3258*0Sstevel@tonic-gate 
3259*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
3260*0Sstevel@tonic-gate 
3261*0Sstevel@tonic-gate 	if (! mdisok(ep))
3262*0Sstevel@tonic-gate 		return (-1);
3263*0Sstevel@tonic-gate 
3264*0Sstevel@tonic-gate 	return (0);
3265*0Sstevel@tonic-gate }
3266*0Sstevel@tonic-gate 
3267*0Sstevel@tonic-gate /*
3268*0Sstevel@tonic-gate  * Calls to suspend, resume or reinit the rpc.mdcommd daemon.
3269*0Sstevel@tonic-gate  * This allows a node to remotely suspend, reinit and resume the
3270*0Sstevel@tonic-gate  * rpc.mdcommd daemon on the given hostname node.  Used by libmeta
3271*0Sstevel@tonic-gate  * to lock out class 1 messages (metainit, etc) on all nodes when running
3272*0Sstevel@tonic-gate  * metaset and metadb commands on this node.
3273*0Sstevel@tonic-gate  *
3274*0Sstevel@tonic-gate  * When suspending the commd, the suspend request will fail until all
3275*0Sstevel@tonic-gate  * messages have been drained from the rpc.mdcommd.  This routine will
3276*0Sstevel@tonic-gate  * spin sending the suspend request until the rpc.mdcommd is drained
3277*0Sstevel@tonic-gate  * or until rpc.mdcommd returns a failure other than MDMNE_SET_NOT_DRAINED.
3278*0Sstevel@tonic-gate  *
3279*0Sstevel@tonic-gate  * Also used to send the rpc.mdcommd daemon a new nodelist by draining all
3280*0Sstevel@tonic-gate  * messages from the mdcommd and sending a reinit command to have mdcommd
3281*0Sstevel@tonic-gate  * get the new nodelist from rpc.metad.  Used when nodelist is changed
3282*0Sstevel@tonic-gate  * during:
3283*0Sstevel@tonic-gate  *	- addition or deletion of host from diskset
3284*0Sstevel@tonic-gate  *	- join or withdrawal of host from diskset
3285*0Sstevel@tonic-gate  *	- addition of first disk to diskset (joins all nodes)
3286*0Sstevel@tonic-gate  *	- removal of last disk from diskset (withdraws all nodes)
3287*0Sstevel@tonic-gate  */
3288*0Sstevel@tonic-gate int
3289*0Sstevel@tonic-gate clnt_mdcommdctl(
3290*0Sstevel@tonic-gate 	char			*hostname,
3291*0Sstevel@tonic-gate 	int			flag_action,
3292*0Sstevel@tonic-gate 	mdsetname_t		*sp,
3293*0Sstevel@tonic-gate 	md_mn_msgclass_t	class,
3294*0Sstevel@tonic-gate 	uint_t			flags,
3295*0Sstevel@tonic-gate 	md_error_t		*ep
3296*0Sstevel@tonic-gate )
3297*0Sstevel@tonic-gate {
3298*0Sstevel@tonic-gate 	CLIENT				*clntp;
3299*0Sstevel@tonic-gate 	mdrpc_mdcommdctl_args		*args;
3300*0Sstevel@tonic-gate 	mdrpc_mdcommdctl_2_args		v2_args;
3301*0Sstevel@tonic-gate 	mdrpc_generic_res		res;
3302*0Sstevel@tonic-gate 	int				version;
3303*0Sstevel@tonic-gate 	int				suspend_spin = 0;
3304*0Sstevel@tonic-gate 
3305*0Sstevel@tonic-gate 	/* initialize */
3306*0Sstevel@tonic-gate 	mdclrerror(ep);
3307*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
3308*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
3309*0Sstevel@tonic-gate 
3310*0Sstevel@tonic-gate 	/* build args */
3311*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
3312*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_mdcommdctl_2_args_u.rev1;
3313*0Sstevel@tonic-gate 	args->flag_action = flag_action;
3314*0Sstevel@tonic-gate 	args->setno = sp->setno;
3315*0Sstevel@tonic-gate 	args->class = class;
3316*0Sstevel@tonic-gate 	args->flags = flags;
3317*0Sstevel@tonic-gate 
3318*0Sstevel@tonic-gate 	/* do it */
3319*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
3320*0Sstevel@tonic-gate 		int	bool;
3321*0Sstevel@tonic-gate 		/*
3322*0Sstevel@tonic-gate 		 * Call v2 procedure directly if rpc.metad on this node is
3323*0Sstevel@tonic-gate 		 * sending message to itself.
3324*0Sstevel@tonic-gate 		 */
3325*0Sstevel@tonic-gate 		if (flag_action == COMMDCTL_SUSPEND) {
3326*0Sstevel@tonic-gate 			suspend_spin = 1;
3327*0Sstevel@tonic-gate 			while (suspend_spin) {
3328*0Sstevel@tonic-gate 				suspend_spin = 0;
3329*0Sstevel@tonic-gate 				bool = mdrpc_mdcommdctl_2_svc(&v2_args, &res,
3330*0Sstevel@tonic-gate 					NULL);
3331*0Sstevel@tonic-gate 				assert(bool == TRUE);
3332*0Sstevel@tonic-gate 				/*
3333*0Sstevel@tonic-gate 				 * If set not yet drained, wait a second
3334*0Sstevel@tonic-gate 				 * and try again.
3335*0Sstevel@tonic-gate 				 */
3336*0Sstevel@tonic-gate 				if (mdisdserror(&(res.status),
3337*0Sstevel@tonic-gate 				    MDE_DS_COMMDCTL_SUSPEND_NYD)) {
3338*0Sstevel@tonic-gate 					/* Wait a second and try again */
3339*0Sstevel@tonic-gate 					mdclrerror(&(res.status));
3340*0Sstevel@tonic-gate 					(void) sleep(1);
3341*0Sstevel@tonic-gate 					suspend_spin = 1;
3342*0Sstevel@tonic-gate 				}
3343*0Sstevel@tonic-gate 			}
3344*0Sstevel@tonic-gate 		} else {
3345*0Sstevel@tonic-gate 			bool = mdrpc_mdcommdctl_2_svc(&v2_args, &res, NULL);
3346*0Sstevel@tonic-gate 			assert(bool == TRUE);
3347*0Sstevel@tonic-gate 		}
3348*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
3349*0Sstevel@tonic-gate 	} else {
3350*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
3351*0Sstevel@tonic-gate 			return (-1);
3352*0Sstevel@tonic-gate 
3353*0Sstevel@tonic-gate 		/*
3354*0Sstevel@tonic-gate 		 * Check the client handle for the version
3355*0Sstevel@tonic-gate 		 */
3356*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
3357*0Sstevel@tonic-gate 
3358*0Sstevel@tonic-gate 		/*
3359*0Sstevel@tonic-gate 		 * If the client is version 1, return error
3360*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
3361*0Sstevel@tonic-gate 		 */
3362*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
3363*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
3364*0Sstevel@tonic-gate 				sp->setno, hostname, NULL, sp->setname);
3365*0Sstevel@tonic-gate 			metarpcclose(clntp);
3366*0Sstevel@tonic-gate 			return (-1);
3367*0Sstevel@tonic-gate 		}
3368*0Sstevel@tonic-gate 
3369*0Sstevel@tonic-gate 		if (flag_action == COMMDCTL_SUSPEND) {
3370*0Sstevel@tonic-gate 			suspend_spin = 1;
3371*0Sstevel@tonic-gate 			while (suspend_spin) {
3372*0Sstevel@tonic-gate 				suspend_spin = 0;
3373*0Sstevel@tonic-gate 				if (mdrpc_mdcommdctl_2(&v2_args, &res,
3374*0Sstevel@tonic-gate 				    clntp) != RPC_SUCCESS) {
3375*0Sstevel@tonic-gate 					(void) mdrpcerror(ep, clntp,
3376*0Sstevel@tonic-gate 					    hostname,
3377*0Sstevel@tonic-gate 					    dgettext(TEXT_DOMAIN,
3378*0Sstevel@tonic-gate 					    "metad commd control"));
3379*0Sstevel@tonic-gate 				} else {
3380*0Sstevel@tonic-gate 					/*
3381*0Sstevel@tonic-gate 					 * If set not yet drained,
3382*0Sstevel@tonic-gate 					 * wait a second and
3383*0Sstevel@tonic-gate 					 * and try again.
3384*0Sstevel@tonic-gate 					 */
3385*0Sstevel@tonic-gate 					if (mdisdserror(&(res.status),
3386*0Sstevel@tonic-gate 					    MDE_DS_COMMDCTL_SUSPEND_NYD)) {
3387*0Sstevel@tonic-gate 						mdclrerror(&(res.status));
3388*0Sstevel@tonic-gate 						(void) sleep(1);
3389*0Sstevel@tonic-gate 						suspend_spin = 1;
3390*0Sstevel@tonic-gate 					} else {
3391*0Sstevel@tonic-gate 						(void) mdstealerror(ep,
3392*0Sstevel@tonic-gate 						    &res.status);
3393*0Sstevel@tonic-gate 					}
3394*0Sstevel@tonic-gate 				}
3395*0Sstevel@tonic-gate 			}
3396*0Sstevel@tonic-gate 		} else {
3397*0Sstevel@tonic-gate 			if (mdrpc_mdcommdctl_2(&v2_args, &res, clntp)
3398*0Sstevel@tonic-gate 			    != RPC_SUCCESS)
3399*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
3400*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
3401*0Sstevel@tonic-gate 				    "metad commd control"));
3402*0Sstevel@tonic-gate 			else
3403*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
3404*0Sstevel@tonic-gate 		}
3405*0Sstevel@tonic-gate 		metarpcclose(clntp);
3406*0Sstevel@tonic-gate 	}
3407*0Sstevel@tonic-gate 
3408*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
3409*0Sstevel@tonic-gate 
3410*0Sstevel@tonic-gate 	if (! mdisok(ep)) {
3411*0Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
3412*0Sstevel@tonic-gate 			return (-1);
3413*0Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
3414*0Sstevel@tonic-gate 			return (-1);
3415*0Sstevel@tonic-gate 		mdclrerror(ep);
3416*0Sstevel@tonic-gate 	}
3417*0Sstevel@tonic-gate 
3418*0Sstevel@tonic-gate 	return (0);
3419*0Sstevel@tonic-gate }
3420*0Sstevel@tonic-gate 
3421*0Sstevel@tonic-gate /*
3422*0Sstevel@tonic-gate  * Is owner node stale?
3423*0Sstevel@tonic-gate  */
3424*0Sstevel@tonic-gate int
3425*0Sstevel@tonic-gate clnt_mn_is_stale(
3426*0Sstevel@tonic-gate 	char			*hostname,
3427*0Sstevel@tonic-gate 	mdsetname_t		*sp,
3428*0Sstevel@tonic-gate 	int			*ret_bool,
3429*0Sstevel@tonic-gate 	md_error_t		*ep
3430*0Sstevel@tonic-gate )
3431*0Sstevel@tonic-gate {
3432*0Sstevel@tonic-gate 	CLIENT			*clntp;
3433*0Sstevel@tonic-gate 	mdrpc_setno_args	*args;
3434*0Sstevel@tonic-gate 	mdrpc_setno_2_args	v2_args;
3435*0Sstevel@tonic-gate 	mdrpc_bool_res		res;
3436*0Sstevel@tonic-gate 	int			rval = -1;
3437*0Sstevel@tonic-gate 	int			version;
3438*0Sstevel@tonic-gate 
3439*0Sstevel@tonic-gate 	/* initialize */
3440*0Sstevel@tonic-gate 	mdclrerror(ep);
3441*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
3442*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
3443*0Sstevel@tonic-gate 
3444*0Sstevel@tonic-gate 	/* build args */
3445*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
3446*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_setno_2_args_u.rev1;
3447*0Sstevel@tonic-gate 	args->setno = sp->setno;
3448*0Sstevel@tonic-gate 
3449*0Sstevel@tonic-gate 	/* do it */
3450*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
3451*0Sstevel@tonic-gate 		int	bool;
3452*0Sstevel@tonic-gate 		/*
3453*0Sstevel@tonic-gate 		 * Call v2 procedure directly if rpc.metad on this node is
3454*0Sstevel@tonic-gate 		 * sending message to itself.
3455*0Sstevel@tonic-gate 		 */
3456*0Sstevel@tonic-gate 		bool = mdrpc_mn_is_stale_2_svc(&v2_args, &res, NULL);
3457*0Sstevel@tonic-gate 		assert(bool == TRUE);
3458*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
3459*0Sstevel@tonic-gate 	} else {
3460*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
3461*0Sstevel@tonic-gate 			return (-1);
3462*0Sstevel@tonic-gate 
3463*0Sstevel@tonic-gate 		/*
3464*0Sstevel@tonic-gate 		 * Check the client handle for the version
3465*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
3466*0Sstevel@tonic-gate 		 * remote procedure
3467*0Sstevel@tonic-gate 		 */
3468*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
3469*0Sstevel@tonic-gate 
3470*0Sstevel@tonic-gate 		/*
3471*0Sstevel@tonic-gate 		 * If the client is version 1, return error
3472*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
3473*0Sstevel@tonic-gate 		 */
3474*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
3475*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
3476*0Sstevel@tonic-gate 			    sp->setno, hostname, NULL, sp->setname);
3477*0Sstevel@tonic-gate 			metarpcclose(clntp);
3478*0Sstevel@tonic-gate 			return (-1);
3479*0Sstevel@tonic-gate 		} else {
3480*0Sstevel@tonic-gate 			if (mdrpc_mn_is_stale_2(&v2_args, &res, clntp) !=
3481*0Sstevel@tonic-gate 			    RPC_SUCCESS)
3482*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
3483*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN, "metad mn is stale"));
3484*0Sstevel@tonic-gate 			else
3485*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
3486*0Sstevel@tonic-gate 		}
3487*0Sstevel@tonic-gate 
3488*0Sstevel@tonic-gate 		metarpcclose(clntp);
3489*0Sstevel@tonic-gate 	}
3490*0Sstevel@tonic-gate 
3491*0Sstevel@tonic-gate 	if (mdisok(ep)) {
3492*0Sstevel@tonic-gate 		/* do something with the results */
3493*0Sstevel@tonic-gate 		rval = 0;
3494*0Sstevel@tonic-gate 
3495*0Sstevel@tonic-gate 		if (ret_bool != NULL)
3496*0Sstevel@tonic-gate 			*ret_bool = res.value;
3497*0Sstevel@tonic-gate 	}
3498*0Sstevel@tonic-gate 
3499*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_bool_res, (char *)&res);
3500*0Sstevel@tonic-gate 
3501*0Sstevel@tonic-gate 	return (rval);
3502*0Sstevel@tonic-gate }
3503*0Sstevel@tonic-gate 
3504*0Sstevel@tonic-gate /*
3505*0Sstevel@tonic-gate  * Free md_drive_desc linked list of drive descriptors that was alloc'd
3506*0Sstevel@tonic-gate  * from a call to the RPC routine clnt_getdrivedesc.  Drive descriptors
3507*0Sstevel@tonic-gate  * are from another node.
3508*0Sstevel@tonic-gate  */
3509*0Sstevel@tonic-gate void
3510*0Sstevel@tonic-gate free_rem_dd(md_drive_desc *dd)
3511*0Sstevel@tonic-gate {
3512*0Sstevel@tonic-gate 	mdrpc_getdrivedesc_res	res;
3513*0Sstevel@tonic-gate 
3514*0Sstevel@tonic-gate 	/*
3515*0Sstevel@tonic-gate 	 * dummy up a result struct, to do a deep free of the dd.
3516*0Sstevel@tonic-gate 	 * (A deep free means that the xdr_free code will free the
3517*0Sstevel@tonic-gate 	 * linked list of drive descs.)
3518*0Sstevel@tonic-gate 	 */
3519*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
3520*0Sstevel@tonic-gate 	res.dd = (struct md_drive_desc *)dd;
3521*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_getdrivedesc_res, (char *)&res);
3522*0Sstevel@tonic-gate }
3523*0Sstevel@tonic-gate 
3524*0Sstevel@tonic-gate /*
3525*0Sstevel@tonic-gate  * Get a partially filled in drive desc from remote node.  Used in MN
3526*0Sstevel@tonic-gate  * disksets during the reconfig cycle to get the diskset drive
3527*0Sstevel@tonic-gate  * information from another host in order to sync up all nodes.
3528*0Sstevel@tonic-gate  * Used when the drive record information isn't good enough
3529*0Sstevel@tonic-gate  * since the drive record doesn't give the name of
3530*0Sstevel@tonic-gate  * the drive, but just a key into that other node's nodespace.
3531*0Sstevel@tonic-gate  * Returned drive desc has the drive name filled in but no other strings
3532*0Sstevel@tonic-gate  * in the drivename structure.
3533*0Sstevel@tonic-gate  *
3534*0Sstevel@tonic-gate  * Returns a 0 if RPC was successful, 1 otherwise.
3535*0Sstevel@tonic-gate  */
3536*0Sstevel@tonic-gate int
3537*0Sstevel@tonic-gate clnt_getdrivedesc(
3538*0Sstevel@tonic-gate 	char			*hostname,
3539*0Sstevel@tonic-gate 	mdsetname_t		*sp,
3540*0Sstevel@tonic-gate 	md_drive_desc		**ret_dd,
3541*0Sstevel@tonic-gate 	md_error_t		*ep
3542*0Sstevel@tonic-gate )
3543*0Sstevel@tonic-gate {
3544*0Sstevel@tonic-gate 	CLIENT			*clntp;
3545*0Sstevel@tonic-gate 	mdrpc_sp_args		*args;
3546*0Sstevel@tonic-gate 	mdrpc_sp_2_args		v2_args;
3547*0Sstevel@tonic-gate 	mdrpc_getdrivedesc_res	res;
3548*0Sstevel@tonic-gate 	int			version;
3549*0Sstevel@tonic-gate 	int			rval = -1;
3550*0Sstevel@tonic-gate 
3551*0Sstevel@tonic-gate 	/* initialize */
3552*0Sstevel@tonic-gate 	mdclrerror(ep);
3553*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
3554*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
3555*0Sstevel@tonic-gate 
3556*0Sstevel@tonic-gate 	/* build args */
3557*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
3558*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_sp_2_args_u.rev1;
3559*0Sstevel@tonic-gate 	args->sp = sp;
3560*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
3561*0Sstevel@tonic-gate 
3562*0Sstevel@tonic-gate 	/* do it */
3563*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
3564*0Sstevel@tonic-gate 		int	bool;
3565*0Sstevel@tonic-gate 		bool = mdrpc_getdrivedesc_2_svc(&v2_args, &res, NULL);
3566*0Sstevel@tonic-gate 		assert(bool == TRUE);
3567*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
3568*0Sstevel@tonic-gate 	} else {
3569*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
3570*0Sstevel@tonic-gate 			return (-1);
3571*0Sstevel@tonic-gate 
3572*0Sstevel@tonic-gate 		/*
3573*0Sstevel@tonic-gate 		 * Check the client handle for the version
3574*0Sstevel@tonic-gate 		 */
3575*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
3576*0Sstevel@tonic-gate 
3577*0Sstevel@tonic-gate 		/*
3578*0Sstevel@tonic-gate 		 * If the client is version 1, return error
3579*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
3580*0Sstevel@tonic-gate 		 */
3581*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
3582*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
3583*0Sstevel@tonic-gate 			    sp->setno, hostname, NULL, sp->setname);
3584*0Sstevel@tonic-gate 			metarpcclose(clntp);
3585*0Sstevel@tonic-gate 			return (-1);
3586*0Sstevel@tonic-gate 		} else {
3587*0Sstevel@tonic-gate 			if (mdrpc_getdrivedesc_2(&v2_args, &res, clntp)
3588*0Sstevel@tonic-gate 							!= RPC_SUCCESS)
3589*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
3590*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
3591*0Sstevel@tonic-gate 				    "metad get drive desc set"));
3592*0Sstevel@tonic-gate 			else
3593*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
3594*0Sstevel@tonic-gate 		}
3595*0Sstevel@tonic-gate 
3596*0Sstevel@tonic-gate 		metarpcclose(clntp);
3597*0Sstevel@tonic-gate 	}
3598*0Sstevel@tonic-gate 
3599*0Sstevel@tonic-gate 	/* If no ep error and no version mismatch - rpc call worked ok */
3600*0Sstevel@tonic-gate 	if (mdisok(ep)) {
3601*0Sstevel@tonic-gate 		rval = 0;
3602*0Sstevel@tonic-gate 		if (ret_dd != NULL)
3603*0Sstevel@tonic-gate 			*ret_dd = res.dd;
3604*0Sstevel@tonic-gate 		else
3605*0Sstevel@tonic-gate 			xdr_free(xdr_mdrpc_getdrivedesc_res, (char *)&res);
3606*0Sstevel@tonic-gate 	}
3607*0Sstevel@tonic-gate 
3608*0Sstevel@tonic-gate 	return (rval);
3609*0Sstevel@tonic-gate }
3610*0Sstevel@tonic-gate 
3611*0Sstevel@tonic-gate /*
3612*0Sstevel@tonic-gate  * update dr_flags field of drive record.
3613*0Sstevel@tonic-gate  * Also sync up genid of drive descriptors and make set
3614*0Sstevel@tonic-gate  * record and node records match the genid.
3615*0Sstevel@tonic-gate  *
3616*0Sstevel@tonic-gate  * Returns a 0 if RPC was successful, 1 otherwise.
3617*0Sstevel@tonic-gate  */
3618*0Sstevel@tonic-gate int
3619*0Sstevel@tonic-gate clnt_upd_dr_reconfig(
3620*0Sstevel@tonic-gate 	char			*hostname,
3621*0Sstevel@tonic-gate 	mdsetname_t		*sp,
3622*0Sstevel@tonic-gate 	md_drive_desc		*dd,
3623*0Sstevel@tonic-gate 	md_error_t		*ep
3624*0Sstevel@tonic-gate )
3625*0Sstevel@tonic-gate {
3626*0Sstevel@tonic-gate 	CLIENT				*clntp;
3627*0Sstevel@tonic-gate 	mdrpc_upd_dr_flags_2_args	v2_args;
3628*0Sstevel@tonic-gate 	mdrpc_upd_dr_flags_2_args_r1	*v21_args;
3629*0Sstevel@tonic-gate 	mdrpc_generic_res		res;
3630*0Sstevel@tonic-gate 	int				rval;
3631*0Sstevel@tonic-gate 	int				version;
3632*0Sstevel@tonic-gate 
3633*0Sstevel@tonic-gate 	/* initialize */
3634*0Sstevel@tonic-gate 	mdclrerror(ep);
3635*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
3636*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
3637*0Sstevel@tonic-gate 
3638*0Sstevel@tonic-gate 	/* build args */
3639*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
3640*0Sstevel@tonic-gate 	v21_args = &v2_args.mdrpc_upd_dr_flags_2_args_u.rev1;
3641*0Sstevel@tonic-gate 	v21_args->sp = sp;
3642*0Sstevel@tonic-gate 	v21_args->drivedescs = dd;
3643*0Sstevel@tonic-gate 
3644*0Sstevel@tonic-gate 	/* do it */
3645*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
3646*0Sstevel@tonic-gate 		int	bool;
3647*0Sstevel@tonic-gate 
3648*0Sstevel@tonic-gate 		/*
3649*0Sstevel@tonic-gate 		 * If the server is local, we call the v2 procedure
3650*0Sstevel@tonic-gate 		 */
3651*0Sstevel@tonic-gate 		bool = mdrpc_upd_dr_reconfig_2_svc(&v2_args, &res, NULL);
3652*0Sstevel@tonic-gate 		assert(bool == TRUE);
3653*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
3654*0Sstevel@tonic-gate 	} else {
3655*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
3656*0Sstevel@tonic-gate 			return (-1);
3657*0Sstevel@tonic-gate 
3658*0Sstevel@tonic-gate 		/*
3659*0Sstevel@tonic-gate 		 * Check the client handle for the version
3660*0Sstevel@tonic-gate 		 */
3661*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
3662*0Sstevel@tonic-gate 		/*
3663*0Sstevel@tonic-gate 		 * If the client is version 1, return error
3664*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
3665*0Sstevel@tonic-gate 		 */
3666*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
3667*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
3668*0Sstevel@tonic-gate 				sp->setno, hostname, NULL, sp->setname);
3669*0Sstevel@tonic-gate 			metarpcclose(clntp);
3670*0Sstevel@tonic-gate 			return (-1);
3671*0Sstevel@tonic-gate 		} else {
3672*0Sstevel@tonic-gate 			rval = mdrpc_upd_dr_reconfig_2(&v2_args, &res, clntp);
3673*0Sstevel@tonic-gate 
3674*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
3675*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
3676*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN,
3677*0Sstevel@tonic-gate 				    "metad update drive reconfig"));
3678*0Sstevel@tonic-gate 			else
3679*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
3680*0Sstevel@tonic-gate 		}
3681*0Sstevel@tonic-gate 
3682*0Sstevel@tonic-gate 		metarpcclose(clntp);
3683*0Sstevel@tonic-gate 	}
3684*0Sstevel@tonic-gate 
3685*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
3686*0Sstevel@tonic-gate 
3687*0Sstevel@tonic-gate 	if (! mdisok(ep)) {
3688*0Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
3689*0Sstevel@tonic-gate 			return (-1);
3690*0Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
3691*0Sstevel@tonic-gate 			return (-1);
3692*0Sstevel@tonic-gate 		mdclrerror(ep);
3693*0Sstevel@tonic-gate 	}
3694*0Sstevel@tonic-gate 
3695*0Sstevel@tonic-gate 	return (0);
3696*0Sstevel@tonic-gate }
3697*0Sstevel@tonic-gate 
3698*0Sstevel@tonic-gate /*
3699*0Sstevel@tonic-gate  * Reset mirror owner(s) if mirror owner(s) is in the list of
3700*0Sstevel@tonic-gate  * node's specified in the array of nodeids.
3701*0Sstevel@tonic-gate  * This is called when a node has been deleted or withdrawn
3702*0Sstevel@tonic-gate  * from the diskset.
3703*0Sstevel@tonic-gate  */
3704*0Sstevel@tonic-gate int
3705*0Sstevel@tonic-gate clnt_reset_mirror_owner(
3706*0Sstevel@tonic-gate 	char			*hostname,
3707*0Sstevel@tonic-gate 	mdsetname_t		*sp,
3708*0Sstevel@tonic-gate 	int			node_c,
3709*0Sstevel@tonic-gate 	int			node_id[],
3710*0Sstevel@tonic-gate 	md_error_t		*ep
3711*0Sstevel@tonic-gate )
3712*0Sstevel@tonic-gate {
3713*0Sstevel@tonic-gate 	CLIENT			*clntp;
3714*0Sstevel@tonic-gate 	mdrpc_nodeid_args	*args;
3715*0Sstevel@tonic-gate 	mdrpc_nodeid_2_args	v2_args;
3716*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
3717*0Sstevel@tonic-gate 	int			version;
3718*0Sstevel@tonic-gate 
3719*0Sstevel@tonic-gate 	/* initialize */
3720*0Sstevel@tonic-gate 	mdclrerror(ep);
3721*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
3722*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
3723*0Sstevel@tonic-gate 
3724*0Sstevel@tonic-gate 	/* build args */
3725*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
3726*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_nodeid_2_args_u.rev1;
3727*0Sstevel@tonic-gate 	args->sp = sp;
3728*0Sstevel@tonic-gate 	args->cl_sk = cl_get_setkey(sp->setno, sp->setname);
3729*0Sstevel@tonic-gate 	args->nodeid.nodeid_len = node_c;
3730*0Sstevel@tonic-gate 	args->nodeid.nodeid_val = &node_id[0];
3731*0Sstevel@tonic-gate 
3732*0Sstevel@tonic-gate 	/* do it */
3733*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
3734*0Sstevel@tonic-gate 		int	bool;
3735*0Sstevel@tonic-gate 		bool = mdrpc_reset_mirror_owner_2_svc(&v2_args, &res, NULL);
3736*0Sstevel@tonic-gate 		assert(bool == TRUE);
3737*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
3738*0Sstevel@tonic-gate 	} else {
3739*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
3740*0Sstevel@tonic-gate 			return (-1);
3741*0Sstevel@tonic-gate 
3742*0Sstevel@tonic-gate 		/*
3743*0Sstevel@tonic-gate 		 * Check the client handle for the version
3744*0Sstevel@tonic-gate 		 * and invoke the appropriate version of the
3745*0Sstevel@tonic-gate 		 * remote procedure
3746*0Sstevel@tonic-gate 		 */
3747*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
3748*0Sstevel@tonic-gate 
3749*0Sstevel@tonic-gate 		/*
3750*0Sstevel@tonic-gate 		 * If the client is version 1, return error
3751*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
3752*0Sstevel@tonic-gate 		 */
3753*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
3754*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
3755*0Sstevel@tonic-gate 			    sp->setno, hostname, NULL, sp->setname);
3756*0Sstevel@tonic-gate 			metarpcclose(clntp);
3757*0Sstevel@tonic-gate 			return (-1);
3758*0Sstevel@tonic-gate 		} else {
3759*0Sstevel@tonic-gate 			if (mdrpc_reset_mirror_owner_2(&v2_args, &res, clntp)
3760*0Sstevel@tonic-gate 			    != RPC_SUCCESS)
3761*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
3762*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
3763*0Sstevel@tonic-gate 					"metad reset mirror owner"));
3764*0Sstevel@tonic-gate 			else
3765*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
3766*0Sstevel@tonic-gate 		}
3767*0Sstevel@tonic-gate 
3768*0Sstevel@tonic-gate 		metarpcclose(clntp);
3769*0Sstevel@tonic-gate 	}
3770*0Sstevel@tonic-gate 
3771*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
3772*0Sstevel@tonic-gate 
3773*0Sstevel@tonic-gate 	if (! mdisok(ep))
3774*0Sstevel@tonic-gate 		return (-1);
3775*0Sstevel@tonic-gate 
3776*0Sstevel@tonic-gate 	return (0);
3777*0Sstevel@tonic-gate }
3778*0Sstevel@tonic-gate 
3779*0Sstevel@tonic-gate /*
3780*0Sstevel@tonic-gate  * Call to suspend and resume I/O for given diskset(s).
3781*0Sstevel@tonic-gate  * This allows a node to remotely suspend and resume I/O on
3782*0Sstevel@tonic-gate  * a MN diskset.  A diskset number of 0 represents all MN disksets.
3783*0Sstevel@tonic-gate  */
3784*0Sstevel@tonic-gate int
3785*0Sstevel@tonic-gate clnt_mn_susp_res_io(
3786*0Sstevel@tonic-gate 	char			*hostname,
3787*0Sstevel@tonic-gate 	set_t			setno,
3788*0Sstevel@tonic-gate 	int			cmd,
3789*0Sstevel@tonic-gate 	md_error_t		*ep
3790*0Sstevel@tonic-gate )
3791*0Sstevel@tonic-gate {
3792*0Sstevel@tonic-gate 	CLIENT					*clntp;
3793*0Sstevel@tonic-gate 	mdrpc_mn_susp_res_io_args		*args;
3794*0Sstevel@tonic-gate 	mdrpc_mn_susp_res_io_2_args		v2_args;
3795*0Sstevel@tonic-gate 	mdrpc_generic_res			res;
3796*0Sstevel@tonic-gate 	int					version;
3797*0Sstevel@tonic-gate 
3798*0Sstevel@tonic-gate 	/* initialize */
3799*0Sstevel@tonic-gate 	mdclrerror(ep);
3800*0Sstevel@tonic-gate 	(void) memset(&v2_args, 0, sizeof (v2_args));
3801*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
3802*0Sstevel@tonic-gate 
3803*0Sstevel@tonic-gate 	/* build args */
3804*0Sstevel@tonic-gate 	v2_args.rev = MD_METAD_ARGS_REV_1;
3805*0Sstevel@tonic-gate 	args = &v2_args.mdrpc_mn_susp_res_io_2_args_u.rev1;
3806*0Sstevel@tonic-gate 	args->susp_res_cmd = cmd;
3807*0Sstevel@tonic-gate 	args->susp_res_setno = setno;
3808*0Sstevel@tonic-gate 
3809*0Sstevel@tonic-gate 	/* do it */
3810*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
3811*0Sstevel@tonic-gate 		int	bool;
3812*0Sstevel@tonic-gate 		/*
3813*0Sstevel@tonic-gate 		 * Call v2 procedure directly if rpc.metad on this node is
3814*0Sstevel@tonic-gate 		 * sending message to itself.
3815*0Sstevel@tonic-gate 		 */
3816*0Sstevel@tonic-gate 		bool = mdrpc_mn_susp_res_io_2_svc(&v2_args, &res, NULL);
3817*0Sstevel@tonic-gate 		assert(bool == TRUE);
3818*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
3819*0Sstevel@tonic-gate 	} else {
3820*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
3821*0Sstevel@tonic-gate 			return (-1);
3822*0Sstevel@tonic-gate 
3823*0Sstevel@tonic-gate 		/*
3824*0Sstevel@tonic-gate 		 * Check the client handle for the version
3825*0Sstevel@tonic-gate 		 */
3826*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
3827*0Sstevel@tonic-gate 
3828*0Sstevel@tonic-gate 		/*
3829*0Sstevel@tonic-gate 		 * If the client is version 1, return error
3830*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
3831*0Sstevel@tonic-gate 		 */
3832*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
3833*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
3834*0Sstevel@tonic-gate 			    setno, hostname, NULL, NULL);
3835*0Sstevel@tonic-gate 			metarpcclose(clntp);
3836*0Sstevel@tonic-gate 			return (-1);
3837*0Sstevel@tonic-gate 		} else {
3838*0Sstevel@tonic-gate 			if (mdrpc_mn_susp_res_io_2(&v2_args, &res, clntp)
3839*0Sstevel@tonic-gate 							!= RPC_SUCCESS)
3840*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
3841*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
3842*0Sstevel@tonic-gate 				    "metad mn_susp_res_io control"));
3843*0Sstevel@tonic-gate 			else
3844*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
3845*0Sstevel@tonic-gate 		}
3846*0Sstevel@tonic-gate 
3847*0Sstevel@tonic-gate 		metarpcclose(clntp);
3848*0Sstevel@tonic-gate 	}
3849*0Sstevel@tonic-gate 
3850*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
3851*0Sstevel@tonic-gate 
3852*0Sstevel@tonic-gate 	if (! mdisok(ep)) {
3853*0Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
3854*0Sstevel@tonic-gate 			return (-1);
3855*0Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
3856*0Sstevel@tonic-gate 			return (-1);
3857*0Sstevel@tonic-gate 		mdclrerror(ep);
3858*0Sstevel@tonic-gate 	}
3859*0Sstevel@tonic-gate 
3860*0Sstevel@tonic-gate 	return (0);
3861*0Sstevel@tonic-gate }
3862*0Sstevel@tonic-gate 
3863*0Sstevel@tonic-gate /*
3864*0Sstevel@tonic-gate  * Resnarf the set after the set has been imported
3865*0Sstevel@tonic-gate  *
3866*0Sstevel@tonic-gate  * We should never be making this procedure call
3867*0Sstevel@tonic-gate  * over the wire, it's sole purpose is to snarf
3868*0Sstevel@tonic-gate  * the imported set on the localhost.
3869*0Sstevel@tonic-gate  */
3870*0Sstevel@tonic-gate int
3871*0Sstevel@tonic-gate clnt_resnarf_set(
3872*0Sstevel@tonic-gate 	char		*hostname,
3873*0Sstevel@tonic-gate 	set_t		setno,
3874*0Sstevel@tonic-gate 	md_error_t	*ep
3875*0Sstevel@tonic-gate )
3876*0Sstevel@tonic-gate {
3877*0Sstevel@tonic-gate 	CLIENT			*clntp;
3878*0Sstevel@tonic-gate 	mdrpc_setno_2_args	args;
3879*0Sstevel@tonic-gate 	mdrpc_generic_res	res;
3880*0Sstevel@tonic-gate 	int			rval = -1;
3881*0Sstevel@tonic-gate 	int			version;
3882*0Sstevel@tonic-gate 
3883*0Sstevel@tonic-gate 	/* initialize */
3884*0Sstevel@tonic-gate 	mdclrerror(ep);
3885*0Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
3886*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
3887*0Sstevel@tonic-gate 
3888*0Sstevel@tonic-gate 	/* build args */
3889*0Sstevel@tonic-gate 	args.rev = MD_METAD_ARGS_REV_1;
3890*0Sstevel@tonic-gate 	args.mdrpc_setno_2_args_u.rev1.setno = setno;
3891*0Sstevel@tonic-gate 	args.mdrpc_setno_2_args_u.rev1.cl_sk = NULL;
3892*0Sstevel@tonic-gate 
3893*0Sstevel@tonic-gate 	/* do it */
3894*0Sstevel@tonic-gate 	if (strcmp(mynode(), hostname) == 0) {
3895*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
3896*0Sstevel@tonic-gate 			return (-1);
3897*0Sstevel@tonic-gate 
3898*0Sstevel@tonic-gate 		/* Check the client handle for the version */
3899*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
3900*0Sstevel@tonic-gate 
3901*0Sstevel@tonic-gate 		/* If the client is version 1, return error */
3902*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
3903*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_CANTRESNARF, MD_SET_BAD,
3904*0Sstevel@tonic-gate 			    mynode(), NULL, NULL);
3905*0Sstevel@tonic-gate 		} else {
3906*0Sstevel@tonic-gate 			rval = mdrpc_resnarf_set_2(&args, &res, clntp);
3907*0Sstevel@tonic-gate 
3908*0Sstevel@tonic-gate 			if (rval != RPC_SUCCESS)
3909*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
3910*0Sstevel@tonic-gate 				    dgettext(TEXT_DOMAIN, "metad resnarf set"));
3911*0Sstevel@tonic-gate 			else
3912*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
3913*0Sstevel@tonic-gate 		}
3914*0Sstevel@tonic-gate 
3915*0Sstevel@tonic-gate 		metarpcclose(clntp);
3916*0Sstevel@tonic-gate 
3917*0Sstevel@tonic-gate 	} else {
3918*0Sstevel@tonic-gate 		(void) mddserror(ep, MDE_DS_CANTRESNARF, MD_SET_BAD,
3919*0Sstevel@tonic-gate 		    mynode(), NULL, NULL);
3920*0Sstevel@tonic-gate 	}
3921*0Sstevel@tonic-gate 
3922*0Sstevel@tonic-gate 	if (mdisok(ep))
3923*0Sstevel@tonic-gate 		rval = 0;
3924*0Sstevel@tonic-gate 
3925*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
3926*0Sstevel@tonic-gate 
3927*0Sstevel@tonic-gate 	return (rval);
3928*0Sstevel@tonic-gate }
3929*0Sstevel@tonic-gate 
3930*0Sstevel@tonic-gate /*
3931*0Sstevel@tonic-gate  * Call to start a resync for a given diskset.
3932*0Sstevel@tonic-gate  * Used when a node has been added to a diskset.
3933*0Sstevel@tonic-gate  * Should be called after rpc.mdcommd is resumed.
3934*0Sstevel@tonic-gate  */
3935*0Sstevel@tonic-gate int
3936*0Sstevel@tonic-gate clnt_mn_mirror_resync_all(
3937*0Sstevel@tonic-gate 	char			*hostname,
3938*0Sstevel@tonic-gate 	set_t			setno,
3939*0Sstevel@tonic-gate 	md_error_t		*ep
3940*0Sstevel@tonic-gate )
3941*0Sstevel@tonic-gate {
3942*0Sstevel@tonic-gate 	CLIENT					*clntp;
3943*0Sstevel@tonic-gate 	mdrpc_setno_2_args			args;
3944*0Sstevel@tonic-gate 	mdrpc_generic_res			res;
3945*0Sstevel@tonic-gate 	int					version;
3946*0Sstevel@tonic-gate 
3947*0Sstevel@tonic-gate 	/* initialize */
3948*0Sstevel@tonic-gate 	mdclrerror(ep);
3949*0Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
3950*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
3951*0Sstevel@tonic-gate 
3952*0Sstevel@tonic-gate 	/* build args */
3953*0Sstevel@tonic-gate 	args.rev = MD_METAD_ARGS_REV_1;
3954*0Sstevel@tonic-gate 	args.mdrpc_setno_2_args_u.rev1.setno = setno;
3955*0Sstevel@tonic-gate 	args.mdrpc_setno_2_args_u.rev1.cl_sk = NULL;
3956*0Sstevel@tonic-gate 
3957*0Sstevel@tonic-gate 	/* do it */
3958*0Sstevel@tonic-gate 	if (md_in_daemon && strcmp(mynode(), hostname) == 0) {
3959*0Sstevel@tonic-gate 		int	bool;
3960*0Sstevel@tonic-gate 		/*
3961*0Sstevel@tonic-gate 		 * Call v2 procedure directly if rpc.metad on this node is
3962*0Sstevel@tonic-gate 		 * sending message to itself.
3963*0Sstevel@tonic-gate 		 */
3964*0Sstevel@tonic-gate 		bool = mdrpc_mn_mirror_resync_all_2_svc(&args, &res, NULL);
3965*0Sstevel@tonic-gate 		assert(bool == TRUE);
3966*0Sstevel@tonic-gate 		(void) mdstealerror(ep, &res.status);
3967*0Sstevel@tonic-gate 	} else {
3968*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
3969*0Sstevel@tonic-gate 			return (-1);
3970*0Sstevel@tonic-gate 
3971*0Sstevel@tonic-gate 		/*
3972*0Sstevel@tonic-gate 		 * Check the client handle for the version
3973*0Sstevel@tonic-gate 		 */
3974*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
3975*0Sstevel@tonic-gate 
3976*0Sstevel@tonic-gate 		/*
3977*0Sstevel@tonic-gate 		 * If the client is version 1, return error
3978*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
3979*0Sstevel@tonic-gate 		 */
3980*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
3981*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
3982*0Sstevel@tonic-gate 			    setno, hostname, NULL, NULL);
3983*0Sstevel@tonic-gate 			metarpcclose(clntp);
3984*0Sstevel@tonic-gate 			return (-1);
3985*0Sstevel@tonic-gate 		} else {
3986*0Sstevel@tonic-gate 			if (mdrpc_mn_mirror_resync_all_2(&args, &res, clntp)
3987*0Sstevel@tonic-gate 							!= RPC_SUCCESS)
3988*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
3989*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
3990*0Sstevel@tonic-gate 				    "metad mn_mirror_resync_all"));
3991*0Sstevel@tonic-gate 			else
3992*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
3993*0Sstevel@tonic-gate 		}
3994*0Sstevel@tonic-gate 
3995*0Sstevel@tonic-gate 		metarpcclose(clntp);
3996*0Sstevel@tonic-gate 	}
3997*0Sstevel@tonic-gate 
3998*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
3999*0Sstevel@tonic-gate 
4000*0Sstevel@tonic-gate 	if (! mdisok(ep)) {
4001*0Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
4002*0Sstevel@tonic-gate 			return (-1);
4003*0Sstevel@tonic-gate 		if (strcmp(mynode(), hostname) == 0)
4004*0Sstevel@tonic-gate 			return (-1);
4005*0Sstevel@tonic-gate 		mdclrerror(ep);
4006*0Sstevel@tonic-gate 	}
4007*0Sstevel@tonic-gate 
4008*0Sstevel@tonic-gate 	return (0);
4009*0Sstevel@tonic-gate }
4010*0Sstevel@tonic-gate 
4011*0Sstevel@tonic-gate /*
4012*0Sstevel@tonic-gate  * Call to update the ABR state for all soft partitions.
4013*0Sstevel@tonic-gate  * Used when a node has been added to a diskset.
4014*0Sstevel@tonic-gate  * Should be called after rpc.mdcommd is resumed.
4015*0Sstevel@tonic-gate  */
4016*0Sstevel@tonic-gate int
4017*0Sstevel@tonic-gate clnt_mn_sp_update_abr(
4018*0Sstevel@tonic-gate 	char			*hostname,
4019*0Sstevel@tonic-gate 	set_t			setno,
4020*0Sstevel@tonic-gate 	md_error_t		*ep
4021*0Sstevel@tonic-gate )
4022*0Sstevel@tonic-gate {
4023*0Sstevel@tonic-gate 	CLIENT					*clntp;
4024*0Sstevel@tonic-gate 	mdrpc_setno_2_args			args;
4025*0Sstevel@tonic-gate 	mdrpc_generic_res			res;
4026*0Sstevel@tonic-gate 	int					version;
4027*0Sstevel@tonic-gate 
4028*0Sstevel@tonic-gate 	/* initialize */
4029*0Sstevel@tonic-gate 	mdclrerror(ep);
4030*0Sstevel@tonic-gate 	(void) memset(&args, 0, sizeof (args));
4031*0Sstevel@tonic-gate 	(void) memset(&res, 0, sizeof (res));
4032*0Sstevel@tonic-gate 
4033*0Sstevel@tonic-gate 	/* build args */
4034*0Sstevel@tonic-gate 	args.rev = MD_METAD_ARGS_REV_1;
4035*0Sstevel@tonic-gate 	args.mdrpc_setno_2_args_u.rev1.setno = setno;
4036*0Sstevel@tonic-gate 	args.mdrpc_setno_2_args_u.rev1.cl_sk = NULL;
4037*0Sstevel@tonic-gate 
4038*0Sstevel@tonic-gate 	/*
4039*0Sstevel@tonic-gate 	 * No need to call function if adding local node as ABR cannot
4040*0Sstevel@tonic-gate 	 * be set.
4041*0Sstevel@tonic-gate 	 */
4042*0Sstevel@tonic-gate 	if (strcmp(mynode(), hostname) != 0) {
4043*0Sstevel@tonic-gate 		if ((clntp = metarpcopen(hostname, CL_LONG_TMO, ep)) == NULL)
4044*0Sstevel@tonic-gate 			return (-1);
4045*0Sstevel@tonic-gate 
4046*0Sstevel@tonic-gate 		/*
4047*0Sstevel@tonic-gate 		 * Check the client handle for the version
4048*0Sstevel@tonic-gate 		 */
4049*0Sstevel@tonic-gate 		CLNT_CONTROL(clntp, CLGET_VERS, (char *)&version);
4050*0Sstevel@tonic-gate 
4051*0Sstevel@tonic-gate 		/*
4052*0Sstevel@tonic-gate 		 * If the client is version 1, return error
4053*0Sstevel@tonic-gate 		 * otherwise, make the remote procedure call.
4054*0Sstevel@tonic-gate 		 */
4055*0Sstevel@tonic-gate 		if (version == METAD_VERSION) { /* version 1 */
4056*0Sstevel@tonic-gate 			(void) mddserror(ep, MDE_DS_RPCVERSMISMATCH,
4057*0Sstevel@tonic-gate 			    setno, hostname, NULL, NULL);
4058*0Sstevel@tonic-gate 			metarpcclose(clntp);
4059*0Sstevel@tonic-gate 			return (-1);
4060*0Sstevel@tonic-gate 		} else {
4061*0Sstevel@tonic-gate 			if (mdrpc_mn_sp_update_abr_2(&args, &res, clntp)
4062*0Sstevel@tonic-gate 							!= RPC_SUCCESS)
4063*0Sstevel@tonic-gate 				(void) mdrpcerror(ep, clntp, hostname,
4064*0Sstevel@tonic-gate 				dgettext(TEXT_DOMAIN,
4065*0Sstevel@tonic-gate 				    "metad mn_sp_update_abr"));
4066*0Sstevel@tonic-gate 			else
4067*0Sstevel@tonic-gate 				(void) mdstealerror(ep, &res.status);
4068*0Sstevel@tonic-gate 		}
4069*0Sstevel@tonic-gate 
4070*0Sstevel@tonic-gate 		metarpcclose(clntp);
4071*0Sstevel@tonic-gate 	}
4072*0Sstevel@tonic-gate 
4073*0Sstevel@tonic-gate 	xdr_free(xdr_mdrpc_generic_res, (char *)&res);
4074*0Sstevel@tonic-gate 
4075*0Sstevel@tonic-gate 	if (! mdisok(ep)) {
4076*0Sstevel@tonic-gate 		if (! mdanyrpcerror(ep))
4077*0Sstevel@tonic-gate 			return (-1);
4078*0Sstevel@tonic-gate 		mdclrerror(ep);
4079*0Sstevel@tonic-gate 	}
4080*0Sstevel@tonic-gate 
4081*0Sstevel@tonic-gate 	return (0);
4082*0Sstevel@tonic-gate }
4083