[PATCH 3/5] discover/handler: Implement temporary autoboot messages
Jeremy Kerr
jk at ozlabs.org
Tue Jul 3 16:34:45 AEST 2018
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;
+
+ 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;
--
2.14.1
More information about the Petitboot
mailing list