[Libguestfs] [PATCH v2 5/7] daemon: Reimplement list_dm_devices API in OCaml.

Richard W.M. Jones
Mon, 07 Sep 2020 09:43:58 -0000

Simple refactoring.  The only annoying point is requiring an extra
module because of OCaml module dependency restrictions.
---
 .gitignore                |  1 +
 daemon/Makefile.am        |  3 ++
 daemon/lvm.c              | 76 ---------------------------------------
 daemon/lvm_dm.ml          | 39 ++++++++++++++++++++
 generator/actions_core.ml |  1 +
 5 files changed, 44 insertions(+), 76 deletions(-)

diff --git a/.gitignore b/.gitignore
index 39354de51..71a84fd9d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -164,6 +164,7 @@ Makefile.in
 /daemon/link.mli
 /daemon/listfs.mli
 /daemon/lvm.mli
+/daemon/lvm_dm.mli
 /daemon/lvm-tokenization.c
 /daemon/md.mli
 /daemon/mount.mli
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 480192e1c..038be592c 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -50,6 +50,7 @@ generator_built = \
 	link.mli \
 	listfs.mli \
 	lvm.mli \
+	lvm_dm.mli \
 	md.mli \
 	mount.mli \
 	optgroups.ml \
@@ -289,6 +290,7 @@ SOURCES_MLI = \
 	link.mli \
 	listfs.mli \
 	lvm.mli \
+	lvm_dm.mli \
 	lvm_utils.mli \
 	md.mli \
 	mount.mli \
@@ -321,6 +323,7 @@ SOURCES_ML = \
 	link.ml \
 	lvm.ml \
 	lvm_utils.ml \
+	lvm_dm.ml \
 	findfs.ml \
 	md.ml \
 	mount.ml \
diff --git a/daemon/lvm.c b/daemon/lvm.c
index a78b344db..039240866 100644
--- a/daemon/lvm.c
+++ b/daemon/lvm.c
@@ -764,82 +764,6 @@ do_lvm_canonical_lv_name (const char *device)
   return canonical;             /* caller frees */
 }

-/* List everything in /dev/mapper which *isn't* an LV (RHBZ#688062). */
-char **
-do_list_dm_devices (void)
-{
-  CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (ret);
-  struct dirent *d;
-  DIR *dir;
-  int r;
-
-  dir = opendir ("/dev/mapper");
-  if (!dir) {
-    reply_with_perror ("opendir: /dev/mapper");
-    return NULL;
-  }
-
-  while (1) {
-    CLEANUP_FREE char *devname = NULL;
-
-    errno = 0;
-    d = readdir (dir);
-    if (d == NULL) break;
-
-    /* Ignore . and .. */
-    if (STREQ (d->d_name, ".") || STREQ (d->d_name,
".."))
-      continue;
-
-    /* Ignore /dev/mapper/control which is used internally by dm. */
-    if (STREQ (d->d_name, "control"))
-      continue;
-
-    if (asprintf (&devname, "/dev/mapper/%s", d->d_name) ==
-1) {
-      reply_with_perror ("asprintf");
-      closedir (dir);
-      return NULL;
-    }
-
-    /* Ignore dm devices which are LVs. */
-    r = lv_canonical (devname, NULL);
-    if (r == -1) {
-      closedir (dir);
-      return NULL;
-    }
-    if (r)
-      continue;
-
-    /* Not an LV, so add it. */
-    if (add_string (&ret, devname) == -1) {
-      closedir (dir);
-      return NULL;
-    }
-  }
-
-  /* Did readdir fail? */
-  if (errno != 0) {
-    reply_with_perror ("readdir: /dev/mapper");
-    closedir (dir);
-    return NULL;
-  }
-
-  /* Close the directory handle. */
-  if (closedir (dir) == -1) {
-    reply_with_perror ("closedir: /dev/mapper");
-    return NULL;
-  }
-
-  /* Sort the output (may be empty). */
-  if (ret.size > 0)
-    sort_strings (ret.argv, ret.size);
-
-  /* NULL-terminate the list. */
-  if (end_stringsbuf (&ret) == -1)
-    return NULL;
-
-  return take_stringsbuf (&ret);
-}
-
 char *
 do_vgmeta (const char *vg, size_t *size_r)
 {
diff --git a/daemon/lvm_dm.ml b/daemon/lvm_dm.ml
new file mode 100644
index 000000000..474ba8377
--- /dev/null
+++ b/daemon/lvm_dm.ml
@@ -0,0 +1,39 @@
+(* guestfs-inspection
+ * Copyright (C) 2009-2020 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+open Unix
+open Printf
+
+open Std_utils
+
+open Utils
+
+(* List everything in /dev/mapper which *isn't* an LV (RHBZ#688062). *)
+let list_dm_devices () +  let ds = Sys.readdir "/dev/mapper" in
+  let ds = Array.to_list ds in
+  let ds = List.sort compare ds in
+
+  (* Ignore /dev/mapper/control which is used internally by d-m. *)
+  let ds = List.filter ((<>) "control") ds in
+
+  let ds = List.map ((^) "/dev/mapper/") ds in
+
+  (* Only keep devices which are _not_ LVs. *)
+  let ds = List.filter (fun d -> Lvm_utils.lv_canonical d = None) ds in
+  ds
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index 54156b2b8..0dec3b86d 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -6180,6 +6180,7 @@ parameter." };
   { defaults with
     name = "list_dm_devices"; added = (1, 11, 15);
     style = RStringList (RDevice, "devices"), [], [];
+    impl = OCaml "Lvm_dm.list_dm_devices";
     shortdesc = "list device mapper devices";
     longdesc = "\
 List all device mapper devices.
--
2.27.0