xref: /titanic_41/usr/src/lib/lvm/libmeta/common/meta_namespace.c (revision 583bd2f30cd5d28d321c7bf1988876625975a6f6)
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 *
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 *
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 = (uint64_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
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 = (uint64_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 *
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
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
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 *
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 *
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 int
396 add_name(
397 	mdsetname_t	*sp,
398 	side_t		sideno,
399 	mdkey_t		key,
400 	char		*dname,
401 	minor_t		mnum,
402 	char		*bname,
403 	md_error_t	*ep
404 )
405 {
406 	struct mdnm_params	nm;
407 
408 	(void) memset(&nm, '\0', sizeof (nm));
409 	nm.setno = sp->setno;
410 	nm.side = sideno;
411 	nm.key = key;
412 	nm.mnum = mnum;
413 	(void) strncpy(nm.drvnm, dname, sizeof (nm.drvnm));
414 	nm.devname_len = strlen(bname) + 1;
415 	nm.devname = (uintptr_t)bname;
416 
417 	if (metaioctl(MD_IOCSET_NM, &nm, &nm.mde, bname) < 0)
418 		return (mdstealerror(ep, &nm.mde));
419 
420 	return (nm.key);
421 }
422 
423 /*
424  * Remove the device name which corresponds to the given device number.
425  */
426 int
427 del_name(
428 	mdsetname_t	*sp,
429 	side_t		sideno,
430 	mdkey_t		key,
431 	md_error_t	*ep
432 )
433 {
434 	struct mdnm_params	nm;
435 
436 	(void) memset(&nm, '\0', sizeof (nm));
437 	nm.setno = sp->setno;
438 	nm.side = sideno;
439 	nm.key = key;
440 
441 	if (metaioctl(MD_IOCREM_NM, &nm, &nm.mde, NULL) != 0)
442 		return (mdstealerror(ep, &nm.mde));
443 
444 	return (0);
445 }
446 
447 static void
448 empty_devicelist()
449 {
450 	side_t	sideno;
451 
452 	for (sideno = 0; sideno < MD_MNMAXSIDES; sideno++) {
453 		if (devlist[sideno].bname != (char *)NULL) {
454 			Free(devlist[sideno].bname);
455 			Free(devlist[sideno].dname);
456 			devlist[sideno].mnum = NODEV;
457 		}
458 	}
459 }
460 
461 static void
462 add_to_devicelist(
463 	side_t		sideno,
464 	char		*bname,
465 	char		*dname,
466 	minor_t		mnum
467 )
468 {
469 	devlist[sideno].bname = Strdup(bname);
470 	devlist[sideno].dname = Strdup(dname);
471 
472 	devlist[sideno].mnum = mnum;
473 }
474 
475 /*
476  * Build a list of the names on the systems, if this fails the caller
477  * will tidy up the entries in the devlist.
478  */
479 static int
480 build_sidenamelist(
481 	mdsetname_t	*sp,
482 	mdname_t	*np,
483 	md_error_t	*ep
484 )
485 {
486 	side_t		sideno = MD_SIDEWILD;
487 	minor_t		mnum = NODEV;
488 	char		*bname = NULL;
489 	char		*dname = NULL;
490 	int		err;
491 
492 	/*CONSTCOND*/
493 	while (1) {
494 
495 		if ((err = meta_getnextside_devinfo(sp, np->bname, &sideno,
496 		    &bname, &dname, &mnum, ep)) == -1)
497 			return (-1);
498 
499 		if (err == 0)
500 			break;
501 
502 		/* the sideno gives us the index into the array */
503 		add_to_devicelist(sideno, bname, dname, mnum);
504 	}
505 	return (0);
506 }
507 
508 /*
509  * add name key
510  * the meta_create* functions should be the only ones using this. The
511  * adding of a name to the namespace must be done in a particular order
512  * to devid support for the disksets. The order is: add the 'local' side
513  * first of all, so the devid lookup in the kernel will use the correct
514  * device information and then add in the other sides.
515  */
516 int
517 add_key_name(
518 	mdsetname_t	*sp,
519 	mdname_t	*np,
520 	mdnamelist_t	**nlpp,
521 	md_error_t	*ep
522 )
523 {
524 	int		err;
525 	side_t		sideno = MD_SIDEWILD;
526 	side_t		thisside;
527 	mdkey_t		key = MD_KEYWILD;
528 	md_set_desc	*sd;
529 	int		maxsides;
530 
531 	/* should have a set */
532 	assert(sp != NULL);
533 
534 	if (! metaislocalset(sp)) {
535 		if ((sd = metaget_setdesc(sp, ep)) == NULL) {
536 			return (-1);
537 		}
538 	}
539 
540 	if (build_sidenamelist(sp, np, ep) == -1) {
541 		empty_devicelist();
542 		return (-1);
543 	}
544 
545 	/*
546 	 * When a disk is added into the namespace the local information for
547 	 * that disk is added in first of all. For the local set this is not
548 	 * a concern and for the host that owns the diskset it is not a concern
549 	 * but when a disk is added in the remote namespace we *must* use the
550 	 * local information for that disk first of all. This is because when
551 	 * in the kernel (md_setdevname) the passed in dev_t is used to find
552 	 * the devid of the disk. This means we have to cater for the following:
553 	 *
554 	 * - a disk on the remote host having the dev_t that has been passed
555 	 *   into the kernel and this disk is not actually the disk that is
556 	 *   being added into the diskset.
557 	 * - the dev_t does not exist on this node
558 	 *
559 	 * So putting in the local information first of all makes sure that the
560 	 * dev_t passed into the kernel is correct with respect to that node
561 	 * and then any further additions for that name match on the key
562 	 * passed back.
563 	 */
564 	thisside = getmyside(sp, ep);
565 
566 	if (devlist[thisside].dname == NULL ||
567 	    strlen(devlist[thisside].dname) == 0) {
568 		/*
569 		 * Did not find the disk information for the disk. This can
570 		 * be because of an inconsistancy in the namespace: that is the
571 		 * devid we have in the namespace does not exist on the
572 		 * system and thus when looking up the disk information
573 		 * using this devid we fail to find anything.
574 		 */
575 		(void) mdcomperror(ep, MDE_SP_COMP_OPEN_ERR, 0, np->dev,
576 		    np->cname);
577 		empty_devicelist();
578 		return (-1);
579 	}
580 
581 	if ((err = add_name(sp, thisside, key, devlist[thisside].dname,
582 	    devlist[thisside].mnum, devlist[thisside].bname, ep)) == -1) {
583 		empty_devicelist();
584 		return (-1);
585 	}
586 
587 	/* We now have a 'key' so add in the other sides */
588 	key = (mdkey_t)err;
589 
590 	if (metaislocalset(sp))
591 		goto done;
592 
593 	if (MD_MNSET_DESC(sd))
594 		maxsides = MD_MNMAXSIDES;
595 	else
596 		maxsides = MD_MAXSIDES;
597 
598 	for (sideno = 0; sideno < maxsides; sideno++) {
599 		/* ignore thisside, as it has been added above */
600 		if (sideno == thisside)
601 			continue;
602 
603 		if (devlist[sideno].dname != NULL) {
604 			err = add_name(sp, sideno, key, devlist[sideno].dname,
605 			    devlist[sideno].mnum, devlist[sideno].bname, ep);
606 			if (err == -1) {
607 				empty_devicelist();
608 				return (-1);
609 			}
610 		}
611 	}
612 
613 done:
614 	empty_devicelist();
615 	/* save key, return success */
616 	np->key = key;
617 	if (nlpp != NULL)
618 		(void) metanamelist_append(nlpp, np);
619 	return (0);
620 }
621 
622 /*
623  * delete name key
624  * the meta_create* functions should be the only ones using this. The
625  * removal of the names must be done in a particular order: remove the
626  * non-local entries first of all and then finally the local entry.
627  */
628 int
629 del_key_name(
630 	mdsetname_t	*sp,
631 	mdname_t	*np,
632 	md_error_t	*ep
633 )
634 {
635 	side_t		sideno = MD_SIDEWILD;
636 	int		err;
637 	int		retval = 0;
638 	side_t		thisside;
639 
640 	/* should have a set */
641 	assert(sp != NULL);
642 
643 	/* should have a key */
644 	assert((np->key != MD_KEYWILD) && (np->key != MD_KEYBAD));
645 
646 	thisside = getmyside(sp, ep);
647 
648 	/* remove the remote sides first of all */
649 	for (;;) {
650 		if ((err = meta_getnextside_devinfo(sp, np->bname, &sideno,
651 		    NULL, NULL, NULL, ep)) == -1)
652 			return (-1);
653 
654 		if (err == 0)
655 			break;
656 
657 		/* ignore thisside */
658 		if (thisside == sideno) {
659 			continue;
660 		}
661 		if ((err = del_name(sp, sideno, np->key, ep)) == -1)
662 			retval = -1;
663 	}
664 
665 	/* now remove this side */
666 	if (retval == 0)
667 		if ((err = del_name(sp, thisside, np->key, ep)) == -1)
668 			retval = -1;
669 
670 	np->key = MD_KEYBAD;
671 	return (retval);
672 }
673 
674 /*
675  * delete namelist keys
676  * the meta_create* functions should be the only ones using this
677  */
678 int
679 del_key_names(
680 	mdsetname_t	*sp,
681 	mdnamelist_t	*nlp,
682 	md_error_t	*ep
683 )
684 {
685 	mdnamelist_t	*p;
686 	md_error_t	status = mdnullerror;
687 	int		rval = 0;
688 
689 	/* if ignoring errors */
690 	if (ep == NULL)
691 		ep = &status;
692 
693 	/* delete names */
694 	for (p = nlp; (p != NULL); p = p->next) {
695 		mdname_t	*np = p->namep;
696 
697 		if (del_key_name(sp, np, ep) != 0)
698 			rval = -1;
699 	}
700 
701 	/* cleanup, return success */
702 	if (ep == &status)
703 		mdclrerror(&status);
704 	return (rval);
705 }
706 
707 
708 /*
709  * This routine when is called will store the metadevice name
710  * when it is first created
711  */
712 mdkey_t
713 add_self_name(
714 	mdsetname_t	*sp,
715 	char 		*uname,
716 	md_mkdev_params_t	*params,
717 	md_error_t	*ep
718 )
719 {
720 	char		*p, *devname;
721 	side_t		myside, side;
722 	mdkey_t		key;
723 	md_set_desc	*sd;
724 	int		len;
725 	char		*drvname = params->md_driver.md_drivername;
726 	minor_t		minor = MD_MKMIN(sp->setno, params->un);
727 	md_mnnode_desc	*mnside;
728 
729 	p = strrchr(uname, '/');
730 	p = (p == NULL? uname : ++p);
731 
732 	/*
733 	 * The valid qualified name
734 	 */
735 	if (metaislocalset(sp)) {
736 	    len = strlen(p) + strlen("/dev/md/dsk/") + 1;
737 	    devname = Malloc(len);
738 	    (void) strcpy(devname, "/dev/md/dsk/");
739 	    (void) strcat(devname, p);
740 	} else {
741 	    len = strlen(sp->setname) + strlen(p) +
742 		strlen("/dev/md//dsk/") + 1;
743 	    devname = Malloc(len);
744 	    (void) snprintf(devname, len, "/dev/md/%s/dsk/%s",
745 			sp->setname, p);
746 	}
747 
748 	/*
749 	 * Add self to the namespace
750 	 */
751 	if ((myside = getmyside(sp, ep)) == MD_SIDEWILD) {
752 		Free(devname);
753 		return (-1);
754 	}
755 
756 	if (metaislocalset(sp)) {
757 	    if ((key = add_name(sp, myside, MD_KEYWILD, drvname,
758 		minor, devname, ep)) == MD_KEYBAD) {
759 			Free(devname);
760 			return (-1);
761 	    }
762 	} else {
763 		/*
764 		 * Add myside first and use the returned key to add other sides
765 		 */
766 		if ((key = add_name(sp, myside, MD_KEYWILD, drvname,
767 		    minor, devname, ep)) == MD_KEYBAD) {
768 			Free(devname);
769 			return (-1);
770 		}
771 
772 		/*
773 		 * Add for all other sides
774 		 */
775 		if ((sd = metaget_setdesc(sp, ep)) == NULL) {
776 			Free(devname);
777 			return (-1);
778 		}
779 
780 		if (MD_MNSET_DESC(sd)) {
781 		    for (mnside = sd->sd_nodelist; mnside != NULL;
782 			mnside = mnside->nd_next) {
783 			if (mnside->nd_nodeid == myside)
784 				continue;
785 			if (add_name(sp, mnside->nd_nodeid, key, drvname,
786 			    minor, devname, ep) == -1) {
787 				Free(devname);
788 				return (-1);
789 			}
790 		    }
791 		} else {
792 		    for (side = 0; side < MD_MAXSIDES; side++) {
793 			if (sd->sd_nodes[side][0] == '\0')
794 				continue;
795 			if (side == myside)
796 				continue;
797 			if (add_name(sp, side, key, drvname, minor, devname,
798 			    ep) == -1) {
799 				Free(devname);
800 				return (-1);
801 			}
802 		    }
803 		}
804 	}
805 
806 	Free(devname);
807 	return (key);
808 }
809 
810 
811 /*
812  * This routine when is called will remove the metadevice name
813  * from the namespace and it is the last thing to do in the
814  * metaclear operation
815  */
816 int
817 del_self_name(
818 	mdsetname_t	*sp,
819 	mdkey_t		key,
820 	md_error_t	*ep
821 )
822 {
823 	side_t		myside;
824 	int		rval = 0;
825 	side_t		side;
826 	md_set_desc	*sd;
827 	md_mnnode_desc	*mnside;
828 
829 	assert(key != MD_KEYBAD);
830 
831 	if ((myside = getmyside(sp, ep)) == MD_SIDEWILD)
832 		return (-1);
833 
834 	if (metaislocalset(sp)) {
835 		rval = del_name(sp, myside, key, ep);
836 	} else {
837 		/*
838 		 * Remove all other sides first
839 		 */
840 		if ((sd = metaget_setdesc(sp, ep)) == NULL) {
841 			return (-1);
842 		}
843 
844 		if (MD_MNSET_DESC(sd)) {
845 		    for (mnside = sd->sd_nodelist; mnside != NULL;
846 			mnside = mnside->nd_next) {
847 			if (mnside->nd_nodeid == myside)
848 				continue;
849 			if ((rval = del_name(sp, mnside->nd_nodeid, key,
850 			    ep)) == -1) {
851 				goto out;
852 			}
853 		    }
854 		} else {
855 		    for (side = 0; side < MD_MAXSIDES; side++) {
856 			if (sd->sd_nodes[side][0] == '\0')
857 				continue;
858 			if (side == myside)
859 				continue;
860 			if ((rval = del_name(sp, side, key, ep)) == -1) {
861 				goto out;
862 			}
863 		    }
864 		}
865 
866 		/*
867 		 * del myside
868 		 */
869 		rval = del_name(sp, myside, key, ep);
870 	}
871 
872 out:
873 	return (rval);
874 }
875