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
overlay_fm_init(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
overlay_fm_fini(void)37 overlay_fm_fini(void)
38 {
39 VERIFY(overlay_fm_count == 0);
40 mutex_destroy(&overlay_fm_lock);
41 }
42
43 void
overlay_fm_degrade(overlay_dev_t * odd,const char * msg)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
overlay_fm_restore(overlay_dev_t * odd)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