Commit | Line | Data |
---|---|---|
f5db4af4 JB |
1 | /* |
2 | * Copyright (C) 2006-2009 Red Hat, Inc. | |
3 | * | |
4 | * This file is released under the LGPL. | |
5 | */ | |
6 | ||
7 | #ifndef __DM_LOG_USERSPACE_H__ | |
8 | #define __DM_LOG_USERSPACE_H__ | |
9 | ||
10 | #include <linux/dm-ioctl.h> /* For DM_UUID_LEN */ | |
11 | ||
12 | /* | |
13 | * The device-mapper userspace log module consists of a kernel component and | |
14 | * a user-space component. The kernel component implements the API defined | |
15 | * in dm-dirty-log.h. Its purpose is simply to pass the parameters and | |
16 | * return values of those API functions between kernel and user-space. | |
17 | * | |
18 | * Below are defined the 'request_types' - DM_ULOG_CTR, DM_ULOG_DTR, etc. | |
19 | * These request types represent the different functions in the device-mapper | |
20 | * dirty log API. Each of these is described in more detail below. | |
21 | * | |
22 | * The user-space program must listen for requests from the kernel (representing | |
23 | * the various API functions) and process them. | |
24 | * | |
25 | * User-space begins by setting up the communication link (error checking | |
26 | * removed for clarity): | |
27 | * fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); | |
28 | * addr.nl_family = AF_NETLINK; | |
29 | * addr.nl_groups = CN_IDX_DM; | |
30 | * addr.nl_pid = 0; | |
31 | * r = bind(fd, (struct sockaddr *) &addr, sizeof(addr)); | |
32 | * opt = addr.nl_groups; | |
33 | * setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &opt, sizeof(opt)); | |
34 | * | |
35 | * User-space will then wait to receive requests form the kernel, which it | |
36 | * will process as described below. The requests are received in the form, | |
37 | * ((struct dm_ulog_request) + (additional data)). Depending on the request | |
38 | * type, there may or may not be 'additional data'. In the descriptions below, | |
39 | * you will see 'Payload-to-userspace' and 'Payload-to-kernel'. The | |
40 | * 'Payload-to-userspace' is what the kernel sends in 'additional data' as | |
41 | * necessary parameters to complete the request. The 'Payload-to-kernel' is | |
42 | * the 'additional data' returned to the kernel that contains the necessary | |
43 | * results of the request. The 'data_size' field in the dm_ulog_request | |
44 | * structure denotes the availability and amount of payload data. | |
45 | */ | |
46 | ||
47 | /* | |
48 | * DM_ULOG_CTR corresponds to (found in dm-dirty-log.h): | |
49 | * int (*ctr)(struct dm_dirty_log *log, struct dm_target *ti, | |
50 | * unsigned argc, char **argv); | |
51 | * | |
52 | * Payload-to-userspace: | |
53 | * A single string containing all the argv arguments separated by ' 's | |
54 | * Payload-to-kernel: | |
55 | * None. ('data_size' in the dm_ulog_request struct should be 0.) | |
56 | * | |
57 | * The UUID contained in the dm_ulog_request structure is the reference that | |
58 | * will be used by all request types to a specific log. The constructor must | |
59 | * record this assotiation with instance created. | |
60 | * | |
61 | * When the request has been processed, user-space must return the | |
62 | * dm_ulog_request to the kernel - setting the 'error' field and | |
63 | * 'data_size' appropriately. | |
64 | */ | |
65 | #define DM_ULOG_CTR 1 | |
66 | ||
67 | /* | |
68 | * DM_ULOG_DTR corresponds to (found in dm-dirty-log.h): | |
69 | * void (*dtr)(struct dm_dirty_log *log); | |
70 | * | |
71 | * Payload-to-userspace: | |
72 | * A single string containing all the argv arguments separated by ' 's | |
73 | * Payload-to-kernel: | |
74 | * None. ('data_size' in the dm_ulog_request struct should be 0.) | |
75 | * | |
76 | * The UUID contained in the dm_ulog_request structure is all that is | |
77 | * necessary to identify the log instance being destroyed. There is no | |
78 | * payload data. | |
79 | * | |
80 | * When the request has been processed, user-space must return the | |
81 | * dm_ulog_request to the kernel - setting the 'error' field and clearing | |
82 | * 'data_size' appropriately. | |
83 | */ | |
84 | #define DM_ULOG_DTR 2 | |
85 | ||
86 | /* | |
87 | * DM_ULOG_PRESUSPEND corresponds to (found in dm-dirty-log.h): | |
88 | * int (*presuspend)(struct dm_dirty_log *log); | |
89 | * | |
90 | * Payload-to-userspace: | |
91 | * None. | |
92 | * Payload-to-kernel: | |
93 | * None. | |
94 | * | |
95 | * The UUID contained in the dm_ulog_request structure is all that is | |
96 | * necessary to identify the log instance being presuspended. There is no | |
97 | * payload data. | |
98 | * | |
99 | * When the request has been processed, user-space must return the | |
100 | * dm_ulog_request to the kernel - setting the 'error' field and | |
101 | * 'data_size' appropriately. | |
102 | */ | |
103 | #define DM_ULOG_PRESUSPEND 3 | |
104 | ||
105 | /* | |
106 | * DM_ULOG_POSTSUSPEND corresponds to (found in dm-dirty-log.h): | |
107 | * int (*postsuspend)(struct dm_dirty_log *log); | |
108 | * | |
109 | * Payload-to-userspace: | |
110 | * None. | |
111 | * Payload-to-kernel: | |
112 | * None. | |
113 | * | |
114 | * The UUID contained in the dm_ulog_request structure is all that is | |
115 | * necessary to identify the log instance being postsuspended. There is no | |
116 | * payload data. | |
117 | * | |
118 | * When the request has been processed, user-space must return the | |
119 | * dm_ulog_request to the kernel - setting the 'error' field and | |
120 | * 'data_size' appropriately. | |
121 | */ | |
122 | #define DM_ULOG_POSTSUSPEND 4 | |
123 | ||
124 | /* | |
125 | * DM_ULOG_RESUME corresponds to (found in dm-dirty-log.h): | |
126 | * int (*resume)(struct dm_dirty_log *log); | |
127 | * | |
128 | * Payload-to-userspace: | |
129 | * None. | |
130 | * Payload-to-kernel: | |
131 | * None. | |
132 | * | |
133 | * The UUID contained in the dm_ulog_request structure is all that is | |
134 | * necessary to identify the log instance being resumed. There is no | |
135 | * payload data. | |
136 | * | |
137 | * When the request has been processed, user-space must return the | |
138 | * dm_ulog_request to the kernel - setting the 'error' field and | |
139 | * 'data_size' appropriately. | |
140 | */ | |
141 | #define DM_ULOG_RESUME 5 | |
142 | ||
143 | /* | |
144 | * DM_ULOG_GET_REGION_SIZE corresponds to (found in dm-dirty-log.h): | |
145 | * uint32_t (*get_region_size)(struct dm_dirty_log *log); | |
146 | * | |
147 | * Payload-to-userspace: | |
148 | * None. | |
149 | * Payload-to-kernel: | |
150 | * uint64_t - contains the region size | |
151 | * | |
152 | * The region size is something that was determined at constructor time. | |
153 | * It is returned in the payload area and 'data_size' is set to | |
154 | * reflect this. | |
155 | * | |
156 | * When the request has been processed, user-space must return the | |
157 | * dm_ulog_request to the kernel - setting the 'error' field appropriately. | |
158 | */ | |
159 | #define DM_ULOG_GET_REGION_SIZE 6 | |
160 | ||
161 | /* | |
162 | * DM_ULOG_IS_CLEAN corresponds to (found in dm-dirty-log.h): | |
163 | * int (*is_clean)(struct dm_dirty_log *log, region_t region); | |
164 | * | |
165 | * Payload-to-userspace: | |
166 | * uint64_t - the region to get clean status on | |
167 | * Payload-to-kernel: | |
168 | * int64_t - 1 if clean, 0 otherwise | |
169 | * | |
170 | * Payload is sizeof(uint64_t) and contains the region for which the clean | |
171 | * status is being made. | |
172 | * | |
173 | * When the request has been processed, user-space must return the | |
174 | * dm_ulog_request to the kernel - filling the payload with 0 (not clean) or | |
175 | * 1 (clean), setting 'data_size' and 'error' appropriately. | |
176 | */ | |
177 | #define DM_ULOG_IS_CLEAN 7 | |
178 | ||
179 | /* | |
180 | * DM_ULOG_IN_SYNC corresponds to (found in dm-dirty-log.h): | |
181 | * int (*in_sync)(struct dm_dirty_log *log, region_t region, | |
182 | * int can_block); | |
183 | * | |
184 | * Payload-to-userspace: | |
185 | * uint64_t - the region to get sync status on | |
186 | * Payload-to-kernel: | |
187 | * int64_t - 1 if in-sync, 0 otherwise | |
188 | * | |
189 | * Exactly the same as 'is_clean' above, except this time asking "has the | |
190 | * region been recovered?" vs. "is the region not being modified?" | |
191 | */ | |
192 | #define DM_ULOG_IN_SYNC 8 | |
193 | ||
194 | /* | |
195 | * DM_ULOG_FLUSH corresponds to (found in dm-dirty-log.h): | |
196 | * int (*flush)(struct dm_dirty_log *log); | |
197 | * | |
198 | * Payload-to-userspace: | |
199 | * None. | |
200 | * Payload-to-kernel: | |
201 | * None. | |
202 | * | |
203 | * No incoming or outgoing payload. Simply flush log state to disk. | |
204 | * | |
205 | * When the request has been processed, user-space must return the | |
206 | * dm_ulog_request to the kernel - setting the 'error' field and clearing | |
207 | * 'data_size' appropriately. | |
208 | */ | |
209 | #define DM_ULOG_FLUSH 9 | |
210 | ||
211 | /* | |
212 | * DM_ULOG_MARK_REGION corresponds to (found in dm-dirty-log.h): | |
213 | * void (*mark_region)(struct dm_dirty_log *log, region_t region); | |
214 | * | |
215 | * Payload-to-userspace: | |
216 | * uint64_t [] - region(s) to mark | |
217 | * Payload-to-kernel: | |
218 | * None. | |
219 | * | |
220 | * Incoming payload contains the one or more regions to mark dirty. | |
221 | * The number of regions contained in the payload can be determined from | |
222 | * 'data_size/sizeof(uint64_t)'. | |
223 | * | |
224 | * When the request has been processed, user-space must return the | |
225 | * dm_ulog_request to the kernel - setting the 'error' field and clearing | |
226 | * 'data_size' appropriately. | |
227 | */ | |
228 | #define DM_ULOG_MARK_REGION 10 | |
229 | ||
230 | /* | |
231 | * DM_ULOG_CLEAR_REGION corresponds to (found in dm-dirty-log.h): | |
232 | * void (*clear_region)(struct dm_dirty_log *log, region_t region); | |
233 | * | |
234 | * Payload-to-userspace: | |
235 | * uint64_t [] - region(s) to clear | |
236 | * Payload-to-kernel: | |
237 | * None. | |
238 | * | |
239 | * Incoming payload contains the one or more regions to mark clean. | |
240 | * The number of regions contained in the payload can be determined from | |
241 | * 'data_size/sizeof(uint64_t)'. | |
242 | * | |
243 | * When the request has been processed, user-space must return the | |
244 | * dm_ulog_request to the kernel - setting the 'error' field and clearing | |
245 | * 'data_size' appropriately. | |
246 | */ | |
247 | #define DM_ULOG_CLEAR_REGION 11 | |
248 | ||
249 | /* | |
250 | * DM_ULOG_GET_RESYNC_WORK corresponds to (found in dm-dirty-log.h): | |
251 | * int (*get_resync_work)(struct dm_dirty_log *log, region_t *region); | |
252 | * | |
253 | * Payload-to-userspace: | |
254 | * None. | |
255 | * Payload-to-kernel: | |
256 | * { | |
257 | * int64_t i; -- 1 if recovery necessary, 0 otherwise | |
258 | * uint64_t r; -- The region to recover if i=1 | |
259 | * } | |
260 | * 'data_size' should be set appropriately. | |
261 | * | |
262 | * When the request has been processed, user-space must return the | |
263 | * dm_ulog_request to the kernel - setting the 'error' field appropriately. | |
264 | */ | |
265 | #define DM_ULOG_GET_RESYNC_WORK 12 | |
266 | ||
267 | /* | |
268 | * DM_ULOG_SET_REGION_SYNC corresponds to (found in dm-dirty-log.h): | |
269 | * void (*set_region_sync)(struct dm_dirty_log *log, | |
270 | * region_t region, int in_sync); | |
271 | * | |
272 | * Payload-to-userspace: | |
273 | * { | |
274 | * uint64_t - region to set sync state on | |
275 | * int64_t - 0 if not-in-sync, 1 if in-sync | |
276 | * } | |
277 | * Payload-to-kernel: | |
278 | * None. | |
279 | * | |
280 | * When the request has been processed, user-space must return the | |
281 | * dm_ulog_request to the kernel - setting the 'error' field and clearing | |
282 | * 'data_size' appropriately. | |
283 | */ | |
284 | #define DM_ULOG_SET_REGION_SYNC 13 | |
285 | ||
286 | /* | |
287 | * DM_ULOG_GET_SYNC_COUNT corresponds to (found in dm-dirty-log.h): | |
288 | * region_t (*get_sync_count)(struct dm_dirty_log *log); | |
289 | * | |
290 | * Payload-to-userspace: | |
291 | * None. | |
292 | * Payload-to-kernel: | |
293 | * uint64_t - the number of in-sync regions | |
294 | * | |
295 | * No incoming payload. Kernel-bound payload contains the number of | |
296 | * regions that are in-sync (in a size_t). | |
297 | * | |
298 | * When the request has been processed, user-space must return the | |
299 | * dm_ulog_request to the kernel - setting the 'error' field and | |
300 | * 'data_size' appropriately. | |
301 | */ | |
302 | #define DM_ULOG_GET_SYNC_COUNT 14 | |
303 | ||
304 | /* | |
305 | * DM_ULOG_STATUS_INFO corresponds to (found in dm-dirty-log.h): | |
306 | * int (*status)(struct dm_dirty_log *log, STATUSTYPE_INFO, | |
307 | * char *result, unsigned maxlen); | |
308 | * | |
309 | * Payload-to-userspace: | |
310 | * None. | |
311 | * Payload-to-kernel: | |
312 | * Character string containing STATUSTYPE_INFO | |
313 | * | |
314 | * When the request has been processed, user-space must return the | |
315 | * dm_ulog_request to the kernel - setting the 'error' field and | |
316 | * 'data_size' appropriately. | |
317 | */ | |
318 | #define DM_ULOG_STATUS_INFO 15 | |
319 | ||
320 | /* | |
321 | * DM_ULOG_STATUS_TABLE corresponds to (found in dm-dirty-log.h): | |
322 | * int (*status)(struct dm_dirty_log *log, STATUSTYPE_TABLE, | |
323 | * char *result, unsigned maxlen); | |
324 | * | |
325 | * Payload-to-userspace: | |
326 | * None. | |
327 | * Payload-to-kernel: | |
328 | * Character string containing STATUSTYPE_TABLE | |
329 | * | |
330 | * When the request has been processed, user-space must return the | |
331 | * dm_ulog_request to the kernel - setting the 'error' field and | |
332 | * 'data_size' appropriately. | |
333 | */ | |
334 | #define DM_ULOG_STATUS_TABLE 16 | |
335 | ||
336 | /* | |
337 | * DM_ULOG_IS_REMOTE_RECOVERING corresponds to (found in dm-dirty-log.h): | |
338 | * int (*is_remote_recovering)(struct dm_dirty_log *log, region_t region); | |
339 | * | |
340 | * Payload-to-userspace: | |
341 | * uint64_t - region to determine recovery status on | |
342 | * Payload-to-kernel: | |
343 | * { | |
344 | * int64_t is_recovering; -- 0 if no, 1 if yes | |
345 | * uint64_t in_sync_hint; -- lowest region still needing resync | |
346 | * } | |
347 | * | |
348 | * When the request has been processed, user-space must return the | |
349 | * dm_ulog_request to the kernel - setting the 'error' field and | |
350 | * 'data_size' appropriately. | |
351 | */ | |
352 | #define DM_ULOG_IS_REMOTE_RECOVERING 17 | |
353 | ||
354 | /* | |
355 | * (DM_ULOG_REQUEST_MASK & request_type) to get the request type | |
356 | * | |
357 | * Payload-to-userspace: | |
358 | * A single string containing all the argv arguments separated by ' 's | |
359 | * Payload-to-kernel: | |
360 | * None. ('data_size' in the dm_ulog_request struct should be 0.) | |
361 | * | |
362 | * We are reserving 8 bits of the 32-bit 'request_type' field for the | |
363 | * various request types above. The remaining 24-bits are currently | |
364 | * set to zero and are reserved for future use and compatibility concerns. | |
365 | * | |
21ae2956 | 366 | * User-space should always use DM_ULOG_REQUEST_TYPE to acquire the |
f5db4af4 JB |
367 | * request type from the 'request_type' field to maintain forward compatibility. |
368 | */ | |
369 | #define DM_ULOG_REQUEST_MASK 0xFF | |
370 | #define DM_ULOG_REQUEST_TYPE(request_type) \ | |
371 | (DM_ULOG_REQUEST_MASK & (request_type)) | |
372 | ||
86a54a48 JB |
373 | /* |
374 | * DM_ULOG_REQUEST_VERSION is incremented when there is a | |
375 | * change to the way information is passed between kernel | |
376 | * and userspace. This could be a structure change of | |
377 | * dm_ulog_request or a change in the way requests are | |
378 | * issued/handled. Changes are outlined here: | |
379 | * version 1: Initial implementation | |
380 | */ | |
381 | #define DM_ULOG_REQUEST_VERSION 1 | |
382 | ||
f5db4af4 | 383 | struct dm_ulog_request { |
7ec23d50 JB |
384 | /* |
385 | * The local unique identifier (luid) and the universally unique | |
386 | * identifier (uuid) are used to tie a request to a specific | |
387 | * mirror log. A single machine log could probably make due with | |
388 | * just the 'luid', but a cluster-aware log must use the 'uuid' and | |
389 | * the 'luid'. The uuid is what is required for node to node | |
390 | * communication concerning a particular log, but the 'luid' helps | |
391 | * differentiate between logs that are being swapped and have the | |
392 | * same 'uuid'. (Think "live" and "inactive" device-mapper tables.) | |
393 | */ | |
394 | uint64_t luid; | |
395 | char uuid[DM_UUID_LEN]; | |
86a54a48 | 396 | char padding[3]; /* Padding because DM_UUID_LEN = 129 */ |
f5db4af4 | 397 | |
86a54a48 | 398 | uint32_t version; /* See DM_ULOG_REQUEST_VERSION */ |
f5db4af4 JB |
399 | int32_t error; /* Used to report back processing errors */ |
400 | ||
401 | uint32_t seq; /* Sequence number for request */ | |
402 | uint32_t request_type; /* DM_ULOG_* defined above */ | |
403 | uint32_t data_size; /* How much data (not including this struct) */ | |
404 | ||
405 | char data[0]; | |
406 | }; | |
407 | ||
408 | #endif /* __DM_LOG_USERSPACE_H__ */ |