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