xref: /onnv-gate/usr/src/common/mdesc/mdesc_init_intern.c (revision 221:d5626b06daab)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate #include <sys/types.h>
300Sstevel@tonic-gate #include <sys/param.h>
310Sstevel@tonic-gate #include <sys/mdesc.h>
320Sstevel@tonic-gate #include <sys/mdesc_impl.h>
330Sstevel@tonic-gate 
340Sstevel@tonic-gate md_t *
35*221Sla135387 md_init_intern(uint64_t *ptr, void *(*allocp)(size_t),
36*221Sla135387 			void (*freep)(void *, size_t))
370Sstevel@tonic-gate {
380Sstevel@tonic-gate 	md_impl_t	*mdp;
390Sstevel@tonic-gate 	int		idx;
400Sstevel@tonic-gate 	int		count;
410Sstevel@tonic-gate 	int		done;
420Sstevel@tonic-gate 	mde_str_cookie_t root_name;
430Sstevel@tonic-gate 
440Sstevel@tonic-gate 	/*
450Sstevel@tonic-gate 	 * Very basic checkup for alignment to avoid
460Sstevel@tonic-gate 	 * bus error issues.
470Sstevel@tonic-gate 	 */
480Sstevel@tonic-gate 	if ((((uint64_t)ptr)&7) != 0)
490Sstevel@tonic-gate 		return (NULL);
500Sstevel@tonic-gate 
510Sstevel@tonic-gate 	mdp = (md_impl_t *)allocp(sizeof (md_impl_t));
520Sstevel@tonic-gate 	if (mdp == NULL)
530Sstevel@tonic-gate 		return (NULL);
540Sstevel@tonic-gate 
550Sstevel@tonic-gate 	mdp->allocp = allocp;
560Sstevel@tonic-gate 	mdp->freep = freep;
570Sstevel@tonic-gate 
580Sstevel@tonic-gate 	mdp->caddr = (char *)ptr;
590Sstevel@tonic-gate 
600Sstevel@tonic-gate 	/*
610Sstevel@tonic-gate 	 * setup internal structures
620Sstevel@tonic-gate 	 */
630Sstevel@tonic-gate 	mdp->headerp = (md_header_t *)mdp->caddr;
640Sstevel@tonic-gate 
650Sstevel@tonic-gate 	if (mdtoh32(mdp->headerp->transport_version) != MD_TRANSPORT_VERSION) {
660Sstevel@tonic-gate 		goto cleanup_nohash;
670Sstevel@tonic-gate 	}
680Sstevel@tonic-gate 
690Sstevel@tonic-gate 	mdp->node_blk_size = mdtoh32(mdp->headerp->node_blk_sz);
700Sstevel@tonic-gate 	mdp->name_blk_size = mdtoh32(mdp->headerp->name_blk_sz);
710Sstevel@tonic-gate 	mdp->data_blk_size = mdtoh32(mdp->headerp->data_blk_sz);
720Sstevel@tonic-gate 
730Sstevel@tonic-gate 	mdp->size = MD_HEADER_SIZE+mdp->node_blk_size+
740Sstevel@tonic-gate 	    mdp->name_blk_size+mdp->data_blk_size;
750Sstevel@tonic-gate 
760Sstevel@tonic-gate 	mdp->mdep = (md_element_t *)(mdp->caddr+MD_HEADER_SIZE);
770Sstevel@tonic-gate 	mdp->namep = (char *)(mdp->caddr+MD_HEADER_SIZE+mdp->node_blk_size);
780Sstevel@tonic-gate 	mdp->datap = (uint8_t *)(mdp->caddr+MD_HEADER_SIZE+mdp->name_blk_size+
790Sstevel@tonic-gate 	    mdp->node_blk_size);
800Sstevel@tonic-gate 
810Sstevel@tonic-gate 	mdp->root_node = MDE_INVAL_ELEM_COOKIE;
820Sstevel@tonic-gate 
830Sstevel@tonic-gate 
840Sstevel@tonic-gate 	/*
850Sstevel@tonic-gate 	 * Should do a lot more sanity checking here.
860Sstevel@tonic-gate 	 */
870Sstevel@tonic-gate 
880Sstevel@tonic-gate 	/*
890Sstevel@tonic-gate 	 * Should initialize a name hash here if we intend to use one
900Sstevel@tonic-gate 	 */
910Sstevel@tonic-gate 
920Sstevel@tonic-gate 	/*
930Sstevel@tonic-gate 	 * Setup to find the root node
940Sstevel@tonic-gate 	 */
950Sstevel@tonic-gate 	root_name = md_find_name((md_t *)mdp, "root");
960Sstevel@tonic-gate 	if (root_name == MDE_INVAL_STR_COOKIE) {
970Sstevel@tonic-gate 		goto cleanup;
980Sstevel@tonic-gate 	}
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate 	/*
1010Sstevel@tonic-gate 	 * One more property we need is the count of nodes in the
1020Sstevel@tonic-gate 	 * DAG, not just the number of elements.
1030Sstevel@tonic-gate 	 *
1040Sstevel@tonic-gate 	 * We try and pickup the root node along the way here.
1050Sstevel@tonic-gate 	 */
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate 	for (done = 0, idx = 0, count = 0; !done; ) {
1080Sstevel@tonic-gate 		md_element_t *np;
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate 		np = &(mdp->mdep[idx]);
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate 		switch (MDE_TAG(np)) {
1130Sstevel@tonic-gate 		case MDET_LIST_END:
1140Sstevel@tonic-gate 			done = 1;
1150Sstevel@tonic-gate 			break;
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate 		case MDET_NODE:
1180Sstevel@tonic-gate 			if (root_name == MDE_NAME(np)) {
1190Sstevel@tonic-gate 				if (mdp->root_node != MDE_INVAL_ELEM_COOKIE) {
1200Sstevel@tonic-gate 					/* Gah .. more than one root */
1210Sstevel@tonic-gate 					goto cleanup;
1220Sstevel@tonic-gate 				}
1230Sstevel@tonic-gate 				mdp->root_node = (mde_cookie_t)idx;
1240Sstevel@tonic-gate 			}
1250Sstevel@tonic-gate 			idx = MDE_PROP_INDEX(np);
1260Sstevel@tonic-gate 			count ++;
1270Sstevel@tonic-gate 			break;
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 		default:
1300Sstevel@tonic-gate 			idx++;	/* ignore */
1310Sstevel@tonic-gate 		}
1320Sstevel@tonic-gate 	}
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate 	/*
1350Sstevel@tonic-gate 	 * Ensure there is a root node
1360Sstevel@tonic-gate 	 */
1370Sstevel@tonic-gate 	if (mdp->root_node == MDE_INVAL_ELEM_COOKIE) {
1380Sstevel@tonic-gate 		goto cleanup;
1390Sstevel@tonic-gate 	}
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate 	/*
1420Sstevel@tonic-gate 	 * Register the counts
1430Sstevel@tonic-gate 	 */
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate 	mdp->element_count = idx+1;	/* include LIST_END */
1460Sstevel@tonic-gate 	mdp->node_count = count;
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 	/*
1490Sstevel@tonic-gate 	 * Final sanity check that everything adds up
1500Sstevel@tonic-gate 	 */
1510Sstevel@tonic-gate 	if (mdp->element_count != (mdp->node_blk_size/MD_ELEMENT_SIZE))
1520Sstevel@tonic-gate 		goto cleanup;
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	mdp->md_magic = LIBMD_MAGIC;
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 	return ((md_t *)mdp);
1570Sstevel@tonic-gate 
1580Sstevel@tonic-gate cleanup:;
1590Sstevel@tonic-gate 	/*
1600Sstevel@tonic-gate 	 * Clean up here - including a name hash if
1610Sstevel@tonic-gate 	 * we build one.
1620Sstevel@tonic-gate 	 */
1630Sstevel@tonic-gate cleanup_nohash:;
164*221Sla135387 	mdp->freep(mdp, sizeof (md_impl_t));
1650Sstevel@tonic-gate 	return (NULL);
1660Sstevel@tonic-gate }
167