dm - Import verbatim from NetBSD
[dragonfly.git] / sys / dev / disk / dm / doc / design.txt
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>