X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=lib%2Fdiskimage.ml;h=bdc3d475fd2e89456fde5bcd2505754708cfc712;hb=15ea8d7da6be553a1a21611df57466144c56f129;hp=30a7a39102c2ce7a91a34f2058b5e9c270c13fa7;hpb=3844c0e3ba0eb0e07b7ecabe7794def7dd622c2b;p=virt-df.git diff --git a/lib/diskimage.ml b/lib/diskimage.ml index 30a7a39..bdc3d47 100644 --- a/lib/diskimage.ml +++ b/lib/diskimage.ml @@ -17,223 +17,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *) -open Printf -open ExtList -open Unix +include Diskimage_impl -include Diskimage_utils - -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 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) -> - (* 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) - | _ -> 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 } +(* This just forces the plug-ins to get loaded when anyone references + * this library. You need one line for each plug-in. + *) +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