From patchwork Tue Oct 29 09:15:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeremy Kerr X-Patchwork-Id: 1185931 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 472R6d2fkFz9sPK for ; Tue, 29 Oct 2019 20:26:33 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (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="rCD0G/YY"; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 472R6c5mQtzDqyJ for ; Tue, 29 Oct 2019 20:26:32 +1100 (AEDT) X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Received: from ozlabs.org (bilbo.ozlabs.org [IPv6:2401:3900:2:1::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 472R136BSXzDqwN for ; Tue, 29 Oct 2019 20:21:43 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=pass (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="rCD0G/YY"; dkim-atps=neutral Received: by ozlabs.org (Postfix, from userid 1023) id 472R1256rPz9sPK; Tue, 29 Oct 2019 20:21:42 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ozlabs.org; s=201707; t=1572340902; bh=45OzajebKhRW9UcMK+Ji+B5Qovp2AAv3jxCjJprNky0=; h=From:To:Cc:Subject:Date:From; b=rCD0G/YYjOLH1T20KfvPpVlfHnSUa5wJIUTYWf8LtxIdkHSwyrUCOdmmwKoliqL0x J1vKRhbGIDhLkCdJTP9vFprGjqvD3tRQCt42W9vSUsu+ttkWKgt4ZDxAswASWbpIgj /f8KwJniyihZDV/IkwSVJo4KqzAtTLSrplNy4OIXqR/Q5HeKEZzpPkIfrouVNEWfLB x6yzKDAiE8Xq0Npy1Up+ZhV2CRHKLKVyrTBfpYwdkqq+kRqQK1Ee7UP4upv+I7fa9L y+s4GQrgc4H+PSb6IZ2Luc0SteIj6h6KbXamw8I12dp9wB8T4sgvlJAcdC9xsuZT/u TrO4tGS57ynPQ== From: Jeremy Kerr To: petitboot@lists.ozlabs.org Subject: [PATCH 1/2] discover/boot: add support for `kexec -s` for kexec_file_load Date: Tue, 29 Oct 2019 17:15:39 +0800 Message-Id: <20191029091540.6767-1-jk@ozlabs.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nayna Jain Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" kexec supports a -s option to perform a kexec_file_load syscall (in place of a kexec_load). This is triggered through the -s argument to kexec. This change adds support for calling kexec with -s. If that fails, we fall back to -l. Signed-off-by: Jeremy Kerr Reviewed-by: Joel Stanley --- discover/boot.c | 73 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/discover/boot.c b/discover/boot.c index 91fc46d..a6b88f0 100644 --- a/discover/boot.c +++ b/discover/boot.c @@ -60,14 +60,16 @@ static void __attribute__((format(__printf__, 4, 5))) update_status( */ static int kexec_load(struct boot_task *boot_task) { + const char *load_args[] = {"-s", "-l"}; struct process *process; char *s_initrd = NULL; char *s_args = NULL; const char *argv[8]; char *s_dtb = NULL; const char **p; + char *err_buf; int result; - + size_t i; boot_task->local_initrd_override = NULL; boot_task->local_dtb_override = NULL; @@ -83,7 +85,8 @@ static int kexec_load(struct boot_task *boot_task) " verification failure\n", __func__); } - goto abort_kexec; + validate_boot_files_cleanup(boot_task); + return result; } const char* local_initrd = (boot_task->local_initrd_override) ? @@ -93,20 +96,10 @@ static int kexec_load(struct boot_task *boot_task) const char* local_image = (boot_task->local_image_override) ? boot_task->local_image_override : boot_task->local_image; - process = process_create(boot_task); - if (!process) { - pb_log_fn("failed to create process\n"); - return -1; - } - - process->path = pb_system_apps.kexec; - process->argv = argv; - process->keep_stdout = true; - process->add_stderr = true; - + /* set up process arguments */ p = argv; *p++ = pb_system_apps.kexec; /* 1 */ - *p++ = "-l"; /* 2 */ + *p++ = NULL; /* 2; modified below */ if (pb_log_get_debug()) { *p++ = "--debug"; /* 3 */ @@ -134,21 +127,51 @@ static int kexec_load(struct boot_task *boot_task) *p++ = local_image; /* 7 */ *p++ = NULL; /* 8 */ - result = process_run_sync(process); - if (result) { - pb_log_fn("failed to run process\n"); - goto abort_kexec; - } + err_buf = NULL; - result = process->exit_status; + for (i = 0; i < ARRAY_SIZE(load_args); i++) { + /* our first argument is the action: -s or -l */ + argv[1] = load_args[i]; - if (result) { - pb_log_fn("failed: (%d)\n", result); - update_status(boot_task->status_fn, boot_task->status_arg, - STATUS_ERROR, "%s", process->stdout_buf); + process = process_create(boot_task); + if (!process) { + result = -1; + pb_log_fn("failed to create process\n"); + continue; + } + + process->path = pb_system_apps.kexec; + process->argv = argv; + process->keep_stdout = true; + process->add_stderr = true; + + result = process_run_sync(process); + if (result) { + pb_log_fn("failed to run process\n"); + continue; + } + + if (process_exit_ok(process)) + break; + + result = -1; + + if (process->stdout_len) + err_buf = talloc_strndup(boot_task, process->stdout_buf, + process->stdout_len); + + pb_log_fn("kexec load (%s) failed (rc %d): %s\n", argv[1], + WEXITSTATUS(process->exit_status), + err_buf ?: ""); + + process_release(process); } -abort_kexec: + if (result) + update_status(boot_task->status_fn, boot_task->status_arg, + STATUS_ERROR, _("kexec load failed: %s"), + err_buf ?: "(no output)"); + validate_boot_files_cleanup(boot_task); return result;