June 2025 | ||||||
Mo | Tu | We | Th | Fr | Sa | Su |
26 | 27 | 28 | 29 | 30 | 31 | 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 1 | 2 | 3 | 4 | 5 | 6 |
001: /* 002: * Copyright (C) 2006-2009 Red Hat, Inc. 003: * 004: * This file is released under the LGPL. 005: */ 006: 007: #ifndef __DM_LOG_USERSPACE_H__ 008: #define __DM_LOG_USERSPACE_H__ 009: 010: #include <linux/dm-ioctl.h> /* For DM_UUID_LEN */ 011: 012: /* 013: * The device-mapper userspace log module consists of a kernel component and 014: * a user-space component. The kernel component implements the API defined 015: * in dm-dirty-log.h. Its purpose is simply to pass the parameters and 016: * return values of those API functions between kernel and user-space. 017: * 018: * Below are defined the 'request_types' - DM_ULOG_CTR, DM_ULOG_DTR, etc. 019: * These request types represent the different functions in the device-mapper 020: * dirty log API. Each of these is described in more detail below. 021: * 022: * The user-space program must listen for requests from the kernel (representing 023: * the various API functions) and process them. 024: * 025: * User-space begins by setting up the communication link (error checking 026: * removed for clarity): 027: * fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); 028: * addr.nl_family = AF_NETLINK; 029: * addr.nl_groups = CN_IDX_DM; 030: * addr.nl_pid = 0; 031: * r = bind(fd, (struct sockaddr *) &addr, sizeof(addr)); 032: * opt = addr.nl_groups; 033: * setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &opt, sizeof(opt)); 034: * 035: * User-space will then wait to receive requests form the kernel, which it 036: * will process as described below. The requests are received in the form, 037: * ((struct dm_ulog_request) + (additional data)). Depending on the request 038: * type, there may or may not be 'additional data'. In the descriptions below, 039: * you will see 'Payload-to-userspace' and 'Payload-to-kernel'. The 040: * 'Payload-to-userspace' is what the kernel sends in 'additional data' as 041: * necessary parameters to complete the request. The 'Payload-to-kernel' is 042: * the 'additional data' returned to the kernel that contains the necessary 043: * results of the request. The 'data_size' field in the dm_ulog_request 044: * structure denotes the availability and amount of payload data. 045: */ 046: 047: /* 048: * DM_ULOG_CTR corresponds to (found in dm-dirty-log.h): 049: * int (*ctr)(struct dm_dirty_log *log, struct dm_target *ti, 050: * unsigned argc, char **argv); 051: * 052: * Payload-to-userspace: 053: * A single string containing all the argv arguments separated by ' 's 054: * Payload-to-kernel: 055: * A NUL-terminated string that is the name of the device that is used 056: * as the backing store for the log data. 'dm_get_device' will be called 057: * on this device. ('dm_put_device' will be called on this device 058: * automatically after calling DM_ULOG_DTR.) If there is no device needed 059: * for log data, 'data_size' in the dm_ulog_request struct should be 0. 060: * 061: * The UUID contained in the dm_ulog_request structure is the reference that 062: * will be used by all request types to a specific log. The constructor must 063: * record this association with the instance created. 064: * 065: * When the request has been processed, user-space must return the 066: * dm_ulog_request to the kernel - setting the 'error' field, filling the 067: * data field with the log device if necessary, and setting 'data_size' 068: * appropriately. 069: */ 070: #define DM_ULOG_CTR 1 071: 072: /* 073: * DM_ULOG_DTR corresponds to (found in dm-dirty-log.h): 074: * void (*dtr)(struct dm_dirty_log *log); 075: * 076: * Payload-to-userspace: 077: * A single string containing all the argv arguments separated by ' 's 078: * Payload-to-kernel: 079: * None. ('data_size' in the dm_ulog_request struct should be 0.) 080: * 081: * The UUID contained in the dm_ulog_request structure is all that is 082: * necessary to identify the log instance being destroyed. There is no 083: * payload data. 084: * 085: * When the request has been processed, user-space must return the 086: * dm_ulog_request to the kernel - setting the 'error' field and clearing 087: * 'data_size' appropriately. 088: */ 089: #define DM_ULOG_DTR 2 090: 091: /* 092: * DM_ULOG_PRESUSPEND corresponds to (found in dm-dirty-log.h): 093: * int (*presuspend)(struct dm_dirty_log *log); 094: * 095: * Payload-to-userspace: 096: * None. 097: * Payload-to-kernel: 098: * None. 099: * 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: * 371: * User-space should always use DM_ULOG_REQUEST_TYPE to acquire the 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: 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 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'. 388: */ 389: #define DM_ULOG_REQUEST_VERSION 2 390: 391: struct dm_ulog_request { 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]; 404: char padding[3]; /* Padding because DM_UUID_LEN = 129 */ 405: 406: uint32_t version; /* See DM_ULOG_REQUEST_VERSION */ 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__ */ 417: