grub2/grub2: add Yocto paths to default grub2 conf search paths
[petitboot] / discover / grub2 / grub2.c
1
2 #include <assert.h>
3 #include <string.h>
4 #include <i18n/i18n.h>
5
6 #include <talloc/talloc.h>
7 #include <url/url.h>
8
9 #include <discover/resource.h>
10 #include <discover/parser.h>
11 #include <discover/parser-utils.h>
12
13 #include "grub2.h"
14
15 static const char *const grub2_conf_files[] = {
16         "/grub.cfg",
17         "/menu.lst",
18         "/grub/grub.cfg",
19         "/grub2/grub.cfg",
20         "/grub/menu.lst",
21         "/boot/grub/grub.cfg",
22         "/boot/grub2/grub.cfg",
23         "/boot/grub/menu.lst",
24         "/efi/boot/grub.cfg",
25         "/GRUB.CFG",
26         "/MENU.LST",
27         "/GRUB/GRUB.CFG",
28         "/GRUB2/GRUB.CFG",
29         "/GRUB/MENU.LST",
30         "/BOOT/GRUB/GRUB.CFG",
31         "/BOOT/GRUB/MENU.LST",
32         "/EFI/BOOT/GRUB.CFG",
33         NULL
34 };
35
36 struct grub2_resource_info {
37         char *root;
38         char *path;
39 };
40
41 /* we use slightly different resources for grub2 */
42 struct resource *create_grub2_resource(struct discover_boot_option *opt,
43                 struct discover_device *orig_device,
44                 const char *root, const char *path)
45 {
46         struct grub2_resource_info *info;
47         struct resource *res;
48
49         if (strstr(path, "://")) {
50                 struct pb_url *url = pb_url_parse(opt, path);
51                 if (url)
52                         return create_url_resource(opt, url);
53         }
54
55         res = talloc(opt, struct resource);
56
57         if (root) {
58                 info = talloc(res, struct grub2_resource_info);
59                 talloc_reference(info, root);
60                 info->root = talloc_strdup(info, root);
61                 info->path = talloc_strdup(info, path);
62
63                 res->resolved = false;
64                 res->info = info;
65
66         } else
67                 resolve_resource_against_device(res, orig_device, path);
68
69         return res;
70 }
71
72 bool resolve_grub2_resource(struct device_handler *handler,
73                 struct resource *res)
74 {
75         struct grub2_resource_info *info = res->info;
76         struct discover_device *dev;
77
78         assert(!res->resolved);
79
80         dev = device_lookup_by_uuid(handler, info->root);
81
82         if (!dev)
83                 return false;
84
85         resolve_resource_against_device(res, dev, info->path);
86         talloc_free(info);
87
88         return true;
89 }
90
91 static int grub2_parse(struct discover_context *dc)
92 {
93         const char * const *filename;
94         struct grub2_parser *parser;
95         int len, rc;
96         char *buf;
97
98         /* Support block device boot only at present */
99         if (dc->event)
100                 return -1;
101
102         for (filename = grub2_conf_files; *filename; filename++) {
103                 rc = parser_request_file(dc, dc->device, *filename, &buf, &len);
104                 if (rc)
105                         continue;
106
107                 parser = grub2_parser_create(dc);
108                 grub2_parser_parse(parser, *filename, buf, len);
109                 device_handler_status_dev_info(dc->handler, dc->device,
110                                 _("Parsed GRUB configuration from %s"),
111                                 *filename);
112                 talloc_free(buf);
113                 talloc_free(parser);
114                 break;
115         }
116
117
118         return 0;
119 }
120
121 static struct parser grub2_parser = {
122         .name                   = "grub2",
123         .parse                  = grub2_parse,
124         .resolve_resource       = resolve_grub2_resource,
125 };
126
127 register_parser(grub2_parser);