Message ID | 20180820060958.25546-1-sam@mendozajonas.com |
---|---|
State | Accepted |
Headers | show |
Series | discover: Let 'boot' user-event boot by name | expand |
On Mon, 2018-08-20 at 16:09 +1000, Samuel Mendoza-Jonas wrote: > 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 <sam@mendozajonas.com> > --- > discover/device-handler.c | 22 ++++++++++++++++++++++ > discover/device-handler.h | 3 +++ > discover/user-event.c | 29 +++++++++++++++++++++++------ > 3 files changed, 48 insertions(+), 6 deletions(-) Merged as 7f5a99f0. > > diff --git a/discover/device-handler.c b/discover/device-handler.c > index 9c050293..cf379e78 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 3ca88e4e..9696ec06 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 12577964..734f77b3 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); >
diff --git a/discover/device-handler.c b/discover/device-handler.c index 9c050293..cf379e78 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 3ca88e4e..9696ec06 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 12577964..734f77b3 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);
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 <sam@mendozajonas.com> --- discover/device-handler.c | 22 ++++++++++++++++++++++ discover/device-handler.h | 3 +++ discover/user-event.c | 29 +++++++++++++++++++++++------ 3 files changed, 48 insertions(+), 6 deletions(-)