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 * 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