1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 * evnv.c -- eversholt specific nvpair manipulation functions 27 * 28 * this module provides the simulated fault management exercise. 29 */ 30 31 #pragma ident "%Z%%M% %I% %E% SMI" 32 33 #include <stdio.h> 34 #include <string.h> 35 #include <libnvpair.h> 36 #include "evnv.h" 37 #include "out.h" 38 39 #define min(a, b) (((a) <= (b)) ? (a) : (b)) 40 41 extern nv_alloc_t Eft_nv_hdl; 42 43 static void 44 outindent(int depth) 45 { 46 while (depth-- > 0) 47 out(O_ALTFP|O_VERB3|O_NONL, " "); 48 } 49 50 /* 51 * evnv_cmpnvl -- compare two asrus in their nvlist form 52 */ 53 int 54 evnv_cmpnvl(nvlist_t *nvl1, nvlist_t *nvl2, int depth) 55 { 56 /* 57 * an assumption here is that each list was constructed in the 58 * same order, which is a safe assumption since we built the 59 * list of ourself (well, libtopo did at any rate) 60 */ 61 data_type_t t1, t2; 62 nvlist_t **la1 = NULL; 63 nvlist_t **la2 = NULL; 64 nvlist_t *l1 = NULL; 65 nvlist_t *l2 = NULL; 66 nvpair_t *p1 = NULL; 67 nvpair_t *p2 = NULL; 68 uint64_t lv1, lv2; 69 uint_t m, na1, na2; 70 char *s1, *s2; 71 int ret, i; 72 73 for (;;) { 74 p1 = nvlist_next_nvpair(nvl1, p1); 75 p2 = nvlist_next_nvpair(nvl2, p2); 76 if (p1 == NULL && p2 == NULL) { 77 outindent(depth); 78 out(O_ALTFP|O_VERB3, "equal nvls\n"); 79 return (0); 80 } 81 if (p1 == NULL) 82 return (-1); 83 if (p2 == NULL) 84 return (1); 85 s1 = nvpair_name(p1); 86 s2 = nvpair_name(p2); 87 outindent(depth); 88 out(O_ALTFP|O_VERB3, "cmpnvl: pair %s vs %s", s1, s2); 89 if ((ret = strcmp(s1, s2)) != 0) 90 return (ret); 91 t1 = nvpair_type(p1); 92 t2 = nvpair_type(p2); 93 if (t1 != t2) 94 return (t1 - t2); 95 /* 96 * We don't compare all possible types, just the 97 * ones we know are likely to actually be present 98 * in nvlists we've generated. 99 */ 100 switch (t1) { 101 case DATA_TYPE_NVLIST: 102 (void) nvpair_value_nvlist(p1, &l1); 103 (void) nvpair_value_nvlist(p2, &l2); 104 if ((ret = evnv_cmpnvl(l1, l2, depth + 1)) != 0) 105 return (ret); 106 break; 107 case DATA_TYPE_NVLIST_ARRAY: 108 (void) nvpair_value_nvlist_array(p1, &la1, &na1); 109 (void) nvpair_value_nvlist_array(p2, &la2, &na2); 110 m = min(na1, na2); 111 for (i = 0; i < m; i++) { 112 if ((ret = 113 evnv_cmpnvl(*la1, *la2, depth + 1)) != 0) 114 return (ret); 115 la1++; 116 la2++; 117 } 118 if (na1 < na2) 119 return (-1); 120 else if (na2 < na1) 121 return (1); 122 break; 123 case DATA_TYPE_STRING: 124 (void) nvpair_value_string(p1, &s1); 125 (void) nvpair_value_string(p2, &s2); 126 if ((ret = strcmp(s1, s2)) != 0) { 127 outindent(depth); 128 if (ret < 0) 129 out(O_ALTFP|O_VERB3, 130 "cmpnvl: %s < %s", s1, s2); 131 else 132 out(O_ALTFP|O_VERB3, 133 "cmpnvl: %s > %s", s1, s2); 134 return (ret); 135 } 136 break; 137 case DATA_TYPE_UINT64: 138 lv1 = lv2 = 0; 139 (void) nvpair_value_uint64(p1, &lv1); 140 (void) nvpair_value_uint64(p2, &lv2); 141 outindent(depth); 142 out(O_ALTFP|O_VERB3, "cmpnvl: %llu vs %llu", lv1, lv2); 143 if (lv1 > lv2) 144 return (1); 145 else if (lv2 > lv1) 146 return (-1); 147 break; 148 case DATA_TYPE_INT64: 149 lv1 = lv2 = 0; 150 (void) nvpair_value_int64(p1, (int64_t *)&lv1); 151 (void) nvpair_value_int64(p2, (int64_t *)&lv2); 152 outindent(depth); 153 out(O_ALTFP|O_VERB3, "cmpnvl: %lld vs %lld", lv1, lv2); 154 if (lv1 > lv2) 155 return (1); 156 else if (lv2 > lv1) 157 return (-1); 158 break; 159 case DATA_TYPE_UINT32: 160 lv1 = lv2 = 0; 161 (void) nvpair_value_uint32(p1, (uint32_t *)&lv1); 162 (void) nvpair_value_uint32(p2, (uint32_t *)&lv2); 163 outindent(depth); 164 out(O_ALTFP|O_VERB3, "cmpnvl: %u vs %u", 165 *(uint32_t *)&lv1, *(uint32_t *)&lv2); 166 if (lv1 > lv2) 167 return (1); 168 else if (lv2 > lv1) 169 return (-1); 170 break; 171 case DATA_TYPE_INT32: 172 lv1 = lv2 = 0; 173 (void) nvpair_value_int32(p1, (int32_t *)&lv1); 174 (void) nvpair_value_int32(p2, (int32_t *)&lv2); 175 outindent(depth); 176 out(O_ALTFP|O_VERB3, "cmpnvl: %d vs %d", 177 *(int32_t *)&lv1, *(int32_t *)&lv2); 178 if (lv1 > lv2) 179 return (1); 180 else if (lv2 > lv1) 181 return (-1); 182 break; 183 case DATA_TYPE_UINT16: 184 lv1 = lv2 = 0; 185 (void) nvpair_value_uint16(p1, (uint16_t *)&lv1); 186 (void) nvpair_value_uint16(p2, (uint16_t *)&lv2); 187 outindent(depth); 188 out(O_ALTFP|O_VERB3, "cmpnvl: %u vs %u", 189 *(uint16_t *)&lv1, *(uint16_t *)&lv2); 190 if (lv1 > lv2) 191 return (1); 192 else if (lv2 > lv1) 193 return (-1); 194 break; 195 case DATA_TYPE_INT16: 196 lv1 = lv2 = 0; 197 (void) nvpair_value_int16(p1, (int16_t *)&lv1); 198 (void) nvpair_value_int16(p2, (int16_t *)&lv2); 199 outindent(depth); 200 out(O_ALTFP|O_VERB3, "cmpnvl: %d vs %d", 201 *(int16_t *)&lv1, *(int16_t *)&lv2); 202 if (lv1 > lv2) 203 return (1); 204 else if (lv2 > lv1) 205 return (-1); 206 break; 207 case DATA_TYPE_UINT8: 208 lv1 = lv2 = 0; 209 (void) nvpair_value_uint8(p1, (uint8_t *)&lv1); 210 (void) nvpair_value_uint8(p2, (uint8_t *)&lv2); 211 outindent(depth); 212 out(O_ALTFP|O_VERB3, "cmpnvl: %u vs %u", 213 *(uint8_t *)&lv1, *(uint8_t *)&lv2); 214 if (lv1 > lv2) 215 return (1); 216 else if (lv2 > lv1) 217 return (-1); 218 break; 219 case DATA_TYPE_INT8: 220 lv1 = lv2 = 0; 221 (void) nvpair_value_int8(p1, (int8_t *)&lv1); 222 (void) nvpair_value_int8(p2, (int8_t *)&lv2); 223 outindent(depth); 224 out(O_ALTFP|O_VERB3, "cmpnvl: %d vs %d", 225 *(int8_t *)&lv1, *(int8_t *)&lv2); 226 if (lv1 > lv2) 227 return (1); 228 else if (lv2 > lv1) 229 return (-1); 230 break; 231 } 232 } 233 } 234 235 /* 236 * evnv_dupnvl -- duplicate a payload nvlist, keeping only the interesting stuff 237 */ 238 nvlist_t * 239 evnv_dupnvl(nvlist_t *nvp) 240 { 241 nvlist_t *retval = NULL; 242 int nvret; 243 244 if (nvp == NULL) 245 return (NULL); 246 247 if ((nvret = nvlist_xdup(nvp, &retval, &Eft_nv_hdl)) != 0) 248 out(O_DIE, "dupnvl: dup failed: %d", nvret); 249 250 return (retval); 251 } 252