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