Allow reading and setting the GPT partition attribute flags. --- daemon/parted.ml | 18 +++++++++++++++++- daemon/parted.mli | 3 +++ generator/actions_core.ml | 40 ++++++++++++++++++++++++++++++++++++++++ generator/proc_nr.ml | 2 ++ lib/MAX_PROC_NR | 2 +- 5 files changed, 63 insertions(+), 2 deletions(-) diff --git a/daemon/parted.ml b/daemon/parted.ml index cf1a54a08..5f553c2da 100644 --- a/daemon/parted.ml +++ b/daemon/parted.ml @@ -124,7 +124,19 @@ let part_get_parttype device = | _ -> failwithf "%s: cannot parse the output of parted" device -let hex_chars = "0123456789ABCDEF" +let part_set_gpt_attributes device partnum attributes = + if partnum <= 0 then failwith "partition number must be >= 1"; + + udev_settle (); + + let arg = string_of_int partnum ^ ":=:" ^ attributes in + let r, _, err = + commandr ~fold_stdout_on_stderr:true + "sgdisk" [ device; "-A"; arg ] in + if r <> 0 then + failwithf "sgdisk: %s" err; + + udev_settle () let rec part_get_gpt_type device partnum = sgdisk_info_extract_field device partnum "Partition GUID code" @@ -132,6 +144,8 @@ let rec part_get_gpt_type device partnum = and part_get_gpt_guid device partnum = sgdisk_info_extract_field device partnum "Partition unique GUID" ("-" ^ hex_chars) +and part_get_gpt_attributes device partnum = + sgdisk_info_extract_field device partnum "Attribute flags" hex_chars and sgdisk_info_extract_field device partnum field chars = if partnum <= 0 then failwith "partition number must be >= 1"; @@ -178,6 +192,8 @@ and sgdisk_info_extract_field device partnum field chars = in loop lines +and hex_chars = "0123456789ABCDEF" + and extract_string chars value = (* The value contains only valid GUID characters. *) String.sub value 0 (String.span value chars) diff --git a/daemon/parted.mli b/daemon/parted.mli index cbcb7b503..300adfa75 100644 --- a/daemon/parted.mli +++ b/daemon/parted.mli @@ -30,3 +30,6 @@ val part_get_parttype : string -> string val part_get_gpt_type : string -> int -> string val part_get_gpt_guid : string -> int -> string +val part_get_gpt_attributes : string -> int -> string + +val part_set_gpt_attributes : string -> int -> string -> unit diff --git a/generator/actions_core.ml b/generator/actions_core.ml index 02759a6b7..786953d0c 100644 --- a/generator/actions_core.ml +++ b/generator/actions_core.ml @@ -8265,6 +8265,46 @@ Return the type GUID of numbered GPT partition C<partnum>. For MBR partitions, return an appropriate GUID corresponding to the MBR type. Behaviour is undefined for other partition types." }; + { defaults with + name = "part_set_gpt_attributes"; added = (1, 21, 1); + style = RErr, [String (Device, "device"); Int "partnum"; String (PlainString, "attributes")], []; + impl = OCaml "Parted.part_set_gpt_attributes"; + optional = Some "gdisk"; + tests = [ + InitGPT, Always, TestLastFail ( + [["part_set_gpt_attributes"; "/dev/sda"; "1"; "foo"]]), []; + InitGPT, Always, TestResultString ( + [["part_set_gpt_attributes"; "/dev/sda"; "1"; + "0000000000000004"]; + ["part_get_gpt_attributes"; "/dev/sda"; "1"]], + "0000000000000004"), []; + ]; + shortdesc = "set the attribute flags of a GPT partition"; + longdesc = "\ +Set the attribute flags of numbered GPT partition C<partnum> to C<guid>. Return an +error if the partition table of C<device> isn't GPT, or if C<attributes> is not a +valid hexadecimal value. + +See L<https://en.wikipedia.org/wiki/GUID_Partition_Table#Partition_entries> +for a useful list of partition attributes." }; + + { defaults with + name = "part_get_gpt_attributes"; added = (1, 21, 1); + style = RString (RPlainString, "attributes"), [String (Device, "device"); Int "partnum"], []; + impl = OCaml "Parted.part_get_gpt_attributes"; + optional = Some "gdisk"; + tests = [ + InitGPT, Always, TestResultString ( + [["part_set_gpt_attributes"; "/dev/sda"; "1"; + "0000000000000000"]; + ["part_get_gpt_attributes"; "/dev/sda"; "1"]], + "0000000000000004"), []; + ]; + shortdesc = "get the attribute flags of a GPT partition"; + longdesc = "\ +Return the attribute flags of numbered GPT partition C<partnum> as a hexadecimal bit mask. +For MBR partitions, return all flags set to 0." }; + { defaults with name = "rename"; added = (1, 21, 5); style = RErr, [String (Pathname, "oldpath"); String (Pathname, "newpath")], []; diff --git a/generator/proc_nr.ml b/generator/proc_nr.ml index 3e393da73..9e16ab14a 100644 --- a/generator/proc_nr.ml +++ b/generator/proc_nr.ml @@ -510,6 +510,8 @@ let proc_nr = [ 500, "inspect_get_mountpoints"; 501, "inspect_get_filesystems"; 502, "inspect_get_drive_mappings"; +503, "part_set_gpt_attributes"; +504, "part_get_gpt_attributes"; ] (* End of list. If adding a new entry, add it at the end of the list diff --git a/lib/MAX_PROC_NR b/lib/MAX_PROC_NR index cc5027eed..3091e8eea 100644 --- a/lib/MAX_PROC_NR +++ b/lib/MAX_PROC_NR @@ -1 +1 @@ -502 +504 -- 2.15.1