Refactor the types so we have distinct PV & LV types.
authorRichard W.M. Jones <rjones@redhat.com>
Tue, 15 Apr 2008 12:51:57 +0000 (13:51 +0100)
committerRichard W.M. Jones <rjones@redhat.com>
Tue, 15 Apr 2008 12:51:57 +0000 (13:51 +0100)
virt-df/virt_df.ml
virt-df/virt_df.mli
virt-df/virt_df_lvm2.ml
virt-df/virt_df_main.ml

index 1cd0617..f8f34ab 100644 (file)
@@ -98,7 +98,7 @@ and disk_content =
   [ `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. *)
@@ -117,7 +117,7 @@ and partition_status = Bootable | Nonbootable | Malformed | NullEntry
 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). *)
@@ -135,6 +135,19 @@ and filesystem = {
   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 } =
@@ -211,14 +224,15 @@ let probe_for_pv 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
 
index 4a9368c..b36d003 100644 (file)
@@ -132,7 +132,7 @@ and disk = {
 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 = {
@@ -148,7 +148,7 @@ and partition = {
 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 = {
@@ -164,6 +164,16 @@ 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
@@ -184,7 +194,7 @@ val probe_for_filesystem : device -> filesystem option
 (** 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.
@@ -192,13 +202,11 @@ val lvm_type_register :
     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} *)
 
index 9355597..dc97656 100644 (file)
@@ -24,21 +24,25 @@ open Printf
 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" *)
@@ -47,7 +51,7 @@ and read_pv_label dev =
     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)
@@ -61,4 +65,4 @@ let list_lvs devs = []
 
 (* Register with main code. *)
 let () =
-  lvm_type_register "LVM2" probe_pv list_lvs
+  lvm_type_register plugin_name probe_pv list_lvs
index 82fe920..9cfde39 100644 (file)
@@ -330,7 +330,7 @@ OPTIONS" in
       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 (
@@ -339,8 +339,8 @@ OPTIONS" in
            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
        | _ -> []
@@ -353,18 +353,22 @@ OPTIONS" in
   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