[ `Unknown (* Not probed or unknown. *)
| `Partitions of partitions (* Contains partitions. *)
| `Filesystem of filesystem (* Contains a filesystem directly. *)
- | `PhysicalVolume of string (* Contains an LVM PV. *)
+ | `PhysicalVolume of pv (* Contains an LVM PV. *)
]
(* Partitions. *)
and partition_content =
[ `Unknown (* Not probed or unknown. *)
| `Filesystem of filesystem (* Filesystem. *)
- | `PhysicalVolume of string (* Contains an LVM PV. *)
+ | `PhysicalVolume of pv (* Contains an LVM PV. *)
]
(* Filesystems (also swap devices). *)
fs_inodes_used : int64; (* Inodes in use. *)
}
+(* Physical volumes. *)
+and pv = {
+ lvm_plugin_id : lvm_plugin_id; (* The LVM plug-in. *)
+ pv_uuid : string; (* UUID. *)
+}
+
+(* Logical volumes. *)
+and lv = {
+ lv_dev : device; (* Logical volume device. *)
+}
+
+and lvm_plugin_id = string
+
(* Convert partition, filesystem types to printable strings for debugging. *)
let string_of_partition
{ part_status = status; part_type = typ; part_dev = dev } =
let rec loop = function
| [] -> None
| (lvm_name, (probe_fn, _)) :: rest ->
- if probe_fn dev then Some lvm_name else loop rest
+ try Some (probe_fn lvm_name dev)
+ with Not_found -> loop rest
in
let r = loop !lvm_types in
if debug then (
match r with
| None -> eprintf "no PV found on %s\n%!" dev#name
- | Some lvm_name ->
- eprintf "%s contains a %s PV\n%!" dev#name lvm_name
+ | Some { lvm_plugin_id = name } ->
+ eprintf "%s contains a %s PV\n%!" dev#name name
);
r
and disk_content =
[ `Filesystem of filesystem (** Contains a direct filesystem. *)
| `Partitions of partitions (** Contains partitions. *)
- | `PhysicalVolume of string (** Contains an LVM PV. *)
+ | `PhysicalVolume of pv (** Contains an LVM PV. *)
| `Unknown (** Not probed or unknown. *)
]
and partitions = {
and partition_status = Bootable | Nonbootable | Malformed | NullEntry
and partition_content =
[ `Filesystem of filesystem (** Filesystem. *)
- | `PhysicalVolume of string (** Contains an LVM PV. *)
+ | `PhysicalVolume of pv (** Contains an LVM PV. *)
| `Unknown (** Not probed or unknown. *)
]
and filesystem = {
fs_inodes_avail : int64; (** Inodes free (available). *)
fs_inodes_used : int64; (** Inodes in use. *)
}
+and pv = {
+ lvm_plugin_id : lvm_plugin_id; (** The LVM plug-in which detected
+ this. *)
+ pv_uuid : string; (** UUID. *)
+}
+and lv = {
+ lv_dev : device; (** Logical volume device. *)
+}
+
+and lvm_plugin_id
val string_of_partition : partition -> string
val string_of_filesystem : filesystem -> string
(** Do a filesystem probe on a device. Returns [Some filesystem] or [None]. *)
val lvm_type_register :
- string -> (device -> bool) -> (device list -> device list) -> unit
+ string -> (lvm_plugin_id -> device -> pv) -> (device list -> lv list) -> unit
(** [lvm_type_register lvm_name probe_fn list_lvs_fn]
registers a new LVM type. [probe_fn] is a function which
should probe a device to find out if it contains a PV.
devices (PVs) and construct a list of LV devices.
*)
-val probe_for_pv : device -> string option
-(** Do a PV probe on a device. Returns [Some lvm_name] or [None]. *)
+val probe_for_pv : device -> pv option
+(** Do a PV probe on a device. Returns [Some pv] or [None]. *)
-val list_lvs : string -> device list -> device list
-(** Construct LV devices from a list of PVs. The first argument
- is the [lvm_name] which all PVs should belong to.
-*)
+val list_lvs : lvm_plugin_id -> device list -> lv list
+(** Construct LV devices from a list of PVs. *)
(** {2 Utility functions} *)
open Virt_df_gettext.Gettext
open Virt_df
+let plugin_name = "LVM2"
+
let sector_size = 512
let sector_size64 = 512L
let pv_label_offset = sector_size64
(* Probe to see if it's an LVM2 PV. Look for the "LABELONE" label. *)
-let rec probe_pv dev =
- try ignore (read_pv_label dev); true
- with _ -> false
+let rec probe_pv lvm_plugin_id dev =
+ try
+ let uuid = read_pv_label dev in
+ { lvm_plugin_id = lvm_plugin_id; pv_uuid = uuid }
+ with _ -> raise Not_found
and read_pv_label dev =
(* Load the second sector. *)
let bits = dev#read_bitstring pv_label_offset sector_size in
- Bitmatch.hexdump_bitstring stdout bits;
+ (*Bitmatch.hexdump_bitstring stdout bits;*)
bitmatch bits with
| labelone : 8*8 : bitstring; (* "LABELONE" *)
uuid : 32*8 : bitstring (* UUID *)
when Bitmatch.string_of_bitstring labelone = "LABELONE" &&
Bitmatch.string_of_bitstring lvm2_ver = "LVM2 001" ->
- uuid
+ Bitmatch.string_of_bitstring uuid
| _ ->
invalid_arg (sprintf "read_pv_label: %s: not an LVM2 physical volume"
dev#name)
(* Register with main code. *)
let () =
- lvm_type_register "LVM2" probe_pv list_lvs
+ lvm_type_register plugin_name probe_pv list_lvs
let pvs_on_disks = List.filter_map (
function
| { d_dev = d_dev;
- d_content = `PhysicalVolume lvm_name } -> Some (lvm_name, d_dev)
+ d_content = `PhysicalVolume pv } -> Some (pv, d_dev)
| _ -> None
) disks in
let pvs_on_partitions = List.map (
List.filter_map (
function
| { part_dev = part_dev;
- part_content = `PhysicalVolume lvm_name } ->
- Some (lvm_name, part_dev)
+ part_content = `PhysicalVolume pv } ->
+ Some (pv, part_dev)
| _ -> None
) parts
| _ -> []
let doms = List.map (
fun (dom, lvs) ->
(* Group the LVs by plug-in type. *)
- let cmp ((a:string),_) ((b:string),_) = compare a b in
+ let cmp (a,_) (b,_) = compare a b in
let lvs = List.sort ~cmp lvs in
let lvs = group_by lvs in
let lvs =
- List.map (fun (lvm_name, devs) -> list_lvs lvm_name devs) lvs in
+ List.map (fun (pv, devs) -> list_lvs pv.lvm_plugin_id devs)
+ lvs in
let lvs = List.concat lvs in
(* lvs is a list of potential LV devices. Now run them through the
* probes to see if any contain filesystems.
*)
- let filesystems = List.filter_map probe_for_filesystem lvs in
+ let filesystems =
+ List.filter_map (
+ fun { lv_dev = dev } -> probe_for_filesystem dev
+ ) lvs in
{ dom with dom_lv_filesystems = filesystems }
) doms in