Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: LGPL-2.0+ WITH Linux-syscall-note */
0002 /*
0003  * Copyright (C) 2006-2009 Red Hat, Inc.
0004  *
0005  * This file is released under the LGPL.
0006  */
0007 
0008 #ifndef __DM_LOG_USERSPACE_H__
0009 #define __DM_LOG_USERSPACE_H__
0010 
0011 #include <linux/types.h>
0012 #include <linux/dm-ioctl.h> /* For DM_UUID_LEN */
0013 
0014 /*
0015  * The device-mapper userspace log module consists of a kernel component and
0016  * a user-space component.  The kernel component implements the API defined
0017  * in dm-dirty-log.h.  Its purpose is simply to pass the parameters and
0018  * return values of those API functions between kernel and user-space.
0019  *
0020  * Below are defined the 'request_types' - DM_ULOG_CTR, DM_ULOG_DTR, etc.
0021  * These request types represent the different functions in the device-mapper
0022  * dirty log API.  Each of these is described in more detail below.
0023  *
0024  * The user-space program must listen for requests from the kernel (representing
0025  * the various API functions) and process them.
0026  *
0027  * User-space begins by setting up the communication link (error checking
0028  * removed for clarity):
0029  *  fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
0030  *  addr.nl_family = AF_NETLINK;
0031  *  addr.nl_groups = CN_IDX_DM;
0032  *  addr.nl_pid = 0;
0033  *  r = bind(fd, (struct sockaddr *) &addr, sizeof(addr));
0034  *  opt = addr.nl_groups;
0035  *  setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &opt, sizeof(opt));
0036  *
0037  * User-space will then wait to receive requests form the kernel, which it
0038  * will process as described below.  The requests are received in the form,
0039  * ((struct dm_ulog_request) + (additional data)).  Depending on the request
0040  * type, there may or may not be 'additional data'.  In the descriptions below,
0041  * you will see 'Payload-to-userspace' and 'Payload-to-kernel'.  The
0042  * 'Payload-to-userspace' is what the kernel sends in 'additional data' as
0043  * necessary parameters to complete the request.  The 'Payload-to-kernel' is
0044  * the 'additional data' returned to the kernel that contains the necessary
0045  * results of the request.  The 'data_size' field in the dm_ulog_request
0046  * structure denotes the availability and amount of payload data.
0047  */
0048 
0049 /*
0050  * DM_ULOG_CTR corresponds to (found in dm-dirty-log.h):
0051  * int (*ctr)(struct dm_dirty_log *log, struct dm_target *ti,
0052  *        unsigned argc, char **argv);
0053  *
0054  * Payload-to-userspace:
0055  *  A single string containing all the argv arguments separated by ' 's
0056  * Payload-to-kernel:
0057  *  A NUL-terminated string that is the name of the device that is used
0058  *  as the backing store for the log data.  'dm_get_device' will be called
0059  *  on this device.  ('dm_put_device' will be called on this device
0060  *  automatically after calling DM_ULOG_DTR.)  If there is no device needed
0061  *  for log data, 'data_size' in the dm_ulog_request struct should be 0.
0062  *
0063  * The UUID contained in the dm_ulog_request structure is the reference that
0064  * will be used by all request types to a specific log.  The constructor must
0065  * record this association with the instance created.
0066  *
0067  * When the request has been processed, user-space must return the
0068  * dm_ulog_request to the kernel - setting the 'error' field, filling the
0069  * data field with the log device if necessary, and setting 'data_size'
0070  * appropriately.
0071  */
0072 #define DM_ULOG_CTR                    1
0073 
0074 /*
0075  * DM_ULOG_DTR corresponds to (found in dm-dirty-log.h):
0076  * void (*dtr)(struct dm_dirty_log *log);
0077  *
0078  * Payload-to-userspace:
0079  *  A single string containing all the argv arguments separated by ' 's
0080  * Payload-to-kernel:
0081  *  None.  ('data_size' in the dm_ulog_request struct should be 0.)
0082  *
0083  * The UUID contained in the dm_ulog_request structure is all that is
0084  * necessary to identify the log instance being destroyed.  There is no
0085  * payload data.
0086  *
0087  * When the request has been processed, user-space must return the
0088  * dm_ulog_request to the kernel - setting the 'error' field and clearing
0089  * 'data_size' appropriately.
0090  */
0091 #define DM_ULOG_DTR                    2
0092 
0093 /*
0094  * DM_ULOG_PRESUSPEND corresponds to (found in dm-dirty-log.h):
0095  * int (*presuspend)(struct dm_dirty_log *log);
0096  *
0097  * Payload-to-userspace:
0098  *  None.
0099  * Payload-to-kernel:
0100  *  None.
0101  *
0102  * The UUID contained in the dm_ulog_request structure is all that is
0103  * necessary to identify the log instance being presuspended.  There is no
0104  * payload data.
0105  *
0106  * When the request has been processed, user-space must return the
0107  * dm_ulog_request to the kernel - setting the 'error' field and
0108  * 'data_size' appropriately.
0109  */
0110 #define DM_ULOG_PRESUSPEND             3
0111 
0112 /*
0113  * DM_ULOG_POSTSUSPEND corresponds to (found in dm-dirty-log.h):
0114  * int (*postsuspend)(struct dm_dirty_log *log);
0115  *
0116  * Payload-to-userspace:
0117  *  None.
0118  * Payload-to-kernel:
0119  *  None.
0120  *
0121  * The UUID contained in the dm_ulog_request structure is all that is
0122  * necessary to identify the log instance being postsuspended.  There is no
0123  * payload data.
0124  *
0125  * When the request has been processed, user-space must return the
0126  * dm_ulog_request to the kernel - setting the 'error' field and
0127  * 'data_size' appropriately.
0128  */
0129 #define DM_ULOG_POSTSUSPEND            4
0130 
0131 /*
0132  * DM_ULOG_RESUME corresponds to (found in dm-dirty-log.h):
0133  * int (*resume)(struct dm_dirty_log *log);
0134  *
0135  * Payload-to-userspace:
0136  *  None.
0137  * Payload-to-kernel:
0138  *  None.
0139  *
0140  * The UUID contained in the dm_ulog_request structure is all that is
0141  * necessary to identify the log instance being resumed.  There is no
0142  * payload data.
0143  *
0144  * When the request has been processed, user-space must return the
0145  * dm_ulog_request to the kernel - setting the 'error' field and
0146  * 'data_size' appropriately.
0147  */
0148 #define DM_ULOG_RESUME                 5
0149 
0150 /*
0151  * DM_ULOG_GET_REGION_SIZE corresponds to (found in dm-dirty-log.h):
0152  * __u32 (*get_region_size)(struct dm_dirty_log *log);
0153  *
0154  * Payload-to-userspace:
0155  *  None.
0156  * Payload-to-kernel:
0157  *  __u64 - contains the region size
0158  *
0159  * The region size is something that was determined at constructor time.
0160  * It is returned in the payload area and 'data_size' is set to
0161  * reflect this.
0162  *
0163  * When the request has been processed, user-space must return the
0164  * dm_ulog_request to the kernel - setting the 'error' field appropriately.
0165  */
0166 #define DM_ULOG_GET_REGION_SIZE        6
0167 
0168 /*
0169  * DM_ULOG_IS_CLEAN corresponds to (found in dm-dirty-log.h):
0170  * int (*is_clean)(struct dm_dirty_log *log, region_t region);
0171  *
0172  * Payload-to-userspace:
0173  *  __u64 - the region to get clean status on
0174  * Payload-to-kernel:
0175  *  __s64  - 1 if clean, 0 otherwise
0176  *
0177  * Payload is sizeof(__u64) and contains the region for which the clean
0178  * status is being made.
0179  *
0180  * When the request has been processed, user-space must return the
0181  * dm_ulog_request to the kernel - filling the payload with 0 (not clean) or
0182  * 1 (clean), setting 'data_size' and 'error' appropriately.
0183  */
0184 #define DM_ULOG_IS_CLEAN               7
0185 
0186 /*
0187  * DM_ULOG_IN_SYNC corresponds to (found in dm-dirty-log.h):
0188  * int (*in_sync)(struct dm_dirty_log *log, region_t region,
0189  *        int can_block);
0190  *
0191  * Payload-to-userspace:
0192  *  __u64 - the region to get sync status on
0193  * Payload-to-kernel:
0194  *  __s64 - 1 if in-sync, 0 otherwise
0195  *
0196  * Exactly the same as 'is_clean' above, except this time asking "has the
0197  * region been recovered?" vs. "is the region not being modified?"
0198  */
0199 #define DM_ULOG_IN_SYNC                8
0200 
0201 /*
0202  * DM_ULOG_FLUSH corresponds to (found in dm-dirty-log.h):
0203  * int (*flush)(struct dm_dirty_log *log);
0204  *
0205  * Payload-to-userspace:
0206  *  If the 'integrated_flush' directive is present in the constructor
0207  *  table, the payload is as same as DM_ULOG_MARK_REGION:
0208  *      __u64 [] - region(s) to mark
0209  *  else
0210  *      None
0211  * Payload-to-kernel:
0212  *  None.
0213  *
0214  * If the 'integrated_flush' option was used during the creation of the
0215  * log, mark region requests are carried as payload in the flush request.
0216  * Piggybacking the mark requests in this way allows for fewer communications
0217  * between kernel and userspace.
0218  *
0219  * When the request has been processed, user-space must return the
0220  * dm_ulog_request to the kernel - setting the 'error' field and clearing
0221  * 'data_size' appropriately.
0222  */
0223 #define DM_ULOG_FLUSH                  9
0224 
0225 /*
0226  * DM_ULOG_MARK_REGION corresponds to (found in dm-dirty-log.h):
0227  * void (*mark_region)(struct dm_dirty_log *log, region_t region);
0228  *
0229  * Payload-to-userspace:
0230  *  __u64 [] - region(s) to mark
0231  * Payload-to-kernel:
0232  *  None.
0233  *
0234  * Incoming payload contains the one or more regions to mark dirty.
0235  * The number of regions contained in the payload can be determined from
0236  * 'data_size/sizeof(__u64)'.
0237  *
0238  * When the request has been processed, user-space must return the
0239  * dm_ulog_request to the kernel - setting the 'error' field and clearing
0240  * 'data_size' appropriately.
0241  */
0242 #define DM_ULOG_MARK_REGION           10
0243 
0244 /*
0245  * DM_ULOG_CLEAR_REGION corresponds to (found in dm-dirty-log.h):
0246  * void (*clear_region)(struct dm_dirty_log *log, region_t region);
0247  *
0248  * Payload-to-userspace:
0249  *  __u64 [] - region(s) to clear
0250  * Payload-to-kernel:
0251  *  None.
0252  *
0253  * Incoming payload contains the one or more regions to mark clean.
0254  * The number of regions contained in the payload can be determined from
0255  * 'data_size/sizeof(__u64)'.
0256  *
0257  * When the request has been processed, user-space must return the
0258  * dm_ulog_request to the kernel - setting the 'error' field and clearing
0259  * 'data_size' appropriately.
0260  */
0261 #define DM_ULOG_CLEAR_REGION          11
0262 
0263 /*
0264  * DM_ULOG_GET_RESYNC_WORK corresponds to (found in dm-dirty-log.h):
0265  * int (*get_resync_work)(struct dm_dirty_log *log, region_t *region);
0266  *
0267  * Payload-to-userspace:
0268  *  None.
0269  * Payload-to-kernel:
0270  *  {
0271  *      __s64 i; -- 1 if recovery necessary, 0 otherwise
0272  *      __u64 r; -- The region to recover if i=1
0273  *  }
0274  * 'data_size' should be set appropriately.
0275  *
0276  * When the request has been processed, user-space must return the
0277  * dm_ulog_request to the kernel - setting the 'error' field appropriately.
0278  */
0279 #define DM_ULOG_GET_RESYNC_WORK       12
0280 
0281 /*
0282  * DM_ULOG_SET_REGION_SYNC corresponds to (found in dm-dirty-log.h):
0283  * void (*set_region_sync)(struct dm_dirty_log *log,
0284  *             region_t region, int in_sync);
0285  *
0286  * Payload-to-userspace:
0287  *  {
0288  *      __u64 - region to set sync state on
0289  *      __s64  - 0 if not-in-sync, 1 if in-sync
0290  *  }
0291  * Payload-to-kernel:
0292  *  None.
0293  *
0294  * When the request has been processed, user-space must return the
0295  * dm_ulog_request to the kernel - setting the 'error' field and clearing
0296  * 'data_size' appropriately.
0297  */
0298 #define DM_ULOG_SET_REGION_SYNC       13
0299 
0300 /*
0301  * DM_ULOG_GET_SYNC_COUNT corresponds to (found in dm-dirty-log.h):
0302  * region_t (*get_sync_count)(struct dm_dirty_log *log);
0303  *
0304  * Payload-to-userspace:
0305  *  None.
0306  * Payload-to-kernel:
0307  *  __u64 - the number of in-sync regions
0308  *
0309  * No incoming payload.  Kernel-bound payload contains the number of
0310  * regions that are in-sync (in a size_t).
0311  *
0312  * When the request has been processed, user-space must return the
0313  * dm_ulog_request to the kernel - setting the 'error' field and
0314  * 'data_size' appropriately.
0315  */
0316 #define DM_ULOG_GET_SYNC_COUNT        14
0317 
0318 /*
0319  * DM_ULOG_STATUS_INFO corresponds to (found in dm-dirty-log.h):
0320  * int (*status)(struct dm_dirty_log *log, STATUSTYPE_INFO,
0321  *       char *result, unsigned maxlen);
0322  *
0323  * Payload-to-userspace:
0324  *  None.
0325  * Payload-to-kernel:
0326  *  Character string containing STATUSTYPE_INFO
0327  *
0328  * When the request has been processed, user-space must return the
0329  * dm_ulog_request to the kernel - setting the 'error' field and
0330  * 'data_size' appropriately.
0331  */
0332 #define DM_ULOG_STATUS_INFO           15
0333 
0334 /*
0335  * DM_ULOG_STATUS_TABLE corresponds to (found in dm-dirty-log.h):
0336  * int (*status)(struct dm_dirty_log *log, STATUSTYPE_TABLE,
0337  *       char *result, unsigned maxlen);
0338  *
0339  * Payload-to-userspace:
0340  *  None.
0341  * Payload-to-kernel:
0342  *  Character string containing STATUSTYPE_TABLE
0343  *
0344  * When the request has been processed, user-space must return the
0345  * dm_ulog_request to the kernel - setting the 'error' field and
0346  * 'data_size' appropriately.
0347  */
0348 #define DM_ULOG_STATUS_TABLE          16
0349 
0350 /*
0351  * DM_ULOG_IS_REMOTE_RECOVERING corresponds to (found in dm-dirty-log.h):
0352  * int (*is_remote_recovering)(struct dm_dirty_log *log, region_t region);
0353  *
0354  * Payload-to-userspace:
0355  *  __u64 - region to determine recovery status on
0356  * Payload-to-kernel:
0357  *  {
0358  *      __s64 is_recovering;  -- 0 if no, 1 if yes
0359  *      __u64 in_sync_hint;  -- lowest region still needing resync
0360  *  }
0361  *
0362  * When the request has been processed, user-space must return the
0363  * dm_ulog_request to the kernel - setting the 'error' field and
0364  * 'data_size' appropriately.
0365  */
0366 #define DM_ULOG_IS_REMOTE_RECOVERING  17
0367 
0368 /*
0369  * (DM_ULOG_REQUEST_MASK & request_type) to get the request type
0370  *
0371  * Payload-to-userspace:
0372  *  A single string containing all the argv arguments separated by ' 's
0373  * Payload-to-kernel:
0374  *  None.  ('data_size' in the dm_ulog_request struct should be 0.)
0375  *
0376  * We are reserving 8 bits of the 32-bit 'request_type' field for the
0377  * various request types above.  The remaining 24-bits are currently
0378  * set to zero and are reserved for future use and compatibility concerns.
0379  *
0380  * User-space should always use DM_ULOG_REQUEST_TYPE to acquire the
0381  * request type from the 'request_type' field to maintain forward compatibility.
0382  */
0383 #define DM_ULOG_REQUEST_MASK 0xFF
0384 #define DM_ULOG_REQUEST_TYPE(request_type) \
0385     (DM_ULOG_REQUEST_MASK & (request_type))
0386 
0387 /*
0388  * DM_ULOG_REQUEST_VERSION is incremented when there is a
0389  * change to the way information is passed between kernel
0390  * and userspace.  This could be a structure change of
0391  * dm_ulog_request or a change in the way requests are
0392  * issued/handled.  Changes are outlined here:
0393  *  version 1:  Initial implementation
0394  *  version 2:  DM_ULOG_CTR allowed to return a string containing a
0395  *              device name that is to be registered with DM via
0396  *              'dm_get_device'.
0397  *  version 3:  DM_ULOG_FLUSH is capable of carrying payload for marking
0398  *          regions.  This "integrated flush" reduces the number of
0399  *          requests between the kernel and userspace by effectively
0400  *          merging 'mark' and 'flush' requests.  A constructor table
0401  *          argument ('integrated_flush') is required to turn this
0402  *          feature on, so it is backwards compatible with older
0403  *          userspace versions.
0404  */
0405 #define DM_ULOG_REQUEST_VERSION 3
0406 
0407 struct dm_ulog_request {
0408     /*
0409      * The local unique identifier (luid) and the universally unique
0410      * identifier (uuid) are used to tie a request to a specific
0411      * mirror log.  A single machine log could probably make due with
0412      * just the 'luid', but a cluster-aware log must use the 'uuid' and
0413      * the 'luid'.  The uuid is what is required for node to node
0414      * communication concerning a particular log, but the 'luid' helps
0415      * differentiate between logs that are being swapped and have the
0416      * same 'uuid'.  (Think "live" and "inactive" device-mapper tables.)
0417      */
0418     __u64 luid;
0419     char uuid[DM_UUID_LEN];
0420     char padding[3];        /* Padding because DM_UUID_LEN = 129 */
0421 
0422     __u32 version;       /* See DM_ULOG_REQUEST_VERSION */
0423     __s32 error;          /* Used to report back processing errors */
0424 
0425     __u32 seq;           /* Sequence number for request */
0426     __u32 request_type;  /* DM_ULOG_* defined above */
0427     __u32 data_size;     /* How much data (not including this struct) */
0428 
0429     char data[];
0430 };
0431 
0432 #endif /* __DM_LOG_USERSPACE_H__ */