[Libguestfs] [PATCH v6 23/41] daemon: Reimplement ‘part_get_mbr_id’ API in OCaml.

Richard W.M. Jones
Thu, 15 Jun 2017 17:06:13 -0000

---
 daemon/Makefile.am        |  2 ++
 daemon/parted.c           | 42 ------------------------------------
 daemon/parted.ml          | 55 +++++++++++++++++++++++++++++++++++++++++++++++
 daemon/parted.mli         | 19 ++++++++++++++++
 generator/actions_core.ml |  1 +
 5 files changed, 77 insertions(+), 42 deletions(-)

diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index ae31bf356..7e06daa02 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -267,6 +267,7 @@ SOURCES_MLI = \
 	link.mli \
 	mount.mli \
 	mountable.mli \
+	parted.mli \
 	utils.mli

 SOURCES_ML = \
@@ -281,6 +282,7 @@ SOURCES_ML = \
 	is.ml \
 	link.ml \
 	mount.ml \
+	parted.ml \
 	callbacks.ml \
 	daemon.ml

diff --git a/daemon/parted.c b/daemon/parted.c
index 03e83cb32..a1e5c81cf 100644
--- a/daemon/parted.c
+++ b/daemon/parted.c
@@ -521,48 +521,6 @@ test_sfdisk_has_part_type (void)
   return tested;
 }

-/* Currently we use sfdisk for getting and setting the ID byte.  In
- * future, extend parted to provide this functionality.  As a result
- * of using sfdisk, this won't work for non-MBR-style partitions, but
- * that limitation is noted in the documentation and we can extend it
- * later without breaking the ABI.
- */
-int
-do_part_get_mbr_id (const char *device, int partnum)
-{
-  if (partnum <= 0) {
-    reply_with_error ("partition number must be >= 1");
-    return -1;
-  }
-
-  const char *param = test_sfdisk_has_part_type () ? "--part-type" :
"--print-id";
-
-  char partnum_str[16];
-  snprintf (partnum_str, sizeof partnum_str, "%d", partnum);
-
-  CLEANUP_FREE char *out = NULL, *err = NULL;
-  int r;
-
-  udev_settle ();
-
-  r = command (&out, &err, str_sfdisk, param, device, partnum_str,
NULL);
-  if (r == -1) {
-    reply_with_error ("sfdisk %s: %s", param, err);
-    return -1;
-  }
-
-  udev_settle ();
-
-  /* It's printed in hex ... */
-  unsigned id;
-  if (sscanf (out, "%x", &id) != 1) {
-    reply_with_error ("sfdisk --print-id: cannot parse output: %s",
out);
-    return -1;
-  }
-
-  return id;
-}
-
 int
 do_part_set_mbr_id (const char *device, int partnum, int idbyte)
 {
diff --git a/daemon/parted.ml b/daemon/parted.ml
new file mode 100644
index 000000000..6be41cf66
--- /dev/null
+++ b/daemon/parted.ml
@@ -0,0 +1,55 @@
+(* guestfs-inspection
+ * Copyright (C) 2009-2017 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 Scanf
+
+open Std_utils
+
+open Utils
+
+(* Test if [sfdisk] is recent enough to have [--part-type], to be used
+ * instead of [--print-id] and [--change-id].
+ *)
+let test_sfdisk_has_part_type = lazy (
+  let out = command "sfdisk" ["--help"] in
+  String.find out "--part-type" >= 0
+)
+
+(* Currently we use sfdisk for getting and setting the ID byte.  In
+ * future, extend parted to provide this functionality.  As a result
+ * of using sfdisk, this won't work for non-MBR-style partitions, but
+ * that limitation is noted in the documentation and we can extend it
+ * later without breaking the ABI.
+ *)
+let part_get_mbr_id device partnum +  if partnum <= 0 then
+    failwith "partition number must be >= 1";
+
+  let param +    if Lazy.force test_sfdisk_has_part_type then
+      "--part-type"
+    else
+      "--print-id" in
+
+  udev_settle ();
+  let out +    command "sfdisk" [param; device; string_of_int
partnum] in
+  udev_settle ();
+
+  (* It's printed in hex, possibly with a leading space. *)
+  sscanf out " %x" identity
diff --git a/daemon/parted.mli b/daemon/parted.mli
new file mode 100644
index 000000000..33eb6d30d
--- /dev/null
+++ b/daemon/parted.mli
@@ -0,0 +1,19 @@
+(* guestfs-inspection
+ * Copyright (C) 2009-2017 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.
+ *)
+
+val part_get_mbr_id : string -> int -> int
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index f33bc5320..4bf0c7b70 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -5513,6 +5513,7 @@ See also C<guestfs_part_set_bootable>." };
   { defaults with
     name = "part_get_mbr_id"; added = (1, 3, 2);
     style = RInt "idbyte", [String (Device, "device"); Int
"partnum"], [];
+    impl = OCaml "Parted.part_get_mbr_id";
     fish_output = Some FishOutputHexadecimal;
     tests = [
       InitEmpty, Always, TestResult (
--
2.13.0