xref: /titanic_41/usr/src/common/mdesc/mdesc_init_intern.c (revision 1ae0874509b6811fdde1dfd46f0d93fd09867a3f)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*1ae08745Sheppo  * Common Development and Distribution License (the "License").
6*1ae08745Sheppo  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21*1ae08745Sheppo 
227c478bd9Sstevel@tonic-gate /*
23*1ae08745Sheppo  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <sys/types.h>
307c478bd9Sstevel@tonic-gate #include <sys/param.h>
317c478bd9Sstevel@tonic-gate #include <sys/mdesc.h>
327c478bd9Sstevel@tonic-gate #include <sys/mdesc_impl.h>
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate md_t *
md_init_intern(uint64_t * ptr,void * (* allocp)(size_t),void (* freep)(void *,size_t))3526cf27f0Sla135387 md_init_intern(uint64_t *ptr,  void *(*allocp)(size_t),
3626cf27f0Sla135387 	    void (*freep)(void *, size_t))
377c478bd9Sstevel@tonic-gate {
387c478bd9Sstevel@tonic-gate 	md_impl_t	*mdp;
397c478bd9Sstevel@tonic-gate 	int		idx;
407c478bd9Sstevel@tonic-gate 	int		count;
417c478bd9Sstevel@tonic-gate 	int		done;
42*1ae08745Sheppo 	uint64_t	gen;
437c478bd9Sstevel@tonic-gate 	mde_str_cookie_t root_name;
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate 	/*
467c478bd9Sstevel@tonic-gate 	 * Very basic checkup for alignment to avoid
477c478bd9Sstevel@tonic-gate 	 * bus error issues.
487c478bd9Sstevel@tonic-gate 	 */
490bd5614cSiskreen 	if ((((uintptr_t)ptr) & 7) != 0)
507c478bd9Sstevel@tonic-gate 		return (NULL);
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate 	mdp = (md_impl_t *)allocp(sizeof (md_impl_t));
53*1ae08745Sheppo 
547c478bd9Sstevel@tonic-gate 	if (mdp == NULL)
557c478bd9Sstevel@tonic-gate 		return (NULL);
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate 	mdp->allocp = allocp;
587c478bd9Sstevel@tonic-gate 	mdp->freep = freep;
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate 	mdp->caddr = (char *)ptr;
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	/*
637c478bd9Sstevel@tonic-gate 	 * setup internal structures
647c478bd9Sstevel@tonic-gate 	 */
65*1ae08745Sheppo 
667c478bd9Sstevel@tonic-gate 	mdp->headerp = (md_header_t *)mdp->caddr;
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate 	if (mdtoh32(mdp->headerp->transport_version) != MD_TRANSPORT_VERSION) {
697c478bd9Sstevel@tonic-gate 		goto cleanup_nohash;
707c478bd9Sstevel@tonic-gate 	}
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 	mdp->node_blk_size = mdtoh32(mdp->headerp->node_blk_sz);
737c478bd9Sstevel@tonic-gate 	mdp->name_blk_size = mdtoh32(mdp->headerp->name_blk_sz);
747c478bd9Sstevel@tonic-gate 	mdp->data_blk_size = mdtoh32(mdp->headerp->data_blk_sz);
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate 	mdp->size = MD_HEADER_SIZE + mdp->node_blk_size +
777c478bd9Sstevel@tonic-gate 	    mdp->name_blk_size + mdp->data_blk_size;
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate 	mdp->mdep = (md_element_t *)(mdp->caddr + MD_HEADER_SIZE);
807c478bd9Sstevel@tonic-gate 	mdp->namep = (char *)(mdp->caddr + MD_HEADER_SIZE + mdp->node_blk_size);
81*1ae08745Sheppo 	mdp->datap = (uint8_t *)(mdp->caddr + MD_HEADER_SIZE +
82*1ae08745Sheppo 	    mdp->name_blk_size + mdp->node_blk_size);
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate 	mdp->root_node = MDE_INVAL_ELEM_COOKIE;
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	/*
887c478bd9Sstevel@tonic-gate 	 * Should do a lot more sanity checking here.
897c478bd9Sstevel@tonic-gate 	 */
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 	/*
927c478bd9Sstevel@tonic-gate 	 * Should initialize a name hash here if we intend to use one
937c478bd9Sstevel@tonic-gate 	 */
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 	/*
967c478bd9Sstevel@tonic-gate 	 * Setup to find the root node
977c478bd9Sstevel@tonic-gate 	 */
987c478bd9Sstevel@tonic-gate 	root_name = md_find_name((md_t *)mdp, "root");
997c478bd9Sstevel@tonic-gate 	if (root_name == MDE_INVAL_STR_COOKIE) {
1007c478bd9Sstevel@tonic-gate 		goto cleanup;
1017c478bd9Sstevel@tonic-gate 	}
1027c478bd9Sstevel@tonic-gate 
1037c478bd9Sstevel@tonic-gate 	/*
1047c478bd9Sstevel@tonic-gate 	 * One more property we need is the count of nodes in the
1057c478bd9Sstevel@tonic-gate 	 * DAG, not just the number of elements.
1067c478bd9Sstevel@tonic-gate 	 *
1077c478bd9Sstevel@tonic-gate 	 * We try and pickup the root node along the way here.
1087c478bd9Sstevel@tonic-gate 	 */
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	for (done = 0, idx = 0, count = 0; !done; ) {
1117c478bd9Sstevel@tonic-gate 		md_element_t *np;
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate 		np = &(mdp->mdep[idx]);
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 		switch (MDE_TAG(np)) {
1167c478bd9Sstevel@tonic-gate 		case MDET_LIST_END:
1177c478bd9Sstevel@tonic-gate 			done = 1;
1187c478bd9Sstevel@tonic-gate 			break;
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 		case MDET_NODE:
1217c478bd9Sstevel@tonic-gate 			if (root_name == MDE_NAME(np)) {
1227c478bd9Sstevel@tonic-gate 				if (mdp->root_node != MDE_INVAL_ELEM_COOKIE) {
1237c478bd9Sstevel@tonic-gate 					/* Gah .. more than one root */
1247c478bd9Sstevel@tonic-gate 					goto cleanup;
1257c478bd9Sstevel@tonic-gate 				}
1267c478bd9Sstevel@tonic-gate 				mdp->root_node = (mde_cookie_t)idx;
1277c478bd9Sstevel@tonic-gate 			}
1287c478bd9Sstevel@tonic-gate 			idx = MDE_PROP_INDEX(np);
1297c478bd9Sstevel@tonic-gate 			count++;
1307c478bd9Sstevel@tonic-gate 			break;
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 		default:
1337c478bd9Sstevel@tonic-gate 			idx++;	/* ignore */
1347c478bd9Sstevel@tonic-gate 		}
1357c478bd9Sstevel@tonic-gate 	}
1367c478bd9Sstevel@tonic-gate 
1377c478bd9Sstevel@tonic-gate 	/*
1387c478bd9Sstevel@tonic-gate 	 * Ensure there is a root node
1397c478bd9Sstevel@tonic-gate 	 */
1407c478bd9Sstevel@tonic-gate 	if (mdp->root_node == MDE_INVAL_ELEM_COOKIE) {
1417c478bd9Sstevel@tonic-gate 		goto cleanup;
1427c478bd9Sstevel@tonic-gate 	}
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 	/*
1457c478bd9Sstevel@tonic-gate 	 * Register the counts
1467c478bd9Sstevel@tonic-gate 	 */
1477c478bd9Sstevel@tonic-gate 
1487c478bd9Sstevel@tonic-gate 	mdp->element_count = idx + 1;	/* include LIST_END */
1497c478bd9Sstevel@tonic-gate 	mdp->node_count = count;
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate 	/*
1527c478bd9Sstevel@tonic-gate 	 * Final sanity check that everything adds up
1537c478bd9Sstevel@tonic-gate 	 */
1547c478bd9Sstevel@tonic-gate 	if (mdp->element_count != (mdp->node_blk_size / MD_ELEMENT_SIZE))
1557c478bd9Sstevel@tonic-gate 		goto cleanup;
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate 	mdp->md_magic = LIBMD_MAGIC;
1587c478bd9Sstevel@tonic-gate 
159*1ae08745Sheppo 	/*
160*1ae08745Sheppo 	 * Setup MD generation
161*1ae08745Sheppo 	 */
162*1ae08745Sheppo 	if (md_get_prop_val((md_t *)mdp, mdp->root_node,
163*1ae08745Sheppo 	    "md-generation#", &gen) != 0)
164*1ae08745Sheppo 		mdp->gen = MDESC_INVAL_GEN;
165*1ae08745Sheppo 	else
166*1ae08745Sheppo 		mdp->gen = gen;
167*1ae08745Sheppo 
1687c478bd9Sstevel@tonic-gate 	return ((md_t *)mdp);
1697c478bd9Sstevel@tonic-gate 
170*1ae08745Sheppo cleanup:
1717c478bd9Sstevel@tonic-gate 	/*
1727c478bd9Sstevel@tonic-gate 	 * Clean up here - including a name hash if
1737c478bd9Sstevel@tonic-gate 	 * we build one.
1747c478bd9Sstevel@tonic-gate 	 */
175*1ae08745Sheppo 
176*1ae08745Sheppo cleanup_nohash:
17726cf27f0Sla135387 	mdp->freep(mdp, sizeof (md_impl_t));
1787c478bd9Sstevel@tonic-gate 	return (NULL);
1797c478bd9Sstevel@tonic-gate }
180