[Libguestfs] [PATCH] New API: part_get_part_type for showing partition type

Chen Hanxiao
2015-03-17T06:45:46Z

This patch will add support for getting partition type
of a partiton numbered device.

Signed-off-by: Chen Hanxiao <chenhanxiao@cn.fujitsu.com>
---
 daemon/parted.c      | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++
 generator/actions.ml |  18 +++++++++
 src/MAX_PROC_NR      |   2 +-
 3 files changed, 131 insertions(+), 1 deletion(-)

diff --git a/daemon/parted.c b/daemon/parted.c
index a7bcb99..0ae6e5c 100644
--- a/daemon/parted.c
+++ b/daemon/parted.c
@@ -33,6 +33,10 @@ GUESTFSD_EXT_CMD(str_parted, parted);
 GUESTFSD_EXT_CMD(str_sfdisk, sfdisk);
 GUESTFSD_EXT_CMD(str_sgdisk, sgdisk);

+#ifndef PARTED_NO_M
+# define PARTED_NO_M 0
+#endif
+
 /* Notes:
  *
  * Parted 1.9 sends error messages to stdout, hence use of the
@@ -1022,3 +1026,111 @@ do_part_get_name (const char *device, int partnum)
   reply_with_error ("cannot get the partition name from '%s'
layouts", parttype);
   return NULL;
 }
+
+char *
+do_part_get_part_type (const char *device, int partnum)
+{
+  CLEANUP_FREE char *parttype;
+  char *part_type;
+
+  if (partnum <= 0) {
+    reply_with_error ("partition number must be >= 1");
+    return NULL;
+  }
+
+  parttype = do_part_get_parttype (device);
+  if (parttype == NULL)
+    return NULL;
+
+  if (STREQ (parttype, "gpt")) {
+    part_type = strdup("primary");
+    if (part_type == NULL) {
+      reply_with_error ("strdup failed");
+      return NULL;
+    }
+    return part_type;
+  }
+
+  /* machine parseable output by 'parted -m' did not provide
+   * partition type info.
+   * Use traditional style.
+   */
+  CLEANUP_FREE char *out = print_partition_table (device, PARTED_NO_M);
+  if (!out)
+    return NULL;
+
+  CLEANUP_FREE_STRING_LIST char **lines = split_lines (out);
+
+  if (!lines)
+    return NULL;
+
+  size_t start = 0, end = 0, row;
+
+  for (row = 0; lines[row] != NULL; ++row)
+    if (STRPREFIX (lines[row], "Number")) {
+      start = row + 1;
+      break;
+    }
+
+  if (start == 0) {
+    reply_with_error ("parted output has no \"Number\"
line");
+    return NULL;
+  }
+
+  for (row = start; lines[row] != NULL; ++row)
+    if (STREQ (lines[row], "")) {
+      end = row;
+      break;
+    }
+
+  if (end == 0) {
+    reply_with_error ("parted output has no blank after end of
table");
+    return NULL;
+  }
+
+  /* Now parse the lines. */
+  size_t i;
+  int64_t temp_int64;
+  int part_num;
+  char temp_type[16];
+  for (i = 0, row = start;  row < end; ++i, ++row) {
+    if (sscanf (lines[row], "%d%" SCNi64 "B%" SCNi64
"B%" SCNi64 "B" "%s",
+                &part_num,
+                &temp_int64,
+                &temp_int64,
+                &temp_int64,
+                temp_type) != 5) {
+      reply_with_error ("could not parse row from output of parted print
command: %s", lines[row]);
+      return NULL;
+    }
+
+    if (part_num != partnum)
+        continue;
+
+    if (STRPREFIX (temp_type, "primary")) {
+      part_type = strdup("primary");
+      if (part_type == NULL)
+          goto error;
+    } else if (STRPREFIX (temp_type, "logical")) {
+      part_type = strdup("logical");
+      if (part_type == NULL)
+          goto error;
+    } else if (STRPREFIX (temp_type, "extended")) {
+      part_type = strdup("extended");
+      if (part_type == NULL)
+          goto error;
+    } else
+        goto error;
+
+    return part_type;
+  }
+
+  if (row == end) {
+    reply_with_error ("could not find partnum: %d", partnum);
+    return NULL;
+  }
+
+  error:
+    reply_with_error ("strdup failed");
+    return NULL;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index fb971d3..72418b0 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -12522,6 +12522,24 @@ This will Enable extended inode refs." };
     longdesc = "\
 This enable skinny metadata extent refs." };

+  { defaults with
+    name = "part_get_part_type";
+    style = RString "partitiontype", [Device "device"; Int
"partnum"], [];
+    proc_nr = Some 453;
+    tests = [
+      InitEmpty, Always, TestResultString (
+        [["part_init"; "/dev/sda"; "mbr"];
+         ["part_add"; "/dev/sda"; "p";
"64"; "204799"];
+         ["part_add"; "/dev/sda"; "e";
"204800"; "614400"];
+         ["part_add"; "/dev/sda"; "l";
"204864"; "205988"];
+         ["part_get_part_type"; "/dev/sda";
"5"]], "logical"), []
+    ];
+
+    shortdesc = "get the partition type";
+    longdesc = "\
+This could get the partition type, such as primary, logical,
+on partition numbered C<partnum> on device C<device>." };
+
 ]

 (* Non-API meta-commands available only in guestfish.
diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR
index 8670c73..534b992 100644
--- a/src/MAX_PROC_NR
+++ b/src/MAX_PROC_NR
@@ -1 +1 @@
-452
+453
--
2.1.0