1 (** Diskimage library for reading disk images. *)
2 (* (C) Copyright 2007-2008 Richard W.M. Jones, Red Hat Inc.
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.
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.
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.
21 {2 Machine/device model}
23 The "machine/device model" that we currently understand looks
29 \--- host partitions / disk image files
33 +--> guest partitions (eg. using MBR)
35 \-(1)->+--- filesystems (eg. ext3)
42 (1) Filesystems and PVs may also appear directly on guest
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.
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.
55 Swap space is considered to be a dumb filesystem for the purposes
59 class virtual device :
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.
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. *)
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
84 Note this very rare use of OOP in OCaml!
87 class block_device : string ->
91 method close : unit -> unit
92 method read : int64 -> int -> string
93 method read_bitstring : int64 -> int -> Bitmatch.bitstring
95 (** A concrete device which just direct-maps a file or /dev device. *)
97 class offset_device : string -> int64 -> int64 -> device ->
101 method close : unit -> unit
102 method read : int64 -> int -> string
103 method read_bitstring : int64 -> int -> Bitmatch.bitstring
105 (** A concrete device which maps a linear part of an underlying device.
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]).
112 Useful for things like partitions.
115 val null_device : device
116 (** The null device. Any attempt to read generates an error. *)
119 m_name : string; (** Machine name. *)
120 m_disks : disk list; (** Machine disks. *)
122 (lv * filesystem) list; (** Machine LV filesystems. *)
124 (** A 'machine' is just a convenient holder for collections of disks. *)
127 d_name : string; (** Device name (eg "hda") *)
128 d_dev : device; (** Disk device. *)
129 d_content : disk_content; (** What's on it. *)
131 (** A single physical disk image. *)
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. *)
141 parts_name : string; (** Name of partitioning scheme. *)
142 parts : partition list; (** Partitions. *)
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. *)
150 (** Partitions as found on a disk image. *)
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. *)
160 fs_name : string; (** Name of filesystem. *)
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. *)
175 lvm_plugin_id : lvm_plugin_id; (** The LVM plug-in which detected
177 pv_uuid : string; (** UUID. *)
180 lv_dev : device; (** Logical volume device. *)
182 (** Physical and logical volumes as used by LVM plug-ins. *)
186 val string_of_partition : partition -> string
187 val string_of_filesystem : filesystem -> string
188 (** Convert a partition or filesystem struct to a string (for debugging). *)
190 (** {2 Scanning functions} *)
192 val open_machine : string -> (string * string) list -> machine
193 (** [open_machine m_name devs]
194 creates a {!machine} containing the devices listed.
196 [devs] is a list of pairs of [(name, path)] elements
197 where [name] is something like ["hda"] and [path]
198 is a path to a disk image or [/dev] device.
200 This function does not do any scanning, so all disk
201 contents are just set to [`Unknown] and there are no
202 LV filesystems in the returned structure.
205 val close_machine : machine -> unit
206 (** This is a convenience function which calls the [dev#close]
207 method on any open devices owned by the machine. This just
208 has the effect of closing any file descriptors which are
209 opened by these devices.
212 val scan_machine : machine -> machine
213 (** This does a complete scan of all devices owned by a machine,
214 identifying all partitions, filesystems, physical and logical
215 volumes that are known to this library.
217 Returns an updated {!machine} structure with the scan results.
223 (** If set to true, functions emit debugging information to stderr. *)