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.
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.
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]
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <sys/types.h>
30 #include <sys/param.h>
31 #include <sys/mdesc.h>
32 #include <sys/mdesc_impl.h>
35 md_init_intern(uint64_t *ptr
, void *(*allocp
)(size_t),
36 void (*freep
)(void *, size_t))
43 mde_str_cookie_t root_name
;
46 * Very basic checkup for alignment to avoid
49 if ((((uintptr_t)ptr
) & 7) != 0)
52 mdp
= (md_impl_t
*)allocp(sizeof (md_impl_t
));
60 mdp
->caddr
= (char *)ptr
;
63 * setup internal structures
66 mdp
->headerp
= (md_header_t
*)mdp
->caddr
;
68 if (mdtoh32(mdp
->headerp
->transport_version
) != MD_TRANSPORT_VERSION
) {
72 mdp
->node_blk_size
= mdtoh32(mdp
->headerp
->node_blk_sz
);
73 mdp
->name_blk_size
= mdtoh32(mdp
->headerp
->name_blk_sz
);
74 mdp
->data_blk_size
= mdtoh32(mdp
->headerp
->data_blk_sz
);
76 mdp
->size
= MD_HEADER_SIZE
+ mdp
->node_blk_size
+
77 mdp
->name_blk_size
+ mdp
->data_blk_size
;
79 mdp
->mdep
= (md_element_t
*)(mdp
->caddr
+ MD_HEADER_SIZE
);
80 mdp
->namep
= (char *)(mdp
->caddr
+ MD_HEADER_SIZE
+ mdp
->node_blk_size
);
81 mdp
->datap
= (uint8_t *)(mdp
->caddr
+ MD_HEADER_SIZE
+
82 mdp
->name_blk_size
+ mdp
->node_blk_size
);
84 mdp
->root_node
= MDE_INVAL_ELEM_COOKIE
;
88 * Should do a lot more sanity checking here.
92 * Should initialize a name hash here if we intend to use one
96 * Setup to find the root node
98 root_name
= md_find_name((md_t
*)mdp
, "root");
99 if (root_name
== MDE_INVAL_STR_COOKIE
) {
104 * One more property we need is the count of nodes in the
105 * DAG, not just the number of elements.
107 * We try and pickup the root node along the way here.
110 for (done
= 0, idx
= 0, count
= 0; !done
; ) {
113 np
= &(mdp
->mdep
[idx
]);
115 switch (MDE_TAG(np
)) {
121 if (root_name
== MDE_NAME(np
)) {
122 if (mdp
->root_node
!= MDE_INVAL_ELEM_COOKIE
) {
123 /* Gah .. more than one root */
126 mdp
->root_node
= (mde_cookie_t
)idx
;
128 idx
= MDE_PROP_INDEX(np
);
138 * Ensure there is a root node
140 if (mdp
->root_node
== MDE_INVAL_ELEM_COOKIE
) {
145 * Register the counts
148 mdp
->element_count
= idx
+ 1; /* include LIST_END */
149 mdp
->node_count
= count
;
152 * Final sanity check that everything adds up
154 if (mdp
->element_count
!= (mdp
->node_blk_size
/ MD_ELEMENT_SIZE
))
157 mdp
->md_magic
= LIBMD_MAGIC
;
160 * Setup MD generation
162 if (md_get_prop_val((md_t
*)mdp
, mdp
->root_node
,
163 "md-generation#", &gen
) != 0)
164 mdp
->gen
= MDESC_INVAL_GEN
;
168 return ((md_t
*)mdp
);
172 * Clean up here - including a name hash if
177 mdp
->freep(mdp
, sizeof (md_impl_t
));