[Libguestfs] [PATCH v2 2/3] daemon: list-filesystems: Don't list partitions which cannot hold file system.

Mykola Ivanets stenavin at gmail.com
Thu Jan 25 23:16:20 UTC 2018


Filter out:
1. Partitioned md devices (as we do this for physial devices).
2. Extended MBR partitions.
3. LDM partitions (MBR and GPT partitions used by Windows Logical Disk Manager)
4. Microsoft Reseved Partitions.
---
 daemon/devsparts.ml  |  13 +++++++
 daemon/devsparts.mli |   1 +
 daemon/listfs.ml     | 105 +++++++++++++++++++++++++++------------------------
 3 files changed, 70 insertions(+), 49 deletions(-)

diff --git a/daemon/devsparts.ml b/daemon/devsparts.ml
index 54108bb..42dc78d 100644
--- a/daemon/devsparts.ml
+++ b/daemon/devsparts.ml
@@ -71,6 +71,19 @@ let list_devices () =
     map_block_devices ~return_md:false ((^) "/dev/") in
   sort_device_names devices
 
+let is_partitioned_device device =
+  assert (String.is_prefix device "/dev/");
+  let device = String.sub device 5 (String.length device - 5) in
+  let dir = "/sys/block/" ^ device in
+
+  try
+    (* Open the device's directory under /sys/block/<device> and
+     * look for entries starting with <device>, eg. /sys/block/sda/sda1
+     *)
+    let parts = Array.to_list (Sys.readdir dir) in
+    List.exists (fun part -> String.is_prefix part device) parts
+  with Sys_error (_) -> false
+
 let rec list_partitions () =
   let partitions = map_block_devices ~return_md:true add_partitions in
   let partitions = List.flatten partitions in
diff --git a/daemon/devsparts.mli b/daemon/devsparts.mli
index 7b669c2..d3224a1 100644
--- a/daemon/devsparts.mli
+++ b/daemon/devsparts.mli
@@ -21,5 +21,6 @@ val list_partitions : unit -> string list
 val part_to_dev : string -> string
 val part_to_partnum : string -> int
 val is_whole_device : string -> bool
+val is_partitioned_device : string -> bool
 val nr_devices : unit -> int
 val device_index : string -> int
diff --git a/daemon/listfs.ml b/daemon/listfs.ml
index 370ffb4..1349ae0 100644
--- a/daemon/listfs.ml
+++ b/daemon/listfs.ml
@@ -25,39 +25,18 @@ let rec list_filesystems () =
   let has_ldm = Ldm.available () in
 
   let devices = Devsparts.list_devices () in
-  let partitions = Devsparts.list_partitions () in
+  let devices = List.filter check_device devices in
   let mds = Md.list_md_devices () in
-
-  (* Look to see if any devices directly contain filesystems
-   * (RHBZ#590167).  However vfs-type will fail to tell us anything
-   * useful about devices which just contain partitions, so we also
-   * get the list of partitions and exclude the corresponding devices
-   * by using part-to-dev.
-   *)
-  let devices_containing_partitions = List.fold_left (
-    fun set part ->
-      StringSet.add (Devsparts.part_to_dev part) set
-  ) StringSet.empty partitions in
-  let devices = List.filter (
-    fun dev ->
-      not (StringSet.mem dev devices_containing_partitions)
-  ) devices in
+  let mds = List.filter check_device mds in
 
   (* Use vfs-type to check for filesystems on devices. *)
   let ret = List.filter_map check_with_vfs_type devices in
 
-  (* Use vfs-type to check for filesystems on partitions, but
-   * ignore MBR partition type 42 used by LDM.
-   *)
-  let ret =
-    ret @
-      List.filter_map (
-        fun part ->
-          if not has_ldm || not (is_mbr_partition_type_42 part) then
-            check_with_vfs_type part
-          else
-            None                (* ignore type 42 *)
-      ) partitions in
+  let partitions = Devsparts.list_partitions () in
+  let partitions = List.filter check_partition partitions in
+
+  (* Use vfs-type to check for filesystems on partitions. *)
+  let ret = ret @ List.filter_map check_with_vfs_type partitions in
 
   (* Use vfs-type to check for filesystems on md devices. *)
   let ret = ret @ List.filter_map check_with_vfs_type mds in
@@ -75,16 +54,61 @@ let rec list_filesystems () =
   let ret =
     if has_ldm then (
       let ldmvols = Ldm.list_ldm_volumes () in
-      let ldmparts = Ldm.list_ldm_partitions () in
       (* Use vfs-type to check for filesystems on Windows dynamic disks. *)
-      ret @
-        List.filter_map check_with_vfs_type ldmvols @
-        List.filter_map check_with_vfs_type ldmparts
+      ret @ List.filter_map check_with_vfs_type ldmvols
     )
     else ret in
 
   List.flatten ret
 
+(* Look to see if any devices directly contain filesystems
+ * (RHBZ#590167).  However vfs-type will fail to tell us anything
+ * useful about devices which just contain partitions, so we also
+ * exclude such devices.
+ *)
+and check_device device =
+  not (Devsparts.is_partitioned_device device)
+
+(* We should ignore Windows Logical Disk Manager (LDM) partitions,
+ * because these are members of a Windows dynamic disk group.  Trying
+ * to read them will cause errors (RHBZ#887520).  Assuming that
+ * libguestfs was compiled with ldm support, we'll get the filesystems
+ * on these later.  We also ignores Microsoft Reserved Partitions (MSR)
+ * and extended MBR partitions because they don't contain filesystem.
+ *)
+and check_partition partition =
+  try
+    (* Windows Logical Disk Manager metadata partition. *)
+    let gpt_ldm_metadata = "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3" in
+    (* Windows Logical Disk Manager data partition. *)
+    let gpt_ldm_data = "AF9B60A0-1431-4F62-BC68-3311714A69AD" in
+    (* Microsoft Reserved Partition. *)
+    let gpt_msr = "E3C9E316-0B5C-4DB8-817D-F92DF00215AE" in
+
+    let device = Devsparts.part_to_dev partition in
+    let partnum = Devsparts.part_to_partnum partition in
+
+    let parttype = Parted.part_get_parttype device in
+    let is_gpt = parttype = "gpt" in
+    let is_mbr = parttype = "msdos" in
+
+    (* MBR partition id will be converted into corresponding GPT type. *)
+    let gpt_type = Parted.part_get_gpt_type device partnum in
+
+    let is_ldm = gpt_type = gpt_ldm_metadata || gpt_type = gpt_ldm_data in
+    let is_ldm = Ldm.available () && (is_gpt || is_mbr) && is_ldm in
+    let is_msr = is_gpt && gpt_type = gpt_msr in
+
+    let mbr_type = Parted.part_get_mbr_part_type device partnum in
+    let is_extended = mbr_type = "extended" in
+
+    not (is_ldm || is_msr || is_extended)
+  with exn ->
+        if verbose () then
+          eprintf "check_partition: %s: %s\n"
+            partition (Printexc.to_string exn);
+        true
+
 (* Use vfs-type to check for a filesystem of some sort of [device].
  * Returns [Some [device, vfs_type; ...]] if found (there may be
  * multiple devices found in the case of btrfs), else [None] if nothing
@@ -140,20 +164,3 @@ and check_with_vfs_type device =
 
   else
     Some [mountable, vfs_type]
-
-(* We should ignore partitions that have MBR type byte 0x42, because
- * these are members of a Windows dynamic disk group.  Trying to read
- * them will cause errors (RHBZ#887520).  Assuming that libguestfs was
- * compiled with ldm support, we'll get the filesystems on these later.
- *)
-and is_mbr_partition_type_42 partition =
-  try
-    let partnum = Devsparts.part_to_partnum partition in
-    let device = Devsparts.part_to_dev partition in
-    let mbr_id = Parted.part_get_mbr_id device partnum in
-    mbr_id = 0x42
-  with exn ->
-     if verbose () then
-       eprintf "is_mbr_partition_type_42: %s: %s\n"
-               partition (Printexc.to_string exn);
-     false
-- 
2.9.5




More information about the Libguestfs mailing list