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