summaryrefslogtreecommitdiffstats
path: root/discover/grub2
diff options
context:
space:
mode:
authorJeremy Kerr <jk@ozlabs.org>2019-11-11 17:10:30 +0800
committerJeremy Kerr <jk@ozlabs.org>2019-11-29 13:54:10 +0800
commit9fc2ac627df17ddc8e7c2735053aeb9e1252ff6e (patch)
tree4db4b90abc303519b2fa702509c697bba0bf8dae /discover/grub2
parent51f71178cd82a1cb7fae1a4e6bf40290e41b7d0e (diff)
downloadtalos-petitboot-9fc2ac627df17ddc8e7c2735053aeb9e1252ff6e.tar.gz
talos-petitboot-9fc2ac627df17ddc8e7c2735053aeb9e1252ff6e.zip
discover/grub2: add support for grub2-style path specifiers in resources
This change incorporates the grub2-style (device)/path specifiers in the grub2 parser's resource code. This allows the boot option paths to use device-specific references. Device names are looked-up using the UUID and kernel IDs, but with the lookup logic specific to a new function (grub2_lookup_device), so that can be extended in a future change. Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
Diffstat (limited to 'discover/grub2')
-rw-r--r--discover/grub2/blscfg.c19
-rw-r--r--discover/grub2/builtins.c15
-rw-r--r--discover/grub2/grub2.c56
-rw-r--r--discover/grub2/grub2.h5
4 files changed, 58 insertions, 37 deletions
diff --git a/discover/grub2/blscfg.c b/discover/grub2/blscfg.c
index d4754aa..d08f8f0 100644
--- a/discover/grub2/blscfg.c
+++ b/discover/grub2/blscfg.c
@@ -166,7 +166,6 @@ static void bls_finish(struct conf_context *conf)
struct discover_context *dc = conf->dc;
struct discover_boot_option *opt = state->opt;
struct boot_option *option = opt->option;
- const char *root;
char *filename;
if (!state->image) {
@@ -192,23 +191,21 @@ static void bls_finish(struct conf_context *conf)
else
option->name = talloc_strdup(option, state->image);
- root = script_env_get(state->script, "root");
-
- opt->boot_image = create_grub2_resource(opt, conf->dc->device,
- root, state->image);
+ opt->boot_image = create_grub2_resource(state->script, opt,
+ state->image);
if (state->initrd)
- opt->initrd = create_grub2_resource(opt, conf->dc->device,
- root, state->initrd);
+ opt->initrd = create_grub2_resource(state->script, opt,
+ state->initrd);
if (state->dtb)
- opt->dtb = create_grub2_resource(opt, conf->dc->device,
- root, state->dtb);
+ opt->dtb = create_grub2_resource(state->script, opt,
+ state->dtb);
char* args_sigfile_default = talloc_asprintf(opt,
"%s.cmdline.sig", state->image);
- opt->args_sig_file = create_grub2_resource(opt, conf->dc->device,
- root, args_sigfile_default);
+ opt->args_sig_file = create_grub2_resource(state->script, opt,
+ args_sigfile_default);
talloc_free(args_sigfile_default);
option->is_default = option_is_default(state, option);
diff --git a/discover/grub2/builtins.c b/discover/grub2/builtins.c
index 7cac9f1..765c4d7 100644
--- a/discover/grub2/builtins.c
+++ b/discover/grub2/builtins.c
@@ -46,7 +46,6 @@ static int builtin_linux(struct grub2_script *script,
int argc, char *argv[])
{
struct discover_boot_option *opt = script->opt;
- const char *root;
int i;
if (!opt) {
@@ -61,10 +60,7 @@ static int builtin_linux(struct grub2_script *script,
return -1;
}
- root = script_env_get(script, "root");
-
- opt->boot_image = create_grub2_resource(opt, script->ctx->device,
- root, argv[1]);
+ opt->boot_image = create_grub2_resource(script, opt, argv[1]);
opt->option->boot_args = NULL;
if (argc > 2)
@@ -77,8 +73,8 @@ static int builtin_linux(struct grub2_script *script,
char* args_sigfile_default = talloc_asprintf(opt,
"%s.cmdline.sig", argv[1]);
- opt->args_sig_file = create_grub2_resource(opt, script->ctx->device,
- root, args_sigfile_default);
+ opt->args_sig_file = create_grub2_resource(script, opt,
+ args_sigfile_default);
talloc_free(args_sigfile_default);
return 0;
}
@@ -88,7 +84,6 @@ static int builtin_initrd(struct grub2_script *script,
int argc, char *argv[])
{
struct discover_boot_option *opt = script->opt;
- const char *root;
if (!opt) {
pb_log("grub2 syntax error: 'initrd' statement outside "
@@ -102,9 +97,7 @@ static int builtin_initrd(struct grub2_script *script,
return -1;
}
- root = script_env_get(script, "root");
- opt->initrd = create_grub2_resource(opt, script->ctx->device,
- root, argv[1]);
+ opt->initrd = create_grub2_resource(script, opt, argv[1]);
return 0;
}
diff --git a/discover/grub2/grub2.c b/discover/grub2/grub2.c
index 3873720..a08a320 100644
--- a/discover/grub2/grub2.c
+++ b/discover/grub2/grub2.c
@@ -33,13 +33,35 @@ static const char *const grub2_conf_files[] = {
NULL
};
+static struct discover_device *grub2_lookup_device(
+ struct device_handler *handler, const char *desc)
+{
+ struct discover_device *dev;
+
+ if (!desc || !*desc)
+ return NULL;
+
+ dev = device_lookup_by_id(handler, desc);
+ if (dev)
+ return dev;
+
+ /* for now, only lookup by UUID */
+ dev = device_lookup_by_uuid(handler, desc);
+ if (dev)
+ return dev;
+
+ return NULL;
+}
+
/* we use slightly different resources for grub2 */
-struct resource *create_grub2_resource(struct discover_boot_option *opt,
- struct discover_device *orig_device,
- const char *root, const char *path)
+struct resource *create_grub2_resource(struct grub2_script *script,
+ struct discover_boot_option *opt,
+ const char *path)
{
+ struct discover_device *dev;
struct grub2_file *file;
struct resource *res;
+ const char *root;
if (strstr(path, "://")) {
struct pb_url *url = pb_url_parse(opt, path);
@@ -47,18 +69,29 @@ struct resource *create_grub2_resource(struct discover_boot_option *opt,
return create_url_resource(opt, url);
}
+ file = grub2_parse_file(script, path);
+ if (!file)
+ return NULL;
+
res = talloc(opt, struct resource);
+ root = script_env_get(script, "root");
- if (root) {
- file = talloc(res, struct grub2_file);
+ if (!file->dev && root && strlen(root))
file->dev = talloc_strdup(file, root);
- file->path = talloc_strdup(file, path);
- res->resolved = false;
- res->info = file;
+ /* if we don't have a device specified, or the lookup succeeds now,
+ * then we can resolve the resource right away */
+ if (file->dev)
+ dev = grub2_lookup_device(script->ctx->handler, file->dev);
+ else
+ dev = script->ctx->device;
- } else
- resolve_resource_against_device(res, orig_device, path);
+ if (dev) {
+ resolve_resource_against_device(res, dev, file->path);
+ } else {
+ res->resolved = false;
+ res->info = talloc_steal(opt, file);
+ }
return res;
}
@@ -71,8 +104,7 @@ bool resolve_grub2_resource(struct device_handler *handler,
assert(!res->resolved);
- dev = device_lookup_by_uuid(handler, file->dev);
-
+ dev = grub2_lookup_device(handler, file->dev);
if (!dev)
return false;
diff --git a/discover/grub2/grub2.h b/discover/grub2/grub2.h
index 8c4839b..ef32d4b 100644
--- a/discover/grub2/grub2.h
+++ b/discover/grub2/grub2.h
@@ -191,9 +191,8 @@ void script_register_function(struct grub2_script *script,
void register_builtins(struct grub2_script *script);
/* resources */
-struct resource *create_grub2_resource(struct discover_boot_option *opt,
- struct discover_device *orig_device,
- const char *root, const char *path);
+struct resource *create_grub2_resource(struct grub2_script *script,
+ struct discover_boot_option *opt, const char *path);
bool resolve_grub2_resource(struct device_handler *handler,
struct resource *res);
OpenPOWER on IntegriCloud