1 (** 'df' command for virtual domains. *)
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.
20 (** This module (Virt_df) contains functions and values which are
21 used throughout the plug-ins and main code.
24 val ( +* ) : int32 -> int32 -> int32
25 val ( -* ) : int32 -> int32 -> int32
26 val ( ** ) : int32 -> int32 -> int32
27 val ( /* ) : int32 -> int32 -> int32
28 val ( +^ ) : int64 -> int64 -> int64
29 val ( -^ ) : int64 -> int64 -> int64
30 val ( *^ ) : int64 -> int64 -> int64
31 val ( /^ ) : int64 -> int64 -> int64
32 (** int32 and int64 infix operators for convenience. *)
34 val debug : bool ref (** If true, emit debug info to stderr*)
35 val uri : string option ref (** Hypervisor/libvirt URI. *)
36 val inodes : bool ref (** Display inodes. *)
37 val human : bool ref (** Display human-readable. *)
38 val all : bool ref (** Show all or just active domains. *)
39 val test_files : string list ref (** In test mode (-t) list of files. *)
40 val csv_mode : bool ref (** CSV mode. *)
41 (** State of command line arguments. *)
43 val csv_write : (out_channel -> string list -> unit) option ref
44 (** If virt_df_csv.ml is compiled in then this hook is overridden with
45 a function to write a single line to a CSV file.
49 {2 Domain/device model}
51 The "domain/device model" that we currently understand looks
57 \--- host partitions / disk image files
61 +--> guest partitions (eg. using MBR)
63 \-(1)->+--- filesystems (eg. ext3)
70 (1) Filesystems and PVs may also appear directly on guest
73 Partition schemes (eg. MBR) and filesystems register themselves
74 with this main module and they are queried first to get an idea
75 of the physical devices, partitions and filesystems potentially
76 available to the guest.
78 Volume management schemes (eg. LVM2) register themselves here
79 and are called later with "spare" physical devices and partitions
80 to see if they contain LVM data. If this results in additional
81 logical volumes then these are checked for filesystems.
83 Swap space is considered to be a dumb filesystem for the purposes
87 class virtual device :
89 method virtual name : string
90 method virtual read : int64 -> int -> string
91 method read_bitstring : int64 -> int -> string * int * int
92 method virtual size : int64
95 A virtual (or physical!) device, encapsulating any translation
96 that has to be done to access the device. eg. For partitions
97 there is a simple offset, but for LVM you may need complicated
100 We keep the underlying file descriptors open for the duration
101 of the program. There aren't likely to be many of them, and
102 the program is short-lived, and it's easier than trying to
103 track which device is using what fd. As a result, there is no
104 need for any close/deallocation function.
106 Note the very rare use of OOP in OCaml!
109 class block_device : string ->
112 method read : int64 -> int -> string
113 method read_bitstring : int64 -> int -> string * int * int
116 (** A concrete device which just direct-maps a file or /dev device. *)
118 class offset_device : string -> int64 -> int64 -> device ->
121 method read : int64 -> int -> string
122 method read_bitstring : int64 -> int -> string * int * int
125 (** A concrete device which maps a linear part of an underlying device.
127 [new offset_device name start size dev] creates a new
128 device which maps bytes from [start] to [start+size-1]
129 of the underlying device [dev] (ie. in this device they
130 appear as bytes [0] to [size-1]).
132 Useful for things like partitions.
135 val null_device : device
136 (** The null device. Any attempt to read generates an error. *)
139 dom_name : string; (** Domain name. *)
140 dom_id : int option; (** Domain ID (if running). *)
141 dom_disks : disk list; (** Domain disks. *)
143 (lv * filesystem) list; (** Domain LV filesystems. *)
146 d_type : string option; (** The <disk type=...> *)
147 d_device : string; (** The <disk device=...> (eg "disk") *)
148 d_source : string; (** The <source file=... or dev> *)
149 d_target : string; (** The <target dev=...> (eg "hda") *)
150 d_dev : device; (** Disk device. *)
151 d_content : disk_content; (** What's on it. *)
154 [ `Filesystem of filesystem (** Contains a direct filesystem. *)
155 | `Partitions of partitions (** Contains partitions. *)
156 | `PhysicalVolume of pv (** Contains an LVM PV. *)
157 | `Unknown (** Not probed or unknown. *)
160 parts_name : string; (** Name of partitioning scheme. *)
161 parts : partition list; (** Partitions. *)
164 part_status : partition_status; (** Bootable, etc. *)
165 part_type : int; (** Partition filesystem type. *)
166 part_dev : device; (** Partition device. *)
167 part_content : partition_content; (** What's on it. *)
169 and partition_status = Bootable | Nonbootable | Malformed | NullEntry
170 and partition_content =
171 [ `Filesystem of filesystem (** Filesystem. *)
172 | `PhysicalVolume of pv (** Contains an LVM PV. *)
173 | `Unknown (** Not probed or unknown. *)
176 fs_name : string; (** Name of filesystem. *)
177 fs_block_size : int64; (** Block size (bytes). *)
178 fs_blocks_total : int64; (** Total blocks. *)
179 fs_is_swap : bool; (** If swap, following not valid. *)
180 fs_blocks_reserved : int64; (** Blocks reserved for super-user. *)
181 fs_blocks_avail : int64; (** Blocks free (available). *)
182 fs_blocks_used : int64; (** Blocks in use. *)
183 fs_inodes_total : int64; (** Total inodes. *)
184 fs_inodes_reserved : int64; (** Inodes reserved for super-user. *)
185 fs_inodes_avail : int64; (** Inodes free (available). *)
186 fs_inodes_used : int64; (** Inodes in use. *)
189 lvm_plugin_id : lvm_plugin_id; (** The LVM plug-in which detected
191 pv_uuid : string; (** UUID. *)
194 lv_dev : device; (** Logical volume device. *)
199 val string_of_partition : partition -> string
200 val string_of_filesystem : filesystem -> string
201 (** Convert a partition or filesystem struct to a string (for debugging). *)
203 val canonical_uuid : string -> string
204 (** Convert a UUID which may contain '-' characters to canonical form. *)
206 (** {2 Plug-in registration functions} *)
208 val partition_type_register : string -> (device -> partitions) -> unit
209 (** Register a partition probing plug-in. *)
211 val probe_for_partitions : device -> partitions option
212 (** Do a partition probe on a device. Returns [Some partitions] or [None]. *)
214 val filesystem_type_register : string -> (device -> filesystem) -> unit
215 (** Register a filesystem probing plug-in. *)
217 val probe_for_filesystem : device -> filesystem option
218 (** Do a filesystem probe on a device. Returns [Some filesystem] or [None]. *)
220 val lvm_type_register :
221 string -> (lvm_plugin_id -> device -> pv) -> (device list -> lv list) -> unit
222 (** [lvm_type_register lvm_name probe_fn list_lvs_fn]
223 registers a new LVM type. [probe_fn] is a function which
224 should probe a device to find out if it contains a PV.
225 [list_lvs_fn] is a function which should take a list of
226 devices (PVs) and construct a list of LV devices.
229 val probe_for_pv : device -> pv option
230 (** Do a PV probe on a device. Returns [Some pv] or [None]. *)
232 val list_lvs : lvm_plugin_id -> device list -> lv list
233 (** Construct LV devices from a list of PVs. *)
235 (** {2 Utility functions} *)
237 val group_by : ?cmp:('a -> 'a -> int) -> ('a * 'b) list -> ('a * 'b list) list
238 (** Group a sorted list of pairs by the first element of the pair. *)
240 val range : int -> int -> int list
241 (** [range a b] returns the list of integers [a <= i < b].
242 If [a >= b] then the empty list is returned.