[PATCH 1/2] discover/boot: add support for `kexec -s` for kexec_file_load
Joel Stanley
joel at jms.id.au
Thu Jan 23 21:36:34 AEDT 2020
On Tue, 29 Oct 2019 at 09:26, Jeremy Kerr <jk at ozlabs.org> wrote:
>
> 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 <jk at ozlabs.org>
Reviewed-by: Joel Stanley <joel at jms.id.au>
> ---
> 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;
> --
> 2.20.1
>
> _______________________________________________
> Petitboot mailing list
> Petitboot at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/petitboot
More information about the Petitboot
mailing list