[PATCH 3/5] discover/handler: Implement temporary autoboot messages
Samuel Mendoza-Jonas
sam at mendozajonas.com
Mon Jul 9 14:35:30 AEST 2018
On Tue, 2018-07-03 at 16:34 +1000, Jeremy Kerr wrote:
> Handle incoming requests for temporary autoboot settings.
>
> Signed-off-by: Jeremy Kerr <jk at ozlabs.org>
> ---
> discover/device-handler.c | 70 +++++++++++++++++++++++++++++++++++++++-------
> discover/device-handler.h | 2 ++
> discover/discover-server.c | 16 +++++++++++
> 3 files changed, 78 insertions(+), 10 deletions(-)
>
> diff --git a/discover/device-handler.c b/discover/device-handler.c
> index 7d8b53c..3d75e57 100644
> --- a/discover/device-handler.c
> +++ b/discover/device-handler.c
> @@ -43,8 +43,9 @@
> #include "ipmi.h"
>
> enum default_priority {
> - DEFAULT_PRIORITY_REMOTE = 1,
> - DEFAULT_PRIORITY_LOCAL_FIRST = 2,
> + DEFAULT_PRIORITY_TEMP_USER = 1,
> + DEFAULT_PRIORITY_REMOTE = 2,
> + DEFAULT_PRIORITY_LOCAL_FIRST = 3,
> DEFAULT_PRIORITY_LOCAL_LAST = 0xfe,
> DEFAULT_PRIORITY_DISABLED = 0xff,
> };
> @@ -75,6 +76,7 @@ struct device_handler {
> struct waiter *timeout_waiter;
> bool autoboot_enabled;
> unsigned int sec_to_boot;
> + struct autoboot_option *temp_autoboot;
>
> struct discover_boot_option *default_boot_option;
> int default_boot_option_priority;
> @@ -815,19 +817,30 @@ static int autoboot_option_priority(const struct config *config,
> * for these options.
> */
> static enum default_priority default_option_priority(
> + struct device_handler *handler,
> struct discover_boot_option *opt)
> {
> const struct config *config;
>
> + /* Temporary user-provided autoboot options have highest priority */
> + if (handler->temp_autoboot) {
> + if (autoboot_option_matches(handler->temp_autoboot,
> + opt->device))
> + return DEFAULT_PRIORITY_TEMP_USER;
> +
> + pb_debug("handler: disabled default priority due to "
> + "temporary user override\n");
> + return DEFAULT_PRIORITY_DISABLED;
> + }
> +
> config = config_get();
>
> - /* We give highest priority to IPMI-configured boot options. If
> - * we have an IPMI bootdev configuration set, then we don't allow
> - * any other defaults */
> - if (config->ipmi_bootdev) {
> - bool ipmi_match = ipmi_device_type_matches(config->ipmi_bootdev,
> - opt->device->device->type);
> - if (ipmi_match)
> + /* Next highest priority to IPMI-configured boot options. If we have an
> + * IPMI bootdev configuration set, then we don't allow any other
> + * defaults */
> + if (config->ipmi_bootdev) { bool ipmi_match =
> + ipmi_device_type_matches(config->ipmi_bootdev,
> + opt->device->device->type); if (ipmi_match)
> return DEFAULT_PRIORITY_REMOTE;
>
> pb_debug("handler: disabled default priority due to "
> @@ -863,7 +876,7 @@ static void set_default(struct device_handler *handler,
>
> pb_debug("handler: new default option: %s\n", opt->option->id);
>
> - new_prio = default_option_priority(opt);
> + new_prio = default_option_priority(handler, opt);
>
> /* Anything outside our range prevents a default boot */
> if (new_prio >= DEFAULT_PRIORITY_DISABLED)
> @@ -903,6 +916,43 @@ static void set_default(struct device_handler *handler,
> default_timeout(handler);
> }
>
> +void device_handler_apply_temp_autoboot(struct device_handler *handler,
> + struct autoboot_option *opt)
> +{
> + unsigned int i;
> +
> + handler->temp_autoboot = talloc_steal(handler, opt);
> +
> + if (!handler->autoboot_enabled)
> + return;
> +
> + if (!handler->default_boot_option)
> + return;
Hi Jeremy,
If I'm reading this correctly, applying a temporary autoboot override is
a one-time event in that it checks the currently available boot options
and sets a default if one matches the device type. But this won't be
applied to newly found boot options right? So a new boot option that is
higher in the boot order could come along and supersede what is set here?
Cheers,
Sam
> +
> + if (autoboot_option_matches(opt, handler->default_boot_option->device))
> + return;
> +
> + /* cancel the default, and rescan available options */
> + device_handler_cancel_default(handler);
> +
> + handler->autoboot_enabled = true;
> +
> + for (i = 0; i < handler->n_devices; i++) {
> + struct discover_device *dev = handler->devices[i];
> + struct discover_boot_option *boot_opt;
> +
> + if (!autoboot_option_matches(opt, dev))
> + continue;
> +
> + list_for_each_entry(&dev->boot_options, boot_opt, list) {
> + if (boot_opt->option->is_default) {
> + set_default(handler, boot_opt);
> + break;
> + }
> + }
> + }
> +}
> +
> static bool resource_is_resolved(struct resource *res)
> {
> return !res || res->resolved;
> diff --git a/discover/device-handler.h b/discover/device-handler.h
> index 771cd06..b215663 100644
> --- a/discover/device-handler.h
> +++ b/discover/device-handler.h
> @@ -163,6 +163,8 @@ void device_handler_process_url(struct device_handler *handler,
> void device_handler_install_plugin(struct device_handler *handler,
> const char *plugin_file);
> void device_handler_reinit(struct device_handler *handler);
> +void device_handler_apply_temp_autoboot(struct device_handler *handler,
> + struct autoboot_option *opt);
>
> int device_request_write(struct discover_device *dev, bool *release);
> void device_release_write(struct discover_device *dev, bool release);
> diff --git a/discover/discover-server.c b/discover/discover-server.c
> index 814053d..3377fa6 100644
> --- a/discover/discover-server.c
> +++ b/discover/discover-server.c
> @@ -247,6 +247,7 @@ static int write_config_message(struct discover_server *server,
>
> static int discover_server_process_message(void *arg)
> {
> + struct autoboot_option *autoboot_opt;
> struct pb_protocol_message *message;
> struct boot_command *boot_command;
> struct client *client = arg;
> @@ -311,6 +312,21 @@ static int discover_server_process_message(void *arg)
> device_handler_install_plugin(client->server->device_handler,
> url);
> break;
> +
> + case PB_PROTOCOL_ACTION_TEMP_AUTOBOOT:
> + autoboot_opt = talloc_zero(client, struct autoboot_option);
> + rc = pb_protocol_deserialise_temp_autoboot(autoboot_opt,
> + message);
> + if (rc) {
> + pb_log("can't parse temporary autoboot message\n");
> + return 0;
> + }
> +
> + device_handler_apply_temp_autoboot(
> + client->server->device_handler,
> + autoboot_opt);
> + break;
> +
> default:
> pb_log("%s: invalid action %d\n", __func__, message->action);
> return 0;
More information about the Petitboot
mailing list