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);
}
示例#3
0
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);
}