Home | History | Annotate | Line # | Download | only in doc
      1 		Device-mapper to libdevmapper protocol
      2 		
      3 
      4 
      5   1) Device mapper device in a POV of LVM it is an Logical Volume. 
      6      Logical Volume is virtual block device is made from logical blocks.
      7      These blocks are mapped to real device blocks with algorithm called 
      8      target.
      9      
     10      Functions available to dm device:
     11      	       create, remove, list, status of device.
     12 
     13   2) device mapper target is function which  defines how are Logical blocks 
     14      mapped to physical. There are many targets linear, stripe, mirror etc.
     15 
     16      Functions available to dm device:
     17      	       list available targets. They can be added with module in linux.
     18 
     19   3) dm table.
     20      Every device-mapper device consists from one or more tables.
     21      Table specifies start, length of logical blocks and target which is used
     22      to map them to physical blocks.
     23 
     24      {start} {length} {target} | {device} {target parameters}
     25      
     26      after | are target specific parameters listed. 
     27 
     28      Functions available to dm device:
     29      	       load, unload, table_status.
     30 
     31 
     32    List of available ioct calls
     33    
     34    DM_VERSION
     35    DM_REMOVE_ALL
     36    DM_LIST_DEVICES
     37    DM_DEV_CREATE
     38    DM_DEV_REMOVE
     39    DM_DEV_RENAME
     40    DM_DEV_SUSPEND
     41    DM_DEV_STATUS
     42    DM_DEV_WAIT
     43    DM_TABLE_LOAD
     44    DM_TABLE_CLEAR
     45    DM_TABLE_DEPS
     46    DM_TABLE_STATUS
     47    DM_LIST_VERSIONS
     48    DM_TARGET_MSG   
     49    DM_DEV_SET_GEOMETRY    
     50 
     51    1) DM_VERSION 
     52 
     53       in: struct dm-ioctl
     54 
     55       out: struct dm-ioctl
     56 
     57       Function:
     58 	 sends libdevmapper ioctl protocol version to kernel and ask for kernel version.
     59 	 If major and minor numbers are good we can continue.
     60 
     61    2) DM_REMOVE_ALL
     62       
     63       in: none
     64 
     65       out: none
     66 
     67       Function:
     68 	This ioctl will remove all DM devices/tables from DM driver.
     69 
     70   3) DM_LIST_DEVICES
     71      
     72      in: none
     73 	
     74      out: List of structures describing all devices created in driver.
     75 
     76      Function: 
     77        List all devices created in driver. (linux use struct dm_name_list)
     78 
     79      Implementation:
     80        Kernel driver will place list of struct dm_name_list behind 
     81        struct dm_ioctl in userspace. Kernel driver will list through
     82        the all devices and copyout info about them.
     83 
     84   4) DM_DEV_CREATE
     85      
     86      in: struct dm-ioctl(name/uuid)
     87 
     88      out: none
     89 
     90      Function:
     91        Create device in dm driver, with specified name/uuid(uuid is preferred). 
     92        (linux use struct dm_name_list)
     93        
     94  5) DM_DEV_REMOVE
     95      
     96     in: struct dm-ioctl(name/uuid)
     97 
     98     out: none
     99 
    100     Function:
    101       Remove device from dm driver list, also remove device tables.
    102 
    103  6) DM_DEV_RENAME
    104     
    105     in: struct dm-ioctl(name/uuid) and string found after dm-ioctl struct in buffer
    106 
    107     out: none
    108 
    109     Function:
    110       Rename device from name to string.
    111 
    112     Implementation:
    113        Kernel driver will find device with name from struct dm_ioctl-name/uuid.
    114        Change name of selected device to string found behind struct dm_ioctl header 
    115        in userspace buffer.
    116 
    117  7) DM_DEV_SUSPEND
    118     
    119     in: dm-ioctl(name/uuid)
    120 
    121     out: none
    122 
    123     Function: 
    124       Suspend all io's  on device, after this ioctl. Already started io's will be done.
    125       Newer can't be started.
    126 
    127  8) DM_DEV_STATUS
    128 
    129     in: dm-ioctl(name/uuid)
    130 
    131     out: dm-ioctl (minor,open_count,target_count)
    132 
    133     Function: 
    134       Return status info about selected device
    135 
    136     Implementation:
    137        Kernel driver will find device with name from struct dm_ioctl-name/uuid.
    138        Change values minor,open_count,target_count in dm_ioctl struct for 
    139        selected device.
    140 
    141  9) DM_DEV_WAIT
    142 
    143     in: dm-ioctl(name/uuid)
    144 
    145     out: none
    146 
    147     Function: 
    148       Wait for device event to happen.
    149 
    150  10) DM_TABLE_LOAD
    151 
    152      in: dm-ioctl(name/uuid),table specification
    153 
    154      out: none
    155  
    156      Function: 
    157        Load table to selected device. Table is loaded to unused slot and than switched.
    158        (linux use struct dm_target_spec)
    159        
    160      Implementation:
    161        Kernel driver will find device with name from struct dm_ioctl-name/uuid.
    162        Table is added to the inactive slot. Every device can have more than one 
    163        table loaded. Tables are stored in SLIST. This ioctl also open physical 
    164        device specified in table and add it to dm_device specific pdev list.
    165 
    166  11) DM_TABLE_CLEAR
    167 
    168      in: dm-ioctl(name/uuid)
    169 
    170      out: none
    171 
    172      Function: 
    173        Remove table from unused slot. 
    174 
    175  12) DM_TABLE_DEPS
    176 
    177      in: dm-ioctl(name/uuid)
    178 
    179      out: list of dependencies devices
    180 
    181      Function: 
    182        Return set of device dependencies e.g. mirror device for mirror target etc..
    183 
    184  13) DM_TABLE_STATUS
    185 
    186      in: dm-ioctl(name/uuid)
    187 
    188      out: list of used tables from selected devices (linux use struct dm_target_spec)
    189 
    190      Function: 
    191        List all tables in active slot in device with name name/uuid.       
    192 
    193      Implementation:
    194        Kernel driver will find device with name from struct dm_ioctl-name/uuid.
    195        DM driver will copyout dm_target_spec structures behind struct dm_ioctl.
    196 
    197  14) DM_LIST_VERSIONS	
    198      
    199      in: none
    200 
    201      out: list of all targets in device-mapper driver (linux use struct dm_target_versions)
    202 
    203      Function:
    204        List all available targets to libdevmapper.
    205 
    206      Implementation:
    207        Kernel driver will copy out known target versions.
    208 
    209  15) DM_TARGET_MSG
    210      
    211      in: message to driver (linux use struct dm_target_msg)
    212 
    213      out: none
    214 
    215      Function:
    216       Send message to kernel driver target.
    217      
    218 
    219  16) DM_DEV_SET_GEOMETRY
    220 
    221      Function:
    222        Set geometry of device-mapper driver.
    223 
    224 
    225 	    	NetBSD device-mapper driver implementation
    226 		
    227    device-mapper devices -> devs dm_dev.c
    228 
    229    This entity is created with DM_DEV_CREATE ioctl, and stores info 
    230    about every device in device mapper driver. It has two slots for 
    231    active and inactive table, list of active physical devices added 
    232    to this device and list of upcalled devices (for targets which use
    233    more than one physical device e.g. mirror, snapshot etc..).
    234 
    235    device-mapper physical devices -> pdevs dm_pdev.c
    236 
    237    This structure contains opened device VNODES. Because I physical 
    238    device can be found in more than one table loaded to different 
    239    dm devices. When device is destroyed I decrement all reference 
    240    counters for all added pdevs (I remove pdevs with ref_cnt == 0).
    241 
    242    device-mapper tables -> table  dm_table.c, dm_ioctl.c
    243    
    244    Table describe how is dm device made. What blocks are mapped with 
    245    what target. In our implementation every table contains pointer to
    246    target specific config data. These config_data are allocated in 
    247    DM_TABLE_LOAD function with target_init routine. Every table 
    248    contains pointer to used target.
    249 
    250    device-mapper targets -> target dm_target.c
    251    
    252    Target describes mapping of logical blocks to physical. It has 
    253    function pointers to function which does init, strategy, destroy,
    254    upcall functions.
    255 
    256    P.S I want to thank reinod@ for great help and guidance :).
    257    
    258 	
    259 
    260 		Design of new device-mapper ioctl interface
    261 
    262    Basic architecture of device-mapper -> libdevmapper ioctl interface is this. 
    263    Libdevmapper allocate buffer with size of data_size. At the start of this buffer 
    264    dm-ioctl structure is placed. any additional information from/to kernel are placed
    265    behind end (start of data part is pointed with data_start var.) of dm-ioctl struct. 
    266    
    267    Kernel driver then after ioctl call have to copyin data from userspace to kernel.
    268    When kernel driver want to send data back to user space library it must copyout 
    269    data from kernel.
    270 
    271 1) In Linux device-mapper ioctl interface implementation there are these ioctls.
    272 
    273    DM_VERSION                 *
    274    DM_REMOVE_ALL	      
    275    DM_LIST_DEVICES	      *
    276    DM_DEV_CREATE	      *
    277    DM_DEV_REMOVE	      *
    278    DM_DEV_RENAME	      *
    279    DM_DEV_SUSPEND	      
    280    DM_DEV_STATUS	      *
    281    DM_DEV_WAIT		      
    282    DM_TABLE_LOAD	      *
    283    DM_TABLE_CLEAR	      *
    284    DM_TABLE_DEPS	      
    285    DM_TABLE_STATUS	      *
    286    DM_LIST_VERSIONS	      *
    287    DM_TARGET_MSG   
    288    DM_DEV_SET_GEOMETRY
    289 
    290 * means implemented in current version of NetBSD device-mapper.
    291 
    292   1a) struct dm_ioctl based ioctl calls
    293         These ioctl calls communicate only with basic dm_ioctl structure. 
    294 	
    295 	  DM_VERSION
    296   	  DM_DEV_STATUS
    297 	  DM_DEV_CREATE	  
    298 
    299   Protocol structure:
    300 	  
    301   struct dm_ioctl {
    302 	uint32_t version[3];	/* device-mapper kernel/userspace version */
    303 	uint32_t data_size;	/* total size of data passed in
    304 				 * including this struct */
    305 
    306 	uint32_t data_start;	/* offset to start of data
    307 				 * relative to start of this struct */
    308 
    309 	uint32_t target_count;	/* in/out */ /* This should be set when DM_TABLE_STATUS is called */
    310 	int32_t  open_count;	/* device open count */
    311 	uint32_t flags;		/* information flags  */
    312         uint32_t event_nr;      /* event counters not implemented */
    313 	uint32_t padding;
    314 
    315 	uint64_t dev;		/* dev_t */
    316 
    317 	char name[DM_NAME_LEN];	/* device name */
    318 	char uuid[DM_UUID_LEN];	/* unique identifier for
    319 				 * the block device */
    320 
    321         void *user_space_addr;  /*this is needed for netbsd 
    322 				  because they differently 
    323 				  implement ioctl syscall*/
    324   };
    325 
    326  As SOC task I want to replace this structure with proplib dict. Proplib dict 
    327  basic structure should be:
    328 
    329  Note: I don't need data_star, data_size and use_space_addr. They are needed 
    330        for current implementation. 
    331 
    332        <dict>
    333                <key>version</key>
    334                <string>...</string>
    335 
    336                <key>target_count</key>
    337 	       <integer></integer>
    338 
    339                <key>open_count</key>
    340 	       <integer></integer>
    341 
    342                <key>flags</key>
    343 	       <integer></integer>
    344 
    345                <key>event_nr</key>
    346 	       <integer></integer>
    347 
    348 	       <key>dev</key>
    349 	       <integer></integer>
    350 	       
    351 	       <key>name</key>
    352                <string>...</string>
    353 
    354                <key>uuid</key>
    355                <string>...</string>
    356 
    357 
    358 	       <dict>
    359 	        <!-- ioctl specific data -->
    360 	       </dict>
    361        </dict>
    362 
    363     1b) DM_LIST_VERSIONS ioctl
    364 
    365     This ioctl is used to get list of supported targets from kernel. Target 
    366     define mapping of Logical blocks to physical blocks on real device.
    367     There are linear, zero, error, mirror, snapshot, multipath etc... targets.
    368 
    369     For every target kernel driver should copyout this structure to userspace.
    370 
    371     Protocol structure:
    372 
    373     struct dm_target_versions {
    374         uint32_t next;
    375         uint32_t version[3];
    376 
    377         char name[0];
    378     };
    379 
    380     Because I need more than one dm_target_version I will need one major proplib 
    381     dictionary to store children dictionaries with target data.
    382 
    383     <dict>
    384         <dict ID="id">
    385 	   <key>version</key>
    386            <string>...</string>	
    387 
    388 	   <key>name</key>
    389 	   <string>...</string>	
    390 	</dict>
    391     </dict>
    392 
    393     2a) DM_LIST_DEVICES 
    394     
    395     This ioctl is used to list all devices defined in kernel driver. 
    396 
    397     Protocol structure:
    398     
    399     struct dm_name_list {
    400         uint64_t dev;
    401         uint32_t next;          /* offset to the next record from
    402                                    the _start_ of this */
    403         char name[0];
    404     };
    405 
    406     Again because I can have more than one device in kernel driver I need one parent 
    407     dictionary and more children dictionaries.
    408 
    409         <dict>
    410           <dict ID="id">
    411 	   <key>dev</key>
    412            <integer>...</integer>	
    413 
    414 	   <key>name</key>
    415 	   <string>...</string>	
    416 	  </dict>
    417         </dict>
    418 	
    419    2b) DM_DEV_RENAME 
    420       This ioctl is called when libdevmapper want to rename device-mapper device.
    421       Libdevmapper library appends null terminated string to dm_ioctl struct in 
    422       userspace..
    423       
    424       <dict>
    425             <key>name</key>
    426       	    <string>...</string>
    427       </dict>
    428       
    429    2c) DM_DEV_CREATE, DM_DEV_REMOVE, DM_DEV_STATUS 
    430        Modify only dm_ioctl structure so I don't need to specify new structures.
    431 
    432 
    433   3a) DM_TABLE_LOAD, DM_TABLE_STATUS
    434       DM_TABLE_LOAD ioctl loads table to device. DM_TABLE_STATUS send info about 
    435       every table for selected device to userspace. Table is different for every 
    436       target basic table structure is this 
    437 
    438       {start} {length} {target} {additional information}
    439 
    440       e.g. 
    441       0 100 zero 
    442 
    443       0 100 linear /dev/wdba 384      
    444 
    445       Protocol structure:
    446 
    447       struct dm_target_spec {
    448         uint64_t sector_start;
    449         uint64_t length;
    450         int32_t status;         /* used when reading from kernel only */
    451 
    452         uint32_t next;
    453 
    454         char target_type[DM_MAX_TYPE_NAME];
    455         
    456         /*
    457          * Parameter string starts immediately after this object.
    458          * Be careful to add padding after string to ensure correct
    459          * alignment of subsequent dm_target_spec.
    460 	 */
    461       };
    462 
    463       <dict>
    464 	<key>sector_start</key>
    465 	<integer>...</integer>
    466 
    467 	<key>length</key>
    468 	<integer>...</integer>
    469 
    470 	<key>target_type</key>
    471 	<string>...</string>
    472 	
    473 	<key>additional info</key>
    474 	<string>...</string>
    475       </dict>
    476