You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
135 lines
4.3 KiB
135 lines
4.3 KiB
1 month ago
|
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
|
||
|
|