]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/gpt.c
man/crypttab: rework formatting in "key acquisition section"
[thirdparty/systemd.git] / src / shared / gpt.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "gpt.h"
4 #include "string-util.h"
5 #include "utf8.h"
6
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."
15 #endif
16
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 }
24
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 },
52 #endif
53 #ifdef GPT_ROOT_SECONDARY
54 _GPT_ARCH_SEXTET(SECONDARY, "secondary"),
55 #endif
56
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 },
66 {}
67 };
68
69 static const GptPartitionType *gpt_partition_type_find_by_uuid(sd_id128_t id) {
70
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;
74
75 return NULL;
76 }
77
78 const char *gpt_partition_type_uuid_to_string(sd_id128_t id) {
79 const GptPartitionType *pt;
80
81 pt = gpt_partition_type_find_by_uuid(id);
82 if (!pt)
83 return NULL;
84
85 return pt->name;
86 }
87
88 const char *gpt_partition_type_uuid_to_string_harder(
89 sd_id128_t id,
90 char buffer[static SD_ID128_UUID_STRING_MAX]) {
91
92 const char *s;
93
94 assert(buffer);
95
96 s = gpt_partition_type_uuid_to_string(id);
97 if (s)
98 return s;
99
100 return sd_id128_to_uuid_string(id, buffer);
101 }
102
103 int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret) {
104 assert(s);
105
106 for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++)
107 if (streq(s, gpt_partition_type_table[i].name)) {
108 if (ret)
109 *ret = gpt_partition_type_table[i].uuid;
110 return 0;
111 }
112
113 return sd_id128_from_string(s, ret);
114 }
115
116 Architecture gpt_partition_type_uuid_to_arch(sd_id128_t id) {
117 const GptPartitionType *pt;
118
119 pt = gpt_partition_type_find_by_uuid(id);
120 if (!pt)
121 return _ARCHITECTURE_INVALID;
122
123 return pt->arch;
124 }
125
126 int gpt_partition_label_valid(const char *s) {
127 _cleanup_free_ char16_t *recoded = NULL;
128
129 recoded = utf8_to_utf16(s, strlen(s));
130 if (!recoded)
131 return -ENOMEM;
132
133 return char16_strlen(recoded) <= GPT_LABEL_MAX;
134 }
135
136 static GptPartitionType gpt_partition_type_from_uuid(sd_id128_t id) {
137 const GptPartitionType *pt;
138
139 pt = gpt_partition_type_find_by_uuid(id);
140 if (pt)
141 return *pt;
142
143 return (GptPartitionType) { .uuid = id, .arch = _ARCHITECTURE_INVALID };
144 }
145
146 bool gpt_partition_type_is_root(sd_id128_t id) {
147 return gpt_partition_type_from_uuid(id).is_root;
148 }
149
150 bool gpt_partition_type_is_root_verity(sd_id128_t id) {
151 return gpt_partition_type_from_uuid(id).is_root_verity;
152 }
153
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;
156 }
157
158 bool gpt_partition_type_is_usr(sd_id128_t id) {
159 return gpt_partition_type_from_uuid(id).is_usr;
160 }
161
162 bool gpt_partition_type_is_usr_verity(sd_id128_t id) {
163 return gpt_partition_type_from_uuid(id).is_usr_verity;
164 }
165
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;
168 }
169
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) ||
173 sd_id128_in_set(id,
174 GPT_HOME,
175 GPT_SRV,
176 GPT_VAR,
177 GPT_TMP,
178 GPT_XBOOTLDR) ||
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 */
181 }
182
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) ||
186 sd_id128_in_set(id,
187 GPT_HOME,
188 GPT_SRV,
189 GPT_VAR,
190 GPT_TMP,
191 GPT_XBOOTLDR);
192 }
193
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) ||
199 sd_id128_in_set(id,
200 GPT_HOME,
201 GPT_SRV,
202 GPT_VAR,
203 GPT_TMP,
204 GPT_XBOOTLDR,
205 GPT_SWAP);
206 }