From: Nikolay Ivanets <stenavin(a)gmail.com>
Instead of parsing 'parted' output OCaml implementation relies on the following
facts:
1. MBR partition table can hold up to 4 "primary" partitions.
2. Partition with number greater then 4 is "logical" partition.
3. Partition with number less then or equal to 4 with MBR ID 0x05 or 0x0f is
"extended" partition (
http://thestarman.pcministry.com/asm/mbr/PartTypes.htm;
https://en.wikipedia.org/wiki/Partition_type) or "primary" otherwise.
---
daemon/parted.c | 106 --------------------------------------
daemon/parted.ml | 13 +++++
generator/actions_core.ml | 1 +
3 files changed, 14 insertions(+), 106 deletions(-)
diff --git a/daemon/parted.c b/daemon/parted.c
index e5435b5ea..d67c6c507 100644
--- a/daemon/parted.c
+++ b/daemon/parted.c
@@ -602,112 +602,6 @@ do_part_get_name (const char *device, int partnum)
}
}
-char *
-do_part_get_mbr_part_type (const char *device, int partnum)
-{
- CLEANUP_FREE char *parttype;
- char *part_type;
-
- parttype = do_part_get_parttype (device);
- if (parttype == NULL)
- return NULL;
-
- /* machine parseable output by 'parted -m' did not provide
- * partition type info.
- * Use traditional style.
- */
- CLEANUP_FREE char *out = print_partition_table (device, false);
- 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] = {'\0'};
- for (i = 0, row = start; row < end; ++i, ++row) {
- if (STREQ (parttype, "gpt")) {
- memcpy (temp_type, "primary", strlen ("primary"));
- if (sscanf (lines[row], "%d%" SCNi64 "B%" SCNi64 "B%"
SCNi64 "B",
- &part_num,
- &temp_int64,
- &temp_int64,
- &temp_int64) != 4) {
- reply_with_error ("could not parse row from output of parted print command:
%s", lines[row]);
- return NULL;
- }
- } else {
- if (sscanf (lines[row], "%d%" SCNi64 "B%" SCNi64 "B%"
SCNi64 "B" "%15s",
- &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;
-}
-
static char *
extract_uuid (const char *value)
{
diff --git a/daemon/parted.ml b/daemon/parted.ml
index ce8da8a60..42ccb84c5 100644
--- a/daemon/parted.ml
+++ b/daemon/parted.ml
@@ -125,6 +125,19 @@ let part_get_parttype device =
| _ ->
failwithf "%s: cannot parse the output of parted" device
+let part_get_mbr_part_type device partnum =
+ let parttype = part_get_parttype device in
+ let mbr_id = part_get_mbr_id device partnum in
+
+ (* 0x05 - extended partition.
+ * 0x0f - extended partition using BIOS INT 13h extensions.
+ *)
+ match parttype, partnum, mbr_id with
+ | "msdos", (1|2|3|4), (0x05|0x0f) -> "extended"
+ | "msdos", (1|2|3|4), _ -> "primary"
+ | "msdos", _, _ -> "logical"
+ | _, _, _ -> "primary"
+
let part_set_gpt_attributes device partnum attributes =
if partnum <= 0 then failwith "partition number must be >= 1";
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index 394576398..a049159ec 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -9213,6 +9213,7 @@ All data will be zeroed, but metadata and the like is
preserved." };
{ defaults with
name = "part_get_mbr_part_type"; added = (1, 29, 32);
style = RString (RPlainString, "partitiontype"), [String (Device,
"device"); Int "partnum"], [];
+ impl = OCaml "Parted.part_get_mbr_part_type";
tests = [
InitEmpty, Always, TestResultString (
[["part_init"; "/dev/sda"; "mbr"];
--
2.17.0