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