From patchwork Tue Jul 3 06:34:45 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Kerr X-Patchwork-Id: 938404 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41KZDX6ryGz9s3q for ; Tue, 3 Jul 2018 16:37:32 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ozlabs.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=ozlabs.org header.i=@ozlabs.org header.b="dFpQplj1"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 41KZDX5LfgzF1LP for ; Tue, 3 Jul 2018 16:37:32 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=ozlabs.org Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=ozlabs.org header.i=@ozlabs.org header.b="dFpQplj1"; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Received: from ozlabs.org (bilbo.ozlabs.org [203.11.71.1]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 41KZDG29bVzF1LP for ; Tue, 3 Jul 2018 16:37:18 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=ozlabs.org Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=ozlabs.org header.i=@ozlabs.org header.b="dFpQplj1"; dkim-atps=neutral Received: by ozlabs.org (Postfix, from userid 1023) id 41KZDG0Gbfz9s3Z; Tue, 3 Jul 2018 16:37:17 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ozlabs.org; s=201707; t=1530599838; bh=oNOm7LwqtfrR9ulLtCm8en333BIP4v9KaWVz7bpBfcQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dFpQplj12FjNJb8r279LXCTi2/466piK+lf6NKIl3CSVhCNSQuq3QI7hdYREsFVa/ kaf6GpKzYWo/39EDKzNx77/D5byxZZ/7nNvuc9uTh15VNzkWhvTm1PO/8GHcr2jajE lSNFusqPX+u9s5LL8QAjYO0XT0Cr13L3YvpJ6J6NWjklZcOc4ztZLraPeQR86tOcf/ rr/kV3RVWZZiDd13ij6htaiaAcm06vZ0F9HvyXR9e/Ermxr4fZKcYCaEuStAmTuNmz jeOankFA8OUv3bqH0hW+H6J3A+IUZhcP0oNrun5pwOi8CU1Sw+ynol84DaTJUe12Z/ D8zW0oSVzxWuQ== From: Jeremy Kerr To: petitboot@lists.ozlabs.org Subject: [PATCH 3/5] discover/handler: Implement temporary autoboot messages Date: Tue, 3 Jul 2018 16:34:45 +1000 Message-Id: <20180703063447.8338-4-jk@ozlabs.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180703063447.8338-1-jk@ozlabs.org> References: <20180703063447.8338-1-jk@ozlabs.org> X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: yewei@inspur.com MIME-Version: 1.0 Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" Handle incoming requests for temporary autoboot settings. Signed-off-by: Jeremy Kerr --- 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;