Print this page
NEX-3177 enums and string arrays required to be in sync.
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Steve Peng <steve.peng@nexenta.com>
SUP-930 Freed and reused idm_conn_t buffer leads to system panic.
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Steve Ping <steve.ping@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/sys/idm/idm_conn_sm.h
+++ new/usr/src/uts/common/sys/idm/idm_conn_sm.h
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
26 26 */
27 27 #ifndef _IDM_CONN_SM_H_
28 28 #define _IDM_CONN_SM_H_
29 29
30 30 #ifdef __cplusplus
31 31 extern "C" {
32 32 #endif
33 33
34 34
35 35 /*
36 36 * IDM connection state machine events. Most events get generated internally
37 37 * either by the state machine or by the IDM TX/RX code. For example when IDM
38 38 * receives a login request for a target connectionit will generate a
39 39 * CE_LOGIN_RCV event. Similarly when the target sends a successful login
40 40 * response IDM generate a "CE_LOGIN_SUCCESS_SND" event. The following
41 41 * events are not detected on the TX/RX path and must be generated explicitly
42 42 * by the client when appropriate:
43 43 *
44 44 * CE_LOGOUT_OTHER_CONN_RCV
45 45 * CE_ASYNC_DROP_CONN_RCV (Only because the message may be received on
46 46 * a different connection from the connection being dropped)
47 47 * CE_ASYNC_DROP_ALL_CONN_RCV
48 48 * CE_LOGOUT_OTHER_CONN_SND
49 49 * CE_ASYNC_DROP_ALL_CONN_SND
50 50 *
51 51 * The following events might occur in any state since they are driven
52 52 * by the PDU's that IDM receives:
53 53 *
54 54 * CE_LOGIN_RCV
55 55 * CE_LOGIN_SUCCESS_RCV
56 56 * CE_LOGIN_FAIL_RCV
57 57 * CE_LOGOUT_SUCCESS_RCV
|
↓ open down ↓ |
57 lines elided |
↑ open up ↑ |
58 58 * CE_LOGOUT_FAIL_RCV
59 59 * CE_ASYNC_LOGOUT_RCV
60 60 * CE_MISC_RCV
61 61 * CE_RX_PROTOCOL_ERROR
62 62 */
63 63
64 64 #define IDM_LOGIN_SECONDS 20
65 65 #define IDM_LOGOUT_SECONDS 20
66 66 #define IDM_CLEANUP_SECONDS 0
67 67
68 +#define IDM_CONN_EVENT_LIST() \
69 + item(CE_UNDEFINED) \
70 + /* Initiator events */ \
71 + item(CE_CONNECT_REQ) \
72 + item(CE_CONNECT_FAIL) \
73 + item(CE_CONNECT_SUCCESS) \
74 + item(CE_LOGIN_SND) \
75 + item(CE_LOGIN_SUCCESS_RCV) \
76 + item(CE_LOGIN_FAIL_RCV) \
77 + item(CE_LOGOUT_THIS_CONN_SND) \
78 + item(CE_LOGOUT_OTHER_CONN_SND) \
79 + item(CE_LOGOUT_SESSION_SND) \
80 + item(CE_LOGOUT_SUCCESS_RCV) \
81 + item(CE_LOGOUT_FAIL_RCV) \
82 + item(CE_ASYNC_LOGOUT_RCV) \
83 + item(CE_ASYNC_DROP_CONN_RCV) \
84 + item(CE_ASYNC_DROP_ALL_CONN_RCV) \
85 + /* Target events */ \
86 + item(CE_CONNECT_ACCEPT) \
87 + item(CE_CONNECT_REJECT) \
88 + item(CE_LOGIN_RCV) \
89 + item(CE_LOGIN_TIMEOUT) \
90 + item(CE_LOGIN_SUCCESS_SND) \
91 + item(CE_LOGIN_FAIL_SND) \
92 + item(CE_LOGIN_FAIL_SND_DONE) \
93 + item(CE_LOGOUT_THIS_CONN_RCV) \
94 + item(CE_LOGOUT_OTHER_CONN_RCV) \
95 + item(CE_LOGOUT_SESSION_RCV) \
96 + item(CE_LOGOUT_SUCCESS_SND) \
97 + item(CE_LOGOUT_SUCCESS_SND_DONE) \
98 + item(CE_LOGOUT_FAIL_SND) \
99 + item(CE_LOGOUT_FAIL_SND_DONE) \
100 + item(CE_CLEANUP_TIMEOUT) \
101 + item(CE_ASYNC_LOGOUT_SND) \
102 + item(CE_ASYNC_DROP_CONN_SND) \
103 + item(CE_ASYNC_DROP_ALL_CONN_SND) \
104 + item(CE_LOGOUT_TIMEOUT) \
105 + /* Common events */ \
106 + item(CE_TRANSPORT_FAIL) \
107 + item(CE_MISC_TX) \
108 + item(CE_TX_PROTOCOL_ERROR) \
109 + item(CE_MISC_RX) \
110 + item(CE_RX_PROTOCOL_ERROR) \
111 + item(CE_LOGOUT_SESSION_SUCCESS) \
112 + item(CE_CONN_REINSTATE) \
113 + item(CE_CONN_REINSTATE_SUCCESS) \
114 + item(CE_CONN_REINSTATE_FAIL) \
115 + item(CE_ENABLE_DM_SUCCESS) \
116 + item(CE_ENABLE_DM_FAIL) \
117 + /* Add new events above CE_MAX_EVENT */ \
118 + item(CE_MAX_EVENT)
119 +
68 120 /* Update idm_ce_name table whenever connection events are modified */
69 121 typedef enum {
70 - CE_UNDEFINED = 0,
71 -
72 - /* Initiator events */
73 - CE_CONNECT_REQ,
74 - CE_CONNECT_FAIL,
75 - CE_CONNECT_SUCCESS,
76 - CE_LOGIN_SND,
77 - CE_LOGIN_SUCCESS_RCV,
78 - CE_LOGIN_FAIL_RCV,
79 - CE_LOGOUT_THIS_CONN_SND,
80 - CE_LOGOUT_OTHER_CONN_SND,
81 - CE_LOGOUT_SESSION_SND,
82 - CE_LOGOUT_SUCCESS_RCV,
83 - CE_LOGOUT_FAIL_RCV,
84 - CE_ASYNC_LOGOUT_RCV,
85 - CE_ASYNC_DROP_CONN_RCV,
86 - CE_ASYNC_DROP_ALL_CONN_RCV,
87 -
88 - /* Target events */
89 - CE_CONNECT_ACCEPT,
90 - CE_CONNECT_REJECT,
91 - CE_LOGIN_RCV,
92 - CE_LOGIN_TIMEOUT,
93 - CE_LOGIN_SUCCESS_SND,
94 - CE_LOGIN_FAIL_SND,
95 - CE_LOGIN_FAIL_SND_DONE,
96 - CE_LOGOUT_THIS_CONN_RCV,
97 - CE_LOGOUT_OTHER_CONN_RCV,
98 - CE_LOGOUT_SESSION_RCV,
99 - CE_LOGOUT_SUCCESS_SND,
100 - CE_LOGOUT_SUCCESS_SND_DONE,
101 - CE_LOGOUT_FAIL_SND,
102 - CE_LOGOUT_FAIL_SND_DONE,
103 - CE_CLEANUP_TIMEOUT,
104 - CE_ASYNC_LOGOUT_SND,
105 - CE_ASYNC_DROP_CONN_SND,
106 - CE_ASYNC_DROP_ALL_CONN_SND,
107 - CE_LOGOUT_TIMEOUT,
108 -
109 - /* Common events */
110 - CE_TRANSPORT_FAIL,
111 - CE_MISC_TX,
112 - CE_TX_PROTOCOL_ERROR,
113 - CE_MISC_RX,
114 - CE_RX_PROTOCOL_ERROR,
115 - CE_LOGOUT_SESSION_SUCCESS,
116 - CE_CONN_REINSTATE,
117 - CE_CONN_REINSTATE_SUCCESS,
118 - CE_CONN_REINSTATE_FAIL,
119 - CE_ENABLE_DM_SUCCESS,
120 - CE_ENABLE_DM_FAIL,
121 -
122 - /* Add new events above CE_MAX_EVENT */
123 - CE_MAX_EVENT
122 +#define item(a) a,
123 + IDM_CONN_EVENT_LIST()
124 +#undef item
124 125 } idm_conn_event_t;
125 126
126 127 #ifdef IDM_CONN_SM_STRINGS
127 128 /* An array of event text values, for use in logging events */
128 129 static const char *idm_ce_name[CE_MAX_EVENT+1] = {
129 - "CE_UNDEFINED",
130 - "CE_CONNECT_REQ",
131 - "CE_CONNECT_FAIL",
132 - "CE_CONNECT_SUCCESS",
133 - "CE_LOGIN_SND",
134 - "CE_LOGIN_SUCCESS_RCV",
135 - "CE_LOGIN_FAIL_RCV",
136 - "CE_LOGOUT_THIS_CONN_SND",
137 - "CE_LOGOUT_OTHER_CONN_SND",
138 - "CE_LOGOUT_SESSION_SND",
139 - "CE_LOGOUT_SUCCESS_RCV",
140 - "CE_LOGOUT_FAIL_RCV",
141 - "CE_ASYNC_LOGOUT_RCV",
142 - "CE_ASYNC_DROP_CONN_RCV",
143 - "CE_ASYNC_DROP_ALL_CONN_RCV",
144 - "CE_CONNECT_ACCEPT",
145 - "CE_CONNECT_REJECT",
146 - "CE_LOGIN_RCV",
147 - "CE_LOGIN_TIMEOUT",
148 - "CE_LOGIN_SUCCESS_SND",
149 - "CE_LOGIN_FAIL_SND",
150 - "CE_LOGIN_FAIL_SND_DONE",
151 - "CE_LOGOUT_THIS_CONN_RCV",
152 - "CE_LOGOUT_OTHER_CONN_RCV",
153 - "CE_LOGOUT_SESSION_RCV",
154 - "CE_LOGOUT_SUCCESS_SND",
155 - "CE_LOGOUT_SUCCESS_SND_DONE",
156 - "CE_LOGOUT_FAIL_SND",
157 - "CE_LOGOUT_FAIL_SND_DONE",
158 - "CE_CLEANUP_TIMEOUT",
159 - "CE_ASYNC_LOGOUT_SND",
160 - "CE_ASYNC_DROP_CONN_SND",
161 - "CE_ASYNC_DROP_ALL_CONN_SND",
162 - "CE_LOGOUT_TIMEOUT",
163 - "CE_TRANSPORT_FAIL",
164 - "CE_MISC_TX",
165 - "CE_TX_PROTOCOL_ERROR",
166 - "CE_MISC_RX",
167 - "CE_RX_PROTOCOL_ERROR",
168 - "CE_LOGOUT_SESSION_SUCCESS",
169 - "CE_CONN_REINSTATE",
170 - "CE_CONN_REINSTATE_SUCCESS",
171 - "CE_CONN_REINSTATE_FAIL",
172 - "CE_ENABLE_DM_SUCCESS",
173 - "CE_ENABLE_DM_FAIL",
174 - "CE_MAX_EVENT"
130 +#define item(a) #a,
131 + IDM_CONN_EVENT_LIST()
132 +#undef item
175 133 };
176 134 #endif
177 135
136 +#define CONN_STATE_LIST() \
137 + item(CS_S0_UNDEFINED) \
138 + item(CS_S1_FREE) \
139 + item(CS_S2_XPT_WAIT) \
140 + item(CS_S3_XPT_UP) \
141 + item(CS_S4_IN_LOGIN) \
142 + item(CS_S5_LOGGED_IN) \
143 + item(CS_S6_IN_LOGOUT) \
144 + item(CS_S7_LOGOUT_REQ) \
145 + item(CS_S8_CLEANUP) \
146 + item(CS_S9_INIT_ERROR) \
147 + item(CS_S10_IN_CLEANUP) \
148 + item(CS_S11_COMPLETE) \
149 + item(CS_S12_ENABLE_DM) \
150 + item(CS_S9A_REJECTED) \
151 + item(CS_S9B_WAIT_SND_DONE) \
152 + /* Add new connection states above CS_MAX_STATE */ \
153 + item(CS_MAX_STATE)
154 +
178 155 /* Update idm_cs_name table whenever connection states are modified */
179 156 typedef enum {
180 - CS_S0_UNDEFINED = 0,
181 -
182 - CS_S1_FREE,
183 - CS_S2_XPT_WAIT,
184 - CS_S3_XPT_UP,
185 - CS_S4_IN_LOGIN,
186 - CS_S5_LOGGED_IN,
187 - CS_S6_IN_LOGOUT,
188 - CS_S7_LOGOUT_REQ,
189 - CS_S8_CLEANUP,
190 - CS_S9_INIT_ERROR,
191 - CS_S10_IN_CLEANUP,
192 - CS_S11_COMPLETE,
193 - CS_S12_ENABLE_DM,
194 - CS_S9A_REJECTED,
195 - CS_S9B_WAIT_SND_DONE,
196 -
197 - /* Add new connection states above CS_MAX_STATE */
198 - CS_MAX_STATE
157 +#define item(a) a,
158 + CONN_STATE_LIST()
159 +#undef item
199 160 } idm_conn_state_t;
200 161
201 162 #ifdef IDM_CONN_SM_STRINGS
202 163 /* An array of state text values, for use in logging state transitions */
203 164 static const char *idm_cs_name[CS_MAX_STATE+1] = {
204 - "CS_S0_UNDEFINED",
205 - "CS_S1_FREE",
206 - "CS_S2_XPT_WAIT",
207 - "CS_S3_XPT_UP",
208 - "CS_S4_IN_LOGIN",
209 - "CS_S5_LOGGED_IN",
210 - "CS_S6_IN_LOGOUT",
211 - "CS_S7_LOGOUT_REQ",
212 - "CS_S8_CLEANUP",
213 - "CS_S9_INIT_ERROR",
214 - "CS_S10_IN_CLEANUP",
215 - "CS_S11_COMPLETE",
216 - "CS_S12_ENABLE_DM",
217 - "CS_S9A_REJECTED",
218 - "CS_S9B_WAIT_SND_DONE",
219 - "CS_MAX_STATE"
165 +#define item(a) #a,
166 + CONN_STATE_LIST()
167 +#undef item
220 168 };
221 169 #endif
222 170
223 171 /*
224 172 * Currently the state machine has a condition where idm_login_timeout() is
225 173 * left active after the connection has been closed. This causes the system
226 174 * to panic when idm_login_timeout() modifies the freed memory. In an attempt
227 175 * to isolate and find this issue special attention is being placed on
228 176 * the ic_state_timeout value. After each untimeout call the value will now
229 177 * be cleared. Just before the value is set the code will check for 0 and
230 178 * display an error. One final change is being done in idm_conn_sm_fini() which
231 179 * if ic_state_machine is not 0, an error message will be displayed and
232 180 * untimeout() called. That should prevent customer sites from seeing the
233 181 * panic. The code also calls ASSERT(0) which should cause a panic during
234 182 * system test.
235 183 */
236 184 #define IDM_SM_TIMER_CHECK(ic) \
237 185 if (ic->ic_state_timeout) { \
238 186 cmn_err(CE_WARN, "%s: existing timeout still set. " \
239 187 "state: %s, last: %s\n", __func__, \
240 188 idm_cs_name[ic->ic_state], \
241 189 idm_cs_name[ic->ic_last_state]); \
242 190 ASSERT(0); \
243 191 }
244 192
245 193 #define IDM_SM_TIMER_CLEAR(ic) \
246 194 (void) untimeout(ic->ic_state_timeout); \
247 195 ic->ic_state_timeout = 0;
248 196
249 197 typedef enum {
250 198 CT_NONE = 0,
251 199 CT_RX_PDU,
252 200 CT_TX_PDU
253 201 } idm_pdu_event_type_t;
254 202
255 203 typedef enum {
256 204 CA_TX_PROTOCOL_ERROR, /* Send "protocol error" to state machine */
257 205 CA_RX_PROTOCOL_ERROR, /* Send "protocol error" to state machine */
258 206 CA_FORWARD, /* State machine event and forward to client */
259 207 CA_DROP /* Drop PDU */
260 208 } idm_pdu_event_action_t;
261 209
262 210 typedef struct {
263 211 struct idm_conn_s *iec_ic;
264 212 idm_conn_event_t iec_event;
265 213 uintptr_t iec_info;
266 214 idm_pdu_event_type_t iec_pdu_event_type;
267 215 boolean_t iec_pdu_forwarded;
268 216 } idm_conn_event_ctx_t;
269 217
270 218 idm_status_t
271 219 idm_conn_sm_init(struct idm_conn_s *ic);
272 220
273 221 void
274 222 idm_conn_sm_fini(struct idm_conn_s *ic);
275 223
276 224 idm_status_t
277 225 idm_notify_client(struct idm_conn_s *ic, idm_client_notify_t cn,
278 226 uintptr_t data);
279 227
280 228 void
281 229 idm_conn_event(struct idm_conn_s *ic, idm_conn_event_t event, uintptr_t data);
282 230
283 231 void
284 232 idm_conn_event(struct idm_conn_s *ic, idm_conn_event_t event, uintptr_t data);
285 233
286 234 void
287 235 idm_conn_event_locked(struct idm_conn_s *ic, idm_conn_event_t event,
288 236 uintptr_t event_info, idm_pdu_event_type_t pdu_event_type);
289 237
290 238 idm_status_t
291 239 idm_conn_reinstate_event(struct idm_conn_s *old_ic, struct idm_conn_s *new_ic);
292 240
293 241 void
294 242 idm_conn_tx_pdu_event(struct idm_conn_s *ic, idm_conn_event_t event,
295 243 uintptr_t data);
296 244
297 245 void
298 246 idm_conn_rx_pdu_event(struct idm_conn_s *ic, idm_conn_event_t event,
299 247 uintptr_t data);
300 248
301 249 char *
302 250 idm_conn_state_str(struct idm_conn_s *ic);
303 251
304 252 #ifdef __cplusplus
305 253 }
306 254 #endif
307 255
308 256 #endif /* _IDM_CONN_SM_H_ */
|
↓ open down ↓ |
79 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX