/*
* 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
* 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"
#ifdef _KERNEL
#else /* _KERNEL */
#include <string.h>
#include <strings.h>
#endif /* _KERNEL */
#include <sys/mdesc_impl.h>
do { \
typedef struct {
} md_diff_t;
typedef struct {
/*
* Internal utility functions
*/
/*
* 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.
*/
{
int idx;
int md1count = 0;
int md2count = 0;
/* variables used to gather results */
int nadd = 0;
int nrem = 0;
int nmatch = 0;
/* sanity check params */
return (MD_INVAL_DIFF_COOKIE);
if ((start1 == MDE_INVAL_ELEM_COOKIE) ||
(start2 == MDE_INVAL_ELEM_COOKIE))
return (MD_INVAL_DIFF_COOKIE);
return (MD_INVAL_DIFF_COOKIE);
/*
* Prepare an array of the matching nodes from the first MD.
*/
if (mdd_scan_for_nodes(md1p,
return (MD_INVAL_DIFF_COOKIE);
/* sanity check that all nodes are unique */
if (md1nodesp &&
md1count);
return (MD_INVAL_DIFF_COOKIE);
}
/*
* Prepare an array of the matching nodes from the second MD.
*/
if (mdd_scan_for_nodes(md2p,
return (MD_INVAL_DIFF_COOKIE);
/* sanity check that all nodes are unique */
if (md2nodesp &&
md1count);
md2count);
return (MD_INVAL_DIFF_COOKIE);
}
/* setup our result structure */
/*
* Special cases for empty lists
*/
/* all the nodes found were added */
return ((mde_cookie_t)diff_res);
}
/* all the nodes found were removed */
return ((mde_cookie_t)diff_res);
}
/* 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.
*/
/* array of seen flags only needed for md2 */
/*
* 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.
*/
if (match == MD_DIFF_NOMATCH)
/* record deleted node */
else {
/* record matched node pair */
nmatch++;
/* mark that this match has been recorded */
}
}
/*
* Make a pass through the md2 array. Any nodes that have
* not been marked as seen have been added.
*/
/* record added node */
}
/* fill in the added node list */
if (nadd) {
}
/* fill in the removed node list */
if (nrem) {
}
/* fill in the matching node lists */
if (nmatch) {
}
/* clean up */
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
{
return (-1);
}
/*
* 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
{
return (-1);
}
/*
* 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
{
return (-1);
}
/*
* Deallocate any storage used to store results of a previous
* md_diff_init() call. Returns 0 on success and -1 on failure.
*/
int
{
return (-1);
sizeof (mde_cookie_t));
sizeof (mde_cookie_t));
sizeof (mde_cookie_t));
sizeof (mde_cookie_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
{
return (-1);
/* get the number of nodes of interest in the DAG */
if (*countp == 0) {
return (0);
}
/* allocate the storage */
/* populate our array with the matching nodes */
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
{
int idx;
int match;
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
{
int match;
int idx;
continue;
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
{
int idx;
/* make sure we are starting at the beginning of the nodes */
return (MD_DIFF_NOMATCH);
int type;
/*
* Check node A for the property of interest
*/
char *elemname;
continue;
/* found the property of interest */
break;
}
}
/* node A is not of interest */
if (!nodea_interest)
return (MD_DIFF_NOMATCH);
/*
* Check node B for the property of interest
*/
char *elemname;
continue;
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:
return (MD_DIFF_NOMATCH);
break;
case MDET_PROP_STR: {
return (MD_DIFF_NOMATCH);
break;
}
case MDET_PROP_DAT: {
return (MD_DIFF_NOMATCH);
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);
}