xref: /illumos-gate/usr/src/cmd/fm/fminject/common/inj_main.c (revision 03100a6332bd4edc7a53091fcf7c9a7131bcdaa7)
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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <sys/sysevent/eventdefs.h>
30 #include <sys/fm/util.h>
31 #include <fm/fmd_log.h>
32 #include <libsysevent.h>
33 
34 #include <inj.h>
35 #include <inj_err.h>
36 #include <inj_string.h>
37 
38 int verbose;
39 int quiet;
40 
41 static int
42 usage(void)
43 {
44 	(void) fprintf(stderr, "Usage: %s [-nqv] [-c chan] [file]\n"
45 	    "\t-c  specify alternate channel to use for publication\n"
46 	    "\t-n  compile program but do not inject any events\n"
47 	    "\t-q  enable quiet mode (silence status messages)\n"
48 	    "\t-v  enable verbose output (display event details)\n",
49 	    getpname());
50 
51 	return (E_USAGE);
52 }
53 
54 /*
55  * Sysevent-based event delivery
56  */
57 static void *
58 sev_open(const char *chan)
59 {
60 	evchan_t *hdl;
61 
62 	if (chan == NULL)
63 		chan = FM_ERROR_CHAN;
64 
65 	if ((errno = sysevent_evc_bind(chan, &hdl,
66 	    EVCH_CREAT | EVCH_HOLD_PEND)) != 0)
67 		die("can't bind to error channel %s", chan);
68 
69 	return (hdl);
70 }
71 
72 static void
73 sev_send(void *arg, nvlist_t *msg)
74 {
75 	if ((errno = sysevent_evc_publish(arg, EC_FM, ESC_FM_ERROR,
76 	    "com.sun", getpname(), msg, EVCH_SLEEP)) != 0)
77 		warn("failed to send event");
78 }
79 
80 static void
81 sev_close(void *arg)
82 {
83 	sysevent_evc_unbind(arg);
84 }
85 
86 static inj_mode_ops_t sysevent_ops = {
87 	sev_open,
88 	sev_send,
89 	sev_close
90 };
91 
92 /*
93  * Simulated delivery
94  */
95 /*ARGSUSED*/
96 static void *
97 sim_open(const char *arg)
98 {
99 	return ((void *)1);
100 }
101 
102 /*ARGSUSED*/
103 static void
104 sim_send(void *arg, nvlist_t *msg)
105 {
106 }
107 
108 /*ARGSUSED*/
109 static void
110 sim_close(void *arg)
111 {
112 }
113 
114 static inj_mode_ops_t simulate_ops = {
115 	sim_open,
116 	sim_send,
117 	sim_close
118 };
119 
120 int
121 main(int argc, char *argv[])
122 {
123 	const inj_mode_ops_t *mode = NULL;
124 	void *mode_arg = NULL;
125 	int c;
126 
127 	const char *file;
128 	inj_list_t *program;
129 	fmd_log_t *lp;
130 
131 	while ((c = getopt(argc, argv, "c:nqv")) != EOF) {
132 		switch (c) {
133 		case 'c':
134 			if (mode != NULL || mode_arg != NULL)
135 				return (usage());
136 
137 			mode = &sysevent_ops;
138 			mode_arg = optarg;
139 			break;
140 
141 		case 'n':
142 			if (mode != NULL)
143 				return (usage());
144 
145 			mode = &simulate_ops;
146 			break;
147 
148 		case 'q':
149 			quiet = 1;
150 			break;
151 
152 		case 'v':
153 			verbose = 1;
154 			break;
155 
156 		default:
157 			return (usage());
158 		}
159 	}
160 
161 	if (mode == NULL)
162 		mode = &sysevent_ops;
163 
164 	argc -= optind;
165 	argv += optind;
166 
167 	if (argc == 0)
168 		file = "-";
169 	else if (argc == 1)
170 		file = argv[0];
171 	else
172 		return (usage());
173 
174 	srand48(gethrtime());
175 
176 	if (argc > 0 && (lp = fmd_log_open(FMD_LOG_VERSION, file, &c)) != NULL)
177 		program = inj_logfile_read(lp);
178 	else
179 		program = inj_program_read(file);
180 
181 	inj_program_run(program, mode, mode_arg);
182 	return (0);
183 }
184