xref: /onnv-gate/usr/src/uts/common/io/lvm/md/md_names.c (revision 1945:74cee1cd404b)
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 #include <sys/errno.h>
29 #include <sys/debug.h>
30 #include <sys/sysmacros.h>
31 #include <sys/t_lock.h>
32 #include <sys/stat.h>
33 
34 #define	MDDB
35 #include <sys/lvm/mdvar.h>
36 #include <sys/lvm/md_names.h>
37 #include <sys/ddi.h>
38 #include <sys/sunddi.h>
39 
40 extern md_set_t	md_set[];
41 extern int	*md_nm_snarfed;
42 void		*lookup_entry(struct nm_next_hdr *, set_t,
43 			side_t, mdkey_t, md_dev64_t, int);
44 void		*lookup_shared_entry(struct nm_next_hdr *,
45 			mdkey_t, char *, mddb_recid_t *, int);
46 static void	add_to_devid_list(ddi_devid_t did);
47 static int	devid_is_unique(ddi_devid_t did);
48 static size_t	free_devid_list(int *count);
49 void		md_devid_cleanup(set_t, uint_t);
50 extern md_krwlock_t	nm_lock;
51 
52 typedef enum lookup_dev_result {
53 	LOOKUP_DEV_FOUND,	/* Found a good record. */
54 	LOOKUP_DEV_NOMATCH,	/* No matching record in DB. */
55 	LOOKUP_DEV_CONFLICT	/* Name conflicts with existing record. */
56 } lookup_dev_result_t;
57 
58 /* List of SVM module names. */
59 static char *meta_names[] = {
60 	"md",
61 	MD_STRIPE,
62 	MD_MIRROR,
63 	MD_TRANS,
64 	MD_HOTSPARES,
65 	MD_RAID,
66 	MD_VERIFY,
67 	MD_SP,
68 	MD_NOTIFY
69 };
70 
71 #define	META_NAME_COUNT	(sizeof (meta_names) / sizeof (char *))
72 
73 /*
74  * Used in translating from the md major name on miniroot to
75  * md major name on target system.  This is only needed during
76  * upgrade.
77  */
78 
79 extern major_t md_major, md_major_targ;
80 
81 /*
82  * During upgrade, SVM basically runs with the devt from the target
83  * being upgraded.  Translations are made from the miniroot devt to/from the
84  * target devt when the devt is to be stored in the SVM metadriver's
85  * unit structures.
86  *
87  * The following routines return a translated (aka miniroot) devt:
88  *	- md_getdevnum
89  *	- the metadriver's get_devs routines (stripe_getdevs, etc.)
90  *
91  * By the same token, the major number and major name conversion operations
92  * need to use the name_to_major file from the target system instead
93  * of the name_to_major file on the miniroot.  So, calls to
94  * ddi_name_to_major must be replaced with calls to md_targ_name_to_major
95  * when running on an upgrade.  Same is true with calls to
96  * ddi_major_to_name.
97  */
98 
99 static mdkey_t
100 create_key(struct nm_next_hdr *nh)
101 {
102 	mdkey_t	retval;
103 	struct nm_rec_hdr	*rh = (struct nm_rec_hdr *)nh->nmn_record;
104 
105 	retval = rh->r_next_key;
106 	/* increment the next_key, keeps them unique */
107 	rh->r_next_key++;
108 
109 	return (retval);
110 }
111 
112 static int
113 unused_key(struct nm_next_hdr *nh, int shared, mdkey_t key)
114 {
115 	mdkey_t	min_value;
116 	int	nmspace;
117 
118 	if (shared & NM_DEVID) {
119 		min_value = 1;
120 		nmspace = NM_DEVID;
121 	} else {
122 		min_value = ((shared & NM_SHARED) ? MDDB_FIRST_MODID : 1);
123 		nmspace = 0;
124 	}
125 
126 	/* Just say no if the key passed in is less than the initial */
127 	if (key < min_value)
128 		return (0);
129 
130 	if ((shared & NM_SHARED) && (lookup_shared_entry(nh, key, (char *)0,
131 		NULL, nmspace) != NULL))
132 		return (0);
133 
134 	/*
135 	 * The set num in lookup_entry is not used in this case
136 	 * we dont keep track of the nonshared in the devid nmspace
137 	 */
138 	if (!(shared & NM_NOTSHARED) &&
139 		(lookup_entry(nh, 0, -1, key, NODEV64, 0L) != NULL))
140 		return (0);
141 
142 	return (1);
143 }
144 
145 static void
146 destroy_key(struct nm_next_hdr *nh, int shared, mdkey_t key)
147 {
148 	struct nm_rec_hdr *rh = (struct nm_rec_hdr *)nh->nmn_record;
149 
150 	if ((key + 1) != rh->r_next_key)
151 		return;
152 
153 	while (unused_key(nh, shared, key))
154 		key--;
155 	rh->r_next_key = key + 1;
156 }
157 
158 static void
159 cleanup_unused_rec(set_t setno, int devid_nm)
160 {
161 	mddb_recid_t	recid;
162 	mddb_type_t	hdr, shr, notshr;
163 
164 	hdr = ((devid_nm & NM_DEVID) ? MDDB_DID_NM_HDR : MDDB_NM_HDR);
165 	notshr = ((devid_nm & NM_DEVID) ? MDDB_DID_NM : MDDB_NM);
166 	shr = ((devid_nm & NM_DEVID) ? MDDB_DID_SHR_NM : MDDB_SHR_NM);
167 
168 	recid = mddb_makerecid(setno, 0);
169 	while ((recid = mddb_getnextrec(recid, hdr, 0)) > 0)
170 		if (! (mddb_getrecprivate(recid) & MD_PRV_GOTIT))
171 			mddb_setrecprivate(recid, MD_PRV_PENDDEL);
172 
173 	recid = mddb_makerecid(setno, 0);
174 	while ((recid = mddb_getnextrec(recid, notshr, 0)) > 0)
175 		if (! (mddb_getrecprivate(recid) & MD_PRV_GOTIT))
176 			mddb_setrecprivate(recid, MD_PRV_PENDDEL);
177 
178 	recid = mddb_makerecid(setno, 0);
179 	while ((recid = mddb_getnextrec(recid, shr, 0)) > 0)
180 		if (! (mddb_getrecprivate(recid) & MD_PRV_GOTIT))
181 			mddb_setrecprivate(recid, MD_PRV_PENDDEL);
182 }
183 
184 static int
185 create_hdr(set_t setno, int shared)
186 {
187 	struct nm_header_hdr	*hhdr;
188 	mddb_recid_t		nmid;
189 
190 
191 	if (shared & NM_DEVID) {
192 		/*
193 		 * Deal with the device id name space
194 		 */
195 		nmid = md_set[setno].s_did_nmid =
196 			mddb_createrec(sizeof (struct nm_header),
197 				MDDB_DID_NM_HDR, 1, MD_CRO_32BIT, setno);
198 		/*
199 		 * Out of space
200 		 */
201 		if (nmid < 0)
202 			return (nmid);
203 	} else {
204 		nmid = md_set[setno].s_nmid =
205 			mddb_createrec(sizeof (struct nm_header),
206 				MDDB_NM_HDR, 1, MD_CRO_32BIT, setno);
207 		/*
208 		 * Out of space
209 		 */
210 		if (nmid < 0)
211 			return (nmid);
212 	}
213 
214 	hhdr = kmem_zalloc(sizeof (*hhdr), KM_SLEEP);
215 
216 	if (shared & NM_DEVID) {
217 		md_set[setno].s_did_nm = hhdr;
218 	} else {
219 		md_set[setno].s_nm = hhdr;
220 	}
221 
222 	hhdr->hh_header = (struct nm_header *)mddb_getrecaddr(nmid);
223 	hhdr->hh_names.nmn_record = &(hhdr->hh_header->h_names);
224 	hhdr->hh_shared.nmn_record = &(hhdr->hh_header->h_shared);
225 
226 	/*
227 	 * h_names.r_next_key is set to zero in devid nmspace
228 	 * since we dont keep track of it
229 	 */
230 	if (shared & NM_DEVID) {
231 		hhdr->hh_header->h_names.r_next_key = 0;
232 		hhdr->hh_header->h_shared.r_next_key = 1;
233 	} else {
234 		hhdr->hh_header->h_names.r_next_key = 1;
235 		hhdr->hh_header->h_shared.r_next_key = MDDB_FIRST_MODID;
236 	}
237 
238 	mddb_commitrec_wrapper(nmid);
239 	return (0);
240 }
241 
242 static int
243 create_record(
244 	mddb_recid_t		p_recid,	/* parent recid */
245 	struct nm_next_hdr	*nh,		/* parent record header */
246 	int			shared,
247 	size_t			needed_space)
248 {
249 	struct nm_rec_hdr	*rh = (struct nm_rec_hdr *)nh->nmn_record;
250 	struct nm_next_hdr	*new_nh;
251 	mddb_type_t		rec_type;
252 	size_t			used_size;
253 	size_t			alloc_size;
254 	mddb_recid_t		recids[3];
255 	set_t			setno;
256 	mddb_recid_t		new_id;
257 
258 	setno = mddb_getsetnum(p_recid);
259 
260 	if (shared & NM_DEVID) {
261 		/*
262 		 * Device id name space
263 		 */
264 		rec_type = ((shared & NM_SHARED) ?
265 			MDDB_DID_SHR_NM : MDDB_DID_NM);
266 		used_size = ((shared & NM_SHARED) ?
267 			(sizeof (struct devid_shr_rec) -
268 				sizeof (struct did_shr_name)) :
269 			(sizeof (struct devid_min_rec) -
270 				sizeof (struct did_min_name)));
271 		alloc_size = ((shared & NM_SHARED) ?
272 			NM_DID_ALLOC_SIZE : NM_ALLOC_SIZE);
273 	} else {
274 		rec_type = ((shared & NM_SHARED) ?
275 			MDDB_SHR_NM : MDDB_NM);
276 		used_size = ((shared & NM_SHARED) ?
277 			(sizeof (struct nm_shr_rec) -
278 				sizeof (struct nm_shared_name)) :
279 			(sizeof (struct nm_rec) - sizeof (struct nm_name)));
280 		alloc_size = NM_ALLOC_SIZE;
281 	}
282 
283 	used_size += needed_space;
284 
285 	new_id = mddb_createrec((size_t)alloc_size, rec_type, 1,
286 		MD_CRO_32BIT, setno);
287 	if (new_id < 0)
288 		return (new_id);
289 
290 	recids[0] = rh->r_next_recid = new_id;
291 	recids[1] = p_recid;
292 	recids[2] = 0;
293 
294 	new_nh = (struct nm_next_hdr *)kmem_zalloc(sizeof (*new_nh), KM_SLEEP);
295 	nh->nmn_nextp = new_nh;
296 	new_nh->nmn_record = mddb_getrecaddr(rh->r_next_recid);
297 
298 	((struct nm_rec_hdr *)new_nh->nmn_record)->r_alloc_size = alloc_size;
299 	((struct nm_rec_hdr *)new_nh->nmn_record)->r_used_size =
300 		(uint_t)used_size;
301 
302 	mddb_commitrecs_wrapper(recids);
303 	return (0);
304 }
305 
306 static int
307 expand_record(
308 	struct nm_next_hdr	*parent_nh,	/* parent record header */
309 	mddb_recid_t		parent_recid,	/* parent record id */
310 	struct nm_next_hdr	*nh,		/* record hdr to be expanded */
311 	int			shared)		/* boolean - shared or not */
312 {
313 	struct nm_rec_hdr	*rh = (struct nm_rec_hdr *)nh->nmn_record;
314 	struct nm_rec_hdr	*parent_rh = (struct nm_rec_hdr *)
315 						parent_nh->nmn_record;
316 	struct nm_rec_hdr	*new_rh;
317 	void			*new_rec;
318 	mddb_recid_t		new_id;
319 	mddb_recid_t		old_id;
320 	mddb_recid_t		recids[3];
321 	set_t			setno;
322 	mddb_type_t		rec_type;
323 	size_t			alloc_size;
324 
325 	setno = mddb_getsetnum(parent_recid);
326 
327 	if (shared & NM_DEVID) {
328 		/*
329 		 * Device id name space
330 		 */
331 		rec_type = ((shared & NM_SHARED) ?
332 			MDDB_DID_SHR_NM : MDDB_DID_NM);
333 		alloc_size = ((shared & NM_SHARED) ?
334 			NM_DID_ALLOC_SIZE : NM_ALLOC_SIZE);
335 	} else {
336 		rec_type = ((shared & NM_SHARED) ? MDDB_SHR_NM : MDDB_NM);
337 		alloc_size = NM_ALLOC_SIZE;
338 	}
339 
340 	new_id = mddb_createrec((size_t)rh->r_alloc_size + alloc_size, rec_type,
341 			1, MD_CRO_32BIT, setno);
342 	/*
343 	 * No space
344 	 */
345 	if (new_id < 0)
346 		return (new_id);
347 
348 	new_rec = mddb_getrecaddr(new_id);
349 	(void) bcopy(rh, new_rec, rh->r_alloc_size);
350 
351 	recids[0] = parent_recid;
352 	recids[1] = new_id;
353 	recids[2] = 0;
354 
355 	/* Fix up rec hdr to point at this new record */
356 	nh->nmn_record = new_rec;
357 	old_id = parent_rh->r_next_recid;
358 	parent_rh->r_next_recid = new_id;
359 
360 	if (shared & NM_DEVID)
361 		/*
362 		 * Device id name space
363 		 */
364 		new_rh = ((shared & NM_SHARED) ?
365 		    &((struct devid_shr_rec *)new_rec)->did_rec_hdr :
366 		    &((struct devid_min_rec *)new_rec)->min_rec_hdr);
367 	else
368 		new_rh = ((shared & NM_SHARED) ?
369 		    &((struct nm_shr_rec *)new_rec)->sr_rec_hdr :
370 		    &((struct nm_rec *)new_rec)->r_rec_hdr);
371 
372 	new_rh->r_alloc_size += alloc_size;
373 	if (!(shared & NM_NOCOMMIT))
374 		mddb_commitrecs_wrapper(recids);
375 
376 	/* delete the old record */
377 	mddb_deleterec_wrapper(old_id);
378 
379 	return (0);
380 }
381 
382 struct nm_next_hdr *
383 get_first_record(set_t setno, int alloc, int shared)
384 {
385 	struct nm_next_hdr	*nh;
386 	mddb_recid_t		nmid;
387 
388 	ASSERT(md_get_setstatus(setno) & MD_SET_NM_LOADED);
389 
390 	if (shared & NM_DEVID) {
391 		/*
392 		 * We are dealing with the device id name space.
393 		 * If set is a MN diskset, just return 0 since
394 		 * devids aren't yet supported in MN disksets.
395 		 */
396 		if (MD_MNSET_SETNO(setno))
397 			return ((struct nm_next_hdr *)0);
398 		if (md_set[setno].s_did_nm == NULL)
399 			if (create_hdr(setno, shared) < 0)
400 				return ((struct nm_next_hdr *)0);
401 
402 		nh = ((shared & NM_SHARED) ?
403 		    &((struct nm_header_hdr *)md_set[setno].s_did_nm)->hh_shared
404 		    :
405 		    &((struct nm_header_hdr *)
406 		    md_set[setno].s_did_nm)->hh_names);
407 
408 		nmid = md_set[setno].s_did_nmid;
409 	} else {
410 		/*
411 		 * We are dealing with the regular one (non-devid)
412 		 */
413 		if (md_set[setno].s_nm == NULL)
414 			if (create_hdr(setno, shared) < 0)
415 				return ((struct nm_next_hdr *)0);
416 
417 		nh = ((shared & NM_SHARED) ?
418 		    &((struct nm_header_hdr *)md_set[setno].s_nm)->hh_shared
419 		    :
420 		    &((struct nm_header_hdr *)md_set[setno].s_nm)->hh_names);
421 
422 		nmid = md_set[setno].s_nmid;
423 	}
424 
425 	/*
426 	 * Name space exists
427 	 */
428 	if (nh->nmn_nextp != NULL)
429 		return (nh);
430 
431 	/*
432 	 * If name space is expected and is empty
433 	 */
434 	if (! alloc)
435 		return ((struct nm_next_hdr *)0);
436 
437 	/*
438 	 * Empty is okay alloc it
439 	 */
440 	if (create_record(nmid, nh, shared, 0L) < 0)
441 		return ((struct nm_next_hdr *)0);
442 
443 	return (nh);
444 }
445 
446 
447 void *
448 alloc_entry(
449 	struct nm_next_hdr *nh,		/* parent name header */
450 	mddb_recid_t recid,		/* parent record id */
451 	size_t len,			/* length of entry */
452 	int shared,			/* shared boolean */
453 	mddb_recid_t *id)		/* return of new record id */
454 {
455 	struct nm_rec_hdr	*rh;		/* parent */
456 	mddb_recid_t		this_recid;
457 	struct nm_next_hdr	*this_nh;
458 	struct nm_rec_hdr	*this_rh;
459 	void			*this_rec;
460 	size_t			needed_space;
461 	char			*name;
462 
463 	if (shared & NM_DEVID)
464 		/*
465 		 * Device id name space
466 		 */
467 		needed_space = ((shared & NM_SHARED) ?
468 			sizeof (struct did_shr_name) :
469 			sizeof (struct did_min_name)) + len - 1;
470 	else
471 		needed_space = ((shared & NM_SHARED) ?
472 			sizeof (struct nm_shared_name) :
473 			sizeof (struct nm_name)) + len - 1;
474 
475 	needed_space = roundup(needed_space, sizeof (uint_t));
476 
477 	/* check the next record to see if it has space */
478 	/*CONSTCOND*/
479 	while (1) {
480 		while ((this_nh = nh->nmn_nextp) != NULL) {
481 
482 			rh = (struct nm_rec_hdr *)nh->nmn_record;
483 			this_recid = rh->r_next_recid;
484 			this_rec = this_nh->nmn_record;
485 
486 			if (shared & NM_DEVID)
487 			    this_rh = ((shared & NM_SHARED) ?
488 			    &((struct devid_shr_rec *)this_rec)->did_rec_hdr :
489 			    &((struct devid_min_rec *)this_rec)->min_rec_hdr);
490 			else
491 			    this_rh = ((shared & NM_SHARED) ?
492 			    &((struct nm_shr_rec *)this_rec)->sr_rec_hdr :
493 			    &((struct nm_rec *)this_rec)->r_rec_hdr);
494 
495 			/* check for space in this record */
496 			if ((this_rh->r_alloc_size - this_rh->r_used_size) >=
497 			    needed_space) {
498 				/* allocate space in this record */
499 				name = (char *)this_rec + this_rh->r_used_size;
500 				this_rh->r_used_size += (uint_t)needed_space;
501 				if (!(shared & NM_NOCOMMIT))
502 					mddb_commitrec_wrapper(this_recid);
503 				*id = this_recid;
504 				return ((caddr_t)name);
505 			}
506 
507 			/* if we can expand the record we look again */
508 			if (expand_record(nh, recid, this_nh, shared) == 0)
509 				continue;
510 
511 			/* advance parent to this record, and go try next */
512 			recid = this_recid;
513 			nh = this_nh;
514 		}
515 
516 		/* no space, try creating a new record after parent */
517 		if (create_record(recid, nh, shared, 0L) < 0)
518 			return ((caddr_t)0);
519 	} /* go check the new record */
520 	/* can't get here, but lint seems to think so */
521 	/* NOTREACHED */
522 }
523 
524 static void *
525 get_next_entry(
526 	struct nm_next_hdr *nh,
527 	caddr_t ent,
528 	size_t ent_size,
529 	size_t *off)
530 {
531 
532 	if (((struct nm_rec_hdr *)nh->nmn_record)->r_used_size <=
533 			(*off + ent_size)) {
534 		if (nh->nmn_nextp == NULL)
535 			return ((caddr_t)0);
536 
537 		/* offset == 0, means go to next record */
538 		*off = 0;
539 		return ((caddr_t)0);
540 	}
541 
542 	*off += ent_size;
543 	return ((caddr_t)((char *)ent + ent_size));
544 }
545 
546 static int
547 rem_entry(
548 	struct nm_next_hdr *nh,	/* record header for entry being removed */
549 	mddb_recid_t id,	/* record id for entry being removed */
550 	void *ent,		/* address of entry to be removed */
551 	size_t ent_size,	/* size of entry to be removed */
552 	size_t offset,		/* offset of entry within record */
553 	int devid_nm)		/* which name space? 0 - primary */
554 {
555 	struct nm_next_hdr	*first_nh;
556 	mddb_recid_t		recids[3];
557 	size_t			c = ((struct nm_rec_hdr *)
558 				    nh->nmn_record)->r_used_size - offset -
559 				    ent_size;
560 	set_t			setno;
561 	mdkey_t			ent_key;
562 
563 
564 	setno = mddb_getsetnum(id);
565 	first_nh = get_first_record(setno, 0, devid_nm | NM_NOTSHARED);
566 	ASSERT(first_nh != NULL);
567 
568 	recids[0] = id;
569 	recids[1] = ((devid_nm & NM_DEVID) ? md_set[setno].s_did_nmid :
570 		md_set[setno].s_nmid);
571 	recids[2] = 0;
572 	ent_key = ((devid_nm & NM_DEVID) ?
573 		((struct did_min_name *)ent)->min_key :
574 		((struct nm_name *)ent)->n_key);
575 
576 	if (c == 0)
577 		(void) bzero(ent, ent_size);	/* last entry */
578 	else {
579 		(void) ovbcopy((caddr_t)ent+ent_size, ent, c);
580 		(void) bzero((caddr_t)ent+c, ent_size);
581 	}
582 
583 	((struct nm_rec_hdr *)nh->nmn_record)->r_used_size -= (uint_t)ent_size;
584 
585 	/*
586 	 * We don't keep track of keys in the device id nonshared namespace
587 	 */
588 	if (!devid_nm)
589 		destroy_key(first_nh, NM_NOTSHARED, ent_key);
590 
591 	mddb_commitrecs_wrapper(recids);
592 	return (0);
593 }
594 
595 static int
596 rem_shr_entry(
597 	struct nm_next_hdr *nh,	/* record header for entry being removed */
598 	mddb_recid_t id,	/* record id for entry being removed */
599 	void *ent,		/* address of entry to be removed */
600 	size_t ent_size,	/* size of entry to be removed */
601 	size_t offset,		/* offset of entry within record */
602 	int devid_nm)		/* which name space? 0 - primary */
603 {
604 	struct nm_next_hdr	*first_nh;
605 	mddb_recid_t		recids[3];
606 	size_t			c = ((struct nm_rec_hdr *)
607 				    nh->nmn_record)->r_used_size - offset -
608 				    ent_size;
609 	set_t			setno;
610 	uint_t			count;
611 
612 	setno = mddb_getsetnum(id);
613 	first_nh = get_first_record(setno, 0, devid_nm | NM_SHARED);
614 	ASSERT(first_nh != NULL);
615 
616 	recids[0] = id;
617 	recids[1] = ((devid_nm & NM_DEVID) ? md_set[setno].s_did_nmid :
618 		md_set[setno].s_nmid);
619 	recids[2] = 0;
620 
621 	if (devid_nm & NM_DEVID) {
622 		count = --((struct did_shr_name *)ent)->did_count;
623 	} else {
624 		count = --((struct nm_shared_name *)ent)->sn_count;
625 	}
626 
627 	if (count == 0 || devid_nm & NM_IMP_SHARED) {
628 		mdkey_t	ent_key;
629 
630 		ent_key = ((devid_nm & NM_DEVID) ?
631 			((struct did_shr_name *)ent)->did_key :
632 			((struct nm_shared_name *)ent)->sn_key);
633 
634 		if (c == 0)
635 			(void) bzero(ent, ent_size);	/* last entry */
636 		else {
637 			(void) ovbcopy((caddr_t)ent+ent_size, ent, c);
638 			(void) bzero((caddr_t)ent+c, ent_size);
639 		}
640 
641 		((struct nm_rec_hdr *)nh->nmn_record)->r_used_size -=
642 			(uint_t)ent_size;
643 		destroy_key(first_nh, devid_nm | NM_SHARED, ent_key);
644 	}
645 
646 	if (!(devid_nm & NM_NOCOMMIT))
647 		mddb_commitrecs_wrapper(recids);
648 	return (0);
649 }
650 
651 static mdkey_t
652 setshared_name(set_t setno, char *shrname, mdkey_t shrkey, int devid_nm)
653 {
654 	struct nm_next_hdr	*nh;
655 	struct nm_shared_name	*shn;
656 	struct did_shr_name	*did_shn = (struct did_shr_name *)NULL;
657 	mddb_recid_t		recid;
658 	mddb_recid_t		recids[3];
659 	size_t			len;
660 	mdkey_t			key;
661 	int			shared = NM_SHARED;
662 
663 
664 	if (shrkey == MD_KEYWILD) {
665 		len = ((devid_nm & NM_DEVID) ?
666 		    ddi_devid_sizeof((ddi_devid_t)shrname) :
667 		    (strlen(shrname) + 1));
668 	}
669 	/*
670 	 * If devid_nm is not NULL, nh will point to the did name space
671 	 */
672 	if (devid_nm & NM_NOCOMMIT) {
673 		if ((nh = get_first_record(setno, 0, devid_nm | NM_SHARED))
674 		    == NULL)
675 			return (MD_KEYBAD);
676 	} else {
677 		if ((nh = get_first_record(setno, 1, devid_nm | NM_SHARED))
678 		    == NULL)
679 			return (MD_KEYBAD);
680 	}
681 	if (devid_nm & NM_NOCOMMIT)
682 		shared = NM_NOCOMMIT  | shared;
683 	if (devid_nm & NM_DEVID) {
684 		/*
685 		 * A key has been supplied so find the corresponding entry
686 		 * which must exist.
687 		 */
688 		if (shrkey != MD_KEYWILD) {
689 			did_shn = (struct did_shr_name *)lookup_shared_entry(nh,
690 			    shrkey, NULL, &recid, devid_nm);
691 			if (did_shn == (struct did_shr_name *)NULL)
692 				return (MD_KEYBAD);
693 		} else {
694 			did_shn = (struct did_shr_name *)lookup_shared_entry(nh,
695 			    0, shrname, &recid, devid_nm);
696 		}
697 		if (did_shn != (struct did_shr_name *)NULL) {
698 			did_shn->did_count++;
699 			if (!(devid_nm & NM_NOCOMMIT))
700 				mddb_commitrec_wrapper(recid);
701 			return (did_shn->did_key);
702 		}
703 
704 
705 		/* allocate an entry and fill it in */
706 		if ((did_shn = (struct did_shr_name *)alloc_entry(nh,
707 			md_set[setno].s_did_nmid, len, shared | NM_DEVID,
708 			&recid)) == NULL)
709 			return (MD_KEYBAD);
710 		did_shn->did_key = create_key(nh);
711 		did_shn->did_count = 1;
712 		did_shn->did_size = (ushort_t)len;
713 		/*
714 		 * Let the whole world know it is valid devid
715 		 */
716 		did_shn->did_data = NM_DEVID_VALID;
717 		bcopy((void *)shrname, (void *)did_shn->did_devid, len);
718 		key = did_shn->did_key;
719 	} else {
720 		if ((shn = (struct nm_shared_name *)lookup_shared_entry(nh,
721 			0, shrname, &recid, 0L)) != NULL) {
722 			/* Increment reference count */
723 			shn->sn_count++;
724 			if (!(devid_nm & NM_NOCOMMIT))
725 				mddb_commitrec_wrapper(recid);
726 			return (shn->sn_key);
727 		}
728 
729 		/* allocate an entry and fill it in */
730 		if ((shn = (struct nm_shared_name *)alloc_entry(nh,
731 		    md_set[setno].s_nmid, len, shared, &recid)) == NULL)
732 			return (MD_KEYBAD);
733 		shn->sn_key = create_key(nh);
734 		shn->sn_count = 1;
735 		shn->sn_namlen = (ushort_t)len;
736 		(void) strcpy(shn->sn_name, shrname);
737 		key = shn->sn_key;
738 	}
739 
740 	recids[0] = recid;
741 	recids[1] = ((devid_nm & NM_DEVID) ? md_set[setno].s_did_nmid :
742 			md_set[setno].s_nmid);
743 	recids[2] = 0;
744 
745 	if (!(devid_nm & NM_NOCOMMIT))
746 		mddb_commitrecs_wrapper(recids);
747 	return (key);
748 }
749 
750 void *
751 getshared_name(set_t setno, mdkey_t shrkey, int devid_nm)
752 {
753 	char			*shn;
754 	struct nm_next_hdr	*nh;
755 	mddb_recid_t		recid;
756 
757 	if ((nh = get_first_record(setno, 0, devid_nm | NM_SHARED)) == NULL)
758 		return ((void *)0);
759 
760 	shn = (char *)((devid_nm & NM_DEVID) ?
761 		lookup_shared_entry(nh, shrkey, (char *)0, &recid, devid_nm) :
762 		lookup_shared_entry(nh, shrkey, (char *)0, &recid, 0L));
763 
764 	if (shn == NULL)
765 		return ((void *)0);
766 
767 	return ((void *)((devid_nm & NM_DEVID) ?
768 		((struct did_shr_name *)shn)->did_devid :
769 		((struct nm_shared_name *)shn)->sn_name));
770 }
771 
772 static mdkey_t
773 getshared_key(set_t setno, char *shrname, int devid_nm)
774 {
775 	struct nm_next_hdr	*nh;
776 	char			*shn;
777 	mddb_recid_t		recid;
778 
779 	if ((nh = get_first_record(setno, 1, devid_nm |  NM_SHARED)) == NULL)
780 		return (MD_KEYBAD);
781 
782 	shn = (char *)lookup_shared_entry(nh, 0, shrname, &recid, devid_nm);
783 
784 	if (shn == NULL)
785 		return (MD_KEYBAD);
786 
787 	return (((devid_nm & NM_DEVID) ?
788 		((struct did_shr_name *)shn)->did_key :
789 		((struct nm_shared_name *)shn)->sn_key));
790 }
791 
792 static int
793 setshared_data(set_t setno, mdkey_t shrkey, caddr_t data)
794 {
795 	struct nm_shared_name	*shn;
796 	struct nm_next_hdr	*nh;
797 	mddb_recid_t		recid;
798 
799 	if ((nh = get_first_record(setno, 0, NM_SHARED)) == NULL)
800 		return (ENOENT);
801 
802 	shn = (struct nm_shared_name *)lookup_shared_entry(nh, shrkey,
803 		(char *)0, &recid, 0L);
804 	if (shn == NULL)
805 		return (ENOENT);
806 	shn->sn_data = (uint32_t)(uintptr_t)data;
807 	return (0);
808 }
809 
810 int
811 update_entry(
812 	struct nm_next_hdr	*nh,		/* head record header */
813 	side_t			side,		/* (key 1) side number */
814 	mdkey_t			key,		/* (key 2) via md_setdevname */
815 	int			devid_nm)	/* Which name space? */
816 {
817 	struct nm_rec_hdr	*rh = (struct nm_rec_hdr *)nh->nmn_record;
818 	struct nm_next_hdr	*this_nh = nh->nmn_nextp;
819 	void			*record = this_nh->nmn_record;
820 	mddb_recid_t		recid = rh->r_next_recid;
821 	struct nm_rec_hdr	*this_rh;
822 	caddr_t			n;
823 	size_t			offset, n_offset, n_size;
824 	mdkey_t			n_key;
825 	side_t			n_side;
826 
827 	n_offset = offset = ((devid_nm & NM_DEVID) ?
828 		(sizeof (struct devid_min_rec) - sizeof (struct did_min_name))
829 				:
830 		(sizeof (struct nm_rec) - sizeof (struct nm_name)));
831 
832 	this_rh = ((devid_nm & NM_DEVID) ?
833 		&((struct devid_min_rec *)record)->min_rec_hdr :
834 		&((struct nm_rec *)record)->r_rec_hdr);
835 
836 	n = ((devid_nm & NM_DEVID) ?
837 		((caddr_t)&((struct devid_min_rec *)record)->minor_name[0]) :
838 		((caddr_t)&((struct nm_rec *)record)->r_name[0]));
839 
840 	/*CONSTCOND*/
841 	while (1) {
842 
843 		if (devid_nm & NM_DEVID) {
844 			n_side = ((struct did_min_name *)n)->min_side;
845 			n_key = ((struct did_min_name *)n)->min_key;
846 			n_size = DID_NAMSIZ((struct did_min_name *)n);
847 
848 		} else {
849 			n_side = ((struct nm_name *)n)->n_side;
850 			n_key = ((struct nm_name *)n)->n_key;
851 			n_size = NAMSIZ((struct nm_name *)n);
852 		}
853 
854 		if ((side == n_side) && (key == n_key)) {
855 			mddb_commitrec_wrapper(recid);
856 			return (0);
857 		}
858 
859 		n = (caddr_t)get_next_entry(this_nh, n, n_size, &offset);
860 
861 		if (n == NULL) {
862 			if (offset)
863 				return (ENOENT);
864 
865 			/* Go to next record */
866 			offset = n_offset;
867 			this_nh = this_nh->nmn_nextp;
868 			record = this_nh->nmn_record;
869 			recid = this_rh->r_next_recid;
870 			this_rh = ((devid_nm & NM_DEVID) ?
871 			    &((struct devid_min_rec *)record)->min_rec_hdr
872 			    :
873 			    &((struct nm_rec *)record)->r_rec_hdr);
874 			n = ((devid_nm & NM_DEVID) ?
875 				((caddr_t)&((struct devid_min_rec *)
876 					record)->minor_name[0]) :
877 				((caddr_t)&((struct nm_rec *)
878 					record)->r_name[0]));
879 		}
880 	}
881 	/*NOTREACHED*/
882 }
883 
884 int
885 remove_entry(
886 	struct nm_next_hdr	*nh,		/* head record header */
887 	side_t			side,		/* (key 1) side number */
888 	mdkey_t			key,		/* (key 2) via md_setdevname */
889 	int			devid_nm)	/* which name space? */
890 {
891 	struct nm_rec_hdr	*rh = (struct nm_rec_hdr *)nh->nmn_record;
892 	struct nm_next_hdr	*this_nh = nh->nmn_nextp;
893 	void			*record = this_nh->nmn_record;
894 	mddb_recid_t		recid = rh->r_next_recid;
895 	struct nm_rec_hdr	*this_rh;
896 	caddr_t			n;
897 	size_t			offset, n_offset, n_size;
898 	mdkey_t			n_key;
899 	side_t			n_side;
900 
901 	n_offset = offset = ((devid_nm & NM_DEVID) ?
902 		(sizeof (struct devid_min_rec) - sizeof (struct did_min_name))
903 				:
904 		(sizeof (struct nm_rec) - sizeof (struct nm_name)));
905 
906 	this_rh = ((devid_nm & NM_DEVID) ?
907 		&((struct devid_min_rec *)record)->min_rec_hdr :
908 		&((struct nm_rec *)record)->r_rec_hdr);
909 
910 	n = ((devid_nm & NM_DEVID) ?
911 		((caddr_t)&((struct devid_min_rec *)record)->minor_name[0]) :
912 		((caddr_t)&((struct nm_rec *)record)->r_name[0]));
913 
914 	/*CONSTCOND*/
915 	while (1) {
916 
917 		if (devid_nm & NM_DEVID) {
918 			n_side = ((struct did_min_name *)n)->min_side;
919 			n_key = ((struct did_min_name *)n)->min_key;
920 			n_size = DID_NAMSIZ((struct did_min_name *)n);
921 		} else {
922 			n_side = ((struct nm_name *)n)->n_side;
923 			n_key = ((struct nm_name *)n)->n_key;
924 			n_size = NAMSIZ((struct nm_name *)n);
925 		}
926 
927 		if ((side == n_side) && (key == n_key))
928 			return (rem_entry(this_nh, recid, (char *)n, n_size,
929 				offset, devid_nm));
930 
931 		n = (caddr_t)get_next_entry(this_nh, n, n_size, &offset);
932 
933 		if (n == NULL) {
934 			if (offset)
935 				return (ENOENT);
936 
937 			/* Go to next record */
938 			offset = n_offset;
939 			this_nh = this_nh->nmn_nextp;
940 			record = this_nh->nmn_record;
941 			recid = this_rh->r_next_recid;
942 			this_rh = ((devid_nm & NM_DEVID) ?
943 				&((struct devid_min_rec *)record)->min_rec_hdr
944 					:
945 				&((struct nm_rec *)record)->r_rec_hdr);
946 			n = ((devid_nm & NM_DEVID) ?
947 				((caddr_t)&((struct devid_min_rec *)
948 					record)->minor_name[0]) :
949 				((caddr_t)&((struct nm_rec *)
950 					record)->r_name[0]));
951 		}
952 	}
953 	/*NOTREACHED*/
954 }
955 
956 int
957 remove_shared_entry(
958 	struct nm_next_hdr *nh,	/* First record header to start lookup */
959 	mdkey_t key,		/* Shared key, used as key if nm is NULL */
960 	char *nm,		/* Shared name, used as key if non-NULL */
961 	int devid_nm)		/* which name space? */
962 {
963 	struct nm_rec_hdr	*rh = (struct nm_rec_hdr *)nh->nmn_record;
964 	struct nm_next_hdr	*this_nh = nh->nmn_nextp;
965 	void			*record = this_nh->nmn_record;
966 	struct nm_rec_hdr	*this_rh;
967 	caddr_t			shn;
968 	mddb_recid_t		recid = rh->r_next_recid;
969 	size_t			offset, shn_offset;
970 	size_t			nm_len = 0, shn_size;
971 	mdkey_t			shn_key;
972 	ushort_t		shn_namlen;
973 
974 	if (nm == (char *)0) {
975 		/* No name.  Search by key only. */
976 		if (key == MD_KEYBAD) {
977 			/* No key either.  Nothing to remove. */
978 			return (0);
979 		}
980 	} else {
981 		/* How long is the name? */
982 		nm_len = ((devid_nm & NM_DEVID) ?
983 			ddi_devid_sizeof((ddi_devid_t)nm) :
984 			(strlen(nm) + 1));
985 	}
986 
987 	this_rh = ((devid_nm & NM_DEVID) ?
988 		&((struct devid_shr_rec *)record)->did_rec_hdr :
989 		&((struct nm_shr_rec *)record)->sr_rec_hdr);
990 
991 	shn_offset = offset = ((devid_nm & NM_DEVID) ?
992 		(sizeof (struct devid_shr_rec) - sizeof (struct did_shr_name))
993 			:
994 		(sizeof (struct nm_shr_rec) - sizeof (struct nm_shared_name)));
995 
996 	shn = ((devid_nm & NM_DEVID) ?
997 		((caddr_t)&((struct devid_shr_rec *)record)->device_id[0]) :
998 		((caddr_t)&((struct nm_shr_rec *)record)->sr_name[0]));
999 
1000 	/*CONSTCOND*/
1001 	while (1) {
1002 
1003 		if (devid_nm & NM_DEVID) {
1004 			shn_key = ((struct did_shr_name *)shn)->did_key;
1005 			shn_namlen = ((struct did_shr_name *)shn)->did_size;
1006 			shn_size = DID_SHR_NAMSIZ((struct did_shr_name *)shn);
1007 		} else {
1008 			shn_key = ((struct nm_shared_name *)shn)->sn_key;
1009 			shn_namlen = ((struct nm_shared_name *)shn)->sn_namlen;
1010 			shn_size = SHR_NAMSIZ((struct nm_shared_name *)shn);
1011 		}
1012 
1013 		if ((key != 0) && (key == shn_key))
1014 			return (rem_shr_entry(this_nh, recid, (char *)shn,
1015 				shn_size, offset, devid_nm));
1016 
1017 		if (nm_len == shn_namlen) {
1018 			if (!devid_nm) {
1019 			    if (strcmp(nm, ((struct nm_shared_name *)
1020 					shn)->sn_name) == 0)
1021 				return (rem_shr_entry(this_nh, recid,
1022 					(char *)shn, shn_size, offset,
1023 					devid_nm));
1024 			} else {
1025 
1026 				if (nm == NULL ||
1027 				    ((struct did_shr_name *)shn)->did_devid
1028 				    == NULL) {
1029 					return (0);
1030 				}
1031 			    if (ddi_devid_compare((ddi_devid_t)nm,
1032 				(ddi_devid_t)(((struct did_shr_name *)shn)->
1033 					did_devid)) == 0)
1034 				return (rem_shr_entry(this_nh, recid,
1035 					(char *)shn, shn_size, offset,
1036 					devid_nm));
1037 			}
1038 		}
1039 
1040 		shn = (caddr_t)get_next_entry(this_nh,
1041 			(caddr_t)shn, shn_size, &offset);
1042 
1043 		if (shn == (caddr_t)0) {
1044 			if (offset)
1045 				return (ENOENT);
1046 
1047 			/* Go to next record */
1048 			offset = shn_offset;
1049 			this_nh = this_nh->nmn_nextp;
1050 			record = this_nh->nmn_record;
1051 			recid = this_rh->r_next_recid;
1052 			this_rh = ((devid_nm & NM_DEVID) ?
1053 				&((struct devid_shr_rec *)record)->did_rec_hdr :
1054 				&((struct nm_shr_rec *)record)->sr_rec_hdr);
1055 			shn = ((devid_nm & NM_DEVID) ?
1056 				((caddr_t)&((struct devid_shr_rec *)
1057 					record)->device_id[0]) :
1058 				((caddr_t)&((struct nm_shr_rec *)
1059 					record)->sr_name[0]));
1060 		}
1061 	}
1062 	/*NOTREACHED*/
1063 }
1064 
1065 static md_dev64_t
1066 build_device_number(set_t setno, struct nm_name *n)
1067 {
1068 	major_t	maj;
1069 	char	*shn;
1070 	md_dev64_t dev;
1071 
1072 	/*
1073 	 * Can't determine the driver name
1074 	 */
1075 	if ((shn = (char *)getshared_name(setno, n->n_drv_key, 0L)) == NULL)
1076 		return (NODEV64);
1077 
1078 	if (MD_UPGRADE)
1079 		maj = md_targ_name_to_major(shn);
1080 	else
1081 		maj = ddi_name_to_major(shn);
1082 
1083 	if (maj == (major_t)-1)
1084 		return (NODEV64);
1085 	dev = md_makedevice(maj, n->n_minor);
1086 
1087 	return (dev);
1088 }
1089 
1090 void *
1091 lookup_entry(
1092 	struct nm_next_hdr	*nh,	/* head record header */
1093 	set_t			setno,	/* set to lookup in */
1094 	side_t			side,	/* (key 1) side number */
1095 	mdkey_t			key,	/* (key 2) from md_setdevname */
1096 	md_dev64_t		dev,	/* (alt. key 2) use if key == KEYWILD */
1097 	int			devid_nm /* Which name space? */
1098 )
1099 {
1100 	struct nm_next_hdr	*this_nh = nh->nmn_nextp;
1101 	void			*record;
1102 	struct nm_rec_hdr	*this_rh;
1103 	caddr_t			n;
1104 	size_t			offset, n_offset, n_size;
1105 	side_t			n_side;
1106 	mdkey_t			n_key;
1107 
1108 	if ((key == MD_KEYWILD) && (dev == NODEV64))
1109 		return ((void *)0);
1110 
1111 	if (this_nh == NULL)
1112 		return ((void *)0);
1113 
1114 	record = this_nh->nmn_record;
1115 
1116 	this_rh = ((devid_nm & NM_DEVID) ?
1117 		&((struct devid_min_rec *)record)->min_rec_hdr :
1118 		&((struct nm_rec *)record)->r_rec_hdr);
1119 
1120 	/* code to see if EMPTY record */
1121 	while (this_nh && this_rh->r_used_size == sizeof (struct nm_rec_hdr)) {
1122 		/* Go to next record */
1123 		this_nh = this_nh->nmn_nextp;
1124 		if (this_nh == NULL)
1125 			return ((void *)0);
1126 		record = this_nh->nmn_record;
1127 		this_rh = ((devid_nm & NM_DEVID) ?
1128 			&((struct devid_min_rec *)record)->min_rec_hdr :
1129 			&((struct nm_rec *)record)->r_rec_hdr);
1130 	}
1131 
1132 	/*
1133 	 * n_offset will be used to reset offset
1134 	 */
1135 	n_offset = offset = ((devid_nm & NM_DEVID) ?
1136 		(sizeof (struct devid_min_rec) - sizeof (struct did_min_name)) :
1137 		(sizeof (struct nm_rec) - sizeof (struct nm_name)));
1138 
1139 	n = ((devid_nm & NM_DEVID) ?
1140 		((caddr_t)&((struct devid_min_rec *)record)->minor_name[0]) :
1141 		((caddr_t)&((struct nm_rec *)record)->r_name[0]));
1142 
1143 	/*CONSTCOND*/
1144 	while (1) {
1145 
1146 		if (devid_nm & NM_DEVID) {
1147 			n_side = ((struct did_min_name *)n)->min_side;
1148 			n_key = ((struct did_min_name *)n)->min_key;
1149 			n_size = DID_NAMSIZ((struct did_min_name *)n);
1150 		} else {
1151 			n_side = ((struct nm_name *)n)->n_side;
1152 			n_key = ((struct nm_name *)n)->n_key;
1153 			n_size = NAMSIZ((struct nm_name *)n);
1154 		}
1155 
1156 		if ((side == n_side) || (side == MD_SIDEWILD)) {
1157 
1158 			if ((key != MD_KEYWILD) && (key == n_key))
1159 				return ((void *)n);
1160 
1161 			if ((key == MD_KEYWILD) && !devid_nm &&
1162 			    (dev == build_device_number(setno,
1163 			    (struct nm_name *)n)))
1164 				return ((void *)n);
1165 		}
1166 
1167 		n = (caddr_t)get_next_entry(this_nh, n, n_size, &offset);
1168 
1169 		if (n == NULL) {
1170 			/*
1171 			 * No next record, return
1172 			 */
1173 			if (offset)
1174 				return ((void *)n);
1175 
1176 			/* Go to next record */
1177 			offset = n_offset;
1178 			this_nh = this_nh->nmn_nextp;
1179 			record = this_nh->nmn_record;
1180 			this_rh = ((devid_nm & NM_DEVID) ?
1181 			    &((struct devid_min_rec *)record)->min_rec_hdr :
1182 			    &((struct nm_rec *)record)->r_rec_hdr);
1183 			n = ((devid_nm & NM_DEVID) ?
1184 				((caddr_t)&((struct devid_min_rec *)
1185 					record)->minor_name[0]) :
1186 				((caddr_t)&((struct nm_rec *)
1187 					record)->r_name[0]));
1188 		}
1189 	}
1190 	/*NOTREACHED*/
1191 }
1192 
1193 static int
1194 is_meta_drive(set_t setno, mdkey_t key)
1195 {
1196 	int				i;
1197 	struct nm_next_hdr		*nh;
1198 	struct nm_shared_name		*shn;
1199 
1200 	if ((nh = get_first_record(setno, 0, NM_SHARED)) == NULL)
1201 		return (FALSE);
1202 	if ((shn = (struct nm_shared_name *)lookup_shared_entry(nh,
1203 		key, NULL, NULL, NM_SHARED)) == NULL) {
1204 		return (FALSE);
1205 	}
1206 
1207 	/* See if the name is a metadevice. */
1208 	for (i = 0; i < META_NAME_COUNT; i++) {
1209 		if (strcmp(meta_names[i], shn->sn_name) == 0)
1210 			return (TRUE);
1211 	}
1212 	return (FALSE);
1213 }
1214 
1215 static lookup_dev_result_t
1216 lookup_deventry(
1217 	struct nm_next_hdr	*nh,	/* head record header */
1218 	set_t			setno,	/* set to lookup in */
1219 	side_t			side,	/* (key 1) side number */
1220 	mdkey_t			key,	/* (key 2) from md_setdevname */
1221 	char			*drvnm,	/* drvnm to be stored */
1222 	minor_t			mnum,	/* minor number to be stored */
1223 	char			*dirnm,	/* directory name to be stored */
1224 	char			*filenm, /* device filename to be stored */
1225 	struct nm_name		**ret_rec /* place return found rec. */
1226 )
1227 {
1228 	struct nm_next_hdr	*this_nh = nh->nmn_nextp;
1229 	struct nm_rec		*record;
1230 	struct nm_rec_hdr	*this_rh;
1231 	struct nm_name		*n;
1232 	size_t			offset;
1233 	mdkey_t			dirkey, drvkey;
1234 
1235 	*ret_rec = NULL;
1236 	if (this_nh == NULL)
1237 		return (LOOKUP_DEV_NOMATCH);
1238 
1239 	record = (struct nm_rec *)this_nh->nmn_record;
1240 	this_rh = &record->r_rec_hdr;
1241 	n = &record->r_name[0];
1242 
1243 	offset = sizeof (struct nm_rec) - sizeof (struct nm_name);
1244 
1245 	if ((drvkey = getshared_key(setno, drvnm, 0L)) == MD_KEYBAD)
1246 		return (LOOKUP_DEV_NOMATCH);
1247 
1248 	if (dirnm == NULL) {
1249 		/* No directory name to look up. */
1250 		dirkey = MD_KEYBAD;
1251 	} else {
1252 		/* Look up the directory name */
1253 		if ((dirkey = getshared_key(setno, dirnm, 0L)) == MD_KEYBAD)
1254 			return (LOOKUP_DEV_NOMATCH);
1255 	}
1256 	ASSERT(side != MD_SIDEWILD);
1257 
1258 	/* code to see if EMPTY record */
1259 	while (this_nh && this_rh->r_used_size == sizeof (struct nm_rec_hdr)) {
1260 		/* Go to next record */
1261 		this_nh = this_nh->nmn_nextp;
1262 		if (this_nh == NULL)
1263 			return (LOOKUP_DEV_NOMATCH);
1264 		record = (struct nm_rec *)this_nh->nmn_record;
1265 		this_rh = &record->r_rec_hdr;
1266 		n = &record->r_name[0];
1267 	}
1268 
1269 	/*CONSTCOND*/
1270 	while (1) {
1271 		if ((side == n->n_side) &&
1272 		    ((key == MD_KEYWILD) || (key == n->n_key)) &&
1273 		    (mnum == n->n_minor) &&
1274 		    (drvkey == n->n_drv_key) &&
1275 		    (dirkey == n->n_dir_key) &&
1276 		    (strcmp(filenm, n->n_name) == 0)) {
1277 			*ret_rec = n;
1278 			return (LOOKUP_DEV_FOUND);
1279 		}
1280 
1281 		/*
1282 		 * Now check for a name conflict.  If the filenm of the
1283 		 * current record matches filename passed in we have a
1284 		 * potential conflict.  If all the other parameters match
1285 		 * except for the side number, then this is not a
1286 		 * conflict.  The reason is that there are cases where name
1287 		 * record is added to each side of a set.
1288 		 *
1289 		 * There is one additional complication.  It is only a
1290 		 * conflict if the drvkeys both represent metadevices.  It
1291 		 * is legal for a metadevice and a physical device to have
1292 		 * the same name.
1293 		 */
1294 		if (strcmp(filenm, n->n_name) == 0) {
1295 			int	both_meta;
1296 
1297 			/*
1298 			 * It is hsp and we are trying to add it twice
1299 			 */
1300 			if (strcmp(getshared_name(setno, n->n_drv_key, 0L),
1301 			    MD_HOTSPARES) == 0 && (side == n->n_side) &&
1302 			    find_hot_spare_pool(setno,
1303 				KEY_TO_HSP_ID(setno, n->n_key)) == NULL) {
1304 				/*
1305 				 * All entries removed
1306 				 */
1307 				rw_exit(&nm_lock.lock);
1308 				(void) md_rem_hspname(setno, n->n_key);
1309 				rw_enter(&nm_lock.lock, RW_WRITER);
1310 				return (LOOKUP_DEV_NOMATCH);
1311 			}
1312 
1313 			/*
1314 			 * It is metadevice and we are trying to add it twice
1315 			 */
1316 			if (md_set[setno].s_un[MD_MIN2UNIT(n->n_minor)]
1317 				== NULL && (side == n->n_side) &&
1318 			    ddi_name_to_major(getshared_name(setno,
1319 				n->n_drv_key, 0L)) == md_major) {
1320 				/*
1321 				 * Apparently it is invalid so
1322 				 * clean it up
1323 				 */
1324 				(void) md_remove_minor_node(n->n_minor);
1325 				rw_exit(&nm_lock.lock);
1326 				(void) md_rem_selfname(n->n_minor);
1327 				rw_enter(&nm_lock.lock, RW_WRITER);
1328 				return (LOOKUP_DEV_NOMATCH);
1329 			}
1330 
1331 			/* First see if the two drives are metadevices. */
1332 			if (is_meta_drive(setno, drvkey) &&
1333 				is_meta_drive(setno, n->n_drv_key)) {
1334 				both_meta = TRUE;
1335 			} else {
1336 				both_meta = FALSE;
1337 			}
1338 			/* Check rest of the parameters. */
1339 			if ((both_meta == TRUE) &&
1340 				((key != n->n_key) ||
1341 				(mnum != n->n_minor) ||
1342 				(drvkey != n->n_drv_key) ||
1343 				(dirkey != n->n_dir_key))) {
1344 				return (LOOKUP_DEV_CONFLICT);
1345 			}
1346 		}
1347 		n = (struct nm_name *)get_next_entry(this_nh, (caddr_t)n,
1348 		    NAMSIZ(n), &offset);
1349 
1350 		if (n == (struct nm_name *)0) {
1351 			if (offset)
1352 				return (LOOKUP_DEV_NOMATCH);
1353 
1354 			/* Go to next record */
1355 			offset = sizeof (struct nm_rec) -
1356 			    sizeof (struct nm_name);
1357 			this_nh = this_nh->nmn_nextp;
1358 			record = (struct nm_rec *)this_nh->nmn_record;
1359 			this_rh = &record->r_rec_hdr;
1360 			n = &record->r_name[0];
1361 		}
1362 	}
1363 	/*NOTREACHED*/
1364 }
1365 
1366 void *
1367 lookup_shared_entry(
1368 	struct nm_next_hdr *nh,	/* First record header to start lookup */
1369 	mdkey_t key,		/* Shared key, used as key if nm is NULL */
1370 	char *nm,		/* Shared name, used as key if non-NULL */
1371 	mddb_recid_t *id,	/* mddb record id of record entry is found in */
1372 	int	devid_nm)	/* which name space? */
1373 {
1374 	struct nm_rec_hdr	*rh = (struct nm_rec_hdr *)nh->nmn_record;
1375 	struct nm_next_hdr	*this_nh = nh->nmn_nextp;
1376 	void			*record;
1377 	struct nm_rec_hdr	*this_rh;
1378 	caddr_t			shn;
1379 	size_t			offset, shn_offset;
1380 	size_t			nm_len = 0, shn_size;
1381 	mdkey_t			shn_key;
1382 	ushort_t		shn_namlen;
1383 
1384 	if (this_nh == NULL)
1385 		return ((void *)0);
1386 
1387 	record = this_nh->nmn_record;
1388 
1389 	if (nm != (char *)0)
1390 		nm_len = ((devid_nm & NM_DEVID) ?
1391 			ddi_devid_sizeof((ddi_devid_t)nm) :
1392 			(strlen(nm) + 1));
1393 
1394 	if (id != NULL)
1395 		*id = rh->r_next_recid;
1396 
1397 	this_rh = ((devid_nm & NM_DEVID) ?
1398 		&((struct devid_shr_rec *)record)->did_rec_hdr :
1399 		&((struct nm_shr_rec *)record)->sr_rec_hdr);
1400 
1401 	/* code to see if EMPTY record */
1402 	while (this_nh && this_rh->r_used_size == sizeof (struct nm_rec_hdr)) {
1403 		/* Go to next record */
1404 		this_nh = this_nh->nmn_nextp;
1405 		if (this_nh == NULL)
1406 			return ((void *)0);
1407 		record = this_nh->nmn_record;
1408 		if (id != NULL)
1409 			*id = this_rh->r_next_recid;
1410 
1411 		this_rh = ((devid_nm & NM_DEVID) ?
1412 			&((struct devid_shr_rec *)record)->did_rec_hdr :
1413 			&((struct nm_shr_rec *)record)->sr_rec_hdr);
1414 	}
1415 
1416 	/*
1417 	 * shn_offset will be used to reset offset
1418 	 */
1419 	shn_offset = offset = ((devid_nm & NM_DEVID) ?
1420 		(sizeof (struct devid_shr_rec) - sizeof (struct did_shr_name)) :
1421 		(sizeof (struct nm_shr_rec) - sizeof (struct nm_shared_name)));
1422 
1423 	shn = ((devid_nm & NM_DEVID) ?
1424 		((caddr_t)&((struct devid_shr_rec *)record)->device_id[0]) :
1425 		((caddr_t)&((struct nm_shr_rec *)record)->sr_name[0]));
1426 
1427 	/*CONSTCOND*/
1428 	while (1) {
1429 
1430 		if (devid_nm & NM_DEVID) {
1431 			shn_key = ((struct did_shr_name *)shn)->did_key;
1432 			shn_namlen = ((struct did_shr_name *)shn)->did_size;
1433 			shn_size = DID_SHR_NAMSIZ((struct did_shr_name *)shn);
1434 		} else {
1435 			shn_key = ((struct nm_shared_name *)shn)->sn_key;
1436 			shn_namlen = ((struct nm_shared_name *)shn)->sn_namlen;
1437 			shn_size = SHR_NAMSIZ((struct nm_shared_name *)shn);
1438 		}
1439 
1440 		if ((key != 0) && (key == shn_key))
1441 			return ((void *)shn);
1442 
1443 		/* Lookup by name */
1444 		if (nm != NULL) {
1445 		    if (devid_nm & NM_IMP_SHARED) {
1446 			/*
1447 			 * the nm passed in is "/dev/md" in the import case
1448 			 * and we want to do a partial match on that.
1449 			 */
1450 			if (strncmp(nm, ((struct nm_shared_name *)shn)->sn_name,
1451 			    strlen(nm)) == 0)
1452 			    return ((void *)shn);
1453 		    } else if (nm_len == shn_namlen) {
1454 			if (devid_nm & NM_DEVID) {
1455 			    if (ddi_devid_compare((ddi_devid_t)nm,
1456 				(ddi_devid_t)(((struct did_shr_name *)shn)->
1457 					did_devid)) == 0)
1458 				return ((void *)shn);
1459 			} else {
1460 			    if (strcmp(nm, ((struct nm_shared_name *)
1461 					shn)->sn_name) == 0)
1462 				return ((void *)shn);
1463 			}
1464 		    }
1465 		}
1466 
1467 		shn = (caddr_t)get_next_entry(this_nh,
1468 		    (caddr_t)shn, shn_size, &offset);
1469 
1470 		if (shn == (caddr_t)0) {
1471 			/*
1472 			 * No next record, return
1473 			 */
1474 			if (offset)
1475 				return ((void *)shn);
1476 
1477 			/* Go to next record */
1478 			offset = shn_offset;
1479 			this_nh = this_nh->nmn_nextp;
1480 			record = this_nh->nmn_record;
1481 			if (id != NULL)
1482 				*id = this_rh->r_next_recid;
1483 			this_rh = ((devid_nm & NM_DEVID) ?
1484 				&((struct devid_shr_rec *)record)->did_rec_hdr :
1485 				&((struct nm_shr_rec *)record)->sr_rec_hdr);
1486 			shn = ((devid_nm & NM_DEVID) ?
1487 				((caddr_t)&((struct devid_shr_rec *)
1488 					record)->device_id[0]) :
1489 				((caddr_t)&((struct nm_shr_rec *)
1490 					record)->sr_name[0]));
1491 		}
1492 	}
1493 	/*NOTREACHED*/
1494 }
1495 
1496 
1497 /*
1498  * lookup_hspentry - Getting a hotspare pool entry from the namespace.
1499  *		     Use either the NM key or the hotspare name to find
1500  *		     a matching record in the namespace of the set.
1501  */
1502 void *
1503 lookup_hspentry(
1504 	struct nm_next_hdr	*nh,	/* head record header */
1505 	set_t			setno,	/* set to lookup in */
1506 	side_t			side,	/* (key 1) side number */
1507 	mdkey_t			key,	/* (key 2) from md_setdevname */
1508 	char			*name	/* (alt. key 2), if key == MD_KEYWILD */
1509 )
1510 {
1511 	struct nm_next_hdr	*this_nh = nh->nmn_nextp;
1512 	struct nm_rec		*record;
1513 	struct nm_rec_hdr	*this_rh;
1514 	struct nm_name		*n;
1515 	size_t			offset, n_offset, n_size;
1516 	side_t			n_side;
1517 	mdkey_t			n_key;
1518 	char			*drv_name;
1519 	char			*tmpname;
1520 	char			*setname = NULL;
1521 
1522 	if ((key == MD_KEYWILD) && (name == '\0'))
1523 		return ((void *)0);
1524 
1525 	if (this_nh == NULL)
1526 		return ((void *)0);
1527 
1528 	record = (struct nm_rec *)this_nh->nmn_record;
1529 
1530 	this_rh = &record->r_rec_hdr;
1531 
1532 	if (setno != MD_LOCAL_SET) {
1533 		setname = mddb_getsetname(setno);
1534 		if (setname == NULL)
1535 			return ((void *)0);
1536 	}
1537 
1538 	/* code to see if EMPTY record */
1539 	while (this_nh && this_rh->r_used_size == sizeof (struct nm_rec_hdr)) {
1540 		/* Go to next record */
1541 		this_nh = this_nh->nmn_nextp;
1542 		if (this_nh == NULL)
1543 			return ((void *)0);
1544 		record = this_nh->nmn_record;
1545 		this_rh = &record->r_rec_hdr;
1546 	}
1547 
1548 	/*
1549 	 * n_offset will be used to reset offset
1550 	 */
1551 	n_offset = offset = (sizeof (struct nm_rec) - sizeof (struct nm_name));
1552 
1553 	n = ((struct nm_name *)&record->r_name[0]);
1554 
1555 	tmpname = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
1556 
1557 	/*CONSTCOND*/
1558 	while (1) {
1559 		n_side = n->n_side;
1560 		n_size = NAMSIZ(n);
1561 		if ((drv_name = (char *)getshared_name(setno,
1562 		    n->n_drv_key, 0L)) != NULL) {
1563 
1564 			/* We're only interested in hsp NM records */
1565 			if ((strcmp(drv_name, "md_hotspares") == 0) &&
1566 			    ((side == n_side) || (side == MD_SIDEWILD))) {
1567 				n_key = n->n_key;
1568 
1569 				if ((key != MD_KEYWILD) && (key == n_key))
1570 					goto done;
1571 
1572 				/*
1573 				 * Searching by a hotspare pool name.
1574 				 * Since the input name is of the form
1575 				 * setname/hsp_name, we need to attach
1576 				 * the string 'setname/' in front of the
1577 				 * n->n_name.
1578 				 */
1579 				if (key == MD_KEYWILD) {
1580 					if (setname != NULL)
1581 					    (void) snprintf(tmpname, MAXPATHLEN,
1582 						"%s/%s", setname,
1583 						((struct nm_name *)n)->n_name);
1584 					else
1585 					    (void) snprintf(tmpname, MAXPATHLEN,
1586 						"%s",
1587 						((struct nm_name *)n)->n_name);
1588 
1589 					if ((strcmp(name, tmpname)) == 0)
1590 						goto done;
1591 				}
1592 			}
1593 		}
1594 
1595 		n = (struct nm_name *)get_next_entry(this_nh, (caddr_t)n,
1596 		    n_size, &offset);
1597 
1598 		if (n == NULL) {
1599 			/*
1600 			 * No next record, return
1601 			 */
1602 			if (offset)
1603 				goto done;
1604 
1605 			/* Go to next record */
1606 			offset = n_offset;
1607 			this_nh = this_nh->nmn_nextp;
1608 			record = (struct nm_rec *)this_nh->nmn_record;
1609 			this_rh = &record->r_rec_hdr;
1610 			n = ((struct nm_name *)&record->r_name[0]);
1611 		}
1612 	}
1613 
1614 done:
1615 	kmem_free(tmpname, MAXPATHLEN);
1616 	return ((void *)n);
1617 }
1618 
1619 static int
1620 md_make_devname(struct nm_name *n, set_t setno, char *string, size_t max_size)
1621 {
1622 
1623 	char	*dir_name;
1624 	size_t	dir_len;
1625 
1626 	/*
1627 	 * Can't determine the path
1628 	 */
1629 	if ((dir_name =
1630 	    (char *)getshared_name(setno, n->n_dir_key, 0L)) == NULL)
1631 		return ((int)NODEV64);
1632 
1633 	dir_len = strlen(dir_name);
1634 	if ((dir_len + n->n_namlen) > max_size)
1635 		return (EFAULT);
1636 
1637 	/* Tack the directory and device strings together */
1638 	(void) strcpy(strcpy(string, dir_name) + dir_len, n->n_name);
1639 	return (0);
1640 }
1641 
1642 static void
1643 build_rec_hdr_list(struct nm_next_hdr *nh, mddb_recid_t recid, int shared)
1644 {
1645 	size_t			overhead_size;
1646 	struct nm_rec_hdr	*this_rh;
1647 	uint_t			private;
1648 	struct nm_rec_hdr	*rh = (struct nm_rec_hdr *)nh->nmn_record;
1649 	struct nm_next_hdr	*this_nh;
1650 	set_t			setno;
1651 	int			multi_node = 0;
1652 
1653 	/* If given record is for a multi_node set, set flag */
1654 	setno = DBSET(recid);
1655 	if (MD_MNSET_SETNO(setno))
1656 		multi_node = 1;
1657 
1658 	if (shared & NM_DEVID)
1659 		overhead_size = ((shared & NM_SHARED) ?
1660 		(sizeof (struct devid_shr_rec) - sizeof (struct did_shr_name))
1661 				:
1662 		(sizeof (struct devid_min_rec) - sizeof (struct did_min_name)));
1663 	else
1664 		overhead_size = ((shared & NM_SHARED) ?
1665 		(sizeof (struct nm_shr_rec) - sizeof (struct nm_shared_name)) :
1666 		(sizeof (struct nm_rec) - sizeof (struct nm_name)));
1667 
1668 	while (rh->r_next_recid > 0) {
1669 		this_nh = kmem_zalloc(sizeof (*this_nh), KM_SLEEP);
1670 		nh->nmn_nextp = this_nh;
1671 		this_nh->nmn_record = mddb_getrecaddr(rh->r_next_recid);
1672 
1673 		ASSERT(this_nh->nmn_record != NULL);
1674 
1675 		if (shared & NM_DEVID)
1676 		    this_rh = ((shared & NM_SHARED) ?
1677 		    &((struct devid_shr_rec *)this_nh->nmn_record)->did_rec_hdr
1678 			:
1679 		    &((struct devid_min_rec *)
1680 		    this_nh->nmn_record)->min_rec_hdr);
1681 		else
1682 		    this_rh = ((shared & NM_SHARED) ?
1683 		    &((struct nm_shr_rec *)this_nh->nmn_record)->sr_rec_hdr :
1684 		    &((struct nm_rec *)this_nh->nmn_record)->r_rec_hdr);
1685 
1686 		/*
1687 		 * Check for empty records and clean them up.
1688 		 * For a MN diskset, only do this if master.
1689 		 */
1690 		if ((!multi_node) ||
1691 		    (multi_node && md_set[setno].s_am_i_master)) {
1692 			if (this_rh->r_used_size == overhead_size) {
1693 				mddb_setrecprivate(rh->r_next_recid,
1694 					MD_PRV_PENDDEL);
1695 				rh->r_next_recid = this_rh->r_next_recid;
1696 				kmem_free(this_nh, sizeof (*this_nh));
1697 				nh->nmn_nextp = NULL;
1698 				mddb_setrecprivate(recid, MD_PRV_PENDCOM);
1699 				continue;
1700 			}
1701 		}
1702 
1703 		private = mddb_getrecprivate(rh->r_next_recid);
1704 		mddb_setrecprivate(rh->r_next_recid, (private | MD_PRV_GOTIT));
1705 		recid = rh->r_next_recid;
1706 		rh = this_rh;
1707 		nh = this_nh;
1708 	}
1709 }
1710 
1711 static void
1712 zero_data_ptrs(struct nm_next_hdr *nh, set_t setno)
1713 {
1714 	mdkey_t	i;
1715 	struct nm_rec_hdr	*rh = (struct nm_rec_hdr *)nh->nmn_record;
1716 
1717 	if (rh->r_next_recid == 0)
1718 		return;
1719 
1720 	for (i = MDDB_FIRST_MODID; i < rh->r_next_key; i++)
1721 		(void) setshared_data(setno, i, (caddr_t)-1);
1722 }
1723 
1724 /*
1725  * md_setdevname - Allows putting a device name into the database
1726  */
1727 mdkey_t
1728 md_setdevname(
1729 	set_t		setno,	/* specify which namespace to put in */
1730 	side_t		side,	/* (key 1) side # */
1731 	mdkey_t		key,	/* (key 2) KEYWILD - alloc key, else use key */
1732 	char		*drvnm,	/* store this driver name with devicename */
1733 	minor_t		mnum,	/* store this minor number as well */
1734 	char		*devname,	/* device name to be stored */
1735 	int		imp_flag,	/* used exclusively by import */
1736 	ddi_devid_t	imp_devid,	/* used exclusively by import */
1737 	char		*imp_mname,	/* used exclusively by import */
1738 	set_t		imp_setno,	/* used exclusively by import */
1739 	md_error_t	*ep		/* place to return error info */
1740 )
1741 {
1742 	struct nm_next_hdr	*nh, *did_nh = NULL;
1743 	struct nm_name		*n;
1744 	struct did_min_name	*did_n;
1745 	struct did_min_name	*new_did_n;
1746 	mddb_recid_t		recids[3];
1747 	char			*cp, *dname = NULL, *fname;
1748 	char			c;
1749 	mdkey_t			retval = MD_KEYBAD;
1750 	int			shared, new = 0;
1751 	ddi_devid_t		devid = NULL;
1752 	dev_t			devt;
1753 	char			*mname = NULL;
1754 	side_t			thisside = MD_SIDEWILD;
1755 	lookup_dev_result_t	lookup_res;
1756 	mdkey_t			min_devid_key = MD_KEYWILD;
1757 	size_t			min_len;
1758 
1759 	/*
1760 	 * Don't allow addition of new names to namespace during upgrade.
1761 	 */
1762 	if (MD_UPGRADE)  {
1763 		return (MD_KEYBAD);
1764 	}
1765 
1766 	/*
1767 	 * Make sure devname is not empty
1768 	 */
1769 	if (devname == (char *)NULL || strncmp(devname, "", 1) == 0) {
1770 		cmn_err(CE_WARN, "Unknown device with minor number of %d",
1771 		    mnum);
1772 		return (MD_KEYBAD);
1773 	}
1774 
1775 	/*
1776 	 * Load the devid name space if it exists
1777 	 */
1778 	(void) md_load_namespace(setno, NULL, NM_DEVID);
1779 	if (! md_load_namespace(setno, NULL, 0L)) {
1780 		/*
1781 		 * Unload the devid namespace
1782 		 */
1783 		(void) md_unload_namespace(setno, NM_DEVID);
1784 		return (MD_KEYBAD);
1785 	}
1786 
1787 	rw_enter(&nm_lock.lock, RW_WRITER);
1788 
1789 	/*
1790 	 * Find our what namespace/set/side combination that is
1791 	 * being dealt with. If this is not done then we stand a
1792 	 * chance of adding in incorrect devid dealts to match
1793 	 * the remote side's disk information. For example:
1794 	 * disk c2t0d0s0 may have devt of 32,256 on this side
1795 	 * but 32,567 on the remote side and if this is the case
1796 	 * we do not want to add the devid for disk 32,567 on
1797 	 * this side into the namespace.
1798 	 */
1799 	if (setno == MD_LOCAL_SET && side == 0)
1800 		/* local set/local side */
1801 		thisside = side;
1802 	else if (setno == MD_LOCAL_SET && side > 0) {
1803 		/*
1804 		 * local set/non-local side information ie a set record
1805 		 *
1806 		 * if the key is not set then this is the first time
1807 		 * through this code which means this is the first record
1808 		 * which then means the record to be added is for this node
1809 		 */
1810 		if (key == MD_KEYWILD) {
1811 			thisside = side;
1812 		}
1813 	} else if (setno != MD_LOCAL_SET) {
1814 		/* set record */
1815 		thisside = mddb_getsidenum(setno);
1816 	}
1817 
1818 	/*
1819 	 * Check to see if it has a device id associated with
1820 	 * and if the MDDB_DEVID_STYLE flag is set. If the device
1821 	 * is a metadevice the get_minor_name will fail. No account
1822 	 * of the side information is taken here because it is dealt
1823 	 * with later on.
1824 	 */
1825 	if (!imp_flag) {
1826 		devt = makedevice(ddi_name_to_major(drvnm), mnum);
1827 		if ((ddi_lyr_get_devid(devt, &devid) == DDI_SUCCESS) &&
1828 		    (ddi_lyr_get_minor_name(devt, S_IFBLK, &mname) ==
1829 		    DDI_SUCCESS) &&
1830 		    (((mddb_set_t *)md_set[setno].s_db)->s_lbp->lb_flags &
1831 		    MDDB_DEVID_STYLE))
1832 			/*
1833 			 * Reference the device id namespace
1834 			 */
1835 			shared = NM_DEVID | NM_NOTSHARED;
1836 		else
1837 			shared = NM_NOTSHARED;
1838 	} else {
1839 		/* Importing diskset has devids so store in namespace */
1840 		devid = kmem_alloc(ddi_devid_sizeof(imp_devid), KM_SLEEP);
1841 		bcopy(imp_devid, devid, ddi_devid_sizeof(imp_devid));
1842 		mname = md_strdup(imp_mname);
1843 		shared = NM_DEVID | NM_NOTSHARED;
1844 	}
1845 
1846 	/*
1847 	 * Always lookup the primary name space
1848 	 */
1849 	if ((nh = get_first_record(setno, 1, NM_NOTSHARED)) == NULL) {
1850 		retval = MD_KEYBAD;
1851 		goto out;
1852 	}
1853 
1854 	/*
1855 	 * If it has a device id then get the header for the devid namespace
1856 	 */
1857 	if (shared & NM_DEVID) {
1858 		if ((did_nh = get_first_record(setno, 1, shared)) == NULL) {
1859 			retval = MD_KEYBAD;
1860 			goto out;
1861 		}
1862 	}
1863 
1864 	/* find boundary between filename and directory */
1865 	cp = strrchr(devname, '/');
1866 
1867 	if (cp == NULL) {
1868 		/* No directory part to the name. */
1869 		fname = devname;
1870 		dname = NULL;
1871 	} else {
1872 		/* Isolate the directory name only; save character after '/' */
1873 		c = *(cp + 1);
1874 		*(cp + 1) = '\0';
1875 		dname = md_strdup(devname);
1876 
1877 		/* Restore character after '/' */
1878 		*(cp + 1) = c;
1879 		fname = cp+1;
1880 	}
1881 
1882 	/*
1883 	 * If it already there in the name space
1884 	 */
1885 	lookup_res = lookup_deventry(nh, setno, side, key, drvnm, mnum, dname,
1886 		fname, &n);
1887 
1888 	/* If we are importing the set */
1889 	if (imp_flag && (lookup_res == LOOKUP_DEV_FOUND)) {
1890 		ushort_t	did_sz;
1891 		ddi_devid_t	did;
1892 
1893 		/*
1894 		 * We need to check for the case where there is a disk
1895 		 * already in the namespace with a different ID from
1896 		 * the one we want to add, but the same name. This is
1897 		 * possible in the case of an unavailable disk.
1898 		 */
1899 		rw_exit(&nm_lock.lock);
1900 		if (md_getdevid(setno, side, n->n_key, NULL, &did_sz) != 0)
1901 			did_sz = 0;
1902 		rw_enter(&nm_lock.lock, RW_WRITER);
1903 		if (did_sz > 0) {
1904 			did = kmem_zalloc(did_sz, KM_SLEEP);
1905 			rw_exit(&nm_lock.lock);
1906 			(void) md_getdevid(setno, side, n->n_key, did, &did_sz);
1907 			rw_enter(&nm_lock.lock, RW_WRITER);
1908 			if (ddi_devid_compare(did, devid) == 0) {
1909 				kmem_free(did, did_sz);
1910 				retval = 0;
1911 				goto out;
1912 			}
1913 			kmem_free(did, did_sz);
1914 		}
1915 		/*
1916 		 * This is not the same disk so we haven't really found it.
1917 		 * Thus, we need to say it's "NOMATCH" and create a new
1918 		 * entry.
1919 		 */
1920 		lookup_res = LOOKUP_DEV_NOMATCH;
1921 	}
1922 	switch (lookup_res) {
1923 	case LOOKUP_DEV_FOUND:
1924 		/* If we are importing the set */
1925 		if (md_get_setstatus(imp_setno) & MD_SET_IMPORT) {
1926 			retval = 0;
1927 			goto out;
1928 		}
1929 
1930 		/* Increment reference count */
1931 		retval = n->n_key;
1932 		n->n_count++;
1933 		(void) update_entry(nh, n->n_side, n->n_key, 0L);
1934 
1935 		/* Also in the device id name space if there is one */
1936 		if (did_nh) {
1937 			/*
1938 			 * Use thisside for the sideno as this is the
1939 			 * side this is running on.
1940 			 */
1941 			if ((did_n = (struct did_min_name *)
1942 			    lookup_entry(did_nh, setno, side, n->n_key,
1943 				NODEV64, NM_DEVID)) != NULL) {
1944 
1945 				did_n->min_count++;
1946 				(void) update_entry(did_nh, did_n->min_side,
1947 						did_n->min_key, NM_DEVID);
1948 			} else {
1949 				/*
1950 				 * If a disk device does not support
1951 				 * devid then we would fail to find the
1952 				 * device and then try and add it, bit
1953 				 * silly.
1954 				 */
1955 				goto add_devid;
1956 			}
1957 		}
1958 		goto out;
1959 
1960 	case LOOKUP_DEV_CONFLICT:
1961 		(void) mderror(ep, MDE_NAME_IN_USE);
1962 		retval = MD_KEYBAD;
1963 		goto out;
1964 
1965 	case LOOKUP_DEV_NOMATCH:
1966 		/* Create a new name entry */
1967 		new = 1;
1968 		n = (struct nm_name *)alloc_entry(nh, md_set[setno].s_nmid,
1969 		    strlen(fname)+1, NM_NOTSHARED, &recids[0]);
1970 
1971 		if (n == NULL)
1972 			goto out;
1973 
1974 		n->n_minor = mnum;
1975 		n->n_side = side;
1976 		n->n_key = ((key == MD_KEYWILD) ? create_key(nh) : key);
1977 		n->n_count = 1;
1978 
1979 		/* fill-in filename */
1980 		(void) strcpy(n->n_name, fname);
1981 		n->n_namlen = (ushort_t)(strlen(fname) + 1);
1982 
1983 		/*
1984 		 * If MDE_DB_NOSPACE occurs
1985 		 */
1986 		if (((n->n_drv_key =
1987 			setshared_name(setno, drvnm, MD_KEYWILD, 0L)) ==
1988 			MD_KEYBAD)) {
1989 			/*
1990 			 * Remove entry allocated by alloc_entry
1991 			 * and return MD_KEYBAD
1992 			 */
1993 			(void) remove_entry(nh, n->n_side, n->n_key, 0L);
1994 			goto out;
1995 		}
1996 		if (dname == NULL) {
1997 			/* No directory name implies no key. */
1998 			n->n_dir_key = MD_KEYBAD;
1999 		} else {
2000 			/* We have a directory name to save. */
2001 			if ((n->n_dir_key =
2002 				setshared_name(setno, dname, MD_KEYWILD, 0L)) ==
2003 				MD_KEYBAD) {
2004 				/*
2005 				 * Remove entry allocated by alloc_entry
2006 				 * and return MD_KEYBAD
2007 				 */
2008 				(void) remove_entry(nh, n->n_side, n->n_key,
2009 					0L);
2010 				goto out;
2011 			}
2012 		}
2013 
2014 		recids[1] = md_set[setno].s_nmid;
2015 		recids[2] = 0;
2016 		mddb_commitrecs_wrapper(recids);
2017 		retval = n->n_key;
2018 
2019 		/*
2020 		 * Now to find out if devid's were used for thisside and if
2021 		 * so what is the devid_key for the entry so that the correct
2022 		 * minor name entry (did_n) has the correct devid key.
2023 		 * Also get the minor name of the device, use the minor name
2024 		 * on this side because the assumption is that the slices are
2025 		 * going to be consistant across the nodes.
2026 		 */
2027 		if (key != MD_KEYWILD && (shared & NM_DEVID)) {
2028 			if ((did_n = (struct did_min_name *)
2029 			    lookup_entry(did_nh, setno, thisside, n->n_key,
2030 			    NODEV64, NM_DEVID)) == NULL) {
2031 				shared &= ~NM_DEVID;
2032 			} else {
2033 				min_devid_key = did_n->min_devid_key;
2034 				min_len = (size_t)did_n->min_namlen;
2035 			}
2036 		} else {
2037 
2038 			/*
2039 			 * It is possible for the minor name to be null, for
2040 			 * example a metadevice which means the minor name is
2041 			 * not initialised.
2042 			 */
2043 			if (mname == NULL)
2044 				goto out;
2045 
2046 			min_len = strlen(mname) + 1;
2047 		}
2048 		break;
2049 	}
2050 
2051 	/*
2052 	 * We have the key and if the NM_DEVID bit is on
2053 	 * use the key to add the device id into the device id name space
2054 	 */
2055 
2056 add_devid:
2057 
2058 	if (shared & NM_DEVID) {
2059 		new_did_n = (struct did_min_name *)alloc_entry(did_nh,
2060 			md_set[setno].s_did_nmid, min_len,
2061 			shared, &recids[0]);
2062 
2063 		/*
2064 		 * No space
2065 		 */
2066 		if (new_did_n == NULL) {
2067 		    if (new) {
2068 			(void) remove_entry(nh, n->n_side, n->n_key, 0L);
2069 			retval = MD_KEYBAD;
2070 		    }
2071 		    goto out;
2072 		}
2073 
2074 		new_did_n->min_side = side;
2075 		new_did_n->min_key = n->n_key;
2076 		new_did_n->min_count = n->n_count;
2077 
2078 		/*
2079 		 * If the key is set then we know that there should
2080 		 * be a corresponding devid entry because when the record
2081 		 * associated with the key was created it would have created
2082 		 * a corresponding devid entry, all we need to do is find
2083 		 * that record and increment the count.
2084 		 */
2085 		if (key != MD_KEYWILD) {
2086 
2087 			/*
2088 			 * Need to copy the information from the original
2089 			 * side (thisside).
2090 			 */
2091 			new_did_n->min_devid_key = min_devid_key;
2092 			min_devid_key = setshared_name(setno,
2093 			    (char *)NULL, min_devid_key, NM_DEVID);
2094 			if (new_did_n->min_devid_key != min_devid_key) {
2095 				cmn_err(CE_NOTE,
2096 				    "addname: failed to add to record");
2097 			}
2098 			(void) strcpy(new_did_n->min_name, did_n->min_name);
2099 			new_did_n->min_namlen = (ushort_t)min_len;
2100 		} else {
2101 
2102 			/* use the did_n allocated above! */
2103 			(void) strcpy(new_did_n->min_name, mname);
2104 			new_did_n->min_namlen = (ushort_t)(strlen(mname) + 1);
2105 			new_did_n->min_devid_key = setshared_name(setno,
2106 			    (char *)devid, MD_KEYWILD, NM_DEVID);
2107 		}
2108 		/*
2109 		 * If MDE_DB_NOSPACE occurs
2110 		 */
2111 		if (new_did_n->min_devid_key == MD_KEYBAD) {
2112 			/*
2113 			 * Remove entry allocated by alloc_entry
2114 			 */
2115 			(void) remove_entry(did_nh, new_did_n->min_side,
2116 				new_did_n->min_key, NM_DEVID);
2117 			if (new) {
2118 			    (void) remove_entry(nh, n->n_side, n->n_key, 0L);
2119 			    retval = MD_KEYBAD;
2120 			}
2121 		} else {
2122 			recids[1] = md_set[setno].s_did_nmid;
2123 			recids[2] = 0;
2124 			mddb_commitrecs_wrapper(recids);
2125 		}
2126 	}
2127 out:
2128 	if (devid) {
2129 		ddi_devid_free(devid);
2130 	}
2131 	if (dname)
2132 		freestr(dname);
2133 	if (mname)
2134 		kmem_free(mname, strlen(mname) + 1);
2135 	rw_exit(&nm_lock.lock);
2136 	return (retval);
2137 }
2138 
2139 /*
2140  * md_get_invdid - return the invalid device id's
2141  */
2142 int
2143 md_get_invdid(
2144 	set_t	setno,
2145 	side_t	side,
2146 	int	count,
2147 	int	size,
2148 	void	*ctdptr
2149 )
2150 {
2151 	struct nm_next_hdr	*did_shr_nh, *did_nh = NULL, *nh = NULL;
2152 	struct did_shr_name	*did_shr_n;
2153 	struct did_min_name	*did_n;
2154 	struct nm_name		*n;
2155 	int			key = MD_KEYWILD;
2156 	int			cnt = 0;
2157 	char			*cptr = (char *)ctdptr;
2158 	int			i, dont_add_it;
2159 	char			*tmpctd;
2160 	char			*diskname;
2161 	char			*tmpname;
2162 
2163 	/* first get the invalid devid's from the loc block */
2164 	if ((cnt = mddb_getinvlb_devid(setno, count, size, &cptr)) == -1) {
2165 		return (-1);
2166 	}
2167 
2168 	/*
2169 	 * Load the devid name space if it exists
2170 	 */
2171 	(void) md_load_namespace(setno, NULL, NM_DEVID);
2172 	if (! md_load_namespace(setno, NULL, 0L)) {
2173 		/*
2174 		 * Unload the devid namespace
2175 		 */
2176 		(void) md_unload_namespace(setno, NM_DEVID);
2177 		return (ENOENT);
2178 	}
2179 
2180 	rw_enter(&nm_lock.lock, RW_READER);
2181 
2182 	did_nh = get_first_record(setno, 0, NM_DEVID | NM_NOTSHARED);
2183 	if (did_nh == NULL) {
2184 		rw_exit(&nm_lock.lock);
2185 		return (0);
2186 	}
2187 
2188 	did_shr_nh = get_first_record(setno, 1, NM_DEVID | NM_SHARED);
2189 	if (did_shr_nh == NULL) {
2190 		rw_exit(&nm_lock.lock);
2191 		return (0);
2192 	}
2193 
2194 	nh = get_first_record(setno, 0, NM_NOTSHARED);
2195 	if (nh == NULL) {
2196 		rw_exit(&nm_lock.lock);
2197 		return (0);
2198 	}
2199 	while ((key = md_getnextkey(setno, side, key, NULL)) != MD_KEYWILD) {
2200 		dev_t		devt;
2201 		ddi_devid_t	rtn_devid = NULL;
2202 		int		get_rc;
2203 		int		compare_rc = 1;
2204 
2205 		did_n = (struct did_min_name *)lookup_entry(
2206 				did_nh, setno, side, key, NODEV64, NM_DEVID);
2207 		if (did_n == NULL) {
2208 			continue;
2209 		}
2210 		did_shr_n = (struct did_shr_name *)lookup_shared_entry(
2211 				did_shr_nh, did_n->min_devid_key, (char *)0,
2212 				NULL, NM_DEVID);
2213 		if ((did_shr_n->did_data & NM_DEVID_VALID) != NULL) {
2214 			continue;
2215 		}
2216 		/* found invalid device id. Add to list */
2217 		devt = md_dev64_to_dev(
2218 				md_getdevnum(setno, side, key, MD_TRUST_DEVT));
2219 		get_rc = ddi_lyr_get_devid(devt, &rtn_devid);
2220 		if (get_rc == DDI_SUCCESS) {
2221 			compare_rc = ddi_devid_compare(rtn_devid,
2222 			    (ddi_devid_t)did_shr_n-> did_devid);
2223 			ddi_devid_free(rtn_devid);
2224 		}
2225 
2226 		if ((get_rc == DDI_SUCCESS) && (compare_rc == 0)) {
2227 			did_shr_n->did_data |= NM_DEVID_VALID;
2228 		} else {
2229 			if (cnt++ > count) {
2230 				rw_exit(&nm_lock.lock);
2231 				return (-1);
2232 			}
2233 			n = (struct nm_name *)lookup_entry(
2234 					nh, setno, side, key, NODEV64, 0L);
2235 			if (n == NULL) {
2236 				rw_exit(&nm_lock.lock);
2237 				return ((int)NODEV64);
2238 			}
2239 			tmpctd = ctdptr;
2240 			diskname = md_strdup(n->n_name);
2241 			if (strlen(diskname) > size) {
2242 				kmem_free(diskname, strlen(diskname) + 1);
2243 				rw_exit(&nm_lock.lock);
2244 				return (-1);
2245 			}
2246 			if ((tmpname = strrchr(diskname, 's')) != NULL)
2247 			    *tmpname = '\0';
2248 			dont_add_it = 0;
2249 			for (i = 0; i < (cnt - 1); i++) {
2250 				if (strcmp(diskname, tmpctd) == 0) {
2251 					dont_add_it = 1;
2252 					break;
2253 				}
2254 				tmpctd += size;
2255 			}
2256 			if (dont_add_it == 0) {
2257 				(void) strcpy(cptr, diskname);
2258 				cptr += size;
2259 			}
2260 			kmem_free(diskname, strlen(n->n_name) + 1);
2261 		}
2262 	}
2263 	*cptr = '\0';
2264 	rw_exit(&nm_lock.lock);
2265 	return (0);
2266 }
2267 /*
2268  * md_validate_devid - Checks the device id's to see if they're valid.
2269  *			Returns a count of the number of invalid device id's
2270  */
2271 int
2272 md_validate_devid(
2273 	set_t	setno,
2274 	side_t	side,
2275 	int	*rmaxsz
2276 )
2277 {
2278 	struct nm_next_hdr	*did_shr_nh, *did_nh = NULL;
2279 	struct did_shr_name	*did_shr_n;
2280 	struct did_min_name	*did_n;
2281 	struct nm_name		*n;
2282 	struct nm_next_hdr	*nh = NULL;
2283 	int			cnt = 0;
2284 	int			key = MD_KEYWILD;
2285 	int			maxsz = 0;
2286 	int			len;
2287 
2288 	/*
2289 	 * do the locator blocks first...
2290 	 */
2291 
2292 	if ((cnt = mddb_validate_lb(setno, &maxsz)) == -1) {
2293 		return (-1);
2294 	}
2295 
2296 	/*
2297 	 * Load the devid name space if it exists
2298 	 */
2299 	(void) md_load_namespace(setno, NULL, NM_DEVID);
2300 	if (! md_load_namespace(setno, NULL, 0L)) {
2301 		/*
2302 		 * Unload the devid namespace
2303 		 */
2304 		(void) md_unload_namespace(setno, NM_DEVID);
2305 		return (-1);
2306 	}
2307 
2308 	rw_enter(&nm_lock.lock, RW_READER);
2309 
2310 	did_nh = get_first_record(setno, 0, NM_DEVID | NM_NOTSHARED);
2311 	if (did_nh == NULL) {
2312 		rw_exit(&nm_lock.lock);
2313 		*rmaxsz = maxsz;
2314 		return (cnt);
2315 	}
2316 
2317 	did_shr_nh = get_first_record(setno, 0, NM_DEVID | NM_SHARED);
2318 	if (did_shr_nh == NULL) {
2319 		rw_exit(&nm_lock.lock);
2320 		*rmaxsz = maxsz;
2321 		return (cnt);
2322 	}
2323 
2324 	nh = get_first_record(setno, 0, NM_NOTSHARED);
2325 	if (nh == NULL) {
2326 		rw_exit(&nm_lock.lock);
2327 		*rmaxsz = maxsz;
2328 		return (cnt);
2329 	}
2330 	while ((key = md_getnextkey(setno, side, key, NULL)) != MD_KEYWILD) {
2331 		dev_t		devt;
2332 		ddi_devid_t	rtn_devid = NULL;
2333 		int		get_rc;
2334 		int		compare_rc = 1;
2335 
2336 		did_n = (struct did_min_name *)lookup_entry(
2337 				did_nh, setno, side, key, NODEV64, NM_DEVID);
2338 		if (did_n == NULL) {
2339 			continue;
2340 		}
2341 		did_shr_n = (struct did_shr_name *)lookup_shared_entry(
2342 				did_shr_nh, did_n->min_devid_key, (char *)0,
2343 				NULL, NM_DEVID);
2344 		if ((did_shr_n->did_data & NM_DEVID_VALID) != 0) {
2345 			continue;
2346 		}
2347 
2348 		devt = md_dev64_to_dev(
2349 				md_getdevnum(setno, side, key, MD_TRUST_DEVT));
2350 		get_rc = ddi_lyr_get_devid(devt, &rtn_devid);
2351 		if (get_rc == DDI_SUCCESS) {
2352 			compare_rc = ddi_devid_compare(rtn_devid,
2353 			    (ddi_devid_t)did_shr_n->did_devid);
2354 			ddi_devid_free(rtn_devid);
2355 		}
2356 
2357 		if ((get_rc == DDI_SUCCESS) && (compare_rc == 0)) {
2358 			did_shr_n->did_data |= NM_DEVID_VALID;
2359 		} else {
2360 			/* device id is invalid */
2361 			cnt++;
2362 			n = (struct nm_name *)lookup_entry(
2363 					nh, setno, side, key, NODEV64, 0L);
2364 			if (n == NULL) {
2365 				rw_exit(&nm_lock.lock);
2366 				return ((int)NODEV64);
2367 			}
2368 			/* update max size if necessary */
2369 			len = (int)strlen(n->n_name);
2370 			if (maxsz < len)
2371 				maxsz = len;
2372 		}
2373 	}
2374 	rw_exit(&nm_lock.lock);
2375 	*rmaxsz = maxsz;
2376 	return (cnt);
2377 }
2378 
2379 /*
2380  * md_getdevname - Allows getting a device name from the database.
2381  *		   A pointer to a character array is passed in for
2382  *		   the device name to be built in. Also the max_size
2383  *		   is the maximum number of characters which can be put
2384  *		   in the devname[].
2385  */
2386 int
2387 md_getdevname(
2388 	set_t	setno,		/* which set to get name from */
2389 	side_t	side,		/* (key 1) side number */
2390 	mdkey_t	key,		/* (key 2) key provided by md_setdevname() */
2391 	md_dev64_t	dev,	/* (alt. key 2) use this if key == KEYWILD */
2392 	char	*devname,	/* char array to put device name in */
2393 	size_t	max_size	/* size of char array */
2394 )
2395 {
2396 	struct nm_next_hdr	*nh;
2397 	struct nm_name		*n;
2398 	int			err;
2399 
2400 	/*
2401 	 * Load the devid name space if it exists
2402 	 */
2403 	(void) md_load_namespace(setno, NULL, NM_DEVID);
2404 	if (! md_load_namespace(setno, NULL, 0L)) {
2405 		/*
2406 		 * Unload the devid namespace
2407 		 */
2408 		(void) md_unload_namespace(setno, NM_DEVID);
2409 		return (ENOENT);
2410 	}
2411 
2412 	rw_enter(&nm_lock.lock, RW_READER);
2413 
2414 	if ((nh = get_first_record(setno, 0, NM_NOTSHARED)) == NULL) {
2415 		rw_exit(&nm_lock.lock);
2416 		return (ENOENT);
2417 	}
2418 
2419 	if ((n = (struct nm_name *)lookup_entry(nh, setno, side, key,
2420 	    dev, 0L))
2421 		== NULL) {
2422 		rw_exit(&nm_lock.lock);
2423 		return (ENOENT);
2424 	}
2425 
2426 	err = md_make_devname(n, setno, devname, max_size);
2427 
2428 	rw_exit(&nm_lock.lock);
2429 	return (err);
2430 }
2431 
2432 /*
2433  * md_gethspinfo -  Getting a hsp name or id from the database.
2434  *		    A pointer to a character array is passed in for
2435  *		    the hsp name to be built in. If a match is found,
2436  *		    the corresponding hspid is stored in ret_hspid.
2437  */
2438 int
2439 md_gethspinfo(
2440 	set_t	setno,		/* which set to get name from */
2441 	side_t	side,		/* (key 1) side number */
2442 	mdkey_t	key,		/* (key 2) key provided by md_setdevname() */
2443 	char	*drvnm,		/* return driver name here */
2444 	hsp_t	*ret_hspid,	/* returned key if key is MD_KEYWILD */
2445 	char	*hspname	/* alternate key or returned device name */
2446 )
2447 {
2448 	struct nm_next_hdr	*nh;
2449 	struct nm_name		*n;
2450 	char			*drv_name;
2451 	int			err = 0;
2452 	char			*setname = NULL;
2453 
2454 	/*
2455 	 * Load the devid name space if it exists
2456 	 */
2457 	(void) md_load_namespace(setno, NULL, NM_DEVID);
2458 	if (! md_load_namespace(setno, NULL, 0L)) {
2459 		/*
2460 		 * Unload the devid namespace
2461 		 */
2462 		(void) md_unload_namespace(setno, NM_DEVID);
2463 		return (ENOENT);
2464 	}
2465 
2466 	rw_enter(&nm_lock.lock, RW_READER);
2467 
2468 	if ((nh = get_first_record(setno, 0, NM_NOTSHARED)) == NULL) {
2469 		rw_exit(&nm_lock.lock);
2470 		return (ENOENT);
2471 	}
2472 
2473 	if ((n = (struct nm_name *)lookup_hspentry(nh, setno, side,
2474 	    key, hspname)) == NULL) {
2475 		rw_exit(&nm_lock.lock);
2476 		return (ENOENT);
2477 	}
2478 
2479 	/* Copy the driver name, device name and key for return */
2480 	drv_name = (char *)getshared_name(setno, n->n_drv_key, 0L);
2481 	if (!drv_name || (strlen(drv_name) > MD_MAXDRVNM)) {
2482 		rw_exit(&nm_lock.lock);
2483 		return (EFAULT);
2484 	}
2485 
2486 	/*
2487 	 * Pre-friendly hsp names are of the form hspxxx and we
2488 	 * should not have an entry in the namespace for them.
2489 	 * So make sure the NM entry we get is a hotspare pool.
2490 	 */
2491 	if ((strcmp(drv_name, "md_hotspares")) != 0) {
2492 		rw_exit(&nm_lock.lock);
2493 		return (ENOENT);
2494 	}
2495 	(void) strcpy(drvnm, drv_name);
2496 
2497 	/*
2498 	 * If the input key is not MD_KEYWILD, return the
2499 	 * hspname we found.
2500 	 */
2501 	if (key != MD_KEYWILD) {
2502 		setname = mddb_getsetname(setno);
2503 		if (setname != NULL)
2504 			(void) snprintf(hspname, MAXPATHLEN,
2505 			    "%s/%s", setname, n->n_name);
2506 		else
2507 			(void) snprintf(hspname, MAXPATHLEN,
2508 			    "%s", n->n_name);
2509 	}
2510 
2511 	*ret_hspid = KEY_TO_HSP_ID(setno, n->n_key);
2512 
2513 	rw_exit(&nm_lock.lock);
2514 	return (err);
2515 }
2516 
2517 /*
2518  * md_devid_found  - Check to see if this key has devid entry or not
2519  *		     Return 1 if there is one or 0 if none
2520  */
2521 int
2522 md_devid_found(
2523 	set_t	setno,		/* which set to get name from */
2524 	side_t	side,		/* (key 1) side number */
2525 	mdkey_t	key		/* key used to find entry in namespace */
2526 )
2527 {
2528 	struct nm_next_hdr	*nh;
2529 
2530 	/*
2531 	 * Load the devid name space if it exists
2532 	 */
2533 	(void) md_load_namespace(setno, NULL, NM_DEVID);
2534 	if (! md_load_namespace(setno, NULL, 0L)) {
2535 		/*
2536 		 * Unload the devid namespace
2537 		 */
2538 		(void) md_unload_namespace(setno, NM_DEVID);
2539 		return (0);
2540 	}
2541 
2542 	rw_enter(&nm_lock.lock, RW_READER);
2543 
2544 	if ((nh = get_first_record(setno, 0, NM_DEVID| NM_NOTSHARED)) == NULL) {
2545 		rw_exit(&nm_lock.lock);
2546 		return (0);
2547 	}
2548 
2549 	/*
2550 	 * Look up the key
2551 	 */
2552 	if (lookup_entry(nh, setno, side, key, NODEV64, NM_DEVID) == NULL) {
2553 			/* This key not in database */
2554 			rw_exit(&nm_lock.lock);
2555 			return (0);
2556 	}
2557 
2558 	rw_exit(&nm_lock.lock);
2559 	/* found a key */
2560 	return (1);
2561 }
2562 
2563 
2564 /*
2565  * md_getkeyfromdev  - Allows getting a key from the database by using the dev.
2566  *                     Returns the first key found and the number of keys
2567  *                     found that match dev.
2568  */
2569 int
2570 md_getkeyfromdev(
2571 	set_t	setno,		/* which set to get name from */
2572 	side_t	side,		/* (key 1) side number */
2573 	md_dev64_t	dev,	/* dev to match against */
2574 	mdkey_t	*firstkey,	/* ptr for first key found */
2575 	int	*numkeysmatch	/* ptr to number of keys matching dev */
2576 )
2577 {
2578 	struct nm_next_hdr	*nh;
2579 	struct nm_name		*n;
2580 	int			keynum;
2581 
2582 	/*
2583 	 * Load the devid name space if it exists
2584 	 */
2585 	(void) md_load_namespace(setno, NULL, NM_DEVID);
2586 	if (! md_load_namespace(setno, NULL, 0L)) {
2587 		/*
2588 		 * Unload the devid namespace
2589 		 */
2590 		(void) md_unload_namespace(setno, NM_DEVID);
2591 		return (ENOENT);
2592 	}
2593 
2594 	rw_enter(&nm_lock.lock, RW_READER);
2595 
2596 	if ((nh = get_first_record(setno, 0, NM_NOTSHARED)) == NULL) {
2597 		rw_exit(&nm_lock.lock);
2598 		return (ENOENT);
2599 	}
2600 
2601 	/*
2602 	 * Walk through all keys in the namespace looking for a match
2603 	 * against the given dev.  Count the number of matches and
2604 	 * set firstkey to be first matched key.
2605 	 */
2606 	*numkeysmatch = 0;
2607 	for (keynum = 1; keynum <
2608 	    ((struct nm_rec_hdr *)nh->nmn_record)->r_next_key; keynum++) {
2609 		if ((n = (struct nm_name *)lookup_entry(nh, setno, side,
2610 		    keynum, dev, 0L)) == NULL) {
2611 			/* This key not in database */
2612 			continue;
2613 		} else {
2614 			/* found a key, look for the dev match */
2615 			if (dev == build_device_number(setno,
2616 			    (struct nm_name *)n)) {
2617 				/* found a dev match */
2618 				(*numkeysmatch)++;
2619 				if (*numkeysmatch == 1) {
2620 					*firstkey = n->n_key;
2621 				}
2622 			}
2623 		}
2624 	}
2625 
2626 	rw_exit(&nm_lock.lock);
2627 	return (0);
2628 }
2629 
2630 /*
2631  * md_getnment  - Allows getting a driver name and minor # from the database.
2632  */
2633 int
2634 md_getnment(
2635 	set_t	setno,		/* which set to get name from */
2636 	side_t	side,		/* (key 1) side number */
2637 	mdkey_t	key,		/* (key 2) key provided by md_setdevname() */
2638 	md_dev64_t dev,
2639 	char	*drvnm,		/* char array to put driver name in */
2640 	uint_t	max_size,	/* size of char array */
2641 	major_t	*major,		/* address for major number */
2642 	minor_t	*mnum,		/* address for minor number */
2643 	mdkey_t	*retkey		/* address for returning key */
2644 )
2645 {
2646 	struct nm_next_hdr	*nh;
2647 	struct nm_name		*n;
2648 	char			*drv_name;
2649 
2650 	/*
2651 	 * Load the devid name space if it exists
2652 	 */
2653 	(void) md_load_namespace(setno, NULL, NM_DEVID);
2654 	if (! md_load_namespace(setno, NULL, 0L)) {
2655 		/*
2656 		 * Unload the devid namespace
2657 		 */
2658 		(void) md_unload_namespace(setno, NM_DEVID);
2659 		return (ENOENT);
2660 	}
2661 
2662 	rw_enter(&nm_lock.lock, RW_READER);
2663 
2664 	if ((nh = get_first_record(setno, 0, NM_NOTSHARED)) == NULL) {
2665 		rw_exit(&nm_lock.lock);
2666 		return (ENOENT);
2667 	}
2668 
2669 	if ((n = (struct nm_name *)lookup_entry(nh, setno, side, key,
2670 	    dev, 0L))
2671 		== NULL) {
2672 		rw_exit(&nm_lock.lock);
2673 		return (ENOENT);
2674 	}
2675 
2676 	drv_name = (char *)getshared_name(setno, n->n_drv_key, 0L);
2677 	if (!drv_name || (strlen(drv_name) > max_size)) {
2678 		rw_exit(&nm_lock.lock);
2679 		return (EFAULT);
2680 	}
2681 
2682 	/* Copy the driver name, and fill in the minor number */
2683 	(void) strcpy(drvnm, drv_name);
2684 	if (MD_UPGRADE)
2685 		*major = md_targ_name_to_major(drvnm);
2686 	else
2687 		*major = ddi_name_to_major(drvnm);
2688 	*mnum = n->n_minor;
2689 	*retkey = n->n_key;
2690 
2691 	rw_exit(&nm_lock.lock);
2692 
2693 	return (0);
2694 }
2695 
2696 /*
2697  * md_getdevnum  - Allows getting a device number from the database.
2698  * This routine returns a translated (aka miniroot) md_dev64_t.
2699  */
2700 md_dev64_t
2701 md_getdevnum(
2702 	set_t	setno,		/* which set to get name from */
2703 	side_t	side,		/* (key 1) side number */
2704 	mdkey_t	key,		/* (key 2) key provided by md_setdevname() */
2705 	int	flag)		/* If set then return devt from namespace */
2706 {
2707 	struct nm_next_hdr	*nh, *did_shr_nh, *did_nh = NULL;
2708 	struct nm_name		*n;
2709 	struct did_min_name	*did_n;
2710 	struct did_shr_name	*did_shr_n;
2711 	md_dev64_t		retval, retval_targ;
2712 	int			did_found = 0;
2713 	ddi_devid_t		devid = NULL;
2714 	int			ndevs;
2715 	dev_t			*devs;
2716 	char			*drv, *drvnm, *mname = NULL;
2717 	mddb_recid_t		recids[3];
2718 	int			devid_nm = 0;
2719 
2720 	/*
2721 	 * If a MN diskset and this node is the master OR
2722 	 * if a traditional diskset, then check to see if the
2723 	 * did namespace should be cleaned up.
2724 	 *
2725 	 * Always set MD_SET_DIDCLUP bit in set's status field
2726 	 * so that this check is only done once.
2727 	 */
2728 	if (!(md_get_setstatus(setno) & MD_SET_DIDCLUP)) {
2729 	    if ((MD_MNSET_SETNO(setno) && (md_set[setno].s_am_i_master)) ||
2730 		(!(MD_MNSET_SETNO(setno)))) {
2731 		    if (!(((mddb_set_t *)md_set[setno].s_db)->s_lbp->lb_flags
2732 			& MDDB_DEVID_STYLE) || md_devid_destroy) {
2733 			    (void) md_load_namespace(setno, NULL, NM_DEVID);
2734 			    (void) md_devid_cleanup(setno, 1);
2735 		    }
2736 	    }
2737 	    md_set_setstatus(setno, MD_SET_DIDCLUP);
2738 	}
2739 
2740 	/*
2741 	 * Test the MDDB_DEVID_STYLE bit
2742 	 */
2743 	if (((mddb_set_t *)md_set[setno].s_db)->s_lbp->lb_flags
2744 		& MDDB_DEVID_STYLE) {
2745 		(void) md_load_namespace(setno, NULL, NM_DEVID);
2746 		devid_nm = 1;
2747 	} else {
2748 		(void) md_unload_namespace(setno, NM_DEVID);
2749 	}
2750 
2751 	/*
2752 	 * Load the primary name space
2753 	 */
2754 	if (! md_load_namespace(setno, NULL, 0L)) {
2755 		/*
2756 		 * Unload the devid namespace
2757 		 */
2758 		(void) md_unload_namespace(setno, NM_DEVID);
2759 		return (NODEV64);
2760 	}
2761 
2762 	rw_enter(&nm_lock.lock, RW_READER);
2763 
2764 
2765 	/*
2766 	 * If not even in the primary name space, bail out
2767 	 */
2768 	if (((nh = get_first_record(setno, 0, NM_NOTSHARED)) == NULL) ||
2769 		((n = (struct nm_name *)lookup_entry(nh, setno, side, key,
2770 			NODEV64, 0L)) == NULL)) {
2771 		rw_exit(&nm_lock.lock);
2772 		return (NODEV64);
2773 	}
2774 
2775 	/*
2776 	 * Entry corresponds to this key is referenced and snarfed so
2777 	 * we set the value to 1.  During the name space cleanup we will check
2778 	 * this value and if it is set then we know it is part of the
2779 	 * current configuration.  For any 'key' whose value is not set
2780 	 * then we know it is an 'orphan' entry and will be removed.
2781 	 */
2782 	if (md_nm_snarfed)
2783 		md_nm_snarfed[key] = 1;
2784 
2785 	/*
2786 	 * Reference the device id namespace
2787 	 */
2788 	if (devid_nm) {
2789 	    if (((did_nh = get_first_record(setno, 1, NM_DEVID | NM_NOTSHARED))
2790 		== NULL) || ((did_shr_nh = get_first_record(setno, 1,
2791 			NM_DEVID | NM_SHARED)) == NULL)) {
2792 		devid_nm = 0;
2793 	    }
2794 	}
2795 
2796 	/*
2797 	 * If the key is in the device id name space then
2798 	 * this device has disk tracking info stored
2799 	 */
2800 	if (devid_nm && ((did_n = (struct did_min_name *)lookup_entry(did_nh,
2801 		setno, side, key, NODEV64, NM_DEVID)) != NULL)) {
2802 		/*
2803 		 * Get the minor name and the device id
2804 		 */
2805 		devid = (ddi_devid_t)getshared_name(setno,
2806 						did_n->min_devid_key, NM_DEVID);
2807 
2808 		did_shr_n = (struct did_shr_name *)lookup_shared_entry(
2809 					did_shr_nh, did_n->min_devid_key,
2810 					(char *)0, NULL, NM_DEVID);
2811 
2812 		if ((devid == NULL) || (did_shr_n == NULL)) {
2813 			rw_exit(&nm_lock.lock);
2814 			return (NODEV64);
2815 		}
2816 
2817 
2818 		if (ddi_lyr_devid_to_devlist(devid, did_n->min_name, &ndevs,
2819 			&devs) == DDI_SUCCESS) {
2820 
2821 			md_dev64_t tdev;
2822 			int cnt;
2823 
2824 			did_found = 1;
2825 
2826 			/*
2827 			 * Save the first available devt
2828 			 * During upgrade, this is a miniroot devt.
2829 			 */
2830 
2831 			retval = md_expldev(devs[0]);
2832 
2833 			/*
2834 			 * For a multipath device more than 1 md_dev64_t will
2835 			 * occur. In this case retval will be set to
2836 			 * the md_dev64_t that was previously set.
2837 			 */
2838 
2839 			if (ndevs > 1) {
2840 
2841 				/* get the stored md_dev64_t */
2842 				tdev = build_device_number(setno, n);
2843 				for (cnt = 0; cnt < ndevs; cnt++) {
2844 					if (tdev == md_expldev(devs[cnt])) {
2845 						retval = tdev;
2846 						break;
2847 					}
2848 				}
2849 			}
2850 
2851 			/*
2852 			 * If during upgrade, switch drvnm to be target
2853 			 * device's name, not miniroot's name.
2854 			 */
2855 			if (MD_UPGRADE)
2856 				drvnm = md_targ_major_to_name(md_getmajor
2857 					(md_xlate_mini_2_targ(retval)));
2858 			else
2859 				drvnm = ddi_major_to_name(
2860 						md_getmajor(retval));
2861 
2862 			/*
2863 			 * It is a valid device id
2864 			 */
2865 			did_shr_n->did_data = NM_DEVID_VALID;
2866 
2867 			/*
2868 			 * Free the memory
2869 			 */
2870 			(void) ddi_lyr_free_devlist(devs, ndevs);
2871 		} else {
2872 			/*
2873 			 * Invalid device id, say so
2874 			 * and check flag to see if we can return
2875 			 * devt stored in the namespace
2876 			 */
2877 			did_shr_n->did_data = NM_DEVID_INVALID;
2878 			rw_exit(&nm_lock.lock);
2879 
2880 			/*
2881 			 * If flag does not have MD_TRUST_DEVT bit on
2882 			 * then with the invalid device id we simply cant
2883 			 * trust the devt in the namespace at all
2884 			 *
2885 			 * Bit MD_TRUST_DEVT is set by metadevadm or
2886 			 * when a diskset is taken and it does not have
2887 			 * any associated devid records for the drive
2888 			 * records in the set.
2889 			 *
2890 			 * When this bit is set that means devt can be
2891 			 * trusted and we just go ahead do whatever user
2892 			 * ask for
2893 			 */
2894 			if (!(flag & MD_TRUST_DEVT))
2895 				return (NODEV64);
2896 
2897 			/* build_device_number returns a target devt */
2898 			retval_targ = build_device_number(setno, n);
2899 			/* translate devt to miniroot devt */
2900 			if ((retval = md_xlate_targ_2_mini(retval_targ))
2901 			    == NODEV64) {
2902 				return (NODEV64);
2903 			}
2904 			return (retval);
2905 		}
2906 	}
2907 
2908 
2909 	/*
2910 	 * If no entry is found in the device id name space
2911 	 * It can be one of:
2912 	 *	underlying meta device
2913 	 *	No device id associated
2914 	 *	Has a device id but mddb is in the old fromat
2915 	 */
2916 	if (did_found) {
2917 		/*
2918 		 * Update the name entry if necessary
2919 		 */
2920 		if ((retval_targ = md_xlate_mini_2_targ(retval)) == NODEV64) {
2921 			rw_exit(&nm_lock.lock);
2922 			return (NODEV64);
2923 		}
2924 
2925 		if (n->n_minor != md_getminor(retval_targ))
2926 			n->n_minor = md_getminor(retval_targ);
2927 
2928 		if ((drv =
2929 		    (char *)getshared_name(setno, n->n_drv_key, 0L)) == NULL) {
2930 			rw_exit(&nm_lock.lock);
2931 			return (NODEV64);
2932 		}
2933 
2934 		if (strcmp(drv, drvnm) != 0)
2935 			n->n_drv_key = setshared_name(setno, drvnm,
2936 			    MD_KEYWILD, 0L);
2937 
2938 		if (!(md_get_setstatus(setno) & MD_SET_STALE))
2939 			(void) update_entry(nh, side, key, 0L);
2940 	} else {
2941 		/*
2942 		 * Has a device id associated with it?
2943 		 * If yes, then we will try to add them into the device id nm
2944 		 * build_device_number returns a target devt.
2945 		 */
2946 		if ((retval_targ = build_device_number(setno, n)) == NODEV64) {
2947 			rw_exit(&nm_lock.lock);
2948 			return (NODEV64);
2949 		}
2950 
2951 		/*
2952 		 * We don't translate the devt of the meta device
2953 		 * and currently no device id associated with metadevice
2954 		 */
2955 		if (md_getmajor(retval_targ) != md_major_targ) {
2956 
2957 			if ((retval = md_xlate_targ_2_mini(retval_targ))
2958 			    == NODEV64) {
2959 				rw_exit(&nm_lock.lock);
2960 				return (NODEV64);
2961 			}
2962 
2963 			/*
2964 			 * Add the device id info only if
2965 			 * MDDB_DEVID_STYLE bit is set
2966 			 *
2967 			 */
2968 			if (!devid_nm) {
2969 				rw_exit(&nm_lock.lock);
2970 				return (retval);
2971 			}
2972 
2973 			/*
2974 			 * We can continue if we are here
2975 			 * If retval has a device id, add them
2976 			 */
2977 			if ((ddi_lyr_get_devid(md_dev64_to_dev(retval), &devid)
2978 							== DDI_SUCCESS) &&
2979 			    (ddi_lyr_get_minor_name(md_dev64_to_dev(retval),
2980 							S_IFBLK, &mname)
2981 							== DDI_SUCCESS)) {
2982 				/*
2983 				 * Add them into the devid name space
2984 				 */
2985 				did_n = (struct did_min_name *)alloc_entry(
2986 					did_nh, md_set[setno].s_did_nmid,
2987 					strlen(mname)+1, NM_DEVID|NM_NOTSHARED,
2988 					&recids[0]);
2989 
2990 				if (did_n) {
2991 					did_n->min_side = side;
2992 					did_n->min_key = key;
2993 					did_n->min_count = 1;
2994 					(void) strcpy(did_n->min_name, mname);
2995 					did_n->min_namlen =
2996 					    (ushort_t)(strlen(mname)+1);
2997 					did_n->min_devid_key =
2998 					    setshared_name(setno,
2999 						(char *)devid, MD_KEYWILD,
3000 						NM_DEVID);
3001 					/*
3002 					 * Commit the change to the record
3003 					 */
3004 					if (did_n->min_devid_key == MD_KEYBAD) {
3005 						(void) remove_entry(did_nh,
3006 							did_n->min_side,
3007 							did_n->min_key,
3008 							NM_DEVID);
3009 					} else {
3010 						recids[1] =
3011 						    md_set[setno].s_did_nmid;
3012 						recids[2] = 0;
3013 						mddb_commitrecs_wrapper(recids);
3014 					}
3015 				}
3016 			}
3017 			/*
3018 			 * Free all the memory
3019 			 */
3020 			if (devid)
3021 				ddi_devid_free(devid);
3022 			if (mname)
3023 				kmem_free(mname, strlen(mname) + 1);
3024 		} else {
3025 			retval = md_makedevice(md_major,
3026 						md_getminor(retval_targ));
3027 		}
3028 	}
3029 
3030 	rw_exit(&nm_lock.lock);
3031 	return (retval);
3032 }
3033 
3034 /*
3035  * md_getnextkey  - Allows running thru the list of defined device names.
3036  */
3037 mdkey_t
3038 md_getnextkey(
3039 	set_t	setno,		/* which set to get name from */
3040 	side_t	side,		/* (key 1) side number */
3041 	mdkey_t	key,		/* (key 2) wildcarded or from md_getnextkey() */
3042 	uint_t	*cnt)		/* n_count returns here */
3043 {
3044 	struct nm_next_hdr	*nh;
3045 	struct nm_name		*n = NULL;
3046 	mdkey_t			retval = MD_KEYWILD;
3047 
3048 
3049 	/*
3050 	 * Load the devid name space if it exists
3051 	 */
3052 	(void) md_load_namespace(setno, NULL, NM_DEVID);
3053 	if (! md_load_namespace(setno, NULL, 0L)) {
3054 		/*
3055 		 * Unload the devid namespace
3056 		 */
3057 		(void) md_unload_namespace(setno, NM_DEVID);
3058 		return (MD_KEYWILD);
3059 	}
3060 
3061 	rw_enter(&nm_lock.lock, RW_READER);
3062 
3063 	if ((nh = get_first_record(setno, 0, NM_NOTSHARED)) == NULL) {
3064 		rw_exit(&nm_lock.lock);
3065 		return (MD_KEYWILD);
3066 	}
3067 
3068 	for (key++; key < ((struct nm_rec_hdr *)nh->nmn_record)->r_next_key;
3069 			key++) {
3070 		if ((n = (struct nm_name *)lookup_entry(nh, setno, side, key,
3071 			NODEV64, 0L)) != NULL)
3072 			break;
3073 	}
3074 
3075 	if (n != NULL) {
3076 		if (cnt != NULL)
3077 		    *cnt = n->n_count;
3078 
3079 		retval = n->n_key;
3080 	}
3081 
3082 	rw_exit(&nm_lock.lock);
3083 	return (retval);
3084 }
3085 
3086 /*
3087  * md_update_namespace_did - update the devid portion of the namespace
3088  */
3089 int
3090 md_update_namespace_did(
3091 	set_t		setno,
3092 	side_t		side,
3093 	mdkey_t		key,
3094 	md_error_t	*ep
3095 )
3096 {
3097 	dev_t			devt;
3098 	ddi_devid_t		rtn_devid = NULL;
3099 	ddi_devid_t		devid = NULL;
3100 	struct nm_next_hdr	*did_shr_nh;
3101 	mdkey_t			ent_did_key;
3102 	uint32_t		ent_did_count;
3103 	uint32_t		ent_did_data;
3104 	struct nm_next_hdr	*this_did_shr_nh;
3105 	void			*record;
3106 	size_t			offset;
3107 	struct did_shr_name	*shn;
3108 	mddb_recid_t		recids[3];
3109 	struct nm_next_hdr	*nh;
3110 	struct nm_next_hdr	*this_did_nh;
3111 	struct did_min_name	*n;
3112 	struct did_shr_name	*shr_n;
3113 	mdkey_t			o_key, devid_key;
3114 	size_t			ent_size, size;
3115 
3116 	(void) md_load_namespace(setno, NULL, NM_DEVID);
3117 	if (!md_load_namespace(setno, NULL, 0L)) {
3118 		(void) md_unload_namespace(setno, NM_DEVID);
3119 		return ((int)NODEV64);
3120 	}
3121 	rw_enter(&nm_lock.lock, RW_WRITER);
3122 
3123 	offset = (sizeof (struct devid_shr_rec) - sizeof (struct did_shr_name));
3124 	if ((nh = get_first_record(setno, 0, NM_DEVID | NM_NOTSHARED)) ==
3125 									NULL) {
3126 		rw_exit(&nm_lock.lock);
3127 		return (ENOENT);
3128 	}
3129 
3130 	this_did_nh = nh->nmn_nextp;
3131 	if (this_did_nh  == NULL) {
3132 		rw_exit(&nm_lock.lock);
3133 		return (ENOENT);
3134 	}
3135 	record = this_did_nh->nmn_record;
3136 	if (record == NULL) {
3137 		rw_exit(&nm_lock.lock);
3138 		return (ENOENT);
3139 	}
3140 	if ((n = (struct did_min_name *)lookup_entry(nh, setno, side, key,
3141 	    NODEV64, NM_DEVID)) == NULL) {
3142 		rw_exit(&nm_lock.lock);
3143 		return (ENOENT);
3144 	}
3145 	devid_key = n->min_devid_key;
3146 
3147 	rw_exit(&nm_lock.lock);
3148 	devt = md_dev64_to_dev(
3149 			md_getdevnum(setno, side, key, MD_TRUST_DEVT));
3150 	rw_enter(&nm_lock.lock, RW_WRITER);
3151 	if (ddi_lyr_get_devid(devt, &rtn_devid) == DDI_SUCCESS) {
3152 		did_shr_nh = get_first_record(setno, 0, NM_DEVID | NM_SHARED);
3153 		if (did_shr_nh == NULL) {
3154 			ddi_devid_free(rtn_devid);
3155 			rw_exit(&nm_lock.lock);
3156 			return ((int)NODEV64);
3157 		}
3158 		this_did_shr_nh = did_shr_nh->nmn_nextp;
3159 		record = this_did_shr_nh->nmn_record;
3160 		shn = &((struct devid_shr_rec *)record)->device_id[0];
3161 		shr_n = (struct did_shr_name *)lookup_shared_entry(
3162 				did_shr_nh, n->min_devid_key, (char *)0,
3163 				&recids[0], NM_DEVID);
3164 		if (shr_n == NULL) {
3165 			ddi_devid_free(rtn_devid);
3166 			rw_exit(&nm_lock.lock);
3167 			return (ENOENT);
3168 		}
3169 		o_key = shn->did_key;
3170 		while (devid_key != o_key) {
3171 			shn = (struct did_shr_name *)get_next_entry(
3172 					this_did_shr_nh, (caddr_t)shn,
3173 					DID_SHR_NAMSIZ(shn), &offset);
3174 			if (shn == NULL) {
3175 				if (offset) {
3176 					ddi_devid_free(rtn_devid);
3177 					rw_exit(&nm_lock.lock);
3178 					return (ENOENT);
3179 				}
3180 			}
3181 			o_key = shn->did_key;
3182 		}
3183 		devid = (ddi_devid_t)shr_n->did_devid;
3184 		if (ddi_devid_compare(rtn_devid, devid) != 0) {
3185 			/* remove old devid info */
3186 			ent_did_key = shr_n->did_key;
3187 			ent_did_count = shr_n->did_count;
3188 			ent_did_data = shr_n->did_data;
3189 			ent_size = DID_SHR_NAMSIZ(shr_n);
3190 			size = ((struct nm_rec_hdr *)this_did_shr_nh->
3191 			    nmn_record)->r_used_size - offset - ent_size;
3192 			if (size == 0) {
3193 				(void) bzero(shr_n, ent_size);
3194 			} else {
3195 				(void) ovbcopy((caddr_t)shr_n + ent_size, shr_n,
3196 				    size);
3197 				(void) bzero((caddr_t)shr_n + size, ent_size);
3198 			}
3199 			((struct nm_rec_hdr *)this_did_shr_nh->nmn_record)->
3200 			    r_used_size -= ent_size;
3201 			/* add in new devid info */
3202 			if ((shn = (struct did_shr_name *)alloc_entry(
3203 			    did_shr_nh, md_set[setno].s_did_nmid,
3204 			    ddi_devid_sizeof(rtn_devid),
3205 			    NM_DEVID | NM_SHARED | NM_NOCOMMIT,
3206 			    &recids[0])) == NULL) {
3207 				ddi_devid_free(rtn_devid);
3208 				rw_exit(&nm_lock.lock);
3209 				return (ENOMEM);
3210 			}
3211 			shn->did_key = ent_did_key;
3212 			shn->did_count = ent_did_count;
3213 			ent_did_data |= NM_DEVID_VALID;
3214 			shn->did_data = ent_did_data;
3215 			shn->did_size = ddi_devid_sizeof(rtn_devid);
3216 			bcopy((void *)rtn_devid, (void *)shn->did_devid,
3217 			    shn->did_size);
3218 			recids[1] = md_set[setno].s_nmid;
3219 			recids[2] = 0;
3220 
3221 			mddb_commitrecs_wrapper(recids);
3222 		}
3223 		ddi_devid_free(rtn_devid);
3224 	} else {
3225 		rw_exit(&nm_lock.lock);
3226 		(void) mderror(ep, MDE_NODEVID);
3227 		return (ENOENT);
3228 	}
3229 	rw_exit(&nm_lock.lock);
3230 	return (0);
3231 }
3232 
3233 /*
3234  * md_update_namespace - update namespace device name and pathname
3235  *
3236  */
3237 
3238 int
3239 md_update_namespace(
3240 	set_t	setno,		/* which set to get name from */
3241 	side_t	side,		/* (key 1) side number */
3242 	mdkey_t	key,		/* (key 2) key provided by md_setdevname() */
3243 	char	*devname,	/* device name */
3244 	char	*pathname,	/* pathname to device */
3245 	minor_t	mnum		/* minor numer */
3246 )
3247 {
3248 	struct nm_next_hdr	*nh;
3249 	struct nm_name		*n;
3250 	struct nm_name		*o_n;
3251 	struct nm_next_hdr	*this_nh;
3252 	struct nm_next_hdr	*snh;
3253 	struct nm_shared_name	*shn;
3254 	void			*record;
3255 	mddb_recid_t		recids[3];
3256 	size_t			size;
3257 	mdkey_t			ent_key, ent_drv_key, ent_dir_key, new_dir_key;
3258 	uint32_t		ent_count;
3259 	side_t			ent_side;
3260 	size_t			offset;
3261 	mdkey_t			o_key = NULL;
3262 	char			*old_pathname;
3263 	int			ent_size;
3264 
3265 	if (!md_load_namespace(setno, NULL, 0L)) {
3266 		return (ENOENT);
3267 	}
3268 
3269 	rw_enter(&nm_lock.lock, RW_WRITER);
3270 
3271 	offset = sizeof (struct nm_rec) - sizeof (struct nm_name);
3272 	if ((nh = get_first_record(setno, 0, NM_NOTSHARED)) == NULL) {
3273 		rw_exit(&nm_lock.lock);
3274 		return (ENOENT);
3275 	}
3276 
3277 	this_nh = nh->nmn_nextp;
3278 	record = this_nh->nmn_record;
3279 	o_n = &((struct nm_rec *)record)->r_name[0];
3280 	if ((n = (struct nm_name *)lookup_entry(nh, setno, side, key, NODEV64,
3281 	    0L)) == NULL) {
3282 		rw_exit(&nm_lock.lock);
3283 		return (ENOENT);
3284 	}
3285 
3286 	o_key = o_n->n_key;
3287 	while (key != o_key) {
3288 		o_n = (struct nm_name *)get_next_entry(this_nh, (caddr_t)o_n,
3289 		    NAMSIZ(o_n), &offset);
3290 		if (o_n == NULL) {
3291 			if (offset) {
3292 				rw_exit(&nm_lock.lock);
3293 				return (ENOENT);
3294 			}
3295 		}
3296 		o_key = o_n->n_key;
3297 	}
3298 	/* save the values from the old record */
3299 	ent_side = n->n_side;
3300 	ent_key = n->n_key;
3301 	ent_count = n->n_count;
3302 	ent_drv_key = n->n_drv_key;
3303 	ent_dir_key = n->n_dir_key;
3304 	ent_size = NAMSIZ(n);
3305 	size = ((struct nm_rec_hdr *)this_nh->nmn_record)->r_used_size - offset
3306 	    - ent_size;
3307 
3308 	if (size == 0) {
3309 		(void) bzero(n, ent_size);    /* last entry */
3310 	} else {
3311 		(void) ovbcopy((caddr_t)n + ent_size, n, size);
3312 		(void) bzero((caddr_t)n + size, ent_size);
3313 	}
3314 	((struct nm_rec_hdr *)this_nh->nmn_record)->r_used_size -= ent_size;
3315 
3316 	rw_exit(&nm_lock.lock);
3317 	/* check to see if we have a new pathname */
3318 	old_pathname = md_getshared_name(setno, ent_dir_key);
3319 	if (strcmp(old_pathname, pathname)) {
3320 		/* now see if the new pathname actually exists in our nsp */
3321 		if ((snh = get_first_record(setno, 0, NM_SHARED)) == NULL)
3322 			return (ENOENT);
3323 		shn = (struct nm_shared_name *)lookup_shared_entry(
3324 		    snh, NULL, pathname, &recids[0], 0L);
3325 		if (shn) {
3326 			/* pathname exists so get it's key */
3327 			new_dir_key = shn->sn_key;
3328 		} else {
3329 			/* pathname doesn't exist so create it */
3330 			new_dir_key =
3331 			    md_setshared_name(setno, pathname, NM_NOCOMMIT);
3332 		}
3333 		/* update dir key */
3334 		ent_dir_key = new_dir_key;
3335 	}
3336 
3337 	rw_enter(&nm_lock.lock, RW_WRITER);
3338 	/* Create a name entry */
3339 	n = (struct nm_name *)alloc_entry(nh, md_set[setno].s_nmid,
3340 	    strlen(devname)+1, NM_NOTSHARED | NM_NOCOMMIT, &recids[0]);
3341 
3342 	if (n == NULL) {
3343 		rw_exit(&nm_lock.lock);
3344 		return (ENOMEM);
3345 	}
3346 
3347 	n->n_minor = mnum;
3348 	n->n_side = ent_side;
3349 	n->n_key = ent_key;
3350 	n->n_count = ent_count;
3351 	n->n_drv_key = ent_drv_key;
3352 
3353 	/* fill-in filename */
3354 	(void) strcpy(n->n_name, devname);
3355 	n->n_namlen = (ushort_t)(strlen(devname) + 1);
3356 
3357 	/* directory name */
3358 	n->n_dir_key = ent_dir_key;
3359 
3360 	recids[1] = md_set[setno].s_nmid;
3361 	recids[2] = 0;
3362 
3363 	mddb_commitrecs_wrapper(recids);
3364 
3365 	rw_exit(&nm_lock.lock);
3366 	return (0);
3367 }
3368 
3369 /*
3370  * md_getdevidminor - Get the minor name from the database. The minor
3371  *		      name and the devid id uniquely identify the disk
3372  *		      slice.
3373  */
3374 int
3375 md_getdevidminor(
3376 	set_t	setno,
3377 	side_t	side,
3378 	mdkey_t	key,
3379 	char	*minorname,
3380 	size_t	max_size
3381 )
3382 {
3383 	struct nm_next_hdr	*nh;
3384 	struct did_min_name	*n;
3385 
3386 	/*
3387 	 * Load the devid name space if it exists
3388 	 */
3389 	(void) md_load_namespace(setno, NULL, NM_DEVID);
3390 	if (! md_load_namespace(setno, NULL, 0L)) {
3391 		/*
3392 		 * Unload the devid namespace
3393 		 */
3394 		(void) md_unload_namespace(setno, NM_DEVID);
3395 		return (ENOENT);
3396 	}
3397 
3398 	rw_enter(&nm_lock.lock, RW_READER);
3399 
3400 	/*
3401 	 * The key we have is for the non-shared, regular namespace.  We
3402 	 * have to lookup the min_key in the non-shared, devid namespace.
3403 	 */
3404 	if ((nh = get_first_record(setno, 0, NM_DEVID | NM_NOTSHARED))
3405 	    == NULL) {
3406 		rw_exit(&nm_lock.lock);
3407 		return (ENOENT);
3408 	}
3409 
3410 	if ((n = (struct did_min_name *)lookup_entry(nh, setno, side, key,
3411 	    NODEV64, NM_DEVID)) == NULL) {
3412 		rw_exit(&nm_lock.lock);
3413 		return (ENOENT);
3414 	}
3415 
3416 	if (n->min_namlen > max_size) {
3417 		rw_exit(&nm_lock.lock);
3418 		return (EFAULT);
3419 	}
3420 
3421 	bcopy(&((struct did_min_name *)n)->min_name[0], minorname,
3422 	    n->min_namlen);
3423 
3424 	rw_exit(&nm_lock.lock);
3425 	return (0);
3426 }
3427 
3428 /*
3429  * md_getdevid -   Allows getting a device id from the database.
3430  *		   A pointer to a character array is passed in for
3431  *		   the device id to be copied to.  The size is returned
3432  *		   in *did_size.
3433  */
3434 int
3435 md_getdevid(
3436 	set_t	setno,		/* which set to get name from */
3437 	side_t	side,
3438 	mdkey_t	key,		/* (key 2) key provided by md_setdevname() */
3439 	ddi_devid_t	did,		/* pointer to did string */
3440 	ushort_t	*did_size	/* pointer to size of did string */
3441 )
3442 {
3443 	struct nm_next_hdr	*nh;
3444 	void			*n;
3445 	mddb_recid_t		recid;
3446 
3447 	/*
3448 	 * Load the devid name space if it exists
3449 	 */
3450 	(void) md_load_namespace(setno, NULL, NM_DEVID);
3451 	if (! md_load_namespace(setno, NULL, 0L)) {
3452 		/*
3453 		 * Unload the devid namespace
3454 		 */
3455 		(void) md_unload_namespace(setno, NM_DEVID);
3456 		return (ENOENT);
3457 	}
3458 
3459 	rw_enter(&nm_lock.lock, RW_READER);
3460 
3461 	/*
3462 	 * The key we have is for the non-shared, regular namespace.  We
3463 	 * have to lookup the min_key in the non-shared, devid namespace.
3464 	 */
3465 	if ((nh = get_first_record(setno, 0, NM_DEVID | NM_NOTSHARED))
3466 	    == NULL) {
3467 		rw_exit(&nm_lock.lock);
3468 		return (ENOENT);
3469 	}
3470 
3471 	if ((n = (struct did_min_name *)lookup_entry(nh, setno, side, key,
3472 	    NODEV64, NM_DEVID)) == NULL) {
3473 		rw_exit(&nm_lock.lock);
3474 		return (ENOENT);
3475 	}
3476 
3477 	/*
3478 	 * Now go get the devid.
3479 	 */
3480 	if ((nh = get_first_record(setno, 0, NM_DEVID | NM_SHARED)) == NULL) {
3481 		rw_exit(&nm_lock.lock);
3482 		return (ENOENT);
3483 	}
3484 
3485 	if ((n = (struct did_shr_name *)lookup_shared_entry(nh,
3486 	    ((struct did_min_name *)n)->min_devid_key, (char *)0, &recid,
3487 	    NM_DEVID)) == NULL) {
3488 		rw_exit(&nm_lock.lock);
3489 		return (ENOENT);
3490 	}
3491 
3492 	/*
3493 	 * If did is non-zero then copy devid to buffer, else return
3494 	 * devid size to user.  These are exclusive operations.
3495 	 */
3496 	if (did != NULL) {
3497 		bcopy(&((struct did_shr_name *)n)->did_devid[0], did,
3498 		    *did_size);
3499 	} else {
3500 		*did_size = ((struct did_shr_name *)n)->did_size;
3501 	}
3502 
3503 	rw_exit(&nm_lock.lock);
3504 	return (0);
3505 }
3506 
3507 /*
3508  * md_remdevname - Allows removing a device name from the database.
3509  */
3510 int
3511 md_remdevname(
3512 	set_t			setno,
3513 	side_t			side,
3514 	mdkey_t			key
3515 )
3516 {
3517 	struct nm_next_hdr	*nh, *did_nh;
3518 	struct nm_next_hdr	*shared_nh, *did_shr_nh;
3519 	struct nm_name		*n;
3520 	struct did_min_name	*did_n = NULL;
3521 	mdkey_t			drv_key, dir_key, did_key;
3522 	int			err;
3523 
3524 
3525 	/*
3526 	 * Load the devid name space if it exists
3527 	 */
3528 	(void) md_load_namespace(setno, NULL, NM_DEVID);
3529 	if (! md_load_namespace(setno, NULL, 0L)) {
3530 		/*
3531 		 * Unload the devid namespace
3532 		 */
3533 		(void) md_unload_namespace(setno, NM_DEVID);
3534 		return (ENOENT);
3535 	}
3536 
3537 	rw_enter(&nm_lock.lock, RW_WRITER);
3538 
3539 	if (((nh = get_first_record(setno, 0, NM_NOTSHARED)) == NULL) ||
3540 	    ((shared_nh = get_first_record(setno, 0, NM_SHARED)) == NULL)) {
3541 		rw_exit(&nm_lock.lock);
3542 		return (ENOENT);
3543 	}
3544 
3545 	/*
3546 	 * If it is not in the primary name space, nothing to remove
3547 	 */
3548 	if ((n = (struct nm_name *)lookup_entry(nh, setno, side, key, NODEV64,
3549 		0L)) == NULL) {
3550 		rw_exit(&nm_lock.lock);
3551 		return (ENOENT);
3552 	}
3553 
3554 	/*
3555 	 * If there is non-empty device id name space
3556 	 * Try to locate the entry
3557 	 */
3558 	if (md_set[setno].s_did_nm &&
3559 	    ((did_nh = get_first_record(setno, 0, NM_DEVID | NM_NOTSHARED))
3560 		!= NULL) &&
3561 	    ((did_shr_nh = get_first_record(setno, 0, NM_DEVID | NM_SHARED))
3562 		!= NULL)) {
3563 		did_n = (struct did_min_name *)lookup_entry(did_nh, setno,
3564 			side, key, NODEV64, NM_DEVID);
3565 	}
3566 
3567 	n->n_count--;
3568 	if (n->n_count) {
3569 
3570 		err = update_entry(nh, side, key, 0L);
3571 		/*
3572 		 * Update the device id namespace as well
3573 		 */
3574 		if (did_n) {
3575 			did_n->min_count--;
3576 			(void) update_entry(did_nh, side, key, NM_DEVID);
3577 		}
3578 
3579 		rw_exit(&nm_lock.lock);
3580 		return (err);
3581 	}
3582 
3583 	/* reference count is zero, actually remove the name entry */
3584 	drv_key = n->n_drv_key;
3585 	dir_key = n->n_dir_key;
3586 	did_key = (did_n ? did_n->min_devid_key : 0);
3587 
3588 	if (remove_entry(nh, side, key, 0L)) {
3589 		rw_exit(&nm_lock.lock);
3590 		return (EINVAL);
3591 	}
3592 
3593 	if (remove_shared_entry(shared_nh, drv_key, (char *)0, 0L) ||
3594 		remove_shared_entry(shared_nh, dir_key, (char *)0, 0L)) {
3595 		rw_exit(&nm_lock.lock);
3596 		return (EINVAL);
3597 	}
3598 
3599 	/*
3600 	 * Remove from the device id name space
3601 	 */
3602 	if (did_n) {
3603 		if (remove_entry(did_nh, side, key, NM_DEVID)) {
3604 			rw_exit(&nm_lock.lock);
3605 			return (EINVAL);
3606 		}
3607 
3608 		if (remove_shared_entry(did_shr_nh, did_key, (char *)0,
3609 			NM_DEVID)) {
3610 			rw_exit(&nm_lock.lock);
3611 			return (EINVAL);
3612 		}
3613 	}
3614 
3615 	rw_exit(&nm_lock.lock);
3616 	return (0);
3617 }
3618 
3619 /*
3620  * md_setshared_name -  Puts a name into the shared namespace database, and
3621  *			returns a key (used to get the string back).
3622  *			If the name does not already exist in the namespace
3623  *			then it will be added and the reference count will
3624  *			be set to one;
3625  *			Otherwise the reference count is incremented.
3626  */
3627 mdkey_t
3628 md_setshared_name(set_t setno, char *shrname, int nocommit)
3629 {
3630 	mdkey_t	key;
3631 
3632 
3633 	/*
3634 	 * Load the devid name space if it exists
3635 	 */
3636 	(void) md_load_namespace(setno, NULL, NM_DEVID);
3637 	if (! md_load_namespace(setno, NULL, 0L)) {
3638 		/*
3639 		 * Unload the devid namespace
3640 		 */
3641 		(void) md_unload_namespace(setno, NM_DEVID);
3642 		return (MD_KEYBAD);
3643 	}
3644 
3645 	rw_enter(&nm_lock.lock, RW_WRITER);
3646 
3647 	key = setshared_name(setno, shrname, MD_KEYWILD, nocommit);
3648 
3649 	rw_exit(&nm_lock.lock);
3650 	return (key);
3651 }
3652 
3653 
3654 /*
3655  * md_getshared_name -	Allows converting a key, into the shared namespace
3656  *			database, to the string which it represents.
3657  */
3658 char *
3659 md_getshared_name(set_t setno, mdkey_t shrkey)
3660 {
3661 	char	*string;
3662 
3663 
3664 	/*
3665 	 * Load the devid name space if it exists
3666 	 */
3667 	(void) md_load_namespace(setno, NULL, NM_DEVID);
3668 	if (! md_load_namespace(setno, NULL, 0L)) {
3669 		/*
3670 		 * Unload the devid namespace
3671 		 */
3672 		(void) md_unload_namespace(setno, NM_DEVID);
3673 		return ((char *)0);
3674 	}
3675 
3676 	rw_enter(&nm_lock.lock, RW_READER);
3677 	string = (char *)getshared_name(setno, shrkey, 0L);
3678 	rw_exit(&nm_lock.lock);
3679 
3680 	return (string);
3681 }
3682 
3683 /*
3684  * md_remshared_name - Allows removing of shared name by key.
3685  */
3686 int
3687 md_remshared_name(set_t setno, mdkey_t shrkey)
3688 {
3689 	struct nm_next_hdr	*nh;
3690 
3691 
3692 	/*
3693 	 * Load the devid name space if it exists
3694 	 */
3695 	(void) md_load_namespace(setno, NULL, NM_DEVID);
3696 	if (! md_load_namespace(setno, NULL, 0L)) {
3697 		/*
3698 		 * Unload the devid namespace
3699 		 */
3700 		(void) md_unload_namespace(setno, NM_DEVID);
3701 		return (ENOENT);
3702 	}
3703 
3704 	rw_enter(&nm_lock.lock, RW_WRITER);
3705 
3706 	if ((nh = get_first_record(setno, 0, NM_SHARED)) == NULL) {
3707 		rw_exit(&nm_lock.lock);
3708 		return (ENOENT);
3709 	}
3710 
3711 	if (remove_shared_entry(nh, shrkey, (char *)0, 0L)) {
3712 		rw_exit(&nm_lock.lock);
3713 		return (ENOENT);
3714 	}
3715 
3716 	rw_exit(&nm_lock.lock);
3717 	return (0);
3718 }
3719 
3720 /*
3721  * md_getshared_key - get the key for the given string.
3722  */
3723 mdkey_t
3724 md_getshared_key(set_t setno, char *shrname)
3725 {
3726 	mdkey_t	retval;
3727 
3728 
3729 	/*
3730 	 * Load the devid name space if it exists
3731 	 */
3732 	(void) md_load_namespace(setno, NULL, NM_DEVID);
3733 	if (! md_load_namespace(setno, NULL, 0L)) {
3734 		/*
3735 		 * Unload the devid namespace
3736 		 */
3737 		(void) md_unload_namespace(setno, NM_DEVID);
3738 		return (MD_KEYBAD);
3739 	}
3740 
3741 	rw_enter(&nm_lock.lock, RW_WRITER);
3742 	retval = getshared_key(setno, shrname, 0L);
3743 	rw_exit(&nm_lock.lock);
3744 	return (retval);
3745 }
3746 
3747 /*
3748  * md_load_namespace - Get all the records associated with the namespace
3749  *			out of the database and setup all the incore
3750  *			structures (i.e., pointers).
3751  */
3752 int
3753 md_load_namespace(set_t setno, md_error_t *ep, int devid_nm)
3754 {
3755 	mddb_recid_t		hdr_recid;
3756 	struct nm_header_hdr	*hdr = NULL;
3757 	mddb_type_t		rec_type;
3758 
3759 	if ((md_get_setstatus(setno) & MD_SET_NM_LOADED))
3760 		return (1);
3761 
3762 	if (devid_nm && (md_set[setno].s_did_nm != 0))
3763 		return (1);
3764 
3765 	rec_type = (devid_nm ? MDDB_DID_NM_HDR : MDDB_NM_HDR);
3766 
3767 	hdr_recid = mddb_getnextrec(mddb_makerecid(setno, 0), rec_type, 0);
3768 
3769 	if (hdr_recid < 0) {
3770 		if (ep != NULL)
3771 			return (mddbstatus2error(ep, hdr_recid, NODEV32,
3772 							setno));
3773 		return (0);
3774 	}
3775 
3776 	if (hdr_recid != 0) {
3777 		mddb_recstatus_t status;
3778 
3779 		status = mddb_getrecstatus(hdr_recid);
3780 		if (status == MDDB_NODATA) {
3781 			mddb_setrecprivate(hdr_recid, MD_PRV_PENDDEL);
3782 			hdr_recid = 0;
3783 		} else if (status == MDDB_STALE) {
3784 			if (! (md_get_setstatus(setno) & MD_SET_STALE)) {
3785 				md_set_setstatus(setno, MD_SET_STALE);
3786 				cmn_err(CE_WARN, "md: state database is stale");
3787 			}
3788 		}
3789 	}
3790 
3791 	rw_enter(&nm_lock.lock, RW_WRITER);
3792 
3793 	if (hdr_recid != 0) {
3794 
3795 		hdr = kmem_zalloc(sizeof (*hdr), KM_SLEEP);
3796 		ASSERT(hdr != NULL);
3797 
3798 		if (devid_nm) {
3799 			md_set[setno].s_did_nmid = hdr_recid;
3800 			md_set[setno].s_did_nm = (void *)hdr;
3801 		} else {
3802 			md_set[setno].s_nmid = hdr_recid;
3803 			md_set[setno].s_nm = (void *)hdr;
3804 		}
3805 
3806 		hdr->hh_header = (struct nm_header *)mddb_getrecaddr(hdr_recid);
3807 
3808 		ASSERT(hdr->hh_header != NULL);
3809 
3810 		hdr->hh_names.nmn_record = &(hdr->hh_header->h_names);
3811 		hdr->hh_shared.nmn_record = &(hdr->hh_header->h_shared);
3812 
3813 		mddb_setrecprivate(hdr_recid, MD_PRV_GOTIT);
3814 
3815 		build_rec_hdr_list(&hdr->hh_names, hdr_recid,
3816 				devid_nm | NM_NOTSHARED);
3817 		build_rec_hdr_list(&hdr->hh_shared, hdr_recid,
3818 				devid_nm | NM_SHARED);
3819 
3820 		/*
3821 		 * Only cleanup a MN diskset if this node is master.
3822 		 * Always cleanup traditional diskset.
3823 		 */
3824 		if (!(MD_MNSET_SETNO(setno)) ||
3825 		    (MD_MNSET_SETNO(setno) && md_set[setno].s_am_i_master)) {
3826 			if (devid_nm) {
3827 				cleanup_unused_rec(setno, NM_DEVID);
3828 			} else {
3829 				cleanup_unused_rec(setno, 0L);
3830 			}
3831 		}
3832 	}
3833 
3834 	if (!devid_nm)
3835 		md_set_setstatus(setno, MD_SET_NM_LOADED);
3836 	if (hdr && hdr->hh_header != NULL)
3837 		zero_data_ptrs(&hdr->hh_shared, setno);
3838 	rw_exit(&nm_lock.lock);
3839 	return (1);
3840 }
3841 
3842 void
3843 md_unload_namespace(set_t setno, int devid_nm)
3844 {
3845 	struct nm_header_hdr *hhdr;
3846 	struct nm_next_hdr *nh, *nnh;
3847 
3848 	if (!devid_nm && (md_set[setno].s_nmid == 0))
3849 		return;
3850 
3851 	if (devid_nm && (md_set[setno].s_did_nmid == 0))
3852 		return;
3853 
3854 	rw_enter(&nm_lock.lock, RW_WRITER);
3855 
3856 	hhdr = ((devid_nm & NM_DEVID) ?
3857 		(struct nm_header_hdr *)md_set[setno].s_did_nm :
3858 		(struct nm_header_hdr *)md_set[setno].s_nm);
3859 
3860 	if (devid_nm) {
3861 		md_set[setno].s_did_nmid = 0;
3862 		md_set[setno].s_did_nm = NULL;
3863 	} else {
3864 		md_set[setno].s_nmid = 0;
3865 		md_set[setno].s_nm = NULL;
3866 	}
3867 
3868 	/*
3869 	 * Clear MD_SET_NM_LOADED when the primary is unloaded
3870 	 */
3871 	if (!devid_nm)
3872 		md_clr_setstatus(setno, MD_SET_NM_LOADED);
3873 
3874 	rw_exit(&nm_lock.lock);
3875 
3876 	/*
3877 	 * Free the memory occupied by the namespace records if any has been
3878 	 * allocated.  For the case of a namespace which contains drives not
3879 	 * supporting device id's we must be careful.
3880 	 */
3881 	if (hhdr != NULL) {
3882 		for (nh = hhdr->hh_names.nmn_nextp; nh; nh = nnh) {
3883 			nnh = nh->nmn_nextp;
3884 			kmem_free(nh, sizeof (*nh));
3885 		}
3886 
3887 		for (nh = hhdr->hh_shared.nmn_nextp; nh; nh = nnh) {
3888 			nnh = nh->nmn_nextp;
3889 			kmem_free(nh, sizeof (*nh));
3890 		}
3891 		kmem_free(hhdr, sizeof (*hhdr));
3892 	}
3893 }
3894 
3895 /*
3896  * md_nm_did_chkspace - calculate the approximate DID namespace size based
3897  *			on the component disk devices defined in the primary
3898  *			non-shared namespace for this set.  This is done on
3899  *			the conservative side and may be a block or two too
3900  *			large.  These are MDDB blocks.
3901  *
3902  * This is intended to be called during a replica conversion from non-devid
3903  * format to devid format.  As such no special precautions were taken to
3904  * insure reentrancy.  In particular the code in free_devid_list() that
3905  * initializes the devid_list anchor linkages makes this function non-MT-safe.
3906  */
3907 
3908 int
3909 md_nm_did_chkspace(set_t setno)
3910 {
3911 	struct	nm_next_hdr	*nh;
3912 	struct	nm_name		*n;
3913 	side_t			side = MD_SIDEWILD;
3914 	mdkey_t			key = MD_KEYWILD;
3915 	int			total_size = 0;	/* Total required size */
3916 	int			devid_size = 0;	/* Device id total size */
3917 	int			mname_size = 0;	/* Minor name total size */
3918 	int			namelen = 0;
3919 	int			comp_count = 0;	/* Total number of components */
3920 	int			devid_count = 0; /* Total number of devids */
3921 	ddi_devid_t		devid = NULL;
3922 	char			*mname = NULL;
3923 
3924 	rw_enter(&nm_lock.lock, RW_READER);
3925 
3926 	if ((nh = get_first_record(setno, 0, NM_NOTSHARED)) == NULL) {
3927 		rw_exit(&nm_lock.lock);
3928 		return (total_size);
3929 	}
3930 
3931 	/*
3932 	 * For each key in the non-shared, primary namespace, lookup the
3933 	 * minor name and any associated device id.  These will reside in
3934 	 * the device id namespace of the upgraded system.
3935 	 */
3936 	while ((key = md_getnextkey(setno, side, key, NULL)) != MD_KEYWILD) {
3937 		if ((n = (struct nm_name *)lookup_entry(nh, setno, side, key,
3938 			NODEV64, 0L)) == NULL) {
3939 			break;
3940 		} else {
3941 			md_dev64_t dev64 = build_device_number(setno, n);
3942 			dev_t dev = md_dev64_to_dev(dev64);
3943 
3944 			if (ddi_lyr_get_minor_name(dev, S_IFBLK, &mname)
3945 						!= DDI_SUCCESS) {
3946 				continue;
3947 			} else {
3948 				if (mname) {
3949 					namelen = strlen(mname);
3950 					mname_size += namelen;
3951 					kmem_free(mname, (namelen + 1));
3952 					comp_count++;
3953 				}
3954 			}
3955 			if (ddi_lyr_get_devid(dev, &devid) != DDI_SUCCESS) {
3956 				continue;
3957 			} else {
3958 				if (devid_is_unique(devid)) {
3959 					add_to_devid_list(devid);
3960 				} else {
3961 					ddi_devid_free(devid);
3962 				}
3963 			}
3964 		}
3965 	}
3966 
3967 	devid_size = free_devid_list(&devid_count);
3968 	rw_exit(&nm_lock.lock);
3969 
3970 	/*
3971 	 * Sum things up in this order:
3972 	 * 1) # blocks to hold devid non-shared record blocks
3973 	 * 2) # blocks to hold devid shared record blocks
3974 	 * 3) 1 block to hold devid non-shared nm_rec_hdr's
3975 	 * 4) 1 block to hold mddb_de's for both of these spaces
3976 	 */
3977 
3978 	/*
3979 	 * 1)
3980 	 */
3981 	total_size = roundup(sizeof (struct mddb_rb32) +
3982 	    sizeof (struct nm_rec_hdr) + (sizeof (struct did_min_name) *
3983 	    comp_count) + (mname_size + comp_count), MDDB_BSIZE);
3984 
3985 	/*
3986 	 * 2)
3987 	 */
3988 	total_size += roundup(sizeof (struct mddb_rb32) +
3989 	    sizeof (struct nm_rec_hdr) + (sizeof (struct did_shr_name) *
3990 	    devid_count) + devid_size, MDDB_BSIZE);
3991 
3992 	/*
3993 	 * 3) and 4)
3994 	 */
3995 	total_size += (2 * MDDB_BSIZE);
3996 
3997 	return (total_size/MDDB_BSIZE);
3998 }
3999 
4000 /*
4001  * devid_list - forward list of devid_list structs.
4002  * Managed by routines add_to_devid_list() and free_devid_list() to keep
4003  * track of unique devids associated with components of metadevices.  Entries
4004  * are made at the beginning of the list.
4005  */
4006 static	struct	devid_list {
4007 	size_t	devid_size;
4008 	struct	devid_list	*next;
4009 	ddi_devid_t		devid;
4010 } did_list = { 0, NULL, NULL};
4011 
4012 static	struct	devid_list	*dlp = &did_list;
4013 
4014 /*
4015  * add_to_devid_list - add a struct devid_list to the head of the devid_list
4016  * list.
4017  */
4018 static void
4019 add_to_devid_list(ddi_devid_t did)
4020 {
4021 	struct	devid_list	*curdlp;
4022 
4023 	curdlp = kmem_zalloc(sizeof (struct devid_list), KM_SLEEP);
4024 	curdlp->devid_size = ddi_devid_sizeof(did);
4025 	curdlp->devid = did;
4026 	curdlp->next = dlp->next;
4027 	dlp->next = curdlp;
4028 }
4029 
4030 /*
4031  * free_devid_list - free storage allocated to dev_list list.  Return number
4032  * of entries on list at address supplied by argument count.  Return total
4033  * size of all device ids that were on the list.
4034  */
4035 static size_t
4036 free_devid_list(int *count)
4037 {
4038 	struct	devid_list	*curdlp;
4039 	struct	devid_list	*nextlp;
4040 	size_t	total_size = 0;
4041 	int	n = 0;
4042 
4043 	/*
4044 	 * If there's nothing on the list.
4045 	 */
4046 	if ((curdlp = dlp->next) == NULL) {
4047 		*count = 0;
4048 		return (total_size);
4049 	}
4050 
4051 	while (curdlp) {
4052 		nextlp = curdlp->next;
4053 		total_size += curdlp->devid_size;
4054 		(void) ddi_devid_free(curdlp->devid);
4055 		kmem_free(curdlp, sizeof (struct devid_list));
4056 		curdlp = nextlp;
4057 		n++;
4058 	}
4059 
4060 	/*
4061 	 * Insure that the devid_list anchor linkages are reinitialized in
4062 	 * case of multiple calls (eg during testsuite execution).
4063 	 */
4064 	dlp->next = NULL;
4065 	dlp->devid = NULL;
4066 
4067 	*count = n;
4068 	return (total_size);
4069 }
4070 
4071 /*
4072  * devid_is_unique - search for did on devid_list list.  Return "false" if
4073  * found.
4074  */
4075 static int
4076 devid_is_unique(ddi_devid_t did)
4077 {
4078 	struct	devid_list	*curdlp;
4079 	int	unique = 1;	/* Default to true */
4080 
4081 	/*
4082 	 * If first call.
4083 	 */
4084 	if ((curdlp = dlp->next) == NULL) {
4085 		return (1);
4086 	}
4087 
4088 	while (curdlp) {
4089 		if (ddi_devid_compare(curdlp->devid, did) == 0) {
4090 			unique = 0;
4091 			break;
4092 		}
4093 		curdlp = curdlp->next;
4094 	}
4095 	return (unique);
4096 }
4097 
4098 
4099 /*
4100  * Called after the unit's snarf to cleanup the device id name space
4101  */
4102 void
4103 md_devid_cleanup(set_t setno, uint_t all)
4104 {
4105 	struct nm_next_hdr	*nh, *did_nh, *this_nh, *did_shr_nh;
4106 	struct did_min_name	*did_n;
4107 	size_t			offset, n_offset;
4108 	struct devid_min_rec	*record;
4109 	mdkey_t			did_key;
4110 	size_t			n_size;
4111 	int			doit;
4112 
4113 	/*
4114 	 * If it is an empty name space
4115 	 */
4116 	if (((nh = get_first_record(setno, 0, NM_NOTSHARED)) == NULL) ||
4117 		((did_nh = get_first_record(setno, 1, NM_DEVID | NM_NOTSHARED))
4118 			== NULL) ||
4119 		((did_shr_nh = get_first_record(setno, 1, NM_DEVID |
4120 			NM_SHARED)) == NULL)) {
4121 		return;
4122 	}
4123 
4124 	/*
4125 	 * Or the name space is empty
4126 	 */
4127 	this_nh = did_nh->nmn_nextp;
4128 	record = this_nh->nmn_record;
4129 
4130 	if (((struct nm_rec_hdr *)record)->r_used_size ==
4131 		sizeof (struct nm_rec_hdr)) {
4132 		return;
4133 	}
4134 
4135 	/*
4136 	 * Not empty
4137 	 */
4138 	n_offset = offset = (sizeof (struct devid_min_rec) -
4139 		sizeof (struct did_min_name));
4140 	did_n = &(record->minor_name[0]);
4141 
4142 	/*CONSTCOND*/
4143 	while (1) {
4144 		did_key = did_n->min_devid_key;
4145 		n_size = DID_NAMSIZ((struct did_min_name *)did_n);
4146 
4147 		/*
4148 		 * It is not in the primary, remove it from the devid nmspace
4149 		 */
4150 		doit = (all ? 1 :
4151 			(lookup_entry(nh, setno, MD_SIDEWILD, did_n->min_key,
4152 				NODEV64, 0L) == NULL));
4153 		if (doit) {
4154 			(void) remove_entry(did_nh, did_n->min_side,
4155 					did_n->min_key, NM_DEVID);
4156 			(void) remove_shared_entry(did_shr_nh, did_key,
4157 					(char *)0, NM_DEVID);
4158 			/*
4159 			 * We delete something so reset scan
4160 			 */
4161 			offset = n_offset;
4162 			did_n = &(record->minor_name[0]);
4163 			if (did_n->min_key != NULL) {
4164 				continue;
4165 			} else {
4166 				return;
4167 			}
4168 		}
4169 
4170 		did_n = (struct did_min_name *)get_next_entry(this_nh,
4171 			(caddr_t)did_n, n_size, &offset);
4172 
4173 		/*
4174 		 * Next record?
4175 		 */
4176 		if (did_n == NULL) {
4177 			if (offset)
4178 				return;
4179 			/*
4180 			 * Goto next record
4181 			 */
4182 			offset = n_offset;
4183 			this_nh = this_nh->nmn_nextp;
4184 			record = this_nh->nmn_record;
4185 			did_n = &(record->minor_name[0]);
4186 		}
4187 	}
4188 	/*NOTREACHED*/
4189 }
4190 
4191 
4192 /*
4193  * Resolve md_dev64_t by device id when current configure changes.  This
4194  * can happen before the system reboot or between snarf
4195  * and the first use of metadevice.  The configure change can
4196  * mean poweroff before boot and poweron after boot or recable
4197  * disks between snarf and the first open of metadevice.
4198  */
4199 md_dev64_t
4200 md_resolve_bydevid(minor_t mnum, md_dev64_t device, mdkey_t key)
4201 {
4202 
4203 	struct nm_name		*n;
4204 	struct nm_next_hdr	*nh, *did_nh;
4205 	struct did_min_name	*did_n;
4206 	ddi_devid_t		devid;
4207 	dev_t			*devs; /* ddi returns dev_t not md_dev64_t */
4208 	int			ndevs,
4209 				cnt;
4210 	set_t			setno;
4211 	int			update = 0;
4212 	md_dev64_t		targ_dev;
4213 
4214 	/* assign here so that lint does not complain */
4215 	targ_dev = NODEV64;
4216 
4217 	if (device != NODEV64 && (md_getmajor(device) == md_major))
4218 		return (device);
4219 
4220 	setno = MD_MIN2SET(mnum);
4221 
4222 	if (((nh = get_first_record(setno, 0, NM_NOTSHARED)) == NULL) ||
4223 		((n = (struct nm_name *)lookup_entry(nh, setno, MD_SIDEWILD,
4224 			key, NODEV64, 0L)) == NULL)) {
4225 		return (NODEV64);
4226 	}
4227 
4228 	/*
4229 	 * Something can be resolved by device id
4230 	 * Resolve by the device id and if it can't be resolved
4231 	 * then return whatever passed in
4232 	 */
4233 	if (((did_nh = get_first_record(setno, 0, NM_DEVID | NM_NOTSHARED))
4234 		!= NULL) && ((did_n = (struct did_min_name *)lookup_entry
4235 		(did_nh, setno, MD_SIDEWILD, key, NODEV64, NM_DEVID))
4236 		!= NULL)) {
4237 		/*
4238 		 * Get the current devt and update mddb devt if necessary
4239 		 */
4240 		devid =	(ddi_devid_t)getshared_name(setno,
4241 			did_n->min_devid_key, NM_DEVID);
4242 
4243 		if (devid && (ddi_lyr_devid_to_devlist(devid, did_n->min_name,
4244 			&ndevs, &devs) == DDI_SUCCESS)) {
4245 
4246 			/*
4247 			 * This device has been powered off
4248 			 */
4249 			if (device == NODEV64) {
4250 				device = md_expldev(devs[0]);
4251 				update = 1;
4252 			} else {
4253 				for (cnt = 0; cnt < ndevs; cnt++) {
4254 					if (device == md_expldev(devs[cnt]))
4255 						break;
4256 				}
4257 				if (cnt == ndevs) {
4258 					device = md_expldev(devs[0]);
4259 					update = 1;
4260 				}
4261 			}
4262 
4263 			/*
4264 			 * Have devt so update name space also
4265 			 */
4266 			targ_dev = md_xlate_mini_2_targ(device);
4267 			if (targ_dev == NODEV64)
4268 				return (NODEV64);
4269 
4270 			if (update &&
4271 				!(md_get_setstatus(setno) & MD_SET_STALE)) {
4272 				n->n_minor = md_getminor(targ_dev);
4273 				n->n_drv_key = setshared_name(setno,
4274 					md_targ_major_to_name(
4275 						md_getmajor(targ_dev)),
4276 						MD_KEYWILD, 0L);
4277 				(void) update_entry(nh,
4278 					MD_SIDEWILD, n->n_key, 0L);
4279 			}
4280 			/*
4281 			 * Free memory
4282 			 */
4283 			(void) ddi_lyr_free_devlist(devs, ndevs);
4284 		} else {
4285 			/*
4286 			 * if input devid is null or ddi_devid_lyr_devlist
4287 			 * does not return success then return NODEV64
4288 			 */
4289 			device = NODEV64;
4290 		}
4291 	}
4292 	return (device);
4293 }
4294