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 * namespace utilities
30 */
31
32 #include <meta.h>
33
34 typedef struct deviceinfo {
35 char *bname; /* block name of the device */
36 char *dname; /* driver for the device */
37 minor_t mnum; /* minor number for the device */
38 } deviceinfo_t;
39
40 static deviceinfo_t devlist[MD_MNMAXSIDES];
41
42 /*
43 * Ask the driver for the device name, driver name, and minor number;
44 * which has been stored in the metadevice state database
45 * (on behalf of the utilities).
46 * (by key)
47 */
48 char *
meta_getnmentbykey(set_t setno,side_t sideno,mdkey_t key,char ** drvnm,minor_t * mnum,md_dev64_t * dev,md_error_t * ep)49 meta_getnmentbykey(
50 set_t setno,
51 side_t sideno,
52 mdkey_t key,
53 char **drvnm,
54 minor_t *mnum,
55 md_dev64_t *dev,
56 md_error_t *ep
57 )
58 {
59 struct mdnm_params nm;
60 static char device_name[MAXPATHLEN];
61
62 (void) memset(&nm, '\0', sizeof (nm));
63 nm.setno = setno;
64 nm.side = sideno;
65 nm.key = key;
66 nm.devname = (uint64_t)device_name;
67
68 if (metaioctl(MD_IOCGET_NM, &nm, &nm.mde, NULL) != 0) {
69 (void) mdstealerror(ep, &nm.mde);
70 return (NULL);
71 }
72
73 if (drvnm != NULL)
74 *drvnm = Strdup(nm.drvnm);
75
76 if (mnum != NULL)
77 *mnum = nm.mnum;
78
79 if (dev != NULL)
80 *dev = meta_expldev(makedevice(nm.major, nm.mnum));
81
82 return (Strdup(device_name));
83 }
84
85 /*
86 * Ask the driver for the hsp name, driver name, and minor number;
87 * which has been stored in the metadevice state database
88 * (on behalf of the utilities).
89 * (by key)
90 */
91 char *
meta_gethspnmentbyid(set_t setno,side_t sideno,hsp_t hspid,md_error_t * ep)92 meta_gethspnmentbyid(
93 set_t setno,
94 side_t sideno,
95 hsp_t hspid,
96 md_error_t *ep
97 )
98 {
99 struct mdhspnm_params nm;
100 char *device_name;
101
102 device_name = Malloc(MAXPATHLEN);
103 device_name[0] = '\0';
104
105 (void) memset(&nm, '\0', sizeof (nm));
106 nm.setno = setno;
107 nm.side = sideno;
108 nm.hspid = hspid;
109 nm.ret_hspid = MD_HSPID_WILD;
110 nm.hspname_len = MAXPATHLEN;
111 nm.hspname = (uintptr_t)device_name;
112
113 if (metaioctl(MD_IOCGET_HSP_NM, &nm, &nm.mde, NULL) != 0) {
114 (void) mdstealerror(ep, &nm.mde);
115 Free(device_name);
116 return (NULL);
117 }
118
119 return (device_name);
120 }
121
122 /*
123 * Ask the driver for the hsp_self_id;
124 * which has been stored in the metadevice state database
125 * (on behalf of the utilities).
126 * (by hsp name)
127 */
128 hsp_t
meta_gethspnmentbyname(set_t setno,side_t sideno,char * hspname,md_error_t * ep)129 meta_gethspnmentbyname(
130 set_t setno,
131 side_t sideno,
132 char *hspname,
133 md_error_t *ep
134 )
135 {
136 struct mdhspnm_params nm;
137 char *device_name;
138
139 /* must have a hsp name */
140 assert(hspname != NULL);
141
142 device_name = Malloc(MAXPATHLEN);
143 (void) strcpy(device_name, hspname);
144
145 (void) memset(&nm, '\0', sizeof (nm));
146 nm.setno = setno;
147 nm.side = sideno;
148 nm.hspid = MD_HSPID_WILD;
149 nm.ret_hspid = MD_HSPID_WILD;
150 nm.hspname_len = strlen(device_name) + 1;
151 nm.hspname = (uintptr_t)device_name;
152
153 /*
154 * The ioctl expects the a hsp name and return its hsp_self_id.
155 */
156 if (metaioctl(MD_IOCGET_HSP_NM, &nm, &nm.mde, NULL) != 0) {
157 (void) mdstealerror(ep, &nm.mde);
158 Free(device_name);
159 return (MD_HSP_NONE);
160 }
161
162 if (nm.ret_hspid == MD_HSPID_WILD) {
163 Free(device_name);
164 return (MD_HSP_NONE);
165 }
166
167 Free(device_name);
168 return (nm.ret_hspid);
169 }
170
171
172 /*
173 * Ask the driver for the minor name which has been stored in the
174 * metadevice state database.
175 * (by key)
176 */
177 char *
meta_getdidminorbykey(set_t setno,side_t sideno,mdkey_t key,md_error_t * ep)178 meta_getdidminorbykey(
179 set_t setno,
180 side_t sideno,
181 mdkey_t key,
182 md_error_t *ep
183 )
184 {
185 struct mdnm_params nm;
186 static char minorname[MAXPATHLEN];
187
188 (void) memset(&nm, '\0', sizeof (nm));
189 nm.setno = setno;
190 nm.side = sideno;
191 nm.key = key;
192 nm.minorname = (uint64_t)minorname;
193
194 if (metaioctl(MD_IOCGET_DIDMIN, &nm, &nm.mde, NULL) != 0) {
195 (void) mdstealerror(ep, &nm.mde);
196 return (NULL);
197 }
198
199 return (Strdup(minorname));
200 }
201
202 /*
203 * Ask the driver for the device id string which has been stored in the
204 * metadevice state database (on behalf of the utilities).
205 * (by key)
206 */
207 ddi_devid_t
meta_getdidbykey(set_t setno,side_t sideno,mdkey_t key,md_error_t * ep)208 meta_getdidbykey(
209 set_t setno,
210 side_t sideno,
211 mdkey_t key,
212 md_error_t *ep
213 )
214 {
215 struct mdnm_params nm;
216
217 (void) memset(&nm, '\0', sizeof (nm));
218 nm.setno = setno;
219 nm.side = sideno;
220 nm.key = key;
221
222 /*
223 * First ask the driver for the size of the device id string. This is
224 * signaled by passing the driver a devid_size of zero.
225 */
226 nm.devid_size = 0;
227 if (metaioctl(MD_IOCGET_DID, &nm, &nm.mde, NULL) != 0) {
228 (void) mdstealerror(ep, &nm.mde);
229 return (NULL);
230 }
231
232 /*
233 * If the devid_size is still zero then something is wrong.
234 */
235 if (nm.devid_size == 0) {
236 (void) mdstealerror(ep, &nm.mde);
237 return (NULL);
238 }
239
240 /*
241 * Now go get the actual device id string. Caller is responsible for
242 * free'ing device id memory buffer.
243 */
244 if ((nm.devid = (uintptr_t)malloc(nm.devid_size)) == NULL) {
245 return (NULL);
246 }
247 if (metaioctl(MD_IOCGET_DID, &nm, &nm.mde, NULL) != 0) {
248 (void) mdstealerror(ep, &nm.mde);
249 (void) free((void *)(uintptr_t)nm.devid);
250 return (NULL);
251 }
252
253 return ((void *)(uintptr_t)nm.devid);
254 }
255
256 /*
257 * set the devid.
258 */
259 int
meta_setdid(set_t setno,side_t sideno,mdkey_t key,md_error_t * ep)260 meta_setdid(
261 set_t setno,
262 side_t sideno,
263 mdkey_t key,
264 md_error_t *ep
265 )
266 {
267 struct mdnm_params nm;
268 int i;
269
270 (void) memset(&nm, '\0', sizeof (nm));
271 nm.setno = setno;
272 nm.side = sideno;
273 nm.key = key;
274
275 if (metaioctl(MD_IOCSET_DID, &nm, &nm.mde, NULL) != 0) {
276 (void) mdstealerror(ep, &nm.mde);
277 return (-1);
278 }
279
280 if (setno == MD_LOCAL_SET) {
281 /*
282 * If this is the local set then we are adding in the devids
283 * for the disks in the diskset and so this means adding
284 * a reference count for each side. Need to do this after
285 * the initial add so that the correct devid is picked up.
286 * The key is the key of the drive record and as such this
287 * means the minor number of the device which is used to
288 * get the devid. If the wrong side is used then it would
289 * be possible to get the wrong devid in the namespace, hence
290 * the requirement to process the local side first of all.
291 */
292 for (i = 0 + SKEW; i < MD_MAXSIDES; i++) {
293 /*
294 * We can just call the ioctl again because it will
295 * fail with ENOENT if the side does not exist, and
296 * more importantly does not increment the usage count
297 * on the devid.
298 */
299 nm.side = (side_t)i;
300 if (nm.side == sideno)
301 continue;
302 if (metaioctl(MD_IOCSET_DID, &nm, &nm.mde, NULL) != 0) {
303 if (mdissyserror(&nm.mde, ENODEV)) {
304 mdclrerror(&nm.mde);
305 } else {
306 (void) mdstealerror(ep, &nm.mde);
307 return (-1);
308 }
309 }
310 }
311 }
312 return (0);
313 }
314 /*
315 * Ask the driver for the name, which has been stored in the
316 * metadevice state database (on behalf of the utilities).
317 * (by key)
318 */
319 char *
meta_getnmbykey(set_t setno,side_t sideno,mdkey_t key,md_error_t * ep)320 meta_getnmbykey(
321 set_t setno,
322 side_t sideno,
323 mdkey_t key,
324 md_error_t *ep
325 )
326 {
327 return (meta_getnmentbykey(setno, sideno, key, NULL, NULL, NULL, ep));
328 }
329
330 /*
331 * Ask the driver for the device name, driver name, minor number, and key;
332 * which has been stored in the metadevice state database
333 * (on behalf of the utilities).
334 * (by md_dev64_t)
335 */
336 char *
meta_getnmentbydev(set_t setno,side_t sideno,md_dev64_t dev,char ** drvnm,minor_t * mnum,mdkey_t * key,md_error_t * ep)337 meta_getnmentbydev(
338 set_t setno,
339 side_t sideno,
340 md_dev64_t dev,
341 char **drvnm,
342 minor_t *mnum,
343 mdkey_t *key,
344 md_error_t *ep
345 )
346 {
347 struct mdnm_params nm;
348 static char device_name[MAXPATHLEN];
349
350 /* must have a dev */
351 assert(dev != NODEV64);
352
353 (void) memset(&nm, '\0', sizeof (nm));
354 nm.setno = setno;
355 nm.side = sideno;
356 nm.key = MD_KEYWILD;
357 nm.major = meta_getmajor(dev);
358 nm.mnum = meta_getminor(dev);
359 nm.devname = (uint64_t)device_name;
360
361 if (metaioctl(MD_IOCGET_NM, &nm, &nm.mde, NULL) != 0) {
362 (void) mdstealerror(ep, &nm.mde);
363 return (NULL);
364 }
365
366 /*
367 * With the friendly name work, each metadevice will have
368 * an NM entry. However, to allow backward compatibility,
369 * systems upgraded to a friendly name release won't have
370 * NM entries for the pre-existing top level metadevices. This
371 * implementation allows users to downgrade to a pre-friendly
372 * name release since the configuration information (mddb) is
373 * not modified.
374 *
375 * meta_getnmentbydev is called to get nm entry for all metadevices
376 * and expects the minor and major number and returns a key and
377 * name. For upgraded systems with pre-existing metadevices,
378 * the only returning value will be the name since there's no nm
379 * entry for pre-friendly name top level metadevices. So a return
380 * key for the device will not be available and will be NULL.
381 * Thus, the caller is responsible for making sure the returned key
382 * is valid, not NULL.
383 */
384 if (drvnm != NULL)
385 *drvnm = Strdup(nm.drvnm);
386 if (mnum != NULL)
387 *mnum = nm.mnum;
388
389 if (key != NULL)
390 *key = nm.retkey;
391
392 return (Strdup(device_name));
393 }
394
395 /*
396 * The arguments, minorname and devid, are only used with the partial
397 * import code and should be NULL otherwise.
398 */
399 int
add_name(mdsetname_t * sp,side_t sideno,mdkey_t key,char * dname,minor_t mnum,char * bname,char * minorname,ddi_devid_t devid,md_error_t * ep)400 add_name(
401 mdsetname_t *sp,
402 side_t sideno,
403 mdkey_t key,
404 char *dname,
405 minor_t mnum,
406 char *bname,
407 char *minorname, /* only used with a partial import */
408 ddi_devid_t devid, /* only used with a partial import */
409 md_error_t *ep
410 )
411 {
412 struct mdnm_params nm;
413
414 (void) memset(&nm, '\0', sizeof (nm));
415 nm.setno = sp->setno;
416 nm.side = sideno;
417 nm.key = key;
418 nm.mnum = mnum;
419 (void) strncpy(nm.drvnm, dname, sizeof (nm.drvnm));
420 nm.devname_len = strlen(bname) + 1;
421 nm.devname = (uintptr_t)bname;
422 if (devid && minorname) {
423 nm.minorname_len = strlen(minorname) + 1;
424 nm.minorname = (uintptr_t)minorname;
425 nm.devid_size = devid_sizeof(devid);
426 nm.devid = (uintptr_t)devid;
427 nm.imp_flag = MDDB_C_IMPORT;
428 }
429 if (metaioctl(MD_IOCSET_NM, &nm, &nm.mde, bname) < 0)
430 return (mdstealerror(ep, &nm.mde));
431
432 return (nm.key);
433 }
434
435 /*
436 * Remove the device name which corresponds to the given device number.
437 */
438 int
del_name(mdsetname_t * sp,side_t sideno,mdkey_t key,md_error_t * ep)439 del_name(
440 mdsetname_t *sp,
441 side_t sideno,
442 mdkey_t key,
443 md_error_t *ep
444 )
445 {
446 struct mdnm_params nm;
447
448 (void) memset(&nm, '\0', sizeof (nm));
449 nm.setno = sp->setno;
450 nm.side = sideno;
451 nm.key = key;
452
453 if (metaioctl(MD_IOCREM_NM, &nm, &nm.mde, NULL) != 0)
454 return (mdstealerror(ep, &nm.mde));
455
456 return (0);
457 }
458
459 static void
empty_devicelist()460 empty_devicelist()
461 {
462 side_t sideno;
463
464 for (sideno = 0; sideno < MD_MNMAXSIDES; sideno++) {
465 if (devlist[sideno].bname != (char *)NULL) {
466 Free(devlist[sideno].bname);
467 Free(devlist[sideno].dname);
468 devlist[sideno].mnum = NODEV;
469 }
470 }
471 }
472
473 static void
add_to_devicelist(side_t sideno,char * bname,char * dname,minor_t mnum)474 add_to_devicelist(
475 side_t sideno,
476 char *bname,
477 char *dname,
478 minor_t mnum
479 )
480 {
481 devlist[sideno].bname = Strdup(bname);
482 devlist[sideno].dname = Strdup(dname);
483
484 devlist[sideno].mnum = mnum;
485 }
486
487 /*
488 * Build a list of the names on the systems, if this fails the caller
489 * will tidy up the entries in the devlist.
490 */
491 static int
build_sidenamelist(mdsetname_t * sp,mdname_t * np,md_error_t * ep)492 build_sidenamelist(
493 mdsetname_t *sp,
494 mdname_t *np,
495 md_error_t *ep
496 )
497 {
498 side_t sideno = MD_SIDEWILD;
499 minor_t mnum = NODEV;
500 char *bname = NULL;
501 char *dname = NULL;
502 int err;
503
504 /*CONSTCOND*/
505 while (1) {
506
507 if ((err = meta_getnextside_devinfo(sp, np->bname, &sideno,
508 &bname, &dname, &mnum, ep)) == -1)
509 return (-1);
510
511 if (err == 0)
512 break;
513
514 /* the sideno gives us the index into the array */
515 add_to_devicelist(sideno, bname, dname, mnum);
516 }
517 return (0);
518 }
519
520 /*
521 * add name key
522 * the meta_create* functions should be the only ones using this. The
523 * adding of a name to the namespace must be done in a particular order
524 * to devid support for the disksets. The order is: add the 'local' side
525 * first of all, so the devid lookup in the kernel will use the correct
526 * device information and then add in the other sides.
527 */
528 int
add_key_name(mdsetname_t * sp,mdname_t * np,mdnamelist_t ** nlpp,md_error_t * ep)529 add_key_name(
530 mdsetname_t *sp,
531 mdname_t *np,
532 mdnamelist_t **nlpp,
533 md_error_t *ep
534 )
535 {
536 int err;
537 side_t sideno = MD_SIDEWILD;
538 side_t thisside;
539 mdkey_t key = MD_KEYWILD;
540 md_set_desc *sd;
541 int maxsides;
542
543 /* should have a set */
544 assert(sp != NULL);
545
546 if (! metaislocalset(sp)) {
547 if ((sd = metaget_setdesc(sp, ep)) == NULL) {
548 return (-1);
549 }
550 }
551
552 if (build_sidenamelist(sp, np, ep) == -1) {
553 empty_devicelist();
554 return (-1);
555 }
556
557 /*
558 * When a disk is added into the namespace the local information for
559 * that disk is added in first of all. For the local set this is not
560 * a concern and for the host that owns the diskset it is not a concern
561 * but when a disk is added in the remote namespace we *must* use the
562 * local information for that disk first of all. This is because when
563 * in the kernel (md_setdevname) the passed in dev_t is used to find
564 * the devid of the disk. This means we have to cater for the following:
565 *
566 * - a disk on the remote host having the dev_t that has been passed
567 * into the kernel and this disk is not actually the disk that is
568 * being added into the diskset.
569 * - the dev_t does not exist on this node
570 *
571 * So putting in the local information first of all makes sure that the
572 * dev_t passed into the kernel is correct with respect to that node
573 * and then any further additions for that name match on the key
574 * passed back.
575 */
576 thisside = getmyside(sp, ep);
577
578 if (devlist[thisside].dname == NULL ||
579 strlen(devlist[thisside].dname) == 0) {
580 /*
581 * Did not find the disk information for the disk. This can
582 * be because of an inconsistancy in the namespace: that is the
583 * devid we have in the namespace does not exist on the
584 * system and thus when looking up the disk information
585 * using this devid we fail to find anything.
586 */
587 (void) mdcomperror(ep, MDE_SP_COMP_OPEN_ERR, 0, np->dev,
588 np->cname);
589 empty_devicelist();
590 return (-1);
591 }
592
593 if ((err = add_name(sp, thisside, key, devlist[thisside].dname,
594 devlist[thisside].mnum, devlist[thisside].bname, NULL,
595 NULL, ep)) == -1) {
596 empty_devicelist();
597 return (-1);
598 }
599
600 /* We now have a 'key' so add in the other sides */
601 key = (mdkey_t)err;
602
603 if (metaislocalset(sp))
604 goto done;
605
606 if (MD_MNSET_DESC(sd))
607 maxsides = MD_MNMAXSIDES;
608 else
609 maxsides = MD_MAXSIDES;
610
611 for (sideno = 0; sideno < maxsides; sideno++) {
612 /* ignore thisside, as it has been added above */
613 if (sideno == thisside)
614 continue;
615
616 if (devlist[sideno].dname != NULL) {
617 err = add_name(sp, sideno, key, devlist[sideno].dname,
618 devlist[sideno].mnum, devlist[sideno].bname,
619 NULL, NULL, ep);
620 if (err == -1) {
621 empty_devicelist();
622 return (-1);
623 }
624 }
625 }
626
627 done:
628 empty_devicelist();
629 /* save key, return success */
630 np->key = key;
631 if (nlpp != NULL)
632 (void) metanamelist_append(nlpp, np);
633 return (0);
634 }
635
636 /*
637 * delete name key
638 * the meta_create* functions should be the only ones using this. The
639 * removal of the names must be done in a particular order: remove the
640 * non-local entries first of all and then finally the local entry.
641 */
642 int
del_key_name(mdsetname_t * sp,mdname_t * np,md_error_t * ep)643 del_key_name(
644 mdsetname_t *sp,
645 mdname_t *np,
646 md_error_t *ep
647 )
648 {
649 side_t sideno = MD_SIDEWILD;
650 int err;
651 int retval = 0;
652 side_t thisside;
653
654 /* should have a set */
655 assert(sp != NULL);
656
657 /* should have a key */
658 assert((np->key != MD_KEYWILD) && (np->key != MD_KEYBAD));
659
660 thisside = getmyside(sp, ep);
661
662 /* remove the remote sides first of all */
663 for (;;) {
664 if ((err = meta_getnextside_devinfo(sp, np->bname, &sideno,
665 NULL, NULL, NULL, ep)) == -1)
666 return (-1);
667
668 if (err == 0)
669 break;
670
671 /* ignore thisside */
672 if (thisside == sideno) {
673 continue;
674 }
675 if ((err = del_name(sp, sideno, np->key, ep)) == -1)
676 retval = -1;
677 }
678
679 /* now remove this side */
680 if (retval == 0)
681 if ((err = del_name(sp, thisside, np->key, ep)) == -1)
682 retval = -1;
683
684 np->key = MD_KEYBAD;
685 return (retval);
686 }
687
688 /*
689 * delete namelist keys
690 * the meta_create* functions should be the only ones using this
691 */
692 int
del_key_names(mdsetname_t * sp,mdnamelist_t * nlp,md_error_t * ep)693 del_key_names(
694 mdsetname_t *sp,
695 mdnamelist_t *nlp,
696 md_error_t *ep
697 )
698 {
699 mdnamelist_t *p;
700 md_error_t status = mdnullerror;
701 int rval = 0;
702
703 /* if ignoring errors */
704 if (ep == NULL)
705 ep = &status;
706
707 /* delete names */
708 for (p = nlp; (p != NULL); p = p->next) {
709 mdname_t *np = p->namep;
710
711 if (del_key_name(sp, np, ep) != 0)
712 rval = -1;
713 }
714
715 /* cleanup, return success */
716 if (ep == &status)
717 mdclrerror(&status);
718 return (rval);
719 }
720
721
722 /*
723 * This routine when is called will store the metadevice name
724 * when it is first created
725 */
726 mdkey_t
add_self_name(mdsetname_t * sp,char * uname,md_mkdev_params_t * params,md_error_t * ep)727 add_self_name(
728 mdsetname_t *sp,
729 char *uname,
730 md_mkdev_params_t *params,
731 md_error_t *ep
732 )
733 {
734 char *p, *devname;
735 side_t myside, side;
736 mdkey_t key;
737 md_set_desc *sd;
738 int len;
739 char *drvname = params->md_driver.md_drivername;
740 minor_t minor = MD_MKMIN(sp->setno, params->un);
741 md_mnnode_desc *mnside;
742
743 p = strrchr(uname, '/');
744 if (p == NULL)
745 p = uname;
746 else
747 p++;
748
749 /*
750 * The valid qualified name
751 */
752 if (metaislocalset(sp)) {
753 len = strlen(p) + strlen("/dev/md/dsk/") + 1;
754 devname = Malloc(len);
755 (void) strcpy(devname, "/dev/md/dsk/");
756 (void) strcat(devname, p);
757 } else {
758 len = strlen(sp->setname) + strlen(p) +
759 strlen("/dev/md//dsk/") + 1;
760 devname = Malloc(len);
761 (void) snprintf(devname, len, "/dev/md/%s/dsk/%s",
762 sp->setname, p);
763 }
764
765 /*
766 * Add self to the namespace
767 */
768 if ((myside = getmyside(sp, ep)) == MD_SIDEWILD) {
769 Free(devname);
770 return (-1);
771 }
772
773 if (metaislocalset(sp)) {
774 if ((key = add_name(sp, myside, MD_KEYWILD, drvname,
775 minor, devname, NULL, NULL, ep)) == MD_KEYBAD) {
776 Free(devname);
777 return (-1);
778 }
779 } else {
780 /*
781 * Add myside first and use the returned key to add other sides
782 */
783 if ((key = add_name(sp, myside, MD_KEYWILD, drvname,
784 minor, devname, NULL, NULL, ep)) == MD_KEYBAD) {
785 Free(devname);
786 return (-1);
787 }
788
789 /*
790 * Add for all other sides
791 */
792 if ((sd = metaget_setdesc(sp, ep)) == NULL) {
793 Free(devname);
794 return (-1);
795 }
796
797 if (MD_MNSET_DESC(sd)) {
798 for (mnside = sd->sd_nodelist; mnside != NULL;
799 mnside = mnside->nd_next) {
800 if (mnside->nd_nodeid == myside)
801 continue;
802 if (add_name(sp, mnside->nd_nodeid, key, drvname,
803 minor, devname, NULL, NULL, ep) == -1) {
804 Free(devname);
805 return (-1);
806 }
807 }
808 } else {
809 for (side = 0; side < MD_MAXSIDES; side++) {
810 if (sd->sd_nodes[side][0] == '\0')
811 continue;
812 if (side == myside)
813 continue;
814 if (add_name(sp, side, key, drvname, minor, devname,
815 NULL, NULL, ep) == -1) {
816 Free(devname);
817 return (-1);
818 }
819 }
820 }
821 }
822
823 Free(devname);
824 return (key);
825 }
826
827
828 /*
829 * This routine when is called will remove the metadevice name
830 * from the namespace and it is the last thing to do in the
831 * metaclear operation
832 */
833 int
del_self_name(mdsetname_t * sp,mdkey_t key,md_error_t * ep)834 del_self_name(
835 mdsetname_t *sp,
836 mdkey_t key,
837 md_error_t *ep
838 )
839 {
840 side_t myside;
841 int rval = 0;
842 side_t side;
843 md_set_desc *sd;
844 md_mnnode_desc *mnside;
845
846 assert(key != MD_KEYBAD);
847
848 if ((myside = getmyside(sp, ep)) == MD_SIDEWILD)
849 return (-1);
850
851 if (metaislocalset(sp)) {
852 rval = del_name(sp, myside, key, ep);
853 } else {
854 /*
855 * Remove all other sides first
856 */
857 if ((sd = metaget_setdesc(sp, ep)) == NULL) {
858 return (-1);
859 }
860
861 if (MD_MNSET_DESC(sd)) {
862 for (mnside = sd->sd_nodelist; mnside != NULL;
863 mnside = mnside->nd_next) {
864 if (mnside->nd_nodeid == myside)
865 continue;
866 if ((rval = del_name(sp, mnside->nd_nodeid, key,
867 ep)) == -1) {
868 goto out;
869 }
870 }
871 } else {
872 for (side = 0; side < MD_MAXSIDES; side++) {
873 if (sd->sd_nodes[side][0] == '\0')
874 continue;
875 if (side == myside)
876 continue;
877 if ((rval = del_name(sp, side, key, ep)) == -1) {
878 goto out;
879 }
880 }
881 }
882
883 /*
884 * del myside
885 */
886 rval = del_name(sp, myside, key, ep);
887 }
888
889 out:
890 return (rval);
891 }
892