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 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _INJ_H 28 #define _INJ_H 29 30 /* 31 * FMA Error injector 32 */ 33 34 #include <stdio.h> 35 #include <libnvpair.h> 36 #include <sys/types.h> 37 38 #include <inj_list.h> 39 #include <inj_hash.h> 40 41 #include <fm/fmd_log.h> 42 43 #ifdef __cplusplus 44 extern "C" { 45 #endif 46 47 /* 48 * The injector allows for the declaration, definition, and injection of four 49 * types of things - Events, FMRIs, Authorities, and lists. The first three 50 * are essentially lists with extra membership requirements (FMRIs, for 51 * example, must include a member called `scheme'). So while each has a 52 * different function within the FMA framework, we can use a single struct to 53 * store all three. The inj_itemtype_t enum is used to describe which of the 54 * four types is being represented by a given object. 55 */ 56 typedef enum inj_itemtype { 57 ITEMTYPE_EVENT, 58 ITEMTYPE_FMRI, 59 ITEMTYPE_AUTH, 60 ITEMTYPE_LIST 61 } inj_itemtype_t; 62 63 #define ITEMTYPE_NITEMS 4 64 65 /* 66 * The member name-value pairs of Events, FMRIs, and Authorities are typed. 67 */ 68 typedef enum inj_memtype { 69 MEMTYPE_UNKNOWN, 70 MEMTYPE_INT8, 71 MEMTYPE_INT16, 72 MEMTYPE_INT32, 73 MEMTYPE_INT64, 74 MEMTYPE_UINT8, 75 MEMTYPE_UINT16, 76 MEMTYPE_UINT32, 77 MEMTYPE_UINT64, 78 MEMTYPE_BOOL, 79 MEMTYPE_STRING, 80 MEMTYPE_ENUM, 81 MEMTYPE_EVENT, 82 MEMTYPE_FMRI, 83 MEMTYPE_AUTH, 84 MEMTYPE_LIST 85 } inj_memtype_t; 86 87 /* 88 * Declarations 89 * 90 * Each declared item, be it an event, an fmri, or an authority, consists of 91 * an inj_decl_t and a string of inj_declmem_t's, one of the latter for each 92 * declared member. 93 */ 94 95 #define DECL_F_AUTOENA 0x1 /* ENA member to be auto-generated for event */ 96 97 typedef struct inj_decl { 98 inj_list_t decl_members; /* List of declared members */ 99 inj_hash_t decl_memhash; /* Hash of said members */ 100 101 const char *decl_name; /* Name of declared item */ 102 inj_itemtype_t decl_type; /* Type of declared item */ 103 104 uint_t decl_lineno; /* Line # of first member declared */ 105 uint_t decl_flags; /* DECL_F_* */ 106 } inj_decl_t; 107 108 #define DECLMEM_F_ARRAY 0x1 /* This member is an array of the given type */ 109 110 typedef struct inj_declmem { 111 inj_list_t dlm_memlist; /* List of declared members */ 112 113 const char *dlm_name; /* Name of this member */ 114 inj_memtype_t dlm_type; /* Type of this member */ 115 116 uint_t dlm_flags; /* DECLMEM_F_* */ 117 uint_t dlm_arrdim; /* If arr flag set, dim of array */ 118 119 union { 120 inj_hash_t *_dlm_enumvals; /* If enum, hash of poss. values */ 121 inj_decl_t *_dlm_decl; /* If evt, etc., ptr to decl for same */ 122 } _dlm_u; 123 } inj_declmem_t; 124 125 #define dlm_enumvals _dlm_u._dlm_enumvals 126 #define dlm_decl _dlm_u._dlm_decl 127 128 /* 129 * Definitions 130 * 131 * Each defined item consists of an inj_defn_t and a string of inj_defnmem_t's, 132 * one of the latter for each defined member. The inj_defn_t also contains a 133 * pointer to the corresponding declaration, thus allowing for correctness 134 * checking. 135 */ 136 137 typedef struct inj_defn { 138 inj_list_t defn_members; /* List of defined members */ 139 const char *defn_name; /* Name of this definition */ 140 inj_decl_t *defn_decl; /* Ptr to decl this defn instantiates */ 141 uint_t defn_lineno; /* Line # of first member defined */ 142 143 nvlist_t *defn_nvl; /* Built from validated members */ 144 } inj_defn_t; 145 146 /* 147 * Embodiment of the information that we know about a given defined member at 148 * the time of definition. These values are assigned before the individual 149 * definition members are paired with their corresponding declarations, so we 150 * don't know whether a given IDENT is, for example, an enum or an fmri 151 * reference. Without these values, we wouldn't be able to distinguish between 152 * a quoted string and an identifier, for example, and thus would have a harder 153 * time with syntactic validation. 154 */ 155 typedef enum inj_defnmemtype { 156 DEFNMEM_IMM, 157 DEFNMEM_IDENT, 158 DEFNMEM_QSTRING, 159 DEFNMEM_EVENT, 160 DEFNMEM_FMRI, 161 DEFNMEM_AUTH, 162 DEFNMEM_ARRAY, 163 DEFNMEM_LIST 164 } inj_defnmemtype_t; 165 166 typedef struct inj_defnmem { 167 inj_list_t dfm_memlist; /* List of defined members */ 168 169 inj_defnmemtype_t dfm_type; /* Type of this member, from parser */ 170 uint_t dfm_lineno; /* Last line of this member's defn */ 171 172 union { 173 const char *_dfm_str; /* String value of member */ 174 inj_list_t _dfm_list; /* Enum, evt, auth, arr, list vals */ 175 } _dfm_u; 176 } inj_defnmem_t; 177 178 #define dfm_str _dfm_u._dfm_str 179 #define dfm_list _dfm_u._dfm_list 180 181 /* 182 * Operations performed by the injector (aside from declarations and 183 * definitions) 184 */ 185 186 /* events and priorities list for the randomize command */ 187 typedef struct inj_randelem { 188 struct inj_randelem *re_next; 189 inj_defn_t *re_event; 190 uint_t re_prob; 191 } inj_randelem_t; 192 193 /* 194 * Operations themselves are structured as a tree of inj_cmd_t's. Each one has 195 * a command type and type-specific command data. The "program" is run via 196 * iteration through the tree, with the injector performing the operation 197 * requested by a given node. 198 */ 199 typedef enum inj_cmd_type { 200 CMD_SEND_EVENT, 201 CMD_SLEEP, 202 CMD_REPEAT, 203 CMD_RANDOM 204 } inj_cmd_type_t; 205 206 typedef struct inj_cmd { 207 inj_list_t cmd_list; /* List of commands */ 208 inj_cmd_type_t cmd_type; /* Type of this command */ 209 210 union { 211 inj_defn_t *_cmd_event; /* If send_event, evt to send */ 212 inj_randelem_t **_cmd_rand; /* List of evts & probs */ 213 struct inj_cmd *_cmd_subcmd; /* If repeat, cmd to be rpt'd */ 214 } _cmd_u; 215 uint_t cmd_num; /* If repeat, repeat count */ 216 } inj_cmd_t; 217 218 #define cmd_event _cmd_u._cmd_event 219 #define cmd_rand _cmd_u._cmd_rand 220 #define cmd_subcmd _cmd_u._cmd_subcmd 221 222 /* 223 * We support retargetable event-delivery mechanisms. Each method implements 224 * a copy of the following ops vector, thus allowing us to switch mechanisms 225 * simply by switching the structure. 226 */ 227 typedef struct inj_mode_ops { 228 void *(*mo_open)(const char *); /* Init mechanism */ 229 void (*mo_send)(void *, nvlist_t *); /* Send a single nvlist */ 230 void (*mo_close)(void *); /* Shut down mechanism */ 231 } inj_mode_ops_t; 232 233 extern int verbose; 234 extern int quiet; 235 236 extern inj_list_t *inj_logfile_read(fmd_log_t *); 237 extern inj_list_t *inj_program_read(const char *); 238 extern void inj_program_run(inj_list_t *, const inj_mode_ops_t *, void *); 239 240 extern void *inj_alloc(size_t); 241 extern void *inj_zalloc(size_t); 242 extern void inj_free(void *, size_t); 243 244 #ifdef __cplusplus 245 } 246 #endif 247 248 #endif /* _INJ_H */ 249