design.txt revision 1.2 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
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 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