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