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