1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include "string-util.h"
7 /* Gently push people towards defining GPT type UUIDs for all architectures we know */
8 #if !defined(GPT_ROOT_NATIVE) || \
9 !defined(GPT_ROOT_NATIVE_VERITY) || \
10 !defined(GPT_ROOT_NATIVE_VERITY_SIG) || \
11 !defined(GPT_USR_NATIVE) || \
12 !defined(GPT_USR_NATIVE_VERITY) || \
13 !defined(GPT_USR_NATIVE_VERITY_SIG)
14 #pragma message "Please define GPT partition types for your architecture."
17 #define _GPT_ARCH_SEXTET(arch, name) \
18 { GPT_ROOT_##arch, "root-" name, ARCHITECTURE_##arch, .is_root = true }, \
19 { GPT_ROOT_##arch##_VERITY, "root-" name "-verity", ARCHITECTURE_##arch, .is_root_verity = true }, \
20 { GPT_ROOT_##arch##_VERITY_SIG, "root-" name "-verity-sig", ARCHITECTURE_##arch, .is_root_verity_sig = true }, \
21 { GPT_USR_##arch, "usr-" name, ARCHITECTURE_##arch, .is_usr = true }, \
22 { GPT_USR_##arch##_VERITY, "usr-" name "-verity", ARCHITECTURE_##arch, .is_usr_verity = true }, \
23 { GPT_USR_##arch##_VERITY_SIG, "usr-" name "-verity-sig", ARCHITECTURE_##arch, .is_usr_verity_sig = true }
25 const GptPartitionType gpt_partition_type_table
[] = {
26 _GPT_ARCH_SEXTET(ALPHA
, "alpha"),
27 _GPT_ARCH_SEXTET(ARC
, "arc"),
28 _GPT_ARCH_SEXTET(ARM
, "arm"),
29 _GPT_ARCH_SEXTET(ARM64
, "arm64"),
30 _GPT_ARCH_SEXTET(IA64
, "ia64"),
31 _GPT_ARCH_SEXTET(LOONGARCH64
, "loongarch64"),
32 _GPT_ARCH_SEXTET(MIPS_LE
, "mips-le"),
33 _GPT_ARCH_SEXTET(MIPS64_LE
, "mips64-le"),
34 _GPT_ARCH_SEXTET(PARISC
, "parisc"),
35 _GPT_ARCH_SEXTET(PPC
, "ppc"),
36 _GPT_ARCH_SEXTET(PPC64
, "ppc64"),
37 _GPT_ARCH_SEXTET(PPC64_LE
, "ppc64-le"),
38 _GPT_ARCH_SEXTET(RISCV32
, "riscv32"),
39 _GPT_ARCH_SEXTET(RISCV64
, "riscv64"),
40 _GPT_ARCH_SEXTET(S390
, "s390"),
41 _GPT_ARCH_SEXTET(S390X
, "s390x"),
42 _GPT_ARCH_SEXTET(TILEGX
, "tilegx"),
43 _GPT_ARCH_SEXTET(X86
, "x86"),
44 _GPT_ARCH_SEXTET(X86_64
, "x86-64"),
45 #ifdef GPT_ROOT_NATIVE
46 { GPT_ROOT_NATIVE
, "root", native_architecture(), .is_root
= true },
47 { GPT_ROOT_NATIVE_VERITY
, "root-verity", native_architecture(), .is_root_verity
= true },
48 { GPT_ROOT_NATIVE_VERITY_SIG
, "root-verity-sig", native_architecture(), .is_root_verity_sig
= true },
49 { GPT_USR_NATIVE
, "usr", native_architecture(), .is_usr
= true },
50 { GPT_USR_NATIVE_VERITY
, "usr-verity", native_architecture(), .is_usr_verity
= true },
51 { GPT_USR_NATIVE_VERITY_SIG
, "usr-verity-sig", native_architecture(), .is_usr_verity_sig
= true },
53 #ifdef GPT_ROOT_SECONDARY
54 _GPT_ARCH_SEXTET(SECONDARY
, "secondary"),
57 { GPT_ESP
, "esp", _ARCHITECTURE_INVALID
},
58 { GPT_XBOOTLDR
, "xbootldr", _ARCHITECTURE_INVALID
},
59 { GPT_SWAP
, "swap", _ARCHITECTURE_INVALID
},
60 { GPT_HOME
, "home", _ARCHITECTURE_INVALID
},
61 { GPT_SRV
, "srv", _ARCHITECTURE_INVALID
},
62 { GPT_VAR
, "var", _ARCHITECTURE_INVALID
},
63 { GPT_TMP
, "tmp", _ARCHITECTURE_INVALID
},
64 { GPT_USER_HOME
, "user-home", _ARCHITECTURE_INVALID
},
65 { GPT_LINUX_GENERIC
, "linux-generic", _ARCHITECTURE_INVALID
},
69 static const GptPartitionType
*gpt_partition_type_find_by_uuid(sd_id128_t id
) {
71 for (size_t i
= 0; i
< ELEMENTSOF(gpt_partition_type_table
) - 1; i
++)
72 if (sd_id128_equal(id
, gpt_partition_type_table
[i
].uuid
))
73 return gpt_partition_type_table
+ i
;
78 const char *gpt_partition_type_uuid_to_string(sd_id128_t id
) {
79 const GptPartitionType
*pt
;
81 pt
= gpt_partition_type_find_by_uuid(id
);
88 const char *gpt_partition_type_uuid_to_string_harder(
90 char buffer
[static SD_ID128_UUID_STRING_MAX
]) {
96 s
= gpt_partition_type_uuid_to_string(id
);
100 return sd_id128_to_uuid_string(id
, buffer
);
103 int gpt_partition_type_uuid_from_string(const char *s
, sd_id128_t
*ret
) {
106 for (size_t i
= 0; i
< ELEMENTSOF(gpt_partition_type_table
) - 1; i
++)
107 if (streq(s
, gpt_partition_type_table
[i
].name
)) {
109 *ret
= gpt_partition_type_table
[i
].uuid
;
113 return sd_id128_from_string(s
, ret
);
116 Architecture
gpt_partition_type_uuid_to_arch(sd_id128_t id
) {
117 const GptPartitionType
*pt
;
119 pt
= gpt_partition_type_find_by_uuid(id
);
121 return _ARCHITECTURE_INVALID
;
126 int gpt_partition_label_valid(const char *s
) {
127 _cleanup_free_ char16_t
*recoded
= NULL
;
129 recoded
= utf8_to_utf16(s
, strlen(s
));
133 return char16_strlen(recoded
) <= GPT_LABEL_MAX
;
136 static GptPartitionType
gpt_partition_type_from_uuid(sd_id128_t id
) {
137 const GptPartitionType
*pt
;
139 pt
= gpt_partition_type_find_by_uuid(id
);
143 return (GptPartitionType
) { .uuid
= id
, .arch
= _ARCHITECTURE_INVALID
};
146 bool gpt_partition_type_is_root(sd_id128_t id
) {
147 return gpt_partition_type_from_uuid(id
).is_root
;
150 bool gpt_partition_type_is_root_verity(sd_id128_t id
) {
151 return gpt_partition_type_from_uuid(id
).is_root_verity
;
154 bool gpt_partition_type_is_root_verity_sig(sd_id128_t id
) {
155 return gpt_partition_type_from_uuid(id
).is_root_verity_sig
;
158 bool gpt_partition_type_is_usr(sd_id128_t id
) {
159 return gpt_partition_type_from_uuid(id
).is_usr
;
162 bool gpt_partition_type_is_usr_verity(sd_id128_t id
) {
163 return gpt_partition_type_from_uuid(id
).is_usr_verity
;
166 bool gpt_partition_type_is_usr_verity_sig(sd_id128_t id
) {
167 return gpt_partition_type_from_uuid(id
).is_usr_verity_sig
;
170 bool gpt_partition_type_knows_read_only(sd_id128_t id
) {
171 return gpt_partition_type_is_root(id
) ||
172 gpt_partition_type_is_usr(id
) ||
179 gpt_partition_type_is_root_verity(id
) || /* pretty much implied, but let's set the bit to make things really clear */
180 gpt_partition_type_is_usr_verity(id
); /* ditto */
183 bool gpt_partition_type_knows_growfs(sd_id128_t id
) {
184 return gpt_partition_type_is_root(id
) ||
185 gpt_partition_type_is_usr(id
) ||
194 bool gpt_partition_type_knows_no_auto(sd_id128_t id
) {
195 return gpt_partition_type_is_root(id
) ||
196 gpt_partition_type_is_root_verity(id
) ||
197 gpt_partition_type_is_usr(id
) ||
198 gpt_partition_type_is_usr_verity(id
) ||