[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