libguestfs/0002-daemon-Fix-parsing-in-part_get_gpt_attributes.patch

135 lines
4.3 KiB
Diff
Raw Permalink Normal View History

From 8539b763639cbe80e4b248455c0c28bd8ced9cbe Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 28 Jun 2024 09:42:20 +0100
Subject: [PATCH] daemon: Fix parsing in part_get_gpt_attributes
The actual output of sfdisk --part-attrs is bizarre and doesn't match
the documentation. After looking at the source from util-linux, fix
the parsing to match what sfdisk produces.
Reported-by: Yongkui Guo
Fixes: commit c6c266a85d76dc2db90460202415790c585ac625
Fixes: https://issues.redhat.com/browse/RHEL-35998
(cherry picked from commit 24c1f7b03aab6343e6c826250269e98a6060d762)
---
daemon/sfdisk.ml | 80 +++++++++++++++++++++++++++++++--------
generator/actions_core.ml | 4 +-
2 files changed, 66 insertions(+), 18 deletions(-)
diff --git a/daemon/sfdisk.ml b/daemon/sfdisk.ml
index 2aea399aa..8c8ed2305 100644
--- a/daemon/sfdisk.ml
+++ b/daemon/sfdisk.ml
@@ -114,28 +114,76 @@ let part_get_gpt_attributes device partnum =
command "sfdisk" ["--part-attrs"; device; string_of_int partnum] in
udev_settle ();
+ let out = String.trimr out in
+
(* The output is a whitespace-separated list of:
+ *
* "RequiredPartition" (equivalent to bit 0)
* "NoBlockIOProtocol" (equivalent to bit 1)
* "LegacyBIOSBootable" (equivalent to bit 2)
- * "48", "49", ..., "63"
+ * "GUID:" followed by a comma-separated list of bit numbers
+ *
+ * eg: "LegacyBIOSBootable RequiredPartition GUID:48,49"
+ *
+ * So this is a massive PITA to parse.
*)
- let out = String.trimr out in
- let attrs = String.nsplit " " out in
- List.fold_left (
- fun bits attr ->
+ let rec loop out acc =
+ let len = String.length out in
+ eprintf "part_get_gpt_attributes: %S [%s]\n%!"
+ out (String.concat "," (List.map string_of_int acc));
+ if len = 0 then (
+ acc
+ )
+ else if Char.isspace out.[0] then (
+ let out = String.triml out in
+ loop out acc
+ )
+ else if out.[0] = ',' then (
+ let out = String.sub out 1 (len-1) in
+ loop out acc
+ )
+ else if String.is_prefix out "RequiredPartition" then (
+ let acc = 0 :: acc in
+ let out = String.sub out 17 (len-17) in
+ loop out acc
+ )
+ else if String.is_prefix out "NoBlockIOProtocol" then (
+ let acc = 1 :: acc in
+ let out = String.sub out 17 (len-17) in
+ loop out acc
+ )
+ else if String.is_prefix out "LegacyBIOSBootable" then (
+ let acc = 2 :: acc in
+ let out = String.sub out 18 (len-18) in
+ loop out acc
+ )
+ else if String.is_prefix out "GUID:" then (
+ let out = String.sub out 5 (len-5) in
+ loop out acc
+ )
+ else if Char.isdigit out.[0] then (
+ let n = String.span out "0123456789" in
+ let num, out = String.break n out in
let bit =
- match attr with
- | "" -> -1
- | "RequiredPartition" -> 0
- | "NoBlockIOProtocol" -> 1
- | "LegacyBIOSBootable" -> 2
- | n -> int_of_string n in
- if bit >= 0 then
- Int64.logor bits (Int64.shift_left 1_L bit)
- else
- bits
- ) 0_L attrs
+ try int_of_string num
+ with Failure _ ->
+ failwithf "part_get_gpt_attributes: cannot parse number %S" num in
+ let acc = bit :: acc in
+ loop out acc
+ )
+ else (
+ failwithf "part_get_gpt_attributes: cannot parse %S" out
+ )
+ in
+ let attrs = loop out [] in
+
+ let bits =
+ List.fold_left (
+ fun bits bit -> Int64.logor bits (Int64.shift_left 1_L bit)
+ ) 0_L attrs in
+ eprintf "part_get_gpt_attributes: [%s] -> %Ld\n%!"
+ (String.concat "," (List.map string_of_int attrs)) bits;
+ bits
let part_set_gpt_attributes device partnum attrs =
if partnum <= 0 then
diff --git a/generator/actions_core.ml b/generator/actions_core.ml
index 46ef1422f..ef9096772 100644
--- a/generator/actions_core.ml
+++ b/generator/actions_core.ml
@@ -8188,9 +8188,9 @@ for a useful list of partition attributes." };
tests = [
InitGPT, Always, TestResult (
[["part_set_gpt_attributes"; "/dev/sda"; "1";
- "0"];
+ (* bits 0, 2, 48 and 49 set *) "844424930131973"];
["part_get_gpt_attributes"; "/dev/sda"; "1"]],
- "ret == 0"), [];
+ "ret == 844424930131973"), [];
];
shortdesc = "get the attribute flags of a GPT partition";
longdesc = "\
--
2.43.0