diff options
author | heppo <none@none> | 2006-05-16 16:05:21 -0700 |
---|---|---|
committer | heppo <none@none> | 2006-05-16 16:05:21 -0700 |
commit | 1ae0874509b6811fdde1dfd46f0d93fd09867a3f (patch) | |
tree | 77d0f1125a782e0ad2f4975497b8c299b4849f79 /usr/src/common/mdesc | |
parent | 77ed85091c75f96e0c776b6b222bc51695e3ee0c (diff) | |
download | illumos-joyent-1ae0874509b6811fdde1dfd46f0d93fd09867a3f.tar.gz |
FWARC 2005/633 Project Q Logial Domaining Umbrella
FWARC 2005/739 sun4v channels
FWARC 2006/055 Domain Services
FWARC 2006/072 sun4v virtual devices machine description data
FWARC 2006/074 sun4v interrupt cookies
FWARC 2006/075 Channel devices, Virtual Disk client and server bindings
FWARC 2006/076 Virtual Network Client and switch Bindings
FWARC 2006/081 Virtual Logical Domain Channel (vldc) Bindings
FWARC 2006/086 LDOM variables
FWARC 2006/105 LDOM support for NCP
FWARC 2006/110 Domain Services MD node and other misc properties
FWARC 2006/117 Virtual Console Concentrator Bindings
FWARC 2006/135 sun4v channel console packets
FWARC 2006/140 sun4v channels transport protocol
FWARC 2006/141 FMA Domain Services
FWARC 2006/174 NCS HV Update
FWARC 2006/184 sun4v channels shared memory
FWARC 2006/195 Virtual IO Communication Protocol
PSARC 2006/152 Logical Domain Channels Transport API
6272074 Need interface to determine execution unit sharing.
6354556 Add machine description kernel framework support
6391870 LDoms v1.0 Solaris Changes
Diffstat (limited to 'usr/src/common/mdesc')
-rw-r--r-- | usr/src/common/mdesc/mdesc_diff.c | 602 | ||||
-rw-r--r-- | usr/src/common/mdesc/mdesc_fini.c | 12 | ||||
-rw-r--r-- | usr/src/common/mdesc/mdesc_getbinsize.c | 45 | ||||
-rw-r--r-- | usr/src/common/mdesc/mdesc_getgen.c | 45 | ||||
-rw-r--r-- | usr/src/common/mdesc/mdesc_init_intern.c | 49 | ||||
-rw-r--r-- | usr/src/common/mdesc/mdesc_rootnode.c | 10 | ||||
-rw-r--r-- | usr/src/common/mdesc/mdesc_scandag.c | 11 |
7 files changed, 742 insertions, 32 deletions
diff --git a/usr/src/common/mdesc/mdesc_diff.c b/usr/src/common/mdesc/mdesc_diff.c new file mode 100644 index 0000000000..28f55abc92 --- /dev/null +++ b/usr/src/common/mdesc/mdesc_diff.c @@ -0,0 +1,602 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/types.h> +#ifdef _KERNEL +#include <sys/systm.h> +#else /* _KERNEL */ +#include <string.h> +#include <strings.h> +#endif /* _KERNEL */ +#include <sys/note.h> +#include <sys/mdesc.h> +#include <sys/mdesc_impl.h> + +#define MDD_FREE_CHECK(mdp, ptr, sz) \ + do { \ + if (ptr) mdp->freep(ptr, sz); \ + _NOTE(CONSTCOND) } while (0) + +#define MD_DIFF_MAGIC 0x4D445F4449464621ull /* 'MD_DIFF!' */ +#define MD_DIFF_NOMATCH (-1) +#define MD_DIFF_MATCH (1) + +typedef struct { + mde_cookie_t *mdep; + uint_t nelem; +} md_diff_t; + +typedef struct { + uint64_t mdd_magic; + md_diff_t added; + md_diff_t removed; + md_diff_t match1; + md_diff_t match2; + void *(*allocp)(size_t); + void (*freep)(void *, size_t); +} md_diff_impl_t; + +/* + * Internal utility functions + */ +static int mdd_scan_for_nodes(md_t *mdp, mde_cookie_t start, + char *compnodep, int *countp, mde_cookie_t **nodespp); + +static boolean_t mdd_any_dup_nodes(md_impl_t *mdp, md_prop_match_t *pmp, + int count, mde_cookie_t *nodesp); + +static int mdd_node_list_match(md_impl_t *md1, md_impl_t *md2, + md_element_t *match_nodep, mde_cookie_t *match_listp, + uint8_t *match_seenp, int start, int end, md_prop_match_t *match_elemsp); + +static int mdd_node_compare(md_impl_t *mdap, md_impl_t *mdbp, + md_element_t *nodeap, md_element_t *nodebp, md_prop_match_t *match_elemsp); + +/* + * Given two DAGs and information about how to uniquely identify + * the nodes of interest, determine which nodes have been added + * to the second MD, removed from the first MD, or exist in both + * MDs. This information is recorded and can be accessed using the + * opaque cookie returned to the caller. + */ +md_diff_cookie_t +md_diff_init(md_t *md1p, mde_cookie_t start1, md_t *md2p, mde_cookie_t start2, + char *compnodep, md_prop_match_t *match_fieldsp) +{ + int idx; + md_impl_t *md1 = (md_impl_t *)md1p; + md_impl_t *md2 = (md_impl_t *)md2p; + mde_cookie_t *md1nodesp = NULL; + mde_cookie_t *md2nodesp = NULL; + int md1count = 0; + int md2count = 0; + uint8_t *seenp = NULL; + + /* variables used to gather results */ + md_diff_impl_t *diff_res; + mde_cookie_t *mde_add_scr; + mde_cookie_t *mde_rem_scr; + mde_cookie_t *mde_match1_scr; + mde_cookie_t *mde_match2_scr; + int nadd = 0; + int nrem = 0; + int nmatch = 0; + + /* sanity check params */ + if ((md1p == NULL) || (md2p == NULL)) + return (MD_INVAL_DIFF_COOKIE); + + if ((start1 == MDE_INVAL_ELEM_COOKIE) || + (start2 == MDE_INVAL_ELEM_COOKIE)) + return (MD_INVAL_DIFF_COOKIE); + + if ((compnodep == NULL) || (match_fieldsp == NULL)) + return (MD_INVAL_DIFF_COOKIE); + + /* + * Prepare an array of the matching nodes from the first MD. + */ + if (mdd_scan_for_nodes(md1p, + start1, compnodep, &md1count, &md1nodesp) == -1) + return (MD_INVAL_DIFF_COOKIE); + + /* sanity check that all nodes are unique */ + if (md1nodesp && + mdd_any_dup_nodes(md1, match_fieldsp, md1count, md1nodesp)) { + MDD_FREE_CHECK(md1, md1nodesp, sizeof (mde_cookie_t) * + md1count); + return (MD_INVAL_DIFF_COOKIE); + } + + + /* + * Prepare an array of the matching nodes from the second MD. + */ + if (mdd_scan_for_nodes(md2p, + start2, compnodep, &md2count, &md2nodesp) == -1) + return (MD_INVAL_DIFF_COOKIE); + + /* sanity check that all nodes are unique */ + if (md2nodesp && + mdd_any_dup_nodes(md2, match_fieldsp, md2count, md2nodesp)) { + MDD_FREE_CHECK(md1, md1nodesp, sizeof (mde_cookie_t) * + md1count); + MDD_FREE_CHECK(md2, md2nodesp, sizeof (mde_cookie_t) * + md2count); + return (MD_INVAL_DIFF_COOKIE); + } + + /* setup our result structure */ + diff_res = md1->allocp(sizeof (md_diff_impl_t)); + bzero(diff_res, sizeof (md_diff_impl_t)); + diff_res->allocp = md1->allocp; + diff_res->freep = md1->freep; + diff_res->mdd_magic = MD_DIFF_MAGIC; + + /* + * Special cases for empty lists + */ + if ((md1count == 0) && (md2count != 0)) { + /* all the nodes found were added */ + diff_res->added.mdep = md2nodesp; + diff_res->added.nelem = md2count; + return ((mde_cookie_t)diff_res); + } + + if ((md1count != 0) && (md2count == 0)) { + /* all the nodes found were removed */ + diff_res->removed.mdep = md1nodesp; + diff_res->removed.nelem = md1count; + return ((mde_cookie_t)diff_res); + } + + if ((md1count == 0) && (md2count == 0)) + /* no nodes found */ + return ((mde_cookie_t)diff_res); + + /* + * Both lists have some elements. Allocate some scratch + * buffers to sort them into our three categories, added, + * removed, and matched pairs. + */ + mde_add_scr = diff_res->allocp(sizeof (mde_cookie_t) * md2count); + mde_rem_scr = diff_res->allocp(sizeof (mde_cookie_t) * md1count); + mde_match1_scr = diff_res->allocp(sizeof (mde_cookie_t) * md1count); + mde_match2_scr = diff_res->allocp(sizeof (mde_cookie_t) * md2count); + + /* array of seen flags only needed for md2 */ + seenp = (uint8_t *)diff_res->allocp(sizeof (uint8_t) * md2count); + bzero(seenp, sizeof (uint8_t) * md2count); + + /* + * Make a pass through the md1 node array. Make note of + * any nodes not in the md2 array, indicating that they + * have been removed. Also keep track of the nodes that + * are present in both arrays for the matched pair results. + */ + for (idx = 0; idx < md1count; idx++) { + + md_element_t *elem = &(md1->mdep[md1nodesp[idx]]); + + int match = mdd_node_list_match(md1, md2, elem, md2nodesp, + seenp, 0, md2count - 1, match_fieldsp); + + if (match == MD_DIFF_NOMATCH) + /* record deleted node */ + mde_rem_scr[nrem++] = md1nodesp[idx]; + else { + /* record matched node pair */ + mde_match1_scr[nmatch] = md1nodesp[idx]; + mde_match2_scr[nmatch] = md2nodesp[match]; + nmatch++; + + /* mark that this match has been recorded */ + seenp[match] = 1; + } + } + + /* + * Make a pass through the md2 array. Any nodes that have + * not been marked as seen have been added. + */ + for (idx = 0; idx < md2count; idx++) { + if (!seenp[idx]) + /* record added node */ + mde_add_scr[nadd++] = md2nodesp[idx]; + } + + /* fill in the added node list */ + if (nadd) { + int addsz = sizeof (mde_cookie_t) * nadd; + diff_res->added.mdep = (mde_cookie_t *)diff_res->allocp(addsz); + + bcopy(mde_add_scr, diff_res->added.mdep, addsz); + + diff_res->added.nelem = nadd; + } + + /* fill in the removed node list */ + if (nrem) { + int remsz = sizeof (mde_cookie_t) * nrem; + diff_res->removed.mdep = + (mde_cookie_t *)diff_res->allocp(remsz); + + bcopy(mde_rem_scr, diff_res->removed.mdep, remsz); + diff_res->removed.nelem = nrem; + } + + /* fill in the matching node lists */ + if (nmatch) { + int matchsz = sizeof (mde_cookie_t) * nmatch; + diff_res->match1.mdep = + (mde_cookie_t *)diff_res->allocp(matchsz); + diff_res->match2.mdep = + (mde_cookie_t *)diff_res->allocp(matchsz); + + bcopy(mde_match1_scr, diff_res->match1.mdep, matchsz); + bcopy(mde_match2_scr, diff_res->match2.mdep, matchsz); + diff_res->match1.nelem = nmatch; + diff_res->match2.nelem = nmatch; + } + + /* clean up */ + md1->freep(md1nodesp, sizeof (mde_cookie_t) * md1count); + md2->freep(md2nodesp, sizeof (mde_cookie_t) * md2count); + + diff_res->freep(mde_add_scr, sizeof (mde_cookie_t) * md2count); + diff_res->freep(mde_rem_scr, sizeof (mde_cookie_t) * md1count); + diff_res->freep(mde_match1_scr, sizeof (mde_cookie_t) * md1count); + diff_res->freep(mde_match2_scr, sizeof (mde_cookie_t) * md2count); + + diff_res->freep(seenp, sizeof (uint8_t) * md2count); + + return ((md_diff_cookie_t)diff_res); +} + +/* + * Returns an array of the nodes added to the second MD in a + * previous md_diff_init() call. Returns the number of elements + * in the returned array. If the value is zero, the pointer + * passed back will be NULL. + */ +int +md_diff_added(md_diff_cookie_t mdd, mde_cookie_t **mde_addedp) +{ + md_diff_impl_t *mddp = (md_diff_impl_t *)mdd; + + if ((mddp == NULL) || (mddp->mdd_magic != MD_DIFF_MAGIC)) + return (-1); + + *mde_addedp = mddp->added.mdep; + + return (mddp->added.nelem); +} + +/* + * Returns an array of the nodes removed from the first MD in a + * previous md_diff_init() call. Returns the number of elements + * in the returned array. If the value is zero, the pointer + * passed back will be NULL. + */ +int +md_diff_removed(md_diff_cookie_t mdd, mde_cookie_t **mde_removedp) +{ + md_diff_impl_t *mddp = (md_diff_impl_t *)mdd; + + if ((mddp == NULL) || (mddp->mdd_magic != MD_DIFF_MAGIC)) + return (-1); + + *mde_removedp = mddp->removed.mdep; + + return (mddp->removed.nelem); +} + +/* + * Returns a pair of parallel arrays that contain nodes that were + * considered matching based on the match criteria passed in to + * a previous md_diff_init() call. Returns the number of elements + * in the arrays. If the value is zero, both pointers passed back + * will be NULL. + */ +int +md_diff_matched(md_diff_cookie_t mdd, mde_cookie_t **mde_match1p, + mde_cookie_t **mde_match2p) +{ + md_diff_impl_t *mddp = (md_diff_impl_t *)mdd; + + if ((mddp == NULL) || (mddp->mdd_magic != MD_DIFF_MAGIC)) + return (-1); + + *mde_match1p = mddp->match1.mdep; + *mde_match2p = mddp->match2.mdep; + + return (mddp->match1.nelem); +} + +/* + * Deallocate any storage used to store results of a previous + * md_diff_init() call. Returns 0 on success and -1 on failure. + */ +int +md_diff_fini(md_diff_cookie_t mdd) +{ + md_diff_impl_t *mddp = (md_diff_impl_t *)mdd; + + if ((mddp == NULL) || (mddp->mdd_magic != MD_DIFF_MAGIC)) + return (-1); + + mddp->mdd_magic = 0; + + MDD_FREE_CHECK(mddp, mddp->added.mdep, mddp->added.nelem * + sizeof (mde_cookie_t)); + + MDD_FREE_CHECK(mddp, mddp->removed.mdep, mddp->removed.nelem * + sizeof (mde_cookie_t)); + + MDD_FREE_CHECK(mddp, mddp->match1.mdep, mddp->match1.nelem * + sizeof (mde_cookie_t)); + + MDD_FREE_CHECK(mddp, mddp->match2.mdep, mddp->match2.nelem * + sizeof (mde_cookie_t)); + + mddp->freep(mddp, sizeof (md_diff_impl_t)); + + return (0); +} + +/* + * Walk the "fwd" DAG in an MD and return an array of nodes that are + * of the specified type. The start param is used to start the walk + * from an arbitrary location in the DAG. Returns an array of nodes + * as well as a count of the number of nodes in the array. If the + * count is zero, the node pointer will be passed back as NULL. + * + * Returns: 0 success; -1 failure + */ +static int +mdd_scan_for_nodes(md_t *mdp, + mde_cookie_t start, char *compnodep, int *countp, mde_cookie_t **nodespp) +{ + mde_str_cookie_t cname; + mde_str_cookie_t aname; + md_impl_t *mdip = (md_impl_t *)mdp; + + if (mdip == NULL) + return (-1); + + cname = md_find_name(mdp, compnodep); + aname = md_find_name(mdp, "fwd"); + + /* get the number of nodes of interest in the DAG */ + *countp = md_scan_dag(mdp, start, cname, aname, NULL); + if (*countp == 0) { + *nodespp = NULL; + return (0); + } + + /* allocate the storage */ + *nodespp = mdip->allocp(sizeof (mde_cookie_t) * (*countp)); + + /* populate our array with the matching nodes */ + (void) md_scan_dag(mdp, start, cname, aname, *nodespp); + + return (0); +} + +/* + * Walk an array of nodes and check if there are any duplicate + * nodes. A duplicate is determined based on the specified match + * criteria. Returns B_TRUE if there are any duplicates and B_FALSE + * otherwise. + */ +static boolean_t +mdd_any_dup_nodes(md_impl_t *mdp, md_prop_match_t *pmp, int count, + mde_cookie_t *nodesp) +{ + int idx; + int match; + md_element_t *elem; + + ASSERT(count > 0 || nodesp == NULL); + + for (idx = 0; idx < count; idx++) { + elem = &(mdp->mdep[nodesp[idx]]); + + match = mdd_node_list_match(mdp, mdp, elem, nodesp, NULL, + idx + 1, count - 1, pmp); + + if (match != MD_DIFF_NOMATCH) + return (B_TRUE); + } + + return (B_FALSE); +} + +/* + * Given a node and a array of nodes, compare the node to all elements + * in the specified start-end range of the array. If the node matches + * one of the nodes in the array, return the index of that node. Otherwise + * return MD_DIFF_NOMATCH. + * + * The optional seen array parameter can be used to optimize repeated + * calls to this function. If the seen array indicates that an element + * has already been matched, the full comparison is not necessary. + */ +static int +mdd_node_list_match(md_impl_t *md1, md_impl_t *md2, md_element_t *match_nodep, + mde_cookie_t *match_listp, uint8_t *match_seenp, int start, int end, + md_prop_match_t *match_elemsp) +{ + int match; + int idx; + md_element_t *elem; + + for (idx = start; idx <= end; idx++) { + + if ((match_seenp != NULL) && (match_seenp[idx])) + continue; + + elem = &(md2->mdep[match_listp[idx]]); + + match = mdd_node_compare(md1, md2, match_nodep, elem, + match_elemsp); + if (match == MD_DIFF_MATCH) + return (idx); + } + + return (MD_DIFF_NOMATCH); +} + +/* + * Given two nodes and a list of properties, compare the nodes. + * A match is concluded if both nodes have all of the specified + * properties and all the values of those properties are the + * same. Returns MD_DIFF_NOMATCH if the nodes do not match and + * MD_DIFF_MATCH otherwise. + */ +static int +mdd_node_compare(md_impl_t *mdap, md_impl_t *mdbp, md_element_t *nodeap, + md_element_t *nodebp, md_prop_match_t *match_elemsp) +{ + md_element_t *ap; + md_element_t *bp; + boolean_t nodea_interest; + boolean_t nodeb_interest; + int idx; + + /* make sure we are starting at the beginning of the nodes */ + if ((MDE_TAG(nodeap) != MDET_NODE) || (MDE_TAG(nodebp) != MDET_NODE)) + return (MD_DIFF_NOMATCH); + + for (idx = 0; match_elemsp[idx].type != MDET_LIST_END; idx++) { + + int type; + + nodea_interest = B_FALSE; + nodeb_interest = B_FALSE; + + type = match_elemsp[idx].type; + + /* + * Check node A for the property of interest + */ + for (ap = nodeap; MDE_TAG(ap) != MDET_NODE_END; ap++) { + char *elemname; + + if (MDE_TAG(ap) != type) + continue; + + elemname = mdap->namep + MDE_NAME(ap); + + if (strcmp(elemname, match_elemsp[idx].namep) == 0) { + /* found the property of interest */ + nodea_interest = B_TRUE; + break; + } + } + + /* node A is not of interest */ + if (!nodea_interest) + return (MD_DIFF_NOMATCH); + + /* + * Check node B for the property of interest + */ + for (bp = nodebp; MDE_TAG(bp) != MDET_NODE_END; bp++) { + char *elemname; + + if (MDE_TAG(bp) != type) + continue; + + elemname = mdbp->namep + MDE_NAME(bp); + + if (strcmp(elemname, match_elemsp[idx].namep) == 0) { + nodeb_interest = B_TRUE; + break; + } + } + + /* node B is not of interest */ + if (!nodeb_interest) + return (MD_DIFF_NOMATCH); + + /* + * Both nodes have the property of interest. The + * nodes are not a match unless the value of that + * property match + */ + switch (type) { + case MDET_PROP_VAL: + if (MDE_PROP_VALUE(ap) != MDE_PROP_VALUE(bp)) + return (MD_DIFF_NOMATCH); + break; + + case MDET_PROP_STR: { + char *stra = (char *)(mdap->datap + + MDE_PROP_DATA_OFFSET(ap)); + char *strb = (char *)(mdbp->datap + + MDE_PROP_DATA_OFFSET(bp)); + + if (strcmp(stra, strb) != 0) + return (MD_DIFF_NOMATCH); + break; + } + + case MDET_PROP_DAT: { + + caddr_t dataa; + caddr_t datab; + + if (MDE_PROP_DATA_LEN(ap) != MDE_PROP_DATA_LEN(bp)) + return (MD_DIFF_NOMATCH); + + dataa = (caddr_t)(mdap->datap + + MDE_PROP_DATA_OFFSET(ap)); + datab = (caddr_t)(mdbp->datap + + MDE_PROP_DATA_OFFSET(bp)); + + if (memcmp(dataa, datab, MDE_PROP_DATA_LEN(ap)) != 0) + return (MD_DIFF_NOMATCH); + + break; + } + + default: + /* unsupported prop type */ + return (MD_DIFF_NOMATCH); + } + } + + /* + * All the specified properties exist in both + * nodes and have the same value. The two nodes + * match. + */ + + return (MD_DIFF_MATCH); +} diff --git a/usr/src/common/mdesc/mdesc_fini.c b/usr/src/common/mdesc/mdesc_fini.c index f0b010b386..70340e0b8e 100644 --- a/usr/src/common/mdesc/mdesc_fini.c +++ b/usr/src/common/mdesc/mdesc_fini.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -30,6 +30,10 @@ #include <sys/mdesc.h> #include <sys/mdesc_impl.h> +/* + * Cleanup the internal MD structure. Does not + * deallocate the buffer holding the MD. + */ int md_fini(md_t *ptr) { diff --git a/usr/src/common/mdesc/mdesc_getbinsize.c b/usr/src/common/mdesc/mdesc_getbinsize.c new file mode 100644 index 0000000000..e672806b1f --- /dev/null +++ b/usr/src/common/mdesc/mdesc_getbinsize.c @@ -0,0 +1,45 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/mdesc.h> +#include <sys/mdesc_impl.h> + +size_t +md_get_bin_size(md_t *ptr) +{ + md_impl_t *mdp; + + mdp = (md_impl_t *)ptr; + + if (mdp == NULL) + return (0); + + return (mdp->size); +} diff --git a/usr/src/common/mdesc/mdesc_getgen.c b/usr/src/common/mdesc/mdesc_getgen.c new file mode 100644 index 0000000000..691343d772 --- /dev/null +++ b/usr/src/common/mdesc/mdesc_getgen.c @@ -0,0 +1,45 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/mdesc.h> +#include <sys/mdesc_impl.h> + +uint64_t +md_get_gen(md_t *ptr) +{ + md_impl_t *mdp; + + mdp = (md_impl_t *)ptr; + + if (mdp == NULL) + return (MDESC_INVAL_GEN); + + return (mdp->gen); +} diff --git a/usr/src/common/mdesc/mdesc_init_intern.c b/usr/src/common/mdesc/mdesc_init_intern.c index d4a9226e9e..c2bad6def2 100644 --- a/usr/src/common/mdesc/mdesc_init_intern.c +++ b/usr/src/common/mdesc/mdesc_init_intern.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -32,23 +32,25 @@ #include <sys/mdesc_impl.h> md_t * -md_init_intern(uint64_t *ptr, void *(*allocp)(size_t), - void (*freep)(void *, size_t)) +md_init_intern(uint64_t *ptr, void *(*allocp)(size_t), + void (*freep)(void *, size_t)) { md_impl_t *mdp; int idx; int count; int done; + uint64_t gen; mde_str_cookie_t root_name; /* * Very basic checkup for alignment to avoid * bus error issues. */ - if ((((uintptr_t)ptr)&7) != 0) + if ((((uintptr_t)ptr) & 7) != 0) return (NULL); mdp = (md_impl_t *)allocp(sizeof (md_impl_t)); + if (mdp == NULL) return (NULL); @@ -60,6 +62,7 @@ md_init_intern(uint64_t *ptr, void *(*allocp)(size_t), /* * setup internal structures */ + mdp->headerp = (md_header_t *)mdp->caddr; if (mdtoh32(mdp->headerp->transport_version) != MD_TRANSPORT_VERSION) { @@ -70,13 +73,13 @@ md_init_intern(uint64_t *ptr, void *(*allocp)(size_t), mdp->name_blk_size = mdtoh32(mdp->headerp->name_blk_sz); mdp->data_blk_size = mdtoh32(mdp->headerp->data_blk_sz); - mdp->size = MD_HEADER_SIZE+mdp->node_blk_size+ - mdp->name_blk_size+mdp->data_blk_size; + mdp->size = MD_HEADER_SIZE + mdp->node_blk_size + + mdp->name_blk_size + mdp->data_blk_size; - mdp->mdep = (md_element_t *)(mdp->caddr+MD_HEADER_SIZE); - mdp->namep = (char *)(mdp->caddr+MD_HEADER_SIZE+mdp->node_blk_size); - mdp->datap = (uint8_t *)(mdp->caddr+MD_HEADER_SIZE+mdp->name_blk_size+ - mdp->node_blk_size); + mdp->mdep = (md_element_t *)(mdp->caddr + MD_HEADER_SIZE); + mdp->namep = (char *)(mdp->caddr + MD_HEADER_SIZE + mdp->node_blk_size); + mdp->datap = (uint8_t *)(mdp->caddr + MD_HEADER_SIZE + + mdp->name_blk_size + mdp->node_blk_size); mdp->root_node = MDE_INVAL_ELEM_COOKIE; @@ -123,7 +126,7 @@ md_init_intern(uint64_t *ptr, void *(*allocp)(size_t), mdp->root_node = (mde_cookie_t)idx; } idx = MDE_PROP_INDEX(np); - count ++; + count++; break; default: @@ -142,25 +145,35 @@ md_init_intern(uint64_t *ptr, void *(*allocp)(size_t), * Register the counts */ - mdp->element_count = idx+1; /* include LIST_END */ + mdp->element_count = idx + 1; /* include LIST_END */ mdp->node_count = count; /* * Final sanity check that everything adds up */ - if (mdp->element_count != (mdp->node_blk_size/MD_ELEMENT_SIZE)) + if (mdp->element_count != (mdp->node_blk_size / MD_ELEMENT_SIZE)) goto cleanup; mdp->md_magic = LIBMD_MAGIC; + /* + * Setup MD generation + */ + if (md_get_prop_val((md_t *)mdp, mdp->root_node, + "md-generation#", &gen) != 0) + mdp->gen = MDESC_INVAL_GEN; + else + mdp->gen = gen; + return ((md_t *)mdp); -cleanup:; +cleanup: /* * Clean up here - including a name hash if * we build one. */ -cleanup_nohash:; + +cleanup_nohash: mdp->freep(mdp, sizeof (md_impl_t)); return (NULL); } diff --git a/usr/src/common/mdesc/mdesc_rootnode.c b/usr/src/common/mdesc/mdesc_rootnode.c index 551130fc72..364c5004e2 100644 --- a/usr/src/common/mdesc/mdesc_rootnode.c +++ b/usr/src/common/mdesc/mdesc_rootnode.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -38,7 +38,7 @@ md_root_node(md_t *ptr) mdp = (md_impl_t *)ptr; if (mdp->md_magic != LIBMD_MAGIC) - return (-1); + return (MDE_INVAL_ELEM_COOKIE); return (mdp->root_node); } diff --git a/usr/src/common/mdesc/mdesc_scandag.c b/usr/src/common/mdesc/mdesc_scandag.c index 11b4e24ab2..ad1c74c9c2 100644 --- a/usr/src/common/mdesc/mdesc_scandag.c +++ b/usr/src/common/mdesc/mdesc_scandag.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -19,8 +18,9 @@ * * CDDL HEADER END */ + /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -121,7 +121,8 @@ md_scan_dag(md_t *ptr, -static int mdl_scan_dag(md_impl_t *mdp, +static int +mdl_scan_dag(md_impl_t *mdp, int nodeidx, mde_str_cookie_t node_name_cookie, mde_str_cookie_t arc_name_cookie, |