Parses the basic NTFS structures and prints them out.
[virt-df.git] / lib / diskimage.ml
index b08c50d..bdc3d47 100644 (file)
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *)
 
-open Printf
-open ExtList
-open Unix
+include Diskimage_impl
 
-open Int63.Operators
-
-include Diskimage_utils
-
-(* Use as the natural block size for disk images, but really we should
- * use the 'blockdev -getbsz' command to find the real block size.
+(* This just forces the plug-ins to get loaded when anyone references
+ * this library.  You need one line for each plug-in.
  *)
-let disk_block_size = ~^512
-
-let partition_types = [
-  Diskimage_mbr.plugin_id,
-    ("MBR", Diskimage_mbr.probe);
-]
-
-let filesystem_types = [
-  Diskimage_ext2.plugin_id,
-    ("Linux ext2/3", Diskimage_ext2.probe);
-  Diskimage_linux_swap.plugin_id,
-    ("Linux swap", Diskimage_linux_swap.probe);
-]
-
-let lvm_types = [
-  Diskimage_lvm2.plugin_id,
-    ("Linux LVM2", Diskimage_lvm2.probe, Diskimage_lvm2.list);
-]
-
-let name_of_parts id =
-  let name, _ = List.assoc id partition_types in
-  name
-let name_of_filesystem id =
-  let name, _ = List.assoc id filesystem_types in
-  name
-let name_of_lvm id =
-  let name, _, _ = List.assoc id lvm_types in
-  name
-
-(* Probe a device for partitions.  Returns [Some parts] or [None]. *)
-let probe_for_partitions dev =
-  if !debug then eprintf "probing for partitions on %s ...\n%!" dev#name;
-  let rec loop = function
-    | [] -> None
-    | (parts_plugin_id, (_, probe_fn)) :: rest ->
-       try Some (probe_fn dev)
-       with Not_found -> loop rest
-  in
-  let r = loop partition_types in
-  if !debug then (
-    match r with
-    | None -> eprintf "no partitions found on %s\n%!" dev#name
-    | Some { parts_plugin_id = name; parts = parts } ->
-       eprintf "found %d %s partitions on %s\n"
-         (List.length parts) name dev#name
-  );
-  r
-
-(* Probe a device for a filesystem.  Returns [Some fs] or [None]. *)
-let probe_for_filesystem dev =
-  if !debug then eprintf "probing for a filesystem on %s ...\n%!" dev#name;
-  let rec loop = function
-    | [] -> None
-    | (fs_name, (_, probe_fn)) :: rest ->
-       try Some (probe_fn dev)
-       with Not_found -> loop rest
-  in
-  let r = loop filesystem_types in
-  if !debug then (
-    match r with
-    | None -> eprintf "no filesystem found on %s\n%!" dev#name
-    | Some fs ->
-       eprintf "found a filesystem on %s:\n" dev#name;
-       eprintf "\t%s\n%!" fs.fs_plugin_id
-  );
-  r
-
-(* Probe a device for a PV.  Returns [Some lvm_name] or [None]. *)
-let probe_for_pv dev =
-  if !debug then eprintf "probing if %s is a PV ...\n%!" dev#name;
-  let rec loop = function
-    | [] -> None
-    | (lvm_name, (_, probe_fn, _)) :: 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_plugin_id = name } ->
-       eprintf "%s contains a %s PV\n%!" dev#name name
-  );
-  r
-
-let list_lvs lvm_name devs =
-  let _, _, list_lvs_fn = List.assoc lvm_name lvm_types in
-  list_lvs_fn devs
-
-(* Create machine description. *)
-let open_machine name disks =
-  let disks = List.map (
-    fun (name, path) ->
-      let dev = new block_device path disk_block_size (* XXX *) in
-      { d_name = name; d_dev = dev; d_content = `Unknown }
-  ) disks in
-  { m_name = name; m_disks = disks; m_lv_filesystems = [] }
-
-let close_machine { m_disks = m_disks } =
-  (* Only close the disks, assume all other devices are derived from them. *)
-  List.iter (fun { d_dev = d_dev } -> d_dev#close ()) m_disks
-
-let scan_machine ({ m_disks = m_disks } as machine) =
-  let m_disks = List.map (
-    fun ({ d_dev = dev } as disk) ->
-      let dev = (dev :> device) in
-      (* See if it is partitioned first. *)
-      let parts = probe_for_partitions dev in
-      match parts with
-      | Some parts ->
-         { disk with d_content = `Partitions parts }
-      | None ->
-         (* Not partitioned.  Does it contain a filesystem? *)
-         let fs = probe_for_filesystem dev in
-         match fs with
-         | Some fs ->
-             { disk with d_content = `Filesystem fs }
-         | None ->
-             (* Not partitioned, no filesystem, is it a PV? *)
-             let pv = probe_for_pv dev in
-             match pv with
-             | Some lvm_name ->
-                 { disk with d_content = `PhysicalVolume lvm_name }
-             | None ->
-                 disk (* Spare/unknown. *)
-  ) m_disks in
-
-  (* Now we have either detected partitions or a filesystem on each
-   * physical device (or perhaps neither).  See what is on those
-   * partitions.
-   *)
-  let m_disks = List.map (
-    function
-    | ({ d_dev = dev; d_content = `Partitions parts } as disk) ->
-       let ps = List.map (
-         fun p ->
-           if p.part_status = Bootable || p.part_status = Nonbootable then (
-             let fs = probe_for_filesystem p.part_dev in
-             match fs with
-             | Some fs ->
-                 { p with part_content = `Filesystem fs }
-             | None ->
-                 (* Is it a PV? *)
-                 let pv = probe_for_pv p.part_dev in
-                 match pv with
-                 | Some lvm_name ->
-                     { p with part_content = `PhysicalVolume lvm_name }
-                 | None ->
-                     p (* Spare/unknown. *)
-           ) else p
-       ) parts.parts in
-       let parts = { parts with parts = ps } in
-       { disk with d_content = `Partitions parts }
-    | disk -> disk
-  ) m_disks in
-
-  (* LVM filesystem detection
-   *
-   * Look for all disks/partitions which have been identified as PVs
-   * and pass those back to the respective LVM plugin for LV detection.
-   *
-   * (Note - a two-stage process because an LV can be spread over
-   * several PVs, so we have to detect all PVs belonging to a
-   * domain first).
-   *
-   * XXX To deal with RAID (ie. md devices) we will need to loop
-   * around here because RAID is like LVM except that they normally
-   * present as block devices which can be used by LVM.
-   *)
-  (* First: LV detection.
-   * Find all physical volumes, can be disks or partitions.
-   *)
-  let pvs_on_disks = List.filter_map (
-    function
-    | { d_dev = d_dev;
-       d_content = `PhysicalVolume pv } -> Some (pv, (d_dev :> device))
-    | _ -> None
-  ) m_disks in
-  let pvs_on_partitions = List.map (
-    function
-    | { d_content = `Partitions { parts = parts } } ->
-       List.filter_map (
-         function
-         | { part_dev = part_dev;
-             part_content = `PhysicalVolume pv } ->
-             Some (pv, part_dev)
-         | _ -> None
-       ) parts
-    | _ -> []
-  ) m_disks in
-  let lvs = List.concat (pvs_on_disks :: pvs_on_partitions) in
-
-  (* Second: filesystem on LV detection.
-   * Group the LVs by plug-in type.
-   *)
-  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 (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 (
-      fun ({ lv_dev = dev } as lv) ->
-       match probe_for_filesystem dev with
-       | Some fs -> Some (lv, fs)
-       | None -> None
-    ) lvs in
-
-  { machine with
-      m_disks = m_disks;
-      m_lv_filesystems = filesystems }
+let _ = Diskimage_ext2.id
+let _ = Diskimage_linux_swap.id
+let _ = Diskimage_linux_swsuspend.id
+let _ = Diskimage_fat.id
+let _ = Diskimage_ntfs.id
+let _ = Diskimage_lvm2.id
+let _ = Diskimage_mbr.id