Message ID | 20191029091540.6767-1-jk@ozlabs.org |
---|---|
State | Under Review |
Headers | show |
Series | [1/2] discover/boot: add support for `kexec -s` for kexec_file_load | expand |
On Tue, 29 Oct 2019 at 09:26, Jeremy Kerr <jk@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@ozlabs.org> Reviewed-by: Joel Stanley <joel@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@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/petitboot
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;
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@ozlabs.org> --- discover/boot.c | 73 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 25 deletions(-)