1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2016 Joyent, Inc. 14 */ 15 16 /* 17 * Overlay device FMA operations. 18 * 19 * For more information, see the big theory statement in 20 * uts/common/io/overlay/overlay.c 21 */ 22 23 #include <sys/ddifm.h> 24 #include <sys/overlay_impl.h> 25 26 kmutex_t overlay_fm_lock; 27 uint_t overlay_fm_count; 28 29 void 30 overlay_fm_init(void) 31 { 32 overlay_fm_count = 0; 33 mutex_init(&overlay_fm_lock, NULL, MUTEX_DRIVER, NULL); 34 } 35 36 void 37 overlay_fm_fini(void) 38 { 39 VERIFY(overlay_fm_count == 0); 40 mutex_destroy(&overlay_fm_lock); 41 } 42 43 void 44 overlay_fm_degrade(overlay_dev_t *odd, const char *msg) 45 { 46 mutex_enter(&overlay_fm_lock); 47 mutex_enter(&odd->odd_lock); 48 49 if (msg != NULL) 50 (void) strlcpy(odd->odd_fmamsg, msg, OVERLAY_STATUS_BUFLEN); 51 52 if (odd->odd_flags & OVERLAY_F_DEGRADED) 53 goto out; 54 55 odd->odd_flags |= OVERLAY_F_DEGRADED; 56 overlay_fm_count++; 57 if (overlay_fm_count == 1) { 58 ddi_fm_service_impact(overlay_dip, DDI_SERVICE_DEGRADED); 59 } 60 out: 61 mutex_exit(&odd->odd_lock); 62 mutex_exit(&overlay_fm_lock); 63 } 64 65 void 66 overlay_fm_restore(overlay_dev_t *odd) 67 { 68 mutex_enter(&overlay_fm_lock); 69 mutex_enter(&odd->odd_lock); 70 if (!(odd->odd_flags & OVERLAY_F_DEGRADED)) 71 goto out; 72 73 odd->odd_fmamsg[0] = '\0'; 74 odd->odd_flags &= ~OVERLAY_F_DEGRADED; 75 overlay_fm_count--; 76 if (overlay_fm_count == 0) { 77 ddi_fm_service_impact(overlay_dip, DDI_SERVICE_RESTORED); 78 } 79 out: 80 mutex_exit(&odd->odd_lock); 81 mutex_exit(&overlay_fm_lock); 82 } 83