xref: /illumos-gate/usr/src/cmd/fm/fminject/common/inj.h (revision 2a8bcb4e)
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