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