7712 mandoc -Tlint does always exit with error code 0
[unleashed.git] / usr / src / cmd / lvm / rpc.metamhd / mhd_failfast.c
blob9bdc0ca1e010bda9d1818413a8c1dfdeeaf96230
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright (c) 1994, 2000 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include "mhd_local.h"
31 #include <stropts.h>
32 #include "ff.h"
35 * manipulate failfast driver
39 * disarm failfast
41 int
42 mhd_ff_disarm(
43 mhd_drive_set_t *sp,
44 mhd_error_t *mhep
47 struct strioctl si;
49 MHDPRINTF1(("%s: disarm\n", sp->sr_name));
51 /* check locks */
52 assert(MUTEX_HELD(&sp->sr_mx));
54 /* ignore not open */
55 if (sp->sr_ff < 0)
56 return (0);
58 /* disarm any existing failfast */
59 (void) memset(&si, 0, sizeof (si));
60 si.ic_cmd = FAILFAST_DISARM;
61 si.ic_timout = INFTIM;
62 if (ioctl(sp->sr_ff, I_STR, &si) != 0)
63 return (mhd_error(mhep, errno, "/dev/ff"));
65 /* return success */
66 return (0);
70 * open failfast
72 int
73 mhd_ff_open(
74 mhd_drive_set_t *sp,
75 mhd_error_t *mhep
78 struct strioctl si;
80 /* check locks */
81 assert(MUTEX_HELD(&sp->sr_mx));
82 assert((sp->sr_ff_mode == MHD_FF_DEBUG) ||
83 (sp->sr_ff_mode == MHD_FF_HALT) ||
84 (sp->sr_ff_mode == MHD_FF_PANIC));
86 /* open if not already */
87 if ((sp->sr_ff < 0) &&
88 ((sp->sr_ff = open("/dev/ff", O_RDWR, 0)) < 0)) {
89 return (mhd_error(mhep, errno, "/dev/ff"));
92 /* disarm any existing failfast */
93 if (mhd_ff_disarm(sp, mhep) != 0)
94 return (-1);
96 /* load setname */
97 (void) memset(&si, 0, sizeof (si));
98 si.ic_cmd = FAILFAST_SETNAME;
99 si.ic_timout = INFTIM;
100 si.ic_len = strlen(sp->sr_name);
101 si.ic_dp = sp->sr_name;
102 if (ioctl(sp->sr_ff, I_STR, &si) != 0)
103 return (mhd_error(mhep, errno, "/dev/ff"));
105 /* load failfast mode */
106 (void) memset(&si, 0, sizeof (si));
107 switch (sp->sr_ff_mode) {
108 case MHD_FF_DEBUG:
109 si.ic_cmd = FAILFAST_DEBUG_MODE;
110 break;
111 case MHD_FF_HALT:
112 si.ic_cmd = FAILFAST_HALT_MODE;
113 break;
114 default:
115 assert(0);
116 /* FALLTHROUGH */
117 case MHD_FF_PANIC:
118 si.ic_cmd = FAILFAST_PANIC_MODE;
119 break;
121 si.ic_timout = INFTIM;
122 if (ioctl(sp->sr_ff, I_STR, &si) != 0)
123 return (mhd_error(mhep, errno, "/dev/ff"));
125 /* return success */
126 return (0);
130 * close failfast
133 mhd_ff_close(
134 mhd_drive_set_t *sp,
135 mhd_error_t *mhep
138 int rval = 0;
140 /* check locks */
141 assert(MUTEX_HELD(&sp->sr_mx));
143 /* ignore not open */
144 if (sp->sr_ff < 0)
145 return (0);
147 /* disarm any existing failfast */
148 if (mhd_ff_disarm(sp, mhep) != 0)
149 rval = -1;
151 /* close device */
152 if (close(sp->sr_ff) != 0)
153 rval = mhd_error(mhep, errno, "/dev/ff");
154 sp->sr_ff = -1;
156 /* return success */
157 return (rval);
161 * reset failfast
164 mhd_ff_rearm(
165 mhd_drive_set_t *sp,
166 mhd_error_t *mhep
169 uint_t ff = sp->sr_timeouts.mh_ff;
170 struct strioctl si;
172 MHDPRINTF1(("%s: rearm\n", sp->sr_name));
174 /* check locks */
175 assert(MUTEX_HELD(&sp->sr_mx));
176 assert(sp->sr_ff >= 0);
178 /* if timeout is 0, disarm */
179 if (ff == 0)
180 return (mhd_ff_disarm(sp, mhep));
182 /* rearm failfast */
183 (void) memset(&si, 0, sizeof (si));
184 si.ic_cmd = FAILFAST_ARM;
185 si.ic_timout = INFTIM;
186 si.ic_len = sizeof (ff);
187 si.ic_dp = (char *)&ff;
188 if (ioctl(sp->sr_ff, I_STR, &si) != 0)
189 return (mhd_error(mhep, errno, "/dev/ff"));
191 /* return success */
192 return (0);
196 * die right now
198 void
199 mhd_ff_die(
200 mhd_drive_set_t *sp
203 uint_t ff = 0;
204 struct strioctl si;
206 MHDPRINTF(("%s: die\n", sp->sr_name));
208 /* check locks */
209 assert(MUTEX_HELD(&sp->sr_mx));
210 assert(sp->sr_ff >= 0);
212 /* rearm failfast for now */
213 (void) memset(&si, 0, sizeof (si));
214 si.ic_cmd = FAILFAST_ARM;
215 si.ic_timout = INFTIM;
216 si.ic_len = sizeof (ff);
217 si.ic_dp = (char *)&ff;
218 if (ioctl(sp->sr_ff, I_STR, &si) != 0)
219 mhd_perror("/dev/ff");
223 * check set and reset failfast
225 void
226 mhd_ff_check(
227 mhd_drive_set_t *sp
230 mhd_drive_list_t *dlp = &sp->sr_drives;
231 mhd_msec_t ff = sp->sr_timeouts.mh_ff;
232 mhd_msec_t now = mhd_time();
233 uint_t i, ok, cnt;
235 /* check locks */
236 assert(MUTEX_HELD(&sp->sr_mx));
237 assert(sp->sr_ff >= 0);
238 assert((sp->sr_ff_mode == MHD_FF_DEBUG) ||
239 (sp->sr_ff_mode == MHD_FF_HALT) ||
240 (sp->sr_ff_mode == MHD_FF_PANIC));
242 /* see how many drives are within alloted time */
243 for (ok = cnt = 0, i = 0; (i < dlp->dl_ndrive); ++i) {
244 mhd_drive_t *dp = dlp->dl_drives[i];
246 if (dp->dr_state != DRIVE_PROBING)
247 continue;
248 ++cnt;
250 MHDPRINTF2(("%s: now %llu dr_time %llu diff %llu ff %llu\n",
251 dp->dr_rname, now, dp->dr_time, (now - dp->dr_time), ff));
252 if ((now - dp->dr_time) <= ff)
253 ++ok;
256 /* check for majority */
257 if ((cnt == 0) || (ok >= ((cnt / 2) + 1))) {
258 mhd_error_t status = mhd_null_error;
260 if (mhd_ff_rearm(sp, &status) == 0)
261 return;
262 mhd_clrerror(&status);
265 /* die */
266 mhd_eprintf("%s: failed majority cnt %d ok %d\n",
267 sp->sr_name, cnt, ok);
268 mhd_ff_die(sp);