forked from bottlerocket-os/bottlerocket
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path0014-gpt-add-search-by-partition-label-and-uuid-commands.patch
452 lines (433 loc) · 14.5 KB
/
0014-gpt-add-search-by-partition-label-and-uuid-commands.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
From 334b58a122bad34c7efa1b1ea6d58389477fd255 Mon Sep 17 00:00:00 2001
From: Michael Marineau <michael.marineau@coreos.com>
Date: Thu, 27 Nov 2014 16:34:21 -0800
Subject: [PATCH] gpt: add search by partition label and uuid commands
Builds on the existing filesystem search code. Only for GPT right now.
[markubo: Update to grub-2.06-42.amzn2022. Search functions take a more
general search_flags parameter now instead of a no_floppy flag.]
Signed-off-by: Markus Boehme <markubo@amazon.com>
---
Makefile.util.def | 2 +
grub-core/Makefile.core.def | 10 +++
grub-core/commands/search.c | 49 +++++++++++++++
grub-core/commands/search_part_label.c | 5 ++
grub-core/commands/search_part_uuid.c | 5 ++
grub-core/commands/search_wrap.c | 10 +++
grub-core/lib/gpt.c | 64 ++++++++++++++++++++
include/grub/gpt_partition.h | 16 +++++
include/grub/search.h | 6 ++
tests/gpt_unit_test.c | 84 ++++++++++++++++++++++++++
10 files changed, 251 insertions(+)
create mode 100644 grub-core/commands/search_part_label.c
create mode 100644 grub-core/commands/search_part_uuid.c
diff --git a/Makefile.util.def b/Makefile.util.def
index eb4bc90..8f74405 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -1406,6 +1406,8 @@ program = {
name = gpt_unit_test;
common = tests/gpt_unit_test.c;
common = tests/lib/unit_test.c;
+ common = grub-core/commands/search_part_label.c;
+ common = grub-core/commands/search_part_uuid.c;
common = grub-core/disk/host.c;
common = grub-core/kern/emu/hostfs.c;
common = grub-core/lib/gpt.c;
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 393aecd..3cde624 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1152,6 +1152,16 @@ module = {
common = commands/search_label.c;
};
+module = {
+ name = search_part_uuid;
+ common = commands/search_part_uuid.c;
+};
+
+module = {
+ name = search_part_label;
+ common = commands/search_part_label.c;
+};
+
module = {
name = setpci;
common = commands/setpci.c;
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index 57d26ce..bb0c7cb 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -30,6 +30,9 @@
#include <grub/i18n.h>
#include <grub/disk.h>
#include <grub/partition.h>
+#if defined(DO_SEARCH_PART_UUID) || defined(DO_SEARCH_PART_LABEL)
+#include <grub/gpt_partition.h>
+#endif
GRUB_MOD_LICENSE ("GPLv3+");
@@ -109,6 +112,44 @@ iterate_device (const char *name, void *data)
}
grub_free (buf);
}
+#elif defined(DO_SEARCH_PART_UUID)
+ {
+ grub_device_t dev;
+ char *quid;
+
+ dev = grub_device_open (name);
+ if (dev)
+ {
+ if (grub_gpt_part_uuid (dev, &quid) == GRUB_ERR_NONE)
+ {
+ if (grub_strcasecmp (quid, ctx->key) == 0)
+ found = 1;
+
+ grub_free (quid);
+ }
+
+ grub_device_close (dev);
+ }
+ }
+#elif defined(DO_SEARCH_PART_LABEL)
+ {
+ grub_device_t dev;
+ char *quid;
+
+ dev = grub_device_open (name);
+ if (dev)
+ {
+ if (grub_gpt_part_label (dev, &quid) == GRUB_ERR_NONE)
+ {
+ if (grub_strcmp (quid, ctx->key) == 0)
+ found = 1;
+
+ grub_free (quid);
+ }
+
+ grub_device_close (dev);
+ }
+ }
#else
{
/* SEARCH_FS_UUID or SEARCH_LABEL */
@@ -332,6 +373,10 @@ static grub_command_t cmd;
#ifdef DO_SEARCH_FILE
GRUB_MOD_INIT(search_fs_file)
+#elif defined(DO_SEARCH_PART_UUID)
+GRUB_MOD_INIT(search_part_uuid)
+#elif defined(DO_SEARCH_PART_LABEL)
+GRUB_MOD_INIT(search_part_label)
#elif defined (DO_SEARCH_FS_UUID)
GRUB_MOD_INIT(search_fs_uuid)
#else
@@ -346,6 +391,10 @@ GRUB_MOD_INIT(search_label)
#ifdef DO_SEARCH_FILE
GRUB_MOD_FINI(search_fs_file)
+#elif defined(DO_SEARCH_PART_UUID)
+GRUB_MOD_FINI(search_part_uuid)
+#elif defined(DO_SEARCH_PART_LABEL)
+GRUB_MOD_FINI(search_part_label)
#elif defined (DO_SEARCH_FS_UUID)
GRUB_MOD_FINI(search_fs_uuid)
#else
diff --git a/grub-core/commands/search_part_label.c b/grub-core/commands/search_part_label.c
new file mode 100644
index 0000000..ca906cb
--- /dev/null
+++ b/grub-core/commands/search_part_label.c
@@ -0,0 +1,5 @@
+#define DO_SEARCH_PART_LABEL 1
+#define FUNC_NAME grub_search_part_label
+#define COMMAND_NAME "search.part_label"
+#define HELP_MESSAGE N_("Search devices by partition label. If VARIABLE is specified, the first device found is set to a variable.")
+#include "search.c"
diff --git a/grub-core/commands/search_part_uuid.c b/grub-core/commands/search_part_uuid.c
new file mode 100644
index 0000000..2d1d3d0
--- /dev/null
+++ b/grub-core/commands/search_part_uuid.c
@@ -0,0 +1,5 @@
+#define DO_SEARCH_PART_UUID 1
+#define FUNC_NAME grub_search_part_uuid
+#define COMMAND_NAME "search.part_uuid"
+#define HELP_MESSAGE N_("Search devices by partition UUID. If VARIABLE is specified, the first device found is set to a variable.")
+#include "search.c"
diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
index 0b62acf..82f8e63 100644
--- a/grub-core/commands/search_wrap.c
+++ b/grub-core/commands/search_wrap.c
@@ -36,6 +36,10 @@ static const struct grub_arg_option options[] =
0, 0},
{"fs-uuid", 'u', 0, N_("Search devices by a filesystem UUID."),
0, 0},
+ {"part-label", 'L', 0, N_("Search devices by a partition label."),
+ 0, 0},
+ {"part-uuid", 'U', 0, N_("Search devices by a partition UUID."),
+ 0, 0},
{"set", 's', GRUB_ARG_OPTION_OPTIONAL,
N_("Set a variable to the first device found."), N_("VARNAME"),
ARG_TYPE_STRING},
@@ -72,6 +76,8 @@ enum options
SEARCH_FILE,
SEARCH_LABEL,
SEARCH_FS_UUID,
+ SEARCH_PART_LABEL,
+ SEARCH_PART_UUID,
SEARCH_SET,
SEARCH_NO_FLOPPY,
SEARCH_EFIDISK_ONLY,
@@ -193,6 +199,10 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
grub_search_label (id, var, flags, hints, nhints);
else if (state[SEARCH_FS_UUID].set)
grub_search_fs_uuid (id, var, flags, hints, nhints);
+ else if (state[SEARCH_PART_LABEL].set)
+ grub_search_part_label (id, var, flags, hints, nhints);
+ else if (state[SEARCH_PART_UUID].set)
+ grub_search_part_uuid (id, var, flags, hints, nhints);
else if (state[SEARCH_FILE].set)
grub_search_fs_file (id, var, flags, hints, nhints);
else
diff --git a/grub-core/lib/gpt.c b/grub-core/lib/gpt.c
index 9a1835b..10a4b85 100644
--- a/grub-core/lib/gpt.c
+++ b/grub-core/lib/gpt.c
@@ -18,7 +18,9 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <grub/charset.h>
#include <grub/crypto.h>
+#include <grub/device.h>
#include <grub/disk.h>
#include <grub/misc.h>
#include <grub/mm.h>
@@ -44,6 +46,68 @@ grub_gpt_guid_to_str (grub_gpt_guid_t *guid)
guid->data4[6], guid->data4[7]);
}
+static grub_err_t
+grub_gpt_device_partentry (grub_device_t device,
+ struct grub_gpt_partentry *entry)
+{
+ grub_disk_t disk = device->disk;
+ grub_partition_t p;
+ grub_err_t err;
+
+ if (!disk || !disk->partition)
+ return grub_error (GRUB_ERR_BUG, "not a partition");
+
+ if (grub_strcmp (disk->partition->partmap->name, "gpt"))
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a GPT partition");
+
+ p = disk->partition;
+ disk->partition = p->parent;
+ err = grub_disk_read (disk, p->offset, p->index, sizeof (*entry), entry);
+ disk->partition = p;
+
+ return err;
+}
+
+grub_err_t
+grub_gpt_part_label (grub_device_t device, char **label)
+{
+ struct grub_gpt_partentry entry;
+ const grub_size_t name_len = ARRAY_SIZE (entry.name);
+ const grub_size_t label_len = name_len * GRUB_MAX_UTF8_PER_UTF16 + 1;
+ grub_size_t i;
+ grub_uint8_t *end;
+
+ if (grub_gpt_device_partentry (device, &entry))
+ return grub_errno;
+
+ *label = grub_malloc (label_len);
+ if (!*label)
+ return grub_errno;
+
+ for (i = 0; i < name_len; i++)
+ entry.name[i] = grub_le_to_cpu16 (entry.name[i]);
+
+ end = grub_utf16_to_utf8 ((grub_uint8_t *) *label, entry.name, name_len);
+ *end = '\0';
+
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_gpt_part_uuid (grub_device_t device, char **uuid)
+{
+ struct grub_gpt_partentry entry;
+
+ if (grub_gpt_device_partentry (device, &entry))
+ return grub_errno;
+
+ *uuid = grub_gpt_guid_to_str (&entry.guid);
+ if (!*uuid)
+ return grub_errno;
+
+ return GRUB_ERR_NONE;
+}
+
static grub_uint64_t
grub_gpt_size_to_sectors (grub_gpt_t gpt, grub_size_t size)
{
diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h
index a44c0d5..7b04080 100644
--- a/include/grub/gpt_partition.h
+++ b/include/grub/gpt_partition.h
@@ -49,6 +49,10 @@ char * grub_gpt_guid_to_str (grub_gpt_guid_t *guid);
GRUB_GPT_GUID_INIT (0x0, 0x0, 0x0, \
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
+#define GRUB_GPT_PARTITION_TYPE_EFI_SYSTEM \
+ GRUB_GPT_GUID_INIT (0xc12a7328, 0xf81f, 0x11d2, \
+ 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b)
+
#define GRUB_GPT_PARTITION_TYPE_BIOS_BOOT \
GRUB_GPT_GUID_INIT (0x21686148, 0x6449, 0x6e6f, \
0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49)
@@ -216,4 +220,16 @@ grub_err_t grub_gpt_pmbr_check (struct grub_msdos_partition_mbr *mbr);
grub_err_t grub_gpt_header_check (struct grub_gpt_header *gpt,
unsigned int log_sector_size);
+
+/* Utilities for simple partition data lookups, usage is intended to
+ * be similar to fs->label and fs->uuid functions. */
+
+/* Return the partition label of the device DEVICE in LABEL.
+ * The label is in a new buffer and should be freed by the caller. */
+grub_err_t grub_gpt_part_label (grub_device_t device, char **label);
+
+/* Return the partition uuid of the device DEVICE in UUID.
+ * The label is in a new buffer and should be freed by the caller. */
+grub_err_t grub_gpt_part_uuid (grub_device_t device, char **uuid);
+
#endif /* ! GRUB_GPT_PARTITION_HEADER */
diff --git a/include/grub/search.h b/include/grub/search.h
index 4190aeb..66722a6 100644
--- a/include/grub/search.h
+++ b/include/grub/search.h
@@ -34,5 +34,11 @@ void grub_search_fs_uuid (const char *key, const char *var,
void grub_search_label (const char *key, const char *var,
enum search_flags flags,
char **hints, unsigned nhints);
+void grub_search_part_uuid (const char *key, const char *var,
+ enum search_flags flags,
+ char **hints, unsigned nhints);
+void grub_search_part_label (const char *key, const char *var,
+ enum search_flags flags,
+ char **hints, unsigned nhints);
#endif
diff --git a/tests/gpt_unit_test.c b/tests/gpt_unit_test.c
index 5692a5a..deb55a9 100644
--- a/tests/gpt_unit_test.c
+++ b/tests/gpt_unit_test.c
@@ -21,10 +21,12 @@
#include <grub/disk.h>
#include <grub/emu/hostdisk.h>
#include <grub/emu/misc.h>
+#include <grub/env.h>
#include <grub/err.h>
#include <grub/gpt_partition.h>
#include <grub/msdos_partition.h>
#include <grub/lib/hexdump.h>
+#include <grub/search.h>
#include <grub/test.h>
#include <errno.h>
@@ -534,6 +536,84 @@ repair_test (void)
close_disk (&data);
}
+
+static void
+search_label_test (void)
+{
+ struct test_data data;
+ const char *test_result;
+ char *expected_result;
+
+ open_disk (&data);
+
+ expected_result = grub_xasprintf ("%s,gpt1", data.dev->disk->name);
+ grub_env_unset ("test_result");
+ grub_search_part_label ("EFI SYSTEM", "test_result", 0, NULL, 0);
+ test_result = grub_env_get ("test_result");
+ grub_test_assert (test_result && strcmp (test_result, expected_result) == 0,
+ "wrong device: %s (%s)", test_result, expected_result);
+ grub_free (expected_result);
+
+ expected_result = grub_xasprintf ("%s,gpt2", data.dev->disk->name);
+ grub_env_unset ("test_result");
+ grub_search_part_label ("BIOS BOOT", "test_result", 0, NULL, 0);
+ test_result = grub_env_get ("test_result");
+ grub_test_assert (test_result && strcmp (test_result, expected_result) == 0,
+ "wrong device: %s (%s)", test_result, expected_result);
+ grub_free (expected_result);
+
+ grub_env_unset ("test_result");
+ grub_search_part_label ("bogus name", "test_result", 0, NULL, 0);
+ test_result = grub_env_get ("test_result");
+ grub_test_assert (test_result == NULL,
+ "unexpected device: %s", test_result);
+ grub_test_assert (grub_errno == GRUB_ERR_FILE_NOT_FOUND,
+ "unexpected error: %s", grub_errmsg);
+ grub_errno = GRUB_ERR_NONE;
+
+ close_disk (&data);
+}
+
+static void
+search_uuid_test (void)
+{
+ struct test_data data;
+ const char gpt1_uuid[] = "A0F1792E-B4CE-4136-BCF2-1AFC133C2828";
+ const char gpt2_uuid[] = "876c898d-1b40-4727-a161-edf9b5486674";
+ const char bogus_uuid[] = "1534c928-c50e-4866-9daf-6a9fd7918a76";
+ const char *test_result;
+ char *expected_result;
+
+ open_disk (&data);
+
+ expected_result = grub_xasprintf ("%s,gpt1", data.dev->disk->name);
+ grub_env_unset ("test_result");
+ grub_search_part_uuid (gpt1_uuid, "test_result", 0, NULL, 0);
+ test_result = grub_env_get ("test_result");
+ grub_test_assert (test_result && strcmp (test_result, expected_result) == 0,
+ "wrong device: %s (%s)", test_result, expected_result);
+ grub_free (expected_result);
+
+ expected_result = grub_xasprintf ("%s,gpt2", data.dev->disk->name);
+ grub_env_unset ("test_result");
+ grub_search_part_uuid (gpt2_uuid, "test_result", 0, NULL, 0);
+ test_result = grub_env_get ("test_result");
+ grub_test_assert (test_result && strcmp (test_result, expected_result) == 0,
+ "wrong device: %s (%s)", test_result, expected_result);
+ grub_free (expected_result);
+
+ grub_env_unset ("test_result");
+ grub_search_part_uuid (bogus_uuid, "test_result", 0, NULL, 0);
+ test_result = grub_env_get ("test_result");
+ grub_test_assert (test_result == NULL,
+ "unexpected device: %s", test_result);
+ grub_test_assert (grub_errno == GRUB_ERR_FILE_NOT_FOUND,
+ "unexpected error: %s", grub_errmsg);
+ grub_errno = GRUB_ERR_NONE;
+
+ close_disk (&data);
+}
+
void
grub_unit_test_init (void)
{
@@ -546,6 +626,8 @@ grub_unit_test_init (void)
grub_test_register ("gpt_read_invalid_test", read_invalid_entries_test);
grub_test_register ("gpt_read_fallback_test", read_fallback_test);
grub_test_register ("gpt_repair_test", repair_test);
+ grub_test_register ("gpt_search_label_test", search_label_test);
+ grub_test_register ("gpt_search_uuid_test", search_uuid_test);
}
void
@@ -557,5 +639,7 @@ grub_unit_test_fini (void)
grub_test_unregister ("gpt_read_invalid_test");
grub_test_unregister ("gpt_read_fallback_test");
grub_test_unregister ("gpt_repair_test");
+ grub_test_unregister ("gpt_search_label_test");
+ grub_test_unregister ("gpt_search_uuid_test");
grub_fini_all ();
}
--
2.36.1