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 #include <stdio.h> 32 #include <string.h> 33 #include <libnvpair.h> 34 #include "evnv.h" 35 #include "out.h" 36 37 #define min(a, b) (((a) <= (b)) ? (a) : (b)) 38 39 extern nv_alloc_t Eft_nv_hdl; 40 41 static void 42 outindent(int depth) 43 { 44 while (depth-- > 0) 45 out(O_ALTFP|O_VERB3|O_NONL, " "); 46 } 47 48 /* 49 * evnv_cmpnvl -- compare two asrus in their nvlist form 50 */ 51 int 52 evnv_cmpnvl(nvlist_t *nvl1, nvlist_t *nvl2, int depth) 53 { 54 /* 55 * an assumption here is that each list was constructed in the 56 * same order, which is a safe assumption since we built the 57 * list of ourself (well, libtopo did at any rate) 58 */ 59 data_type_t t1, t2; 60 nvlist_t **la1 = NULL; 61 nvlist_t **la2 = NULL; 62 nvlist_t *l1 = NULL; 63 nvlist_t *l2 = NULL; 64 nvpair_t *p1 = NULL; 65 nvpair_t *p2 = NULL; 66 uint64_t lv1, lv2; 67 uint_t m, na1, na2; 68 char *s1, *s2; 69 int ret, i; 70 71 for (;;) { 72 p1 = nvlist_next_nvpair(nvl1, p1); 73 p2 = nvlist_next_nvpair(nvl2, p2); 74 if (p1 == NULL && p2 == NULL) { 75 outindent(depth); 76 out(O_ALTFP|O_VERB3, "equal nvls\n"); 77 return (0); 78 } 79 if (p1 == NULL) 80 return (-1); 81 if (p2 == NULL) 82 return (1); 83 s1 = nvpair_name(p1); 84 s2 = nvpair_name(p2); 85 outindent(depth); 86 out(O_ALTFP|O_VERB3, "cmpnvl: pair %s vs %s", s1, s2); 87 if ((ret = strcmp(s1, s2)) != 0) 88 return (ret); 89 t1 = nvpair_type(p1); 90 t2 = nvpair_type(p2); 91 if (t1 != t2) 92 return (t1 - t2); 93 /* 94 * We don't compare all possible types, just the 95 * ones we know are likely to actually be present 96 * in nvlists we've generated. 97 */ 98 switch (t1) { 99 case DATA_TYPE_NVLIST: 100 (void) nvpair_value_nvlist(p1, &l1); 101 (void) nvpair_value_nvlist(p2, &l2); 102 if ((ret = evnv_cmpnvl(l1, l2, depth + 1)) != 0) 103 return (ret); 104 break; 105 case DATA_TYPE_NVLIST_ARRAY: 106 (void) nvpair_value_nvlist_array(p1, &la1, &na1); 107 (void) nvpair_value_nvlist_array(p2, &la2, &na2); 108 m = min(na1, na2); 109 for (i = 0; i < m; i++) { 110 if ((ret = 111 evnv_cmpnvl(*la1, *la2, depth + 1)) != 0) 112 return (ret); 113 la1++; 114 la2++; 115 } 116 if (na1 < na2) 117 return (-1); 118 else if (na2 < na1) 119 return (1); 120 break; 121 case DATA_TYPE_STRING: 122 (void) nvpair_value_string(p1, &s1); 123 (void) nvpair_value_string(p2, &s2); 124 if ((ret = strcmp(s1, s2)) != 0) { 125 outindent(depth); 126 if (ret < 0) 127 out(O_ALTFP|O_VERB3, 128 "cmpnvl: %s < %s", s1, s2); 129 else 130 out(O_ALTFP|O_VERB3, 131 "cmpnvl: %s > %s", s1, s2); 132 return (ret); 133 } 134 break; 135 case DATA_TYPE_UINT64: 136 lv1 = lv2 = 0; 137 (void) nvpair_value_uint64(p1, &lv1); 138 (void) nvpair_value_uint64(p2, &lv2); 139 outindent(depth); 140 out(O_ALTFP|O_VERB3, "cmpnvl: %llu vs %llu", lv1, lv2); 141 if (lv1 > lv2) 142 return (1); 143 else if (lv2 > lv1) 144 return (-1); 145 break; 146 case DATA_TYPE_INT64: 147 lv1 = lv2 = 0; 148 (void) nvpair_value_int64(p1, (int64_t *)&lv1); 149 (void) nvpair_value_int64(p2, (int64_t *)&lv2); 150 outindent(depth); 151 out(O_ALTFP|O_VERB3, "cmpnvl: %lld vs %lld", lv1, lv2); 152 if (lv1 > lv2) 153 return (1); 154 else if (lv2 > lv1) 155 return (-1); 156 break; 157 case DATA_TYPE_UINT32: 158 lv1 = lv2 = 0; 159 (void) nvpair_value_uint32(p1, (uint32_t *)&lv1); 160 (void) nvpair_value_uint32(p2, (uint32_t *)&lv2); 161 outindent(depth); 162 out(O_ALTFP|O_VERB3, "cmpnvl: %u vs %u", 163 *(uint32_t *)&lv1, *(uint32_t *)&lv2); 164 if (lv1 > lv2) 165 return (1); 166 else if (lv2 > lv1) 167 return (-1); 168 break; 169 case DATA_TYPE_INT32: 170 lv1 = lv2 = 0; 171 (void) nvpair_value_int32(p1, (int32_t *)&lv1); 172 (void) nvpair_value_int32(p2, (int32_t *)&lv2); 173 outindent(depth); 174 out(O_ALTFP|O_VERB3, "cmpnvl: %d vs %d", 175 *(int32_t *)&lv1, *(int32_t *)&lv2); 176 if (lv1 > lv2) 177 return (1); 178 else if (lv2 > lv1) 179 return (-1); 180 break; 181 case DATA_TYPE_UINT16: 182 lv1 = lv2 = 0; 183 (void) nvpair_value_uint16(p1, (uint16_t *)&lv1); 184 (void) nvpair_value_uint16(p2, (uint16_t *)&lv2); 185 outindent(depth); 186 out(O_ALTFP|O_VERB3, "cmpnvl: %u vs %u", 187 *(uint16_t *)&lv1, *(uint16_t *)&lv2); 188 if (lv1 > lv2) 189 return (1); 190 else if (lv2 > lv1) 191 return (-1); 192 break; 193 case DATA_TYPE_INT16: 194 lv1 = lv2 = 0; 195 (void) nvpair_value_int16(p1, (int16_t *)&lv1); 196 (void) nvpair_value_int16(p2, (int16_t *)&lv2); 197 outindent(depth); 198 out(O_ALTFP|O_VERB3, "cmpnvl: %d vs %d", 199 *(int16_t *)&lv1, *(int16_t *)&lv2); 200 if (lv1 > lv2) 201 return (1); 202 else if (lv2 > lv1) 203 return (-1); 204 break; 205 case DATA_TYPE_UINT8: 206 lv1 = lv2 = 0; 207 (void) nvpair_value_uint8(p1, (uint8_t *)&lv1); 208 (void) nvpair_value_uint8(p2, (uint8_t *)&lv2); 209 outindent(depth); 210 out(O_ALTFP|O_VERB3, "cmpnvl: %u vs %u", 211 *(uint8_t *)&lv1, *(uint8_t *)&lv2); 212 if (lv1 > lv2) 213 return (1); 214 else if (lv2 > lv1) 215 return (-1); 216 break; 217 case DATA_TYPE_INT8: 218 lv1 = lv2 = 0; 219 (void) nvpair_value_int8(p1, (int8_t *)&lv1); 220 (void) nvpair_value_int8(p2, (int8_t *)&lv2); 221 outindent(depth); 222 out(O_ALTFP|O_VERB3, "cmpnvl: %d vs %d", 223 *(int8_t *)&lv1, *(int8_t *)&lv2); 224 if (lv1 > lv2) 225 return (1); 226 else if (lv2 > lv1) 227 return (-1); 228 break; 229 } 230 } 231 } 232 233 /* 234 * evnv_dupnvl -- duplicate a payload nvlist, keeping only the interesting stuff 235 */ 236 nvlist_t * 237 evnv_dupnvl(nvlist_t *nvp) 238 { 239 nvlist_t *retval = NULL; 240 int nvret; 241 242 if (nvp == NULL) 243 return (NULL); 244 245 if ((nvret = nvlist_xdup(nvp, &retval, &Eft_nv_hdl)) != 0) 246 out(O_DIE, "dupnvl: dup failed: %d", nvret); 247 248 return (retval); 249 } 250