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 consits from one or more tables. Table specify 21 Start, length of logical blocks and target which is used to map them to 22 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 Fuction: 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 prefered). 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 foun behind struc 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 spedcified 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 dependiences devices 180 181 Function: 182 Return set of device dependiences 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 behidn 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 Desing 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 aditional 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 2711) 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 then on 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>aditional info</key> 474 <string>...</string> 475 </dict> 476