Home | History | Annotate | Line # | Download | only in include
dm-log-userspace.h revision 1.1.1.1
      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