blob: 04bd8a4eb91acbba65164c41975f455941dca3ad [file] [log] [blame]
Klaus Heinrich Kiwid1cd8c52020-02-27 12:43:47 -03001From 6b25dcfea5b84aebbfd830236c489fc8c2cde02c Mon Sep 17 00:00:00 2001
2From: Jeremy Kerr <jk@ozlabs.org>
3Date: Mon, 4 Nov 2019 14:58:01 +0800
4Subject: [PATCH 07/18] discover/grub2: Add support for UUID and label for
5 'search' command
6
7This change adds support for searching by UUID and filesystem label.
8We still fall back to passthrough if the UUID is not found, but we now
9resolve to device ID strings.
10
11Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
12(cherry picked from commit 1580c6557d4e703348edb0dda83814f8972e9f3d)
13Signed-off-by: Klaus Heinrich Kiwi <klaus@linux.vnet.ibm.com>
14---
15 discover/grub2/builtins.c | 55 +++++++++++++++++++++++++--
16 test/parser/Makefile.am | 2 +
17 test/parser/test-grub2-search-label.c | 47 +++++++++++++++++++++++
18 test/parser/test-grub2-search-uuid.c | 55 +++++++++++++++++++++++++++
19 4 files changed, 156 insertions(+), 3 deletions(-)
20 create mode 100644 test/parser/test-grub2-search-label.c
21 create mode 100644 test/parser/test-grub2-search-uuid.c
22
23diff --git a/discover/grub2/builtins.c b/discover/grub2/builtins.c
24index ab6b0ec..7cac9f1 100644
25--- a/discover/grub2/builtins.c
26+++ b/discover/grub2/builtins.c
27@@ -115,6 +115,21 @@ static const struct option search_options[] = {
28 .has_arg = required_argument,
29 .val = 's',
30 },
31+ {
32+ .name = "file",
33+ .has_arg = no_argument,
34+ .val = 'f',
35+ },
36+ {
37+ .name = "label",
38+ .has_arg = no_argument,
39+ .val = 'l',
40+ },
41+ {
42+ .name = "fs-uuid",
43+ .has_arg = no_argument,
44+ .val = 'u',
45+ },
46 { 0 },
47 };
48
49@@ -122,13 +137,23 @@ static int builtin_search(struct grub2_script *script,
50 void *data __attribute__((unused)),
51 int argc, char *argv[])
52 {
53- const char *env_var, *spec;
54+ const char *env_var, *spec, *res;
55+ struct discover_device *dev;
56+ enum {
57+ LOOKUP_UUID = 'u',
58+ LOOKUP_LABEL = 'l',
59+ LOOKUP_FILE = 'f',
60+ } lookup_type;
61
62 env_var = "root";
63 optind = 0;
64
65+ /* Default to UUID, for backwards compat with earlier petitboot
66+ * versions. This argument is non-optional in GRUB. */
67+ lookup_type = LOOKUP_UUID;
68+
69 for (;;) {
70- int c = getopt_long(argc, argv, ":", search_options, NULL);
71+ int c = getopt_long(argc, argv, ":flu", search_options, NULL);
72 if (c == -1)
73 break;
74
75@@ -136,6 +161,11 @@ static int builtin_search(struct grub2_script *script,
76 case 's':
77 env_var = optarg;
78 break;
79+ case LOOKUP_UUID:
80+ case LOOKUP_LABEL:
81+ case LOOKUP_FILE:
82+ lookup_type = c;
83+ break;
84 case '?':
85 case ':':
86 break;
87@@ -149,8 +179,27 @@ static int builtin_search(struct grub2_script *script,
88 return -1;
89
90 spec = argv[optind];
91+ res = NULL;
92+
93+ switch (lookup_type) {
94+ case LOOKUP_UUID:
95+ dev = device_lookup_by_uuid(script->ctx->handler,
96+ spec);
97+ res = dev ? dev->device->id : spec;
98+ break;
99+ case LOOKUP_LABEL:
100+ dev = device_lookup_by_label(script->ctx->handler,
101+ spec);
102+ if (dev)
103+ res = dev->device->id;
104+ break;
105+ case LOOKUP_FILE:
106+ /* not yet implemented */
107+ break;
108+ }
109
110- script_env_set(script, env_var, spec);
111+ if (res)
112+ script_env_set(script, env_var, res);
113
114 return 0;
115 }
116diff --git a/test/parser/Makefile.am b/test/parser/Makefile.am
117index df9c539..f5985d6 100644
118--- a/test/parser/Makefile.am
119+++ b/test/parser/Makefile.am
120@@ -30,6 +30,8 @@ parser_TESTS = \
121 test/parser/test-grub2-single-line-if \
122 test/parser/test-grub2-pos-param \
123 test/parser/test-grub2-search-args \
124+ test/parser/test-grub2-search-uuid \
125+ test/parser/test-grub2-search-label \
126 test/parser/test-grub2-load-env \
127 test/parser/test-grub2-save-env \
128 test/parser/test-grub2-save-env-dash-f \
129diff --git a/test/parser/test-grub2-search-label.c b/test/parser/test-grub2-search-label.c
130new file mode 100644
131index 0000000..b9ee034
132--- /dev/null
133+++ b/test/parser/test-grub2-search-label.c
134@@ -0,0 +1,47 @@
135+/* check for grub2 search command, searching by partition label */
136+
137+#include "parser-test.h"
138+
139+#if 0 /* PARSER_EMBEDDED_CONFIG */
140+
141+# valid label
142+search --set=v1 --label testlabel
143+
144+v2=prev
145+# invalid label: does not alter v2
146+search --set=v2 --label invalidlabel
147+
148+menuentry $v1 {
149+ linux /vmlinux
150+}
151+
152+menuentry $v2 {
153+ linux /vmlinux
154+}
155+
156+#endif
157+
158+void run_test(struct parser_test *test)
159+{
160+ struct discover_boot_option *opt;
161+ struct discover_context *ctx;
162+ struct discover_device *dev;
163+
164+ ctx = test->ctx;
165+
166+ dev = test_create_device(test, "testdev");
167+ dev->label = "testlabel";
168+ device_handler_add_device(test->handler, dev);
169+
170+ test_read_conf_embedded(test, "/grub/grub.cfg");
171+
172+ test_run_parser(test, "grub2");
173+
174+ check_boot_option_count(ctx, 2);
175+
176+ opt = get_boot_option(ctx, 0);
177+ check_name(opt, "testdev");
178+
179+ opt = get_boot_option(ctx, 1);
180+ check_name(opt, "prev");
181+}
182diff --git a/test/parser/test-grub2-search-uuid.c b/test/parser/test-grub2-search-uuid.c
183new file mode 100644
184index 0000000..7eacd1d
185--- /dev/null
186+++ b/test/parser/test-grub2-search-uuid.c
187@@ -0,0 +1,55 @@
188+/* check for grub2 search command, searching by FS UUID */
189+
190+#include "parser-test.h"
191+
192+#if 0 /* PARSER_EMBEDDED_CONFIG */
193+
194+# valid UUID
195+search --set=v1 --fs-uuid ee0cc6fa-1dba-48f2-8f5b-19e4b8de8c37
196+
197+# invalid UUID: will fall back to passing the UUID through
198+search --set=v2 --fs-uuid 92b0da57-6e04-4e54-960b-85e6bb060433
199+
200+# no 'type' argument defaults to UUID search
201+search --set=v3 ee0cc6fa-1dba-48f2-8f5b-19e4b8de8c37
202+
203+menuentry $v1 {
204+ linux /vmlinux
205+}
206+
207+menuentry $v2 {
208+ linux /vmlinux
209+}
210+
211+menuentry $v3 {
212+ linux /vmlinux
213+}
214+#endif
215+
216+void run_test(struct parser_test *test)
217+{
218+ struct discover_boot_option *opt;
219+ struct discover_context *ctx;
220+ struct discover_device *dev;
221+
222+ ctx = test->ctx;
223+
224+ dev = test_create_device(test, "testdev");
225+ dev->uuid = "ee0cc6fa-1dba-48f2-8f5b-19e4b8de8c37";
226+ device_handler_add_device(test->handler, dev);
227+
228+ test_read_conf_embedded(test, "/grub/grub.cfg");
229+
230+ test_run_parser(test, "grub2");
231+
232+ check_boot_option_count(ctx, 3);
233+
234+ opt = get_boot_option(ctx, 0);
235+ check_name(opt, dev->device->id);
236+
237+ opt = get_boot_option(ctx, 1);
238+ check_name(opt, "92b0da57-6e04-4e54-960b-85e6bb060433");
239+
240+ opt = get_boot_option(ctx, 2);
241+ check_name(opt, dev->device->id);
242+}
243--
2442.17.1
245