rio_main.c (b7d3956b) rio_main.c (25c6ff4b)
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 108 unchanged lines hidden (view full) ---

117 }
118}
119
120
121/*ARGSUSED*/
122static void
123rio_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
124{
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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 108 unchanged lines hidden (view full) ---

117 }
118}
119
120
121/*ARGSUSED*/
122static void
123rio_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
124{
125 nvlist_t **faults;
125 nvlist_t **faults = NULL;
126 nvlist_t *asru;
126 nvlist_t *asru;
127 uint_t nfaults;
127 uint_t nfaults = 0;
128 int f;
128 int f;
129 char devpath[PATH_MAX];
130 char *path;
131 char *uuid;
132 char *scheme;
133 di_retire_t drt = {0};
134 int retire;
129 char *path;
130 char *uuid;
131 char *scheme;
132 di_retire_t drt = {0};
133 int retire;
135 int rval;
134 int rval = 0;
136 int error;
137 char *snglfault = FM_FAULT_CLASS"."FM_ERROR_IO".";
138 boolean_t rtr;
139
140
141 /*
142 * If disabled, we don't do retire. We still do unretires though
143 */

--- 5 unchanged lines hidden (view full) ---

149 drt.rt_abort = (void (*)(void *, const char *, ...))fmd_hdl_abort;
150 drt.rt_debug = (void (*)(void *, const char *, ...))fmd_hdl_debug;
151 drt.rt_hdl = hdl;
152
153 if (strcmp(class, FM_LIST_SUSPECT_CLASS) == 0) {
154 retire = 1;
155 } else if (strcmp(class, FM_LIST_REPAIRED_CLASS) == 0) {
156 retire = 0;
135 int error;
136 char *snglfault = FM_FAULT_CLASS"."FM_ERROR_IO".";
137 boolean_t rtr;
138
139
140 /*
141 * If disabled, we don't do retire. We still do unretires though
142 */

--- 5 unchanged lines hidden (view full) ---

148 drt.rt_abort = (void (*)(void *, const char *, ...))fmd_hdl_abort;
149 drt.rt_debug = (void (*)(void *, const char *, ...))fmd_hdl_debug;
150 drt.rt_hdl = hdl;
151
152 if (strcmp(class, FM_LIST_SUSPECT_CLASS) == 0) {
153 retire = 1;
154 } else if (strcmp(class, FM_LIST_REPAIRED_CLASS) == 0) {
155 retire = 0;
156 } else if (strcmp(class, FM_LIST_UPDATED_CLASS) == 0) {
157 retire = 0;
157 } else if (strncmp(class, snglfault, strlen(snglfault)) == 0) {
158 } else if (strncmp(class, snglfault, strlen(snglfault)) == 0) {
158 fmd_hdl_debug(hdl, "rio_recv: single fault: %s\n", class);
159 return;
159 retire = 1;
160 faults = &nvl;
161 nfaults = 1;
160 } else {
161 fmd_hdl_debug(hdl, "rio_recv: not list.* class: %s\n", class);
162 return;
163 }
164
162 } else {
163 fmd_hdl_debug(hdl, "rio_recv: not list.* class: %s\n", class);
164 return;
165 }
166
165 faults = NULL;
166 nfaults = 0;
167 if (nvlist_lookup_nvlist_array(nvl, FM_SUSPECT_FAULT_LIST,
168 &faults, &nfaults) != 0) {
167 if (nfaults == 0 && nvlist_lookup_nvlist_array(nvl,
168 FM_SUSPECT_FAULT_LIST, &faults, &nfaults) != 0) {
169 fmd_hdl_debug(hdl, "rio_recv: no fault list");
170 return;
171 }
172
169 fmd_hdl_debug(hdl, "rio_recv: no fault list");
170 return;
171 }
172
173 devpath[0] = '\0';
174 rval = 0;
175 for (f = 0; f < nfaults; f++) {
176 if (nvlist_lookup_boolean_value(faults[f], FM_SUSPECT_RETIRE,
177 &rtr) == 0 && !rtr) {
178 fmd_hdl_debug(hdl, "rio_recv: retire suppressed");
179 continue;
180 }
181
182 if (nvlist_lookup_nvlist(faults[f], FM_FAULT_ASRU,

--- 5 unchanged lines hidden (view full) ---

188 scheme = NULL;
189 if (nvlist_lookup_string(asru, FM_FMRI_SCHEME, &scheme) != 0 ||
190 strcmp(scheme, FM_FMRI_SCHEME_DEV) != 0) {
191 fmd_hdl_debug(hdl, "rio_recv: not \"dev\" scheme: %s",
192 scheme ? scheme : "<NULL>");
193 continue;
194 }
195
173 for (f = 0; f < nfaults; f++) {
174 if (nvlist_lookup_boolean_value(faults[f], FM_SUSPECT_RETIRE,
175 &rtr) == 0 && !rtr) {
176 fmd_hdl_debug(hdl, "rio_recv: retire suppressed");
177 continue;
178 }
179
180 if (nvlist_lookup_nvlist(faults[f], FM_FAULT_ASRU,

--- 5 unchanged lines hidden (view full) ---

186 scheme = NULL;
187 if (nvlist_lookup_string(asru, FM_FMRI_SCHEME, &scheme) != 0 ||
188 strcmp(scheme, FM_FMRI_SCHEME_DEV) != 0) {
189 fmd_hdl_debug(hdl, "rio_recv: not \"dev\" scheme: %s",
190 scheme ? scheme : "<NULL>");
191 continue;
192 }
193
196 if (retire && fault_exception(hdl, faults[f]))
194 if (fault_exception(hdl, faults[f]))
197 continue;
198
199 if (nvlist_lookup_string(asru, FM_FMRI_DEV_PATH,
200 &path) != 0 || path[0] == '\0') {
201 fmd_hdl_debug(hdl, "rio_recv: no dev path in asru");
202 continue;
203 }
204
195 continue;
196
197 if (nvlist_lookup_string(asru, FM_FMRI_DEV_PATH,
198 &path) != 0 || path[0] == '\0') {
199 fmd_hdl_debug(hdl, "rio_recv: no dev path in asru");
200 continue;
201 }
202
205 /*
206 * If retire, we retire only if a single ASRU is pinpointed.
207 * We don't do automatic retires if a fault event pinpoints
208 * more than one ASRU.
209 */
210 if (retire) {
203 if (retire) {
211 if (devpath[0] != '\0' && strcmp(path, devpath) != 0) {
212 fmd_hdl_debug(hdl,
213 "rio_recv: Skipping: multiple ASRU");
214 return;
215 } else if (devpath[0] == '\0') {
216 (void) strlcpy(devpath, path, sizeof (devpath));
204 if (fmd_nvl_fmri_has_fault(hdl, asru,
205 FMD_HAS_FAULT_ASRU, NULL) == 1) {
206 error = di_retire_device(path, &drt, 0);
207 if (error != 0) {
208 fmd_hdl_debug(hdl, "rio_recv:"
209 " di_retire_device failed:"
210 " error: %d %s", error, path);
211 rval = -1;
212 }
217 }
218 } else {
213 }
214 } else {
219 error = di_unretire_device(path, &drt);
220 if (error != 0) {
221 fmd_hdl_debug(hdl, "rio_recv: "
222 "di_unretire_device failed: error: %d %s",
223 error, path);
224 rval = -1;
215 if (fmd_nvl_fmri_has_fault(hdl, asru,
216 FMD_HAS_FAULT_ASRU, NULL) == 0) {
217 error = di_unretire_device(path, &drt);
218 if (error != 0) {
219 fmd_hdl_debug(hdl, "rio_recv:"
220 " di_unretire_device failed:"
221 " error: %d %s", error, path);
222 rval = -1;
223 }
225 }
226 }
227 }
228
224 }
225 }
226 }
227
229 if (retire) {
230 if (devpath[0] == '\0')
231 return;
232 error = di_retire_device(devpath, &drt, 0);
233 if (error != 0) {
234 fmd_hdl_debug(hdl, "rio_recv: di_retire_device "
235 "failed: error: %d %s", error, devpath);
236 rval = -1;
237 }
238 }
239
240 /*
241 * The fmd framework takes care of moving a case to the repaired
242 * state. To move the case to the closed state however, we (the
243 * retire agent) need to call fmd_case_uuclose()
244 */
228 /*
229 * The fmd framework takes care of moving a case to the repaired
230 * state. To move the case to the closed state however, we (the
231 * retire agent) need to call fmd_case_uuclose()
232 */
245 if (retire && rval == 0) {
233 if (strcmp(class, FM_LIST_SUSPECT_CLASS) == 0 && rval == 0) {
246 if (nvlist_lookup_string(nvl, FM_SUSPECT_UUID, &uuid) == 0 &&
247 !fmd_case_uuclosed(hdl, uuid)) {
248 fmd_case_uuclose(hdl, uuid);
249 }
250 }
234 if (nvlist_lookup_string(nvl, FM_SUSPECT_UUID, &uuid) == 0 &&
235 !fmd_case_uuclosed(hdl, uuid)) {
236 fmd_case_uuclose(hdl, uuid);
237 }
238 }
239
240 /*
241 * Similarly to move the case to the resolved state, we (the
242 * retire agent) need to call fmd_case_uuresolved()
243 */
244 if (strcmp(class, FM_LIST_REPAIRED_CLASS) == 0 && rval == 0 &&
245 nvlist_lookup_string(nvl, FM_SUSPECT_UUID, &uuid) == 0)
246 fmd_case_uuresolved(hdl, uuid);
251}
252
253static const fmd_hdl_ops_t fmd_ops = {
254 rio_recv, /* fmdo_recv */
255 NULL, /* fmdo_timeout */
256 NULL, /* fmdo_close */
257 NULL, /* fmdo_stats */
258 NULL, /* fmdo_gc */

--- 39 unchanged lines hidden ---
247}
248
249static const fmd_hdl_ops_t fmd_ops = {
250 rio_recv, /* fmdo_recv */
251 NULL, /* fmdo_timeout */
252 NULL, /* fmdo_close */
253 NULL, /* fmdo_stats */
254 NULL, /* fmdo_gc */

--- 39 unchanged lines hidden ---