From 7f5a99f015cb1f48f73acb921beced6daf9fa15d Mon Sep 17 00:00:00 2001 From: Samuel Mendoza-Jonas Date: Mon, 20 Aug 2018 16:09:58 +1000 Subject: discover: Let 'boot' user-event boot by name If a 'name' parameter is used for a boot user event, search existing boot options for one that matches that name on the given device. This allows a pb-event user to boot based on name rather than having to specify the exact boot arguments. Signed-off-by: Samuel Mendoza-Jonas --- discover/device-handler.c | 22 ++++++++++++++++++++++ discover/device-handler.h | 3 +++ discover/user-event.c | 29 +++++++++++++++++++++++------ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/discover/device-handler.c b/discover/device-handler.c index 9c05029..cf379e7 100644 --- a/discover/device-handler.c +++ b/discover/device-handler.c @@ -1404,6 +1404,28 @@ int device_handler_dhcp(struct device_handler *handler, return 0; } +struct discover_boot_option *device_handler_find_option_by_name( + struct device_handler *handler, const char *device, + const char *name) +{ + size_t len = strlen(name); + unsigned int i; + + for (i = 0; i < handler->n_devices; i++) { + struct discover_device *dev = handler->devices[i]; + struct discover_boot_option *opt; + + list_for_each_entry(&dev->boot_options, opt, list) + /* Match exactly, partial matches can be quite common */ + if (strlen(opt->option->name) == len && + !strcmp(opt->option->name, name)) + if (!dev || !strcmp(opt->option->device_id, device)) + return opt; + } + + return NULL; +} + static struct discover_boot_option *find_boot_option_by_id( struct device_handler *handler, const char *id) { diff --git a/discover/device-handler.h b/discover/device-handler.h index 3ca88e4..9696ec0 100644 --- a/discover/device-handler.h +++ b/discover/device-handler.h @@ -157,6 +157,9 @@ void discover_device_set_param(struct discover_device *device, const char *discover_device_get_param(struct discover_device *device, const char *name); +struct discover_boot_option *device_handler_find_option_by_name( + struct device_handler *handler, const char *device, + const char *name); void device_handler_boot(struct device_handler *handler, struct boot_command *cmd); void device_handler_cancel_default(struct device_handler *handler); diff --git a/discover/user-event.c b/discover/user-event.c index 1257796..734f77b 100644 --- a/discover/user-event.c +++ b/discover/user-event.c @@ -482,13 +482,30 @@ static int user_event_url(struct user_event *uev, struct event *event) static int user_event_boot(struct user_event *uev, struct event *event) { struct device_handler *handler = uev->handler; - struct boot_command *cmd = talloc(handler, struct boot_command); + struct boot_command *cmd = talloc_zero(handler, struct boot_command); + struct discover_boot_option *opt; + const char *name; + + name = event_get_param(event, "name"); + if (name) { + pb_log("Finding boot option %s @ %s\n", name, event->device); + opt = device_handler_find_option_by_name(handler, + event->device, name); + if (!opt) { + pb_log("No option with name %s\n", name); + return -1; + } - cmd->option_id = talloc_strdup(cmd, event_get_param(event, "id")); - cmd->boot_image_file = talloc_strdup(cmd, event_get_param(event, "image")); - cmd->initrd_file = talloc_strdup(cmd, event_get_param(event, "initrd")); - cmd->dtb_file = talloc_strdup(cmd, event_get_param(event, "dtb")); - cmd->boot_args = talloc_strdup(cmd, event_get_param(event, "args")); + pb_log("Found option with id %s!\n", opt->option->id); + cmd->option_id = talloc_strdup(cmd, opt->option->id); + } else { + pb_log("Booting based on full boot command\n"); + cmd->option_id = talloc_strdup(cmd, event_get_param(event, "id")); + cmd->boot_image_file = talloc_strdup(cmd, event_get_param(event, "image")); + cmd->initrd_file = talloc_strdup(cmd, event_get_param(event, "initrd")); + cmd->dtb_file = talloc_strdup(cmd, event_get_param(event, "dtb")); + cmd->boot_args = talloc_strdup(cmd, event_get_param(event, "args")); + } device_handler_boot(handler, cmd); -- cgit v1.2.1