[Libguestfs] [PATCH v3 20/23] daemon: Reimplement ‘md_detail’ API in OCaml.

Richard W.M. Jones rjones at redhat.com
Thu Jul 27 19:43:50 UTC 2017


---
 daemon/md.c               | 66 -----------------------------------------------
 daemon/md.ml              | 34 ++++++++++++++++++++++++
 daemon/md.mli             |  1 +
 generator/actions_core.ml |  1 +
 4 files changed, 36 insertions(+), 66 deletions(-)

diff --git a/daemon/md.c b/daemon/md.c
index 55461b95a..973418285 100644
--- a/daemon/md.c
+++ b/daemon/md.c
@@ -216,72 +216,6 @@ do_md_create (const char *name, char *const *devices,
 #pragma GCC diagnostic pop
 #endif
 
-char **
-do_md_detail (const char *md)
-{
-  size_t i;
-  int r;
-
-  CLEANUP_FREE char *out = NULL, *err = NULL;
-  CLEANUP_FREE_STRING_LIST char **lines = NULL;
-
-  CLEANUP_FREE_STRINGSBUF DECLARE_STRINGSBUF (ret);
-
-  const char *mdadm[] = { "mdadm", "-D", "--export", md, NULL };
-  r = commandv (&out, &err, mdadm);
-  if (r == -1) {
-    reply_with_error ("%s", err);
-    return NULL;
-  }
-
-  /* Split the command output into lines */
-  lines = split_lines (out);
-  if (lines == NULL)
-    return NULL;
-
-  /* Parse the output of mdadm -D --export:
-   * MD_LEVEL=raid1
-   * MD_DEVICES=2
-   * MD_METADATA=1.0
-   * MD_UUID=cfa81b59:b6cfbd53:3f02085b:58f4a2e1
-   * MD_NAME=localhost.localdomain:0
-   */
-  for (i = 0; lines[i] != NULL; ++i) {
-    char *line = lines[i];
-
-    /* Skip blank lines (shouldn't happen) */
-    if (line[0] == '\0') continue;
-
-    /* Split the line in 2 at the equals sign */
-    char *eq = strchr (line, '=');
-    if (eq) {
-      *eq = '\0'; eq++;
-
-      /* Remove the MD_ prefix from the key and translate the remainder to lower
-       * case */
-      if (STRPREFIX (line, "MD_")) {
-        line += 3;
-        for (char *j = line; *j != '\0'; j++) {
-          *j = c_tolower (*j);
-        }
-      }
-
-      /* Add the key/value pair to the output */
-      if (add_string (&ret, line) == -1 ||
-          add_string (&ret, eq) == -1) return NULL;
-    } else {
-      /* Ignore lines with no equals sign (shouldn't happen). Log to stderr so
-       * it will show up in LIBGUESTFS_DEBUG. */
-      fprintf (stderr, "md-detail: unexpected mdadm output ignored: %s", line);
-    }
-  }
-
-  if (end_stringsbuf (&ret) == -1)
-    return NULL;
-
-  return take_stringsbuf (&ret);
-}
-
 int
 do_md_stop (const char *md)
 {
diff --git a/daemon/md.ml b/daemon/md.ml
index caf87cf8f..1fd00ebb8 100644
--- a/daemon/md.ml
+++ b/daemon/md.ml
@@ -46,3 +46,37 @@ let list_md_devices () =
 
   (* Return the list sorted. *)
   sort_device_names devs
+
+let md_detail md =
+  let out = command "mdadm" ["-D"; "--export"; md] in
+
+  (* Split the command output into lines. *)
+  let out = String.trim out in
+  let lines = String.nsplit "\n" out in
+  let lines = List.filter ((<>) "") lines in
+
+  (* Parse the output of mdadm -D --export:
+   * MD_LEVEL=raid1
+   * MD_DEVICES=2
+   * MD_METADATA=1.0
+   * MD_UUID=cfa81b59:b6cfbd53:3f02085b:58f4a2e1
+   * MD_NAME=localhost.localdomain:0
+   *)
+  List.map (
+    fun line ->
+      (* Split the line at the equals sign. *)
+      let key, value = String.split "=" line in
+
+      (* Remove the MD_ prefix from the key and translate the
+       * remainder to lower case.
+       *)
+      let key =
+        if String.is_prefix key "MD_" then
+          String.sub key 3 (String.length key - 3)
+        else
+          key in
+      let key = String.lowercase_ascii key in
+
+      (* Add the key/value pair to the output. *)
+      (key, value)
+  ) lines
diff --git a/daemon/md.mli b/daemon/md.mli
index 56b6ea65e..8f0c79a7f 100644
--- a/daemon/md.mli
+++ b/daemon/md.mli
@@ -17,3 +17,4 @@
  *)
 
 val list_md_devices : unit -> string list
+val md_detail : string -> (string * string) list
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index db1411ff8..070a1c641 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -6606,6 +6606,7 @@ List all Linux md devices." };
   { defaults with
     name = "md_detail"; added = (1, 15, 6);
     style = RHashtable (RPlainString, RPlainString, "info"), [String (Device, "md")], [];
+    impl = OCaml "Md.md_detail";
     optional = Some "mdadm";
     shortdesc = "obtain metadata for an MD device";
     longdesc = "\
-- 
2.13.2




More information about the Libguestfs mailing list