xref: /titanic_41/usr/src/lib/lvm/libmeta/common/meta_namespace.c (revision 1687f56b4e67e718c63ad22d6206a0d6bd51820d)
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