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