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