mde_cookie_t md_find_node_prop(md_impl_t *mdp, mde_cookie_t node, mde_str_cookie_t prop_name, int tag_type) { md_element_t *mdep; int idx; if (node == MDE_INVAL_ELEM_COOKIE || prop_name == MDE_INVAL_STR_COOKIE) { return (MDE_INVAL_ELEM_COOKIE); } idx = (int)node; mdep = &(mdp->mdep[idx]); /* Skip over any empty elements */ while (MDE_TAG(mdep) == MDET_NULL) { idx++; mdep++; } /* see if cookie is infact a node */ if (MDE_TAG(mdep) != MDET_NODE) { return (MDE_INVAL_ELEM_COOKIE); } /* * Simply walk the elements in the node * looking for a property with a matching name. */ for (idx++, mdep++; MDE_TAG(mdep) != MDET_NODE_END; idx++, mdep++) { if (MDE_TAG(mdep) == tag_type) { if (MDE_NAME(mdep) == prop_name) { return ((mde_cookie_t)idx); } } } return (MDE_INVAL_ELEM_COOKIE); /* no such property name */ }
/* * This is called before an MD structure is intialized, so * it walks the raw MD looking for the generation property. */ static uint64_t mach_descrip_find_md_gen(caddr_t ptr) { md_header_t *hdrp; md_element_t *mdep; md_element_t *rootnode = NULL; md_element_t *elem = NULL; char *namep; boolean_t done; int idx; hdrp = (md_header_t *)ptr; mdep = (md_element_t *)(ptr + MD_HEADER_SIZE); namep = (char *)(ptr + MD_HEADER_SIZE + hdrp->node_blk_sz); /* * Very basic check for alignment to avoid * bus error issues. */ if ((((uint64_t)ptr) & 7) != 0) return (MDESC_INVAL_GEN); if (mdtoh32(hdrp->transport_version) != MD_TRANSPORT_VERSION) { return (MDESC_INVAL_GEN); } /* * Search for the root node. Perform the walk manually * since the MD structure is not set up yet. */ for (idx = 0, done = B_FALSE; done == B_FALSE; ) { md_element_t *np = &(mdep[idx]); switch (MDE_TAG(np)) { case MDET_LIST_END: done = B_TRUE; break; case MDET_NODE: if (strcmp(namep + MDE_NAME(np), "root") == 0) { /* found root node */ rootnode = np; done = B_TRUE; break; } idx = MDE_PROP_INDEX(np); break; default: /* ignore */ idx++; } } if (rootnode == NULL) { /* root not found */ return (MDESC_INVAL_GEN); } /* search the rootnode for the generation property */ for (elem = (rootnode + 1); MDE_TAG(elem) != MDET_NODE_END; elem++) { char *prop_name; /* generation field is a prop_val */ if (MDE_TAG(elem) != MDET_PROP_VAL) continue; prop_name = namep + MDE_NAME(elem); if (strcmp(prop_name, "md-generation#") == 0) { return (MDE_PROP_VALUE(elem)); } } return (MDESC_INVAL_GEN); }
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, uint8_t *seenp, int *idxp, mde_cookie_t *stashp, int level) { md_element_t *mdep; mdep = &(mdp->mdep[nodeidx]); /* see if cookie is infact a node */ if (MDE_TAG(mdep) != MDET_NODE) return (-1); /* have we been here before ? */ if (seenp[nodeidx]) return (0); seenp[nodeidx] = 1; /* is this node of the type we seek ? */ #ifdef DEBUG_LIBMDESC { int x; for (x = 0; x < level; x++) printf("-"); printf("%d (%s)\n", nodeidx, (char *)(mdp->datap + MDE_NAME(mdep))); } #endif if (MDE_NAME(mdep) == node_name_cookie) { /* record the node in the list and keep searching */ if (stashp != NULL) { stashp[*idxp] = (mde_cookie_t)nodeidx; } (*idxp)++; #ifdef DEBUG_LIBMDESC printf("\t* %d\n", *idxp); #endif } /* * Simply walk the elements in the node. * if we find a matching arc, then recursively call * the subordinate looking for a match */ for (mdep++; MDE_TAG(mdep) != MDET_NODE_END; mdep++) { if (MDE_TAG(mdep) == MDET_PROP_ARC && MDE_NAME(mdep) == arc_name_cookie) { int res; res = mdl_scan_dag(mdp, (int)mdep->d.prop_idx, node_name_cookie, arc_name_cookie, seenp, idxp, stashp, level+1); if (res == -1) return (res); } } return (0); }