Added some examples.
[virt-df.git] / lib / diskimage.mli
1 (** Diskimage library for reading disk images. *)
2 (* (C) Copyright 2007-2008 Richard W.M. Jones, Red Hat Inc.
3    http://libvirt.org/
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *)
19
20 (**
21    {2 Examples}
22
23 {[
24   let machine = open_machine "host" ["hda", "/dev/hda"] in
25   let machine = scan_machine machine in
26   (* do what you want with the scan results ... *)
27   close_machine machine
28 ]}
29 *)
30
31 (**
32    {2 Machine/device model}
33
34    The "machine/device model" that we currently understand looks
35    like this:
36
37 {v
38 machines
39   |
40   \--- host partitions / disk image files
41          ||
42        guest block devices
43          |
44          +--> guest partitions (eg. using MBR)
45          |      |
46          \-(1)->+--- filesystems (eg. ext3)
47                 |
48                 \--- PVs for LVM
49                        |||
50                      VGs and LVs
51 v}
52
53    (1) Filesystems and PVs may also appear directly on guest
54    block devices.
55
56    Partition schemes (eg. MBR) and filesystems register themselves
57    with this main module and they are queried first to get an idea
58    of the physical devices, partitions and filesystems potentially
59    available to the guest.
60
61    Volume management schemes (eg. LVM2) register themselves here
62    and are called later with "spare" physical devices and partitions
63    to see if they contain LVM data.  If this results in additional
64    logical volumes then these are checked for filesystems.
65
66    Swap space is considered to be a dumb filesystem for the purposes
67    of this discussion.
68 *)
69
70 class virtual device :
71   object
72     method virtual name : string
73       (** Return some printable name for the device. *)
74     method virtual size : int64
75       (** Return the size of the device in bytes.
76
77           Note: For some types of devices, the device may have
78           "holes", alignment requirements, etc. so this method doesn't
79           imply that every byte from [0..size-1] is readable. *)
80     method close : unit -> unit
81       (** Close the device.  This must be called to fully free up
82           any resources used by the device. *)
83     method virtual read : int64 -> int -> string
84       (** [read offset len] reads len bytes starting at offset. *)
85     method read_bitstring : int64 -> int -> Bitmatch.bitstring
86       (** [read_bitstring] is the same as [read] but returns
87           a pa_bitmatch-style bitstring. *)
88   end
89   (**
90      A virtual (or physical!) device, encapsulating any translation
91      that has to be done to access the device.  eg. For partitions
92      there is a simple offset, but for LVM you may need complicated
93      table lookups.
94     
95      Note this very rare use of OOP in OCaml!
96   *)
97
98 class block_device : string ->
99   object
100     method name : string
101     method size : int64
102     method close : unit -> unit
103     method read : int64 -> int -> string
104     method read_bitstring : int64 -> int -> Bitmatch.bitstring
105   end
106     (** A concrete device which just direct-maps a file or /dev device. *)
107
108 class offset_device : string -> int64 -> int64 -> device ->
109   object
110     method name : string
111     method size : int64
112     method close : unit -> unit
113     method read : int64 -> int -> string
114     method read_bitstring : int64 -> int -> Bitmatch.bitstring
115   end
116     (** A concrete device which maps a linear part of an underlying device.
117
118         [new offset_device name start size dev] creates a new
119         device which maps bytes from [start] to [start+size-1]
120         of the underlying device [dev] (ie. in this device they
121         appear as bytes [0] to [size-1]).
122
123         Useful for things like partitions.
124     *)
125
126 val null_device : device
127     (** The null device.  Any attempt to read generates an error. *)
128
129 type machine = {
130   m_name : string;                      (** Machine name. *)
131   m_disks : disk list;                  (** Machine disks. *)
132   m_lv_filesystems :
133     (lv * filesystem) list;             (** Machine LV filesystems. *)
134 }
135     (** A 'machine' is just a convenient holder for collections of disks. *)
136
137 and disk = {
138   d_name : string;                      (** Device name (eg "hda") *)
139   d_dev : device;                       (** Disk device. *)
140   d_content : disk_content;             (** What's on it. *)
141 }
142     (** A single physical disk image. *)
143
144 and disk_content =
145     [ `Filesystem of filesystem         (** Contains a direct filesystem. *)
146     | `Partitions of partitions         (** Contains partitions. *)
147     | `PhysicalVolume of pv             (** Contains an LVM PV. *)
148     | `Unknown                          (** Not probed or unknown. *)
149     ]
150
151 and partitions = {
152   parts_plugin_id : parts_plugin_id;    (** Partitioning scheme. *)
153   parts : partition list;               (** Partitions. *)
154 }
155 and partition = {
156   part_status : partition_status;       (** Bootable, etc. *)
157   part_type : int;                      (** Partition filesystem type. *)
158   part_dev : device;                    (** Partition device. *)
159   part_content : partition_content;     (** What's on it. *)
160 }
161     (** Partitions as found on a disk image. *)
162
163 and partition_status = Bootable | Nonbootable | Malformed | NullEntry
164 and partition_content =
165     [ `Filesystem of filesystem         (** Filesystem. *)
166     | `PhysicalVolume of pv             (** Contains an LVM PV. *)
167     | `Unknown                          (** Not probed or unknown. *)
168     ]
169
170 and filesystem = {
171   fs_plugin_id : fs_plugin_id;          (** Filesystem type. *)
172   fs_block_size : int64;                (** Block size (bytes). *)
173   fs_blocks_total : int64;              (** Total blocks. *)
174   fs_is_swap : bool;                    (** If swap, following not valid. *)
175   fs_blocks_reserved : int64;           (** Blocks reserved for super-user. *)
176   fs_blocks_avail : int64;              (** Blocks free (available). *)
177   fs_blocks_used : int64;               (** Blocks in use. *)
178   fs_inodes_total : int64;              (** Total inodes. *)
179   fs_inodes_reserved : int64;           (** Inodes reserved for super-user. *)
180   fs_inodes_avail : int64;              (** Inodes free (available). *)
181   fs_inodes_used : int64;               (** Inodes in use. *)
182 }
183     (** A filesystem. *)
184
185 and pv = {
186   lvm_plugin_id : lvm_plugin_id;        (** The LVM plug-in which detected
187                                             this. *)
188   pv_uuid : string;                     (** UUID. *)
189 }
190 and lv = {
191   lv_dev : device;                      (** Logical volume device. *)
192 }
193     (** Physical and logical volumes as used by LVM plug-ins. *)
194
195 and parts_plugin_id
196 and fs_plugin_id
197 and lvm_plugin_id
198   (** Opaque IDs used to refer to the plug-ins. *)
199
200 val name_of_parts : parts_plugin_id -> string
201 val name_of_filesystem : fs_plugin_id -> string
202 val name_of_lvm : lvm_plugin_id -> string
203   (** Convert plug-in IDs to printable strings. *)
204
205 (** {2 Scanning functions} *)
206
207 val open_machine : string -> (string * string) list -> machine
208   (** [open_machine m_name devs]
209       creates a {!machine} containing the devices listed.
210
211       [devs] is a list of pairs of [(name, path)] elements
212       where [name] is something like ["hda"] and [path]
213       is a path to a disk image or [/dev] device.
214
215       This function does not do any scanning, so all disk
216       contents are just set to [`Unknown] and there are no
217       LV filesystems in the returned structure.
218   *)
219
220 val close_machine : machine -> unit
221   (** This is a convenience function which calls the [dev#close]
222       method on any open devices owned by the machine.  This just
223       has the effect of closing any file descriptors which are
224       opened by these devices.
225   *)
226
227 val scan_machine : machine -> machine
228   (** This does a complete scan of all devices owned by a machine,
229       identifying all partitions, filesystems, physical and logical
230       volumes that are known to this library.
231
232       Returns an updated {!machine} structure with the scan results.
233   *)
234
235 (** {2 Debugging} *)
236
237 val debug : bool ref
238   (** If set to true, functions emit debugging information to stderr. *)