Support for writing output in CSV format.
[virt-df.git] / virt-df / virt_df.mli
1 (** 'df' command for virtual domains. *)
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 (** This module (Virt_df) contains functions and values which are
21     used throughout the plug-ins and main code.
22 *)
23
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. *)
33
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. *)
42
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.
46 *)
47
48 (**
49    {2 Domain/device model}
50
51    The "domain/device model" that we currently understand looks
52    like this:
53
54 {v
55 domains
56   |
57   \--- host partitions / disk image files
58          ||
59        guest block devices
60          |
61          +--> guest partitions (eg. using MBR)
62          |      |
63          \-(1)->+--- filesystems (eg. ext3)
64                 |
65                 \--- PVs for LVM
66                        |||
67                      VGs and LVs
68 v}
69     
70    (1) Filesystems and PVs may also appear directly on guest
71    block devices.
72     
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.
77     
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.
82     
83    Swap space is considered to be a dumb filesystem for the purposes
84    of this discussion.
85 *)
86
87 class virtual device :
88   object
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
93   end
94   (**
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
98      table lookups.
99     
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.
105     
106      Note the very rare use of OOP in OCaml!
107   *)
108
109 class block_device : string ->
110   object
111     method name : string
112     method read : int64 -> int -> string
113     method read_bitstring : int64 -> int -> string * int * int
114     method size : int64
115   end
116     (** A concrete device which just direct-maps a file or /dev device. *)
117
118 class offset_device : string -> int64 -> int64 -> device ->
119   object
120     method name : string
121     method read : int64 -> int -> string
122     method read_bitstring : int64 -> int -> string * int * int
123     method size : int64
124   end
125     (** A concrete device which maps a linear part of an underlying device.
126
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]).
131
132         Useful for things like partitions.
133     *)
134
135 val null_device : device
136     (** The null device.  Any attempt to read generates an error. *)
137
138 type domain = {
139   dom_name : string;                    (** Domain name. *)
140   dom_id : int option;                  (** Domain ID (if running). *)
141   dom_disks : disk list;                (** Domain disks. *)
142   dom_lv_filesystems :
143     (lv * filesystem) list;             (** Domain LV filesystems. *)
144 }
145 and disk = {
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. *)
152 }
153 and disk_content =
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. *)
158     ]
159 and partitions = {
160   parts_name : string;                  (** Name of partitioning scheme. *)
161   parts : partition list;               (** Partitions. *)
162 }
163 and partition = {
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. *)
168 }
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. *)
174     ]
175 and filesystem = {
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. *)
187 }
188 and pv = {
189   lvm_plugin_id : lvm_plugin_id;        (** The LVM plug-in which detected
190                                             this. *)
191   pv_uuid : string;                     (** UUID. *)
192 }
193 and lv = {
194   lv_dev : device;                      (** Logical volume device. *)
195 }
196
197 and lvm_plugin_id
198
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). *)
202
203 val canonical_uuid : string -> string
204 (** Convert a UUID which may contain '-' characters to canonical form. *)
205
206 (** {2 Plug-in registration functions} *)
207
208 val partition_type_register : string -> (device -> partitions) -> unit
209 (** Register a partition probing plug-in. *)
210
211 val probe_for_partitions : device -> partitions option
212 (** Do a partition probe on a device.  Returns [Some partitions] or [None]. *)
213
214 val filesystem_type_register : string -> (device -> filesystem) -> unit
215 (** Register a filesystem probing plug-in. *)
216
217 val probe_for_filesystem : device -> filesystem option
218 (** Do a filesystem probe on a device.  Returns [Some filesystem] or [None]. *)
219
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.
227 *)
228
229 val probe_for_pv : device -> pv option
230 (** Do a PV probe on a device.  Returns [Some pv] or [None]. *)
231
232 val list_lvs : lvm_plugin_id -> device list -> lv list
233 (** Construct LV devices from a list of PVs. *)
234
235 (** {2 Utility functions} *)
236
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. *)
239
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.
243 *)