Whamcloud - gitweb
LUDOC 299 protocol: Spell-check document
[doc/protocol.git] / struct_obd_import.txt
1 Import
2 ^^^^^^
3 [[struct-obd-import]]
4
5 The 'obd_import' structure holds the connection state for between each
6 client and each target it is connected to.
7
8 [source,c]
9 ----
10 struct obd_import {
11         enum lustre_imp_state     imp_state;
12         int                       imp_generation;
13         __u32                     imp_conn_cnt;
14         struct lustre_handle      imp_remote_handle;
15         struct obd_connect_data   imp_connect_data;
16 };
17 ----
18
19 //////////////////////////////////////////////////////////////////////
20 This is the rest of the info associated with obd_import:
21
22 #define IMP_STATE_HIST_LEN 16
23 struct import_state_hist {
24         enum lustre_imp_state ish_state;
25         time_t                ish_time;
26 };
27 struct obd_import {
28         struct portals_handle     imp_handle;
29         atomic_t                  imp_refcount;
30         struct lustre_handle      imp_dlm_handle;
31         struct ptlrpc_connection *imp_connection;
32         struct ptlrpc_client     *imp_client;
33         cfs_list_t        imp_pinger_chain;
34         cfs_list_t        imp_zombie_chain;
35         cfs_list_t        imp_replay_list;
36         cfs_list_t        imp_sending_list;
37         cfs_list_t        imp_delayed_list;
38         cfs_list_t      imp_committed_list;
39         cfs_list_t     *imp_replay_cursor;
40         struct obd_device    *imp_obd;
41         struct ptlrpc_sec    *imp_sec;
42         struct mutex      imp_sec_mutex;
43         cfs_time_t        imp_sec_expire;
44         wait_queue_head_t     imp_recovery_waitq;
45         atomic_t          imp_inflight;
46         atomic_t          imp_unregistering;
47         atomic_t          imp_replay_inflight;
48         atomic_t          imp_inval_count;
49         atomic_t          imp_timeouts;
50         enum lustre_imp_state     imp_state;
51         struct import_state_hist  imp_state_hist[IMP_STATE_HIST_LEN];
52         int               imp_state_hist_idx;
53         int               imp_generation;
54         __u32             imp_conn_cnt;
55         int               imp_last_generation_checked;
56         __u64             imp_last_replay_transno;
57         __u64             imp_peer_committed_transno;
58         __u64             imp_last_transno_checked;
59         struct lustre_handle      imp_remote_handle;
60         cfs_time_t        imp_next_ping;
61         __u64             imp_last_success_conn;
62         cfs_list_t        imp_conn_list;
63         struct obd_import_conn   *imp_conn_current;
64         spinlock_t      imp_lock;
65         /* flags */
66         unsigned long
67                 imp_no_timeout:1,
68                 imp_invalid:1,
69                 imp_deactive:1,
70                 imp_replayable:1,
71                 imp_dlm_fake:1,
72                 imp_server_timeout:1,
73                 imp_delayed_recovery:1,
74                 imp_no_lock_replay:1,
75                 imp_vbr_failed:1,
76                 imp_force_verify:1,
77                 imp_force_next_verify:1,
78                 imp_pingable:1,
79                 imp_resend_replay:1,
80                 imp_no_pinger_recover:1,
81                 imp_need_mne_swab:1,
82                 imp_force_reconnect:1,
83                 imp_connect_tried:1;
84         __u32             imp_connect_op;
85         struct obd_connect_data   imp_connect_data;
86         __u64             imp_connect_flags_orig;
87         int               imp_connect_error;
88         __u32             imp_msg_magic;
89         __u32             imp_msghdr_flags;       /* adjusted based on server capability */
90         struct ptlrpc_request_pool *imp_rq_pool;      /* emergency request pool */
91         struct imp_at         imp_at;         /* adaptive timeout data */
92         time_t            imp_last_reply_time;    /* for health check */
93 };
94 //////////////////////////////////////////////////////////////////////
95
96 //////////////////////////////////////////////////////////////////////
97 ////vvvv
98 The 'imp_handle' value is the unique id for the import, and is used as
99 a hash key to it. It is not used in any of the Lustre
100 protocol messages, but rather is just for internal reference.
101
102 The 'imp_refcount' is also for internal use. The value is incremented
103 with each RPC created, and decremented as the request is freed. When
104 the reference count is zero the import can be freed, as when the
105 target is being disconnected.
106
107 The 'imp_dlm_handle' is a reference to the LDLM export for this
108 client.
109
110 There can be multiple paths through the network to a given
111 target, in which case there would be multiple 'obd_import_conn' items
112 on the 'imp_conn_list'. Each 'obd_imp_conn' includes a
113 'ptlrpc_connection', so 'imp_connection' points to the one that is
114 actually in use.
115
116 The 'imp_client' identifies the (local) portals for sending and
117 receiving messages as well as the client's name. The information is
118 specific to either an MDC or an OSC.
119
120 The 'imp_ping_chain' places the import on a linked list of imports
121 that need periodic pings.
122
123 The 'imp_zombie_chain' places the import on a list ready for being
124 freed. Unused imports ('imp_refcount' is zero) are deleted
125 asynchronously by a garbage collecting process.
126
127 In order to support recovery the client must keep requests that are in
128 the process of being handled by the target.  The target replies to a
129 request as soon as the target has made its local update to
130 memory. When the client receives that reply the request is put on the
131 'imp_replay_list'. In the event of a failure (target crash, lost
132 message) this list is then replayed for the target during the recovery
133 process. When a request has been sent but has not yet received a reply
134 it is placed on the 'imp_sending_list'. In the event of a failure
135 those will simply be replayed after any recovery has been
136 completed. Finally, there may be requests that the client is delaying
137 before it sends them. This can happen if the client is in a degraded
138 mode, as when it is in recovery after a failure. These requests are
139 put on the 'imp_delayed_list' and not processed until recovery is
140 complete and the 'imp_sending_list' has been replayed.
141
142 In order to support recovery 'open' requests must be preserved even
143 after they have completed. Those requests are placed on the
144 'imp_committed_list' and the 'imp_replay_cursor' allows for
145 accelerated access to those items.
146
147 The 'imp_obd' is a reference to the details about the target device
148 that is the subject of this import. There is a lot of state info in
149 there along with many implementation details that are not relevant to
150 the actual Lustre protocol. fixme: I'll want to go through all of the
151 fields in that structure to see which, if any need more
152 documentation.
153
154 The security policy and settings are kept in 'imp_sec', and
155 'imp_sec_mutex' helps manage access to that info. The 'imp_sec_expire'
156 setting is in support of security policies that have an expiration
157 strategy.
158
159 Some processes may need the import to be in a fully connected state in
160 order to proceed. The 'imp_recovery_waitq' is where those threads will
161 wait during recovery.
162
163 The 'imp_inflight' field counts the number of in-flight requests. It
164 is incremented with each request sent and decremented with each reply
165 received.
166
167 The client reserves buffers for the processing of requests and
168 replies, and then informs LNet about those buffers. Buffers may get
169 reused during subsequent processing, but then a point may come when
170 the buffer is no longer going to be used. The client increments the
171 'imp_unregistering' counter and informs LNet the buffer is no longer
172 needed. When LNet has freed the buffer it will notify the client and
173 then the 'imp_unregistering' can be decremented again.
174
175 During recovery the 'imp_reply_inflight' counts the number of requests
176 from the reply list that have been sent and have not been replied to.
177
178 The 'imp_inval_count' field counts how many threads are in the process
179 of cleaning up this connection or waiting for cleanup to complete. The
180 cleanup itself may be needed in the case there is an eviction or other
181 problem (fixme what other problem?). The cleanup may involve freeing
182 allocated resources, updating internal state, running replay lists,
183 and invalidating cache. Since it could take a while there may end up
184 multiple threads waiting on this process to complete.
185
186 The 'imp_timeout' field is a counter that is incremented every time
187 there is a timeout in communication with the target.
188 ////^^^^
189 //////////////////////////////////////////////////////////////////////
190
191 The 'imp_state' tracks the state of the import. It draws from the
192 enumerated set of values:
193
194 .enum_lustre_imp_state
195 [options="header"]
196 |=====
197 | state name              | value
198 | LUSTRE_IMP_CLOSED       | 1
199 | LUSTRE_IMP_NEW          | 2
200 | LUSTRE_IMP_DISCON       | 3
201 | LUSTRE_IMP_CONNECTING   | 4
202 | LUSTRE_IMP_REPLAY       | 5
203 | LUSTRE_IMP_REPLAY_LOCKS | 6
204 | LUSTRE_IMP_REPLAY_WAIT  | 7
205 | LUSTRE_IMP_RECOVER      | 8
206 | LUSTRE_IMP_FULL         | 9
207 | LUSTRE_IMP_EVICTED      | 10
208 |=====
209
210 When the import is itself initialized it is set to
211 LUSTRE_IMP_NEW. When a client initiates a *_CONNECT RPC it sets the
212 state to LUSTRE_IMP_CONNECTING. Similarly, it sets the state to
213 LUSTRE_IMP_DISCON as it initiates a *_DISCONNECT RPC. Receiving the
214 reply to the *DISCONNECT RPC will set the state to
215 LUSTRE_IMP_CLOSED. When a (successful) *_CONNECT RPC reply arrives the
216 state is set to LUSTRE_IMP_FULL. If a target signals a problem or a
217 recovery condition then the state will proceed through the replay and
218 recover states. When the target signals that the client connection is
219 invalid for some reason the state will be set to
220 LUSTRE_IMP_EVICTED. See <<eviction>> and <<recovery>>.
221
222 //////////////////////////////////////////////////////////////////////
223 ////vvvv
224 fixme: what are the transitions between these states? The
225 'imp_state_hist' array maintains a list of the last 16
226 (IMP_STATE_HIST_LEN) states the import was in, along with the time it
227 entered each (fixme: or is it when it left that  state?). The list is
228 maintained in a circular manner, so the 'imp_state_hist_idx' points to
229 the entry in the list for the most recently visited state.
230 ////^^^^
231 //////////////////////////////////////////////////////////////////////
232
233 The 'imp_generation' and 'imp_conn_cnt' fields are monotonically
234 increasing counters. Every time a connection request is sent to the
235 target the 'imp_conn_cnt' counter is incremented, and every time a
236 reply is received for the connection request the 'imp_generation'
237 counter is incremented.
238
239 //////////////////////////////////////////////////////////////////////
240 ////vvvv
241 The 'imp_last_generation_checked' implements an optimization. When a
242 replay process has successfully traversed the reply list the
243 'imp_generation' value is noted here. If the generation has not
244 incremented then the replay list does not need to be traversed again.
245
246 During replay the 'imp_last_replay_transno' is set to the transaction
247 number of the last request being replayed, and
248 'imp_peer_committed_transno' is set to the 'pb_last_committed' value
249 (of the <<ptlrpc_body>>) from replies if that value is higher than the
250 previous 'imp_peer_committed_transno'.  The 'imp_last_transno_checked'
251 field implements an optimization. It is set to the
252 'imp_last_replay_transno' as its replay is initiated.
253
254 If 'imp_last_transno_checked' is still 'imp_last_replay_transno' and
255 'imp_generation' is still 'imp_last_generation_checked' then there
256 are no additional requests ready to be removed from the replay
257 list. Furthermore, 'imp_last_transno_checked' may no longer be needed,
258 since the committed transactions are now maintained on a separate list.
259 ////^^^^
260 //////////////////////////////////////////////////////////////////////
261
262 The 'imp_remote_handle' is the 'lustre_handle' sent by the target in a
263 connection reply message (See <<struct-ptlrpc-body, specifically its
264 'pb_handle' field, and <<ost-connect-rpc>> for OST_CONNECT). It
265 uniquely identifies the target that this import represents. The client
266 will set its 'pb_handle' value to this 'imp_remote_handle' in the
267 descriptor for all subsequent RPC requests to this target (excluding
268 other connect requests, of course).
269
270 //////////////////////////////////////////////////////////////////////
271 ////vvvv
272 There are two separate ping intervals.  If there are no uncommitted
273 messages for the target then the default ping interval, based on the
274 Adaptive Timeout value, is used to set the 'imp_next_ping' to the time
275 the next ping needs to be sent. If there are uncommitted requests then
276 a "short interval" of 7s is used to set the time for the next ping.
277
278 The 'imp_last_success_conn' value is set to the time of the last
279 successful connection. fixme: The source says it is in 64 bit
280 jiffies, but does not further indicate how that value is calculated.
281
282 Since there can actually be multiple connection paths for a target
283 (due to failover or multihomed configurations) the import maintains a
284 list of all the possible connection paths in the list pointed to by
285 the 'imp_conn_list' field. The 'imp_conn_current' points to the one
286 currently in use. Compare with the 'imp_connection' fields. They point
287 to different structures, but each is reachable from the other.
288
289 Most of the flag, state, and list information in the import needs to
290 be accessed atomically. The 'imp_lock' is used to maintain the
291 consistency of the import while it is manipulated by multiple threads.
292
293 The various flags are documented in the source code and are largely
294 obvious from those short comments, reproduced here:
295
296 .import flags
297 [options="header"]
298 |=====
299 | flag                    | explanation
300 | imp_no_timeout          | timeouts are disabled
301 | imp_invalid             | client has been evicted
302 | imp_deactive            | client administratively disabled
303 | imp_replayable          | try to recover the import
304 | imp_dlm_fake            | don't run recovery (timeout instead)
305 | imp_server_timeout      | use 1/2 timeout on MDSs and OSCs
306 | imp_delayed_recovery    | VBR: imp in delayed recovery
307 | imp_no_lock_replay      | VBR: if gap was found then no lock replays
308 | imp_vbr_failed          | recovery by versions was failed
309 | imp_force_verify        | force an immediate ping
310 | imp_force_next_verify   | force a scheduled ping
311 | imp_pingable            | target is pingable
312 | imp_resend_replay       | resend for replay
313 | imp_no_pinger_recover   | disable normal recovery, for test only.
314 | imp_need_mne_swab       | need IR MNE swab
315 | imp_force_reconnect     | import must be reconnected, not new connection
316 | imp_connect_tried       | import has tried to connect with server
317 |=====
318 A few additional notes are in order. The 'imp_dlm_fake' flag signifies
319 that this is not a "real" import, but rather it is a "reverse"import
320 in support of the LDLM. When the LDLM invokes callback operations the
321 messages are initiated at the other end, so there need to a fake
322 import to receive the replies from the operation. Prior to the
323 introduction of adaptive timeouts the servers were given fixed timeout
324 value that were half those used for the clients. The
325 'imp_server_timeout' flag indicated that the import should use the
326 half-sized timeouts, but with the introduction of adaptive timeouts
327 this facility is no longer used. "VBR" is "version based recovery",
328 and it introduces a new possibility for handling requests. Previously,
329 f there were a gap in the transaction number sequence the the requests
330 associated with the missing transaction numbers would be
331 discarded. With VBR those transaction only need to be discarded if
332 there is an actual dependency between the ones that were skipped and
333 the currently latest committed transaction number. fixme: What are the
334 circumstances that would lead to setting the 'imp_force_next_verify'
335 or 'imp_pingable' flags? During recovery, the client sets the
336 'imp_no_pinger_recover' flag, which tells the process to proceed from
337 the current value of 'imp_replay_last_transno'. The
338 'imp_need_mne_swab' flag indicates a version dependent circumstance
339 where swabbing was inadvertently left out of one processing step.
340 ////^^^^
341 //////////////////////////////////////////////////////////////////////