xref: /dragonfly/sys/dev/disk/dm/doc/design.txt (revision e98bdfd3)
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 TAILQ. 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 dm_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