fmd_case.c (162ba6ea) fmd_case.c (44743693)
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

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

15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
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

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

15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Copyright 2007 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/*
30 * FMD Case Subsystem
31 *

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

126static const char *const _fmd_case_snames[] = {
127 "UNSOLVED", /* FMD_CASE_UNSOLVED */
128 "SOLVED", /* FMD_CASE_SOLVED */
129 "CLOSE_WAIT", /* FMD_CASE_CLOSE_WAIT */
130 "CLOSED", /* FMD_CASE_CLOSED */
131 "REPAIRED" /* FMD_CASE_REPAIRED */
132};
133
24 * Use is subject to license terms.
25 */
26
27#pragma ident "%Z%%M% %I% %E% SMI"
28
29/*
30 * FMD Case Subsystem
31 *

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

126static const char *const _fmd_case_snames[] = {
127 "UNSOLVED", /* FMD_CASE_UNSOLVED */
128 "SOLVED", /* FMD_CASE_SOLVED */
129 "CLOSE_WAIT", /* FMD_CASE_CLOSE_WAIT */
130 "CLOSED", /* FMD_CASE_CLOSED */
131 "REPAIRED" /* FMD_CASE_REPAIRED */
132};
133
134extern volatile uint32_t fmd_asru_fake_not_present;
135
134fmd_case_hash_t *
135fmd_case_hash_create(void)
136{
137 fmd_case_hash_t *chp = fmd_alloc(sizeof (fmd_case_hash_t), FMD_SLEEP);
138
139 (void) pthread_rwlock_init(&chp->ch_lock, NULL);
140 chp->ch_hashlen = fmd.d_str_buckets;
141 chp->ch_hash = fmd_zalloc(sizeof (void *) * chp->ch_hashlen, FMD_SLEEP);

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

263 for (cis = cip->ci_suspects; cis != NULL; cis = cis->cis_next) {
264 if (nvlist_lookup_boolean_value(cis->cis_nvl,
265 FM_SUSPECT_MESSAGE, &b) == 0 && b == B_FALSE)
266 msg = B_FALSE;
267
268 if (nvlist_lookup_nvlist(cis->cis_nvl,
269 FM_FAULT_ASRU, &fmri) == 0 && (asru =
270 fmd_asru_hash_lookup_nvl(ahp, fmri, FMD_B_FALSE)) != NULL) {
136fmd_case_hash_t *
137fmd_case_hash_create(void)
138{
139 fmd_case_hash_t *chp = fmd_alloc(sizeof (fmd_case_hash_t), FMD_SLEEP);
140
141 (void) pthread_rwlock_init(&chp->ch_lock, NULL);
142 chp->ch_hashlen = fmd.d_str_buckets;
143 chp->ch_hash = fmd_zalloc(sizeof (void *) * chp->ch_hashlen, FMD_SLEEP);

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

265 for (cis = cip->ci_suspects; cis != NULL; cis = cis->cis_next) {
266 if (nvlist_lookup_boolean_value(cis->cis_nvl,
267 FM_SUSPECT_MESSAGE, &b) == 0 && b == B_FALSE)
268 msg = B_FALSE;
269
270 if (nvlist_lookup_nvlist(cis->cis_nvl,
271 FM_FAULT_ASRU, &fmri) == 0 && (asru =
272 fmd_asru_hash_lookup_nvl(ahp, fmri, FMD_B_FALSE)) != NULL) {
271 *bp++ = (asru->asru_flags & FMD_ASRU_FAULTY) != 0;
273 *bp = 0;
274 if (fmd_asru_fake_not_present ||
275 !fmd_fmri_present(asru->asru_fmri))
276 *bp |= FM_SUSPECT_NOT_PRESENT;
277 if (fmd_asru_fake_not_present ||
278 fmd_fmri_unusable(asru->asru_fmri))
279 *bp |= FM_SUSPECT_UNUSABLE;
280 if (asru->asru_flags & FMD_ASRU_FAULTY)
281 *bp |= FM_SUSPECT_FAULTY;
282 bp++;
272 fmd_asru_hash_release(ahp, asru);
273 } else
274 *bp++ = 0;
275
276 *nvp++ = cis->cis_nvl;
277 }
278
279 if (cip->ci_code == NULL)
280 (void) fmd_case_mkcode(cp);
281
283 fmd_asru_hash_release(ahp, asru);
284 } else
285 *bp++ = 0;
286
287 *nvp++ = cis->cis_nvl;
288 }
289
290 if (cip->ci_code == NULL)
291 (void) fmd_case_mkcode(cp);
292
282 nvl = fmd_protocol_list(class, cip->ci_mod->mod_fmri,
283 cip->ci_uuid, cip->ci_code, cip->ci_nsuspects, nva, ba, msg);
293 if (msg == B_FALSE)
294 cip->ci_flags |= FMD_CF_INVISIBLE;
284
295
296 nvl = fmd_protocol_list(class, cip->ci_mod->mod_fmri, cip->ci_uuid,
297 cip->ci_code, cip->ci_nsuspects, nva, ba, msg, &cip->ci_tv);
298
285 (void) pthread_mutex_unlock(&cip->ci_lock);
286 return (nvl);
287}
288
289/*
290 * Convict suspects in a case by applying a conviction policy and updating the
291 * resource cache prior to emitting the list.suspect event for the given case.
292 * At present, our policy is very simple: convict every suspect in the case.

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

358 nvlist_t *nvl;
359 char *class;
360
361 if (state == FMD_CASE_CURRENT)
362 state = cip->ci_state; /* use current state */
363
364 switch (state) {
365 case FMD_CASE_SOLVED:
299 (void) pthread_mutex_unlock(&cip->ci_lock);
300 return (nvl);
301}
302
303/*
304 * Convict suspects in a case by applying a conviction policy and updating the
305 * resource cache prior to emitting the list.suspect event for the given case.
306 * At present, our policy is very simple: convict every suspect in the case.

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

372 nvlist_t *nvl;
373 char *class;
374
375 if (state == FMD_CASE_CURRENT)
376 state = cip->ci_state; /* use current state */
377
378 switch (state) {
379 case FMD_CASE_SOLVED:
366 fmd_case_convict(cp);
367 nvl = fmd_case_mkevent(cp, FM_LIST_SUSPECT_CLASS);
368 (void) pthread_mutex_lock(&cip->ci_lock);
380 (void) pthread_mutex_lock(&cip->ci_lock);
369 if (cip->ci_diag == NULL)
370 (void) nvlist_xdup(nvl, &cip->ci_diag, &fmd.d_nva);
381 if (cip->ci_tv_valid == 0) {
382 fmd_time_gettimeofday(&cip->ci_tv);
383 cip->ci_tv_valid = 1;
384 }
371 (void) pthread_mutex_unlock(&cip->ci_lock);
385 (void) pthread_mutex_unlock(&cip->ci_lock);
386 fmd_case_convict(cp);
387 nvl = fmd_case_mkevent(cp, FM_LIST_SUSPECT_CLASS);
372 (void) nvlist_lookup_string(nvl, FM_CLASS, &class);
373
374 e = fmd_event_create(FMD_EVT_PROTOCOL, FMD_HRT_NOW, nvl, class);
375 (void) pthread_rwlock_rdlock(&fmd.d_log_lock);
376 fmd_log_append(fmd.d_fltlog, e, cp);
377 (void) pthread_rwlock_unlock(&fmd.d_log_lock);
378 fmd_dispq_dispatch(fmd.d_disp, e, class);
379

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

670
671 if (cip->ci_principal != NULL)
672 fmd_event_rele(cip->ci_principal);
673
674 fmd_free(cip->ci_uuid, cip->ci_uuidlen + 1);
675 fmd_free(cip->ci_code, cip->ci_codelen);
676 (void) fmd_buf_hash_destroy(&cip->ci_bufs);
677
388 (void) nvlist_lookup_string(nvl, FM_CLASS, &class);
389
390 e = fmd_event_create(FMD_EVT_PROTOCOL, FMD_HRT_NOW, nvl, class);
391 (void) pthread_rwlock_rdlock(&fmd.d_log_lock);
392 fmd_log_append(fmd.d_fltlog, e, cp);
393 (void) pthread_rwlock_unlock(&fmd.d_log_lock);
394 fmd_dispq_dispatch(fmd.d_disp, e, class);
395

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

686
687 if (cip->ci_principal != NULL)
688 fmd_event_rele(cip->ci_principal);
689
690 fmd_free(cip->ci_uuid, cip->ci_uuidlen + 1);
691 fmd_free(cip->ci_code, cip->ci_codelen);
692 (void) fmd_buf_hash_destroy(&cip->ci_bufs);
693
678 if (cip->ci_diag != NULL)
679 nvlist_free(cip->ci_diag);
680
681 fmd_module_rele(cip->ci_mod);
682 fmd_free(cip, sizeof (fmd_case_impl_t));
683}
684
685void
686fmd_case_hold(fmd_case_t *cp)
687{
688 fmd_case_impl_t *cip = (fmd_case_impl_t *)cp;

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

826 fmd_module_setcdirty(cip->ci_mod);
827}
828
829void
830fmd_case_recreate_suspect(fmd_case_t *cp, nvlist_t *nvl)
831{
832 fmd_case_impl_t *cip = (fmd_case_impl_t *)cp;
833 fmd_case_susp_t *cis = fmd_alloc(sizeof (fmd_case_susp_t), FMD_SLEEP);
694 fmd_module_rele(cip->ci_mod);
695 fmd_free(cip, sizeof (fmd_case_impl_t));
696}
697
698void
699fmd_case_hold(fmd_case_t *cp)
700{
701 fmd_case_impl_t *cip = (fmd_case_impl_t *)cp;

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

839 fmd_module_setcdirty(cip->ci_mod);
840}
841
842void
843fmd_case_recreate_suspect(fmd_case_t *cp, nvlist_t *nvl)
844{
845 fmd_case_impl_t *cip = (fmd_case_impl_t *)cp;
846 fmd_case_susp_t *cis = fmd_alloc(sizeof (fmd_case_susp_t), FMD_SLEEP);
847 boolean_t b;
834
835 (void) pthread_mutex_lock(&cip->ci_lock);
836 ASSERT(cip->ci_state == FMD_CASE_CLOSED);
837 ASSERT(cip->ci_mod == fmd.d_rmod);
838
839 cis->cis_next = cip->ci_suspects;
840 cis->cis_nvl = nvl;
841
848
849 (void) pthread_mutex_lock(&cip->ci_lock);
850 ASSERT(cip->ci_state == FMD_CASE_CLOSED);
851 ASSERT(cip->ci_mod == fmd.d_rmod);
852
853 cis->cis_next = cip->ci_suspects;
854 cis->cis_nvl = nvl;
855
856 if (nvlist_lookup_boolean_value(nvl,
857 FM_SUSPECT_MESSAGE, &b) == 0 && b == B_FALSE)
858 cip->ci_flags |= FMD_CF_INVISIBLE;
859
842 cip->ci_suspects = cis;
843 cip->ci_nsuspects++;
844
845 (void) pthread_mutex_unlock(&cip->ci_lock);
846}
847
848void
849fmd_case_reset_suspects(fmd_case_t *cp)

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

874 fmd_case_item_t *cit;
875 fmd_asru_t *asru;
876 fmd_event_t *e;
877 nvlist_t *nvl;
878
879 ASSERT(state <= FMD_CASE_REPAIRED);
880 (void) pthread_mutex_lock(&cip->ci_lock);
881
860 cip->ci_suspects = cis;
861 cip->ci_nsuspects++;
862
863 (void) pthread_mutex_unlock(&cip->ci_lock);
864}
865
866void
867fmd_case_reset_suspects(fmd_case_t *cp)

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

892 fmd_case_item_t *cit;
893 fmd_asru_t *asru;
894 fmd_event_t *e;
895 nvlist_t *nvl;
896
897 ASSERT(state <= FMD_CASE_REPAIRED);
898 (void) pthread_mutex_lock(&cip->ci_lock);
899
882 if (!(cip->ci_flags & FMD_CF_SOLVED))
900 if (!(cip->ci_flags & FMD_CF_SOLVED) && !(flags & FMD_CF_SOLVED))
883 flags &= ~(FMD_CF_ISOLATED | FMD_CF_REPAIRED);
884
885 cip->ci_flags |= flags;
886
887 if (cip->ci_state >= state) {
888 (void) pthread_mutex_unlock(&cip->ci_lock);
889 return; /* already in specified state */
890 }

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

991void
992fmd_case_transition_update(fmd_case_t *cp, uint_t state, uint_t flags)
993{
994 fmd_case_impl_t *cip = (fmd_case_impl_t *)cp;
995 fmd_case_susp_t *cis;
996 fmd_asru_t *asru;
997 nvlist_t *nvl;
998
901 flags &= ~(FMD_CF_ISOLATED | FMD_CF_REPAIRED);
902
903 cip->ci_flags |= flags;
904
905 if (cip->ci_state >= state) {
906 (void) pthread_mutex_unlock(&cip->ci_lock);
907 return; /* already in specified state */
908 }

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

1009void
1010fmd_case_transition_update(fmd_case_t *cp, uint_t state, uint_t flags)
1011{
1012 fmd_case_impl_t *cip = (fmd_case_impl_t *)cp;
1013 fmd_case_susp_t *cis;
1014 fmd_asru_t *asru;
1015 nvlist_t *nvl;
1016
999 int present = 0; /* are any suspects present? */
1017 int faulty = 0; /* are any suspects faulty? */
1000 int usable = 0; /* are any suspects usable? */
1001
1002 ASSERT(state >= FMD_CASE_SOLVED);
1003 (void) pthread_mutex_lock(&cip->ci_lock);
1004
1005 for (cis = cip->ci_suspects; cis != NULL; cis = cis->cis_next) {
1006 if (nvlist_lookup_nvlist(cis->cis_nvl, FM_FAULT_ASRU,
1007 &nvl) == 0 && (asru = fmd_asru_hash_lookup_nvl(
1008 fmd.d_asrus, nvl, FMD_B_TRUE)) != NULL) {
1009
1018 int usable = 0; /* are any suspects usable? */
1019
1020 ASSERT(state >= FMD_CASE_SOLVED);
1021 (void) pthread_mutex_lock(&cip->ci_lock);
1022
1023 for (cis = cip->ci_suspects; cis != NULL; cis = cis->cis_next) {
1024 if (nvlist_lookup_nvlist(cis->cis_nvl, FM_FAULT_ASRU,
1025 &nvl) == 0 && (asru = fmd_asru_hash_lookup_nvl(
1026 fmd.d_asrus, nvl, FMD_B_TRUE)) != NULL) {
1027
1010 if ((asru->asru_flags & FMD_ASRU_INTERNAL) ||
1011 fmd_fmri_present(asru->asru_fmri) > 0)
1012 present++;
1028 if (asru->asru_flags & FMD_ASRU_FAULTY)
1029 faulty++;
1013
1030
1014 if (fmd_fmri_unusable(asru->asru_fmri) <= 0)
1031 if (fmd_asru_fake_not_present == 0 &&
1032 fmd_fmri_unusable(asru->asru_fmri) <= 0)
1015 usable++;
1016
1017 fmd_asru_hash_release(fmd.d_asrus, asru);
1018 }
1019 }
1020
1021 (void) pthread_mutex_unlock(&cip->ci_lock);
1022
1033 usable++;
1034
1035 fmd_asru_hash_release(fmd.d_asrus, asru);
1036 }
1037 }
1038
1039 (void) pthread_mutex_unlock(&cip->ci_lock);
1040
1023 if (!present) {
1041 /*
1042 * If none of the suspects were faulty, it implies they were either
1043 * repaired already or not present and the rsrc.age time has expired.
1044 * We can move the state on to repaired.
1045 */
1046 if (!faulty) {
1024 state = MAX(state, FMD_CASE_CLOSE_WAIT);
1025 flags |= FMD_CF_REPAIRED;
1026 } else if (!usable) {
1027 state = MAX(state, FMD_CASE_CLOSE_WAIT);
1028 flags |= FMD_CF_ISOLATED;
1029 }
1030
1031 fmd_case_transition(cp, state, flags);

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

1099 (void) pthread_mutex_unlock(&cip->ci_lock);
1100 return; /* update is not appropriate */
1101 }
1102
1103 for (cis = cip->ci_suspects; cis != NULL; cis = cis->cis_next) {
1104 if (nvlist_lookup_nvlist(cis->cis_nvl, FM_FAULT_ASRU,
1105 &nvl) == 0 && (asru = fmd_asru_hash_lookup_nvl(
1106 fmd.d_asrus, nvl, FMD_B_FALSE)) != NULL) {
1047 state = MAX(state, FMD_CASE_CLOSE_WAIT);
1048 flags |= FMD_CF_REPAIRED;
1049 } else if (!usable) {
1050 state = MAX(state, FMD_CASE_CLOSE_WAIT);
1051 flags |= FMD_CF_ISOLATED;
1052 }
1053
1054 fmd_case_transition(cp, state, flags);

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

1122 (void) pthread_mutex_unlock(&cip->ci_lock);
1123 return; /* update is not appropriate */
1124 }
1125
1126 for (cis = cip->ci_suspects; cis != NULL; cis = cis->cis_next) {
1127 if (nvlist_lookup_nvlist(cis->cis_nvl, FM_FAULT_ASRU,
1128 &nvl) == 0 && (asru = fmd_asru_hash_lookup_nvl(
1129 fmd.d_asrus, nvl, FMD_B_FALSE)) != NULL) {
1107 astate |= fmd_asru_getstate(asru);
1130 astate |= (asru->asru_flags & FMD_ASRU_STATE);
1108 fmd_asru_hash_release(fmd.d_asrus, asru);
1109 }
1110 }
1111
1112 (void) pthread_mutex_unlock(&cip->ci_lock);
1113
1114 if (astate & FMD_ASRU_FAULTY)
1115 return; /* one or more suspects are still marked faulty */

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

1323 return (rv);
1324}
1325
1326int
1327fmd_case_orphaned(fmd_case_t *cp)
1328{
1329 return (((fmd_case_impl_t *)cp)->ci_mod == fmd.d_rmod);
1330}
1131 fmd_asru_hash_release(fmd.d_asrus, asru);
1132 }
1133 }
1134
1135 (void) pthread_mutex_unlock(&cip->ci_lock);
1136
1137 if (astate & FMD_ASRU_FAULTY)
1138 return; /* one or more suspects are still marked faulty */

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

1346 return (rv);
1347}
1348
1349int
1350fmd_case_orphaned(fmd_case_t *cp)
1351{
1352 return (((fmd_case_impl_t *)cp)->ci_mod == fmd.d_rmod);
1353}
1354
1355void
1356fmd_case_settime(fmd_case_t *cp, time_t tv_sec, suseconds_t tv_usec)
1357{
1358 ((fmd_case_impl_t *)cp)->ci_tv.tv_sec = tv_sec;
1359 ((fmd_case_impl_t *)cp)->ci_tv.tv_usec = tv_usec;
1360 ((fmd_case_impl_t *)cp)->ci_tv_valid = 1;
1361}