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