summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamuel Mendoza-Jonas <sam@mendozajonas.com>2016-12-02 15:18:36 +1100
committerSamuel Mendoza-Jonas <sam@mendozajonas.com>2016-12-20 16:40:21 +1100
commit454f924bbcda7904c4348ef45c3d0d293768a48c (patch)
tree46e5d1c6d4dafa0c79247f2571505ef92584de41
parentba14fc8ec91b54be57fdf2ca373e3d140ae2b6d6 (diff)
downloadpetitboot-454f924bbcda7904c4348ef45c3d0d293768a48c.zip
petitboot-454f924bbcda7904c4348ef45c3d0d293768a48c.tar.gz
discover/boot: Improve kexec error reporting
Update kexec_load() to preserve output from the call to `kexec -l`. On error retrieve the resulting error message and update the status line with it to provide a more informative error message. Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
-rw-r--r--discover/boot.c77
1 files changed, 48 insertions, 29 deletions
diff --git a/discover/boot.c b/discover/boot.c
index 82fba2f..5347fd7 100644
--- a/discover/boot.c
+++ b/discover/boot.c
@@ -34,17 +34,38 @@ enum {
BOOT_HOOK_EXIT_UPDATE = 2,
};
+static void __attribute__((format(__printf__, 4, 5))) update_status(
+ boot_status_fn fn, void *arg, int type, char *fmt, ...)
+{
+ struct status status;
+ va_list ap;
+
+ va_start(ap, fmt);
+ status.message = talloc_vasprintf(NULL, fmt, ap);
+ va_end(ap);
+
+ status.type = type;
+
+ pb_debug("boot status: [%d] %s\n", type, status.message);
+
+ fn(arg, &status);
+
+ talloc_free(status.message);
+}
+
/**
* kexec_load - kexec load helper.
*/
static int kexec_load(struct boot_task *boot_task)
{
- int result;
- const char *argv[7];
- const char **p;
+ struct process *process;
char *s_initrd = NULL;
- char *s_dtb = NULL;
char *s_args = NULL;
+ const char *argv[7];
+ char *s_dtb = NULL;
+ const char **p;
+ int result;
+
boot_task->local_initrd_override = NULL;
boot_task->local_dtb_override = NULL;
@@ -70,6 +91,17 @@ 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("%s: failed to create process\n", __func__);
+ return -1;
+ }
+
+ process->path = pb_system_apps.kexec;
+ process->argv = argv;
+ process->keep_stdout = true;
+ process->add_stderr = true;
+
p = argv;
*p++ = pb_system_apps.kexec; /* 1 */
*p++ = "-l"; /* 2 */
@@ -96,10 +128,19 @@ static int kexec_load(struct boot_task *boot_task)
*p++ = local_image; /* 6 */
*p++ = NULL; /* 7 */
- result = process_run_simple_argv(boot_task, argv);
+ result = process_run_sync(process);
+ if (result) {
+ pb_log("%s: failed to run process\n", __func__);
+ goto abort_kexec;
+ }
+
+ result = process->exit_status;
- if (result)
+ if (result) {
pb_log("%s: failed: (%d)\n", __func__, result);
+ update_status(boot_task->status_fn, boot_task->status_arg,
+ STATUS_ERROR, "%s", process->stdout_buf);
+ }
abort_kexec:
gpg_validate_boot_files_cleanup(boot_task);
@@ -143,25 +184,6 @@ static int kexec_reboot(struct boot_task *task)
return result;
}
-static void __attribute__((format(__printf__, 4, 5))) update_status(
- boot_status_fn fn, void *arg, int type, char *fmt, ...)
-{
- struct status status;
- va_list ap;
-
- va_start(ap, fmt);
- status.message = talloc_vasprintf(NULL, fmt, ap);
- va_end(ap);
-
- status.type = type;
-
- pb_debug("boot status: [%d] %s\n", type, status.message);
-
- fn(arg, &status);
-
- talloc_free(status.message);
-}
-
static void boot_hook_update_param(void *ctx, struct boot_task *task,
const char *name, const char *value)
{
@@ -452,6 +474,7 @@ static void boot_process(struct load_url_result *result, void *data)
_("Performing kexec load"));
rc = kexec_load(task);
+ pb_log("%s: kexec_load returned %d\n", __func__, rc);
if (rc == KEXEC_LOAD_DECRYPTION_FALURE) {
update_status(task->status_fn, task->status_arg,
STATUS_ERROR, _("Decryption failed"));
@@ -466,10 +489,6 @@ static void boot_process(struct load_url_result *result, void *data)
STATUS_ERROR,
_("Invalid signature configuration"));
}
- else if (rc) {
- update_status(task->status_fn, task->status_arg,
- STATUS_ERROR, _("kexec load failed"));
- }
no_sig_load:
cleanup_load(task->image_signature);
OpenPOWER on IntegriCloud