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;
+ status.backlog = false;
+
+ 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;
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 */
*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;
+ }
- if (result)
+ result = process->exit_status;
+
+ 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);
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;
- status.progress = -1;
- status.detail = NULL;
-
- 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)
{
return;
update_status(task->status_fn, task->status_arg, STATUS_INFO,
- _("running boot hooks"));
+ _("Running boot hooks"));
boot_hook_setenv(task);
{
if (!result)
return 0;
- if (result->status != LOAD_ERROR)
+
+ if (result->status != LOAD_ERROR) {
+ update_status(task->status_fn, task->status_arg,
+ STATUS_ERROR,
+ _("Loaded %s from %s"), name,
+ pb_url_to_string(result->url));
return 0;
+ }
update_status(task->status_fn, task->status_arg,
STATUS_ERROR,
- _("Couldn't load %s"), name);
+ _("Couldn't load %s from %s"), name,
+ pb_url_to_string(result->url));
return -1;
}
run_boot_hooks(task);
update_status(task->status_fn, task->status_arg, STATUS_INFO,
- _("performing kexec_load"));
+ _("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"));
+ STATUS_ERROR, _("Decryption failed"));
}
else if (rc == KEXEC_LOAD_SIGNATURE_FAILURE) {
update_status(task->status_fn, task->status_arg,
STATUS_ERROR,
- _("signature verification failed"));
+ _("Signature verification failed"));
}
else if (rc == KEXEC_LOAD_SIG_SETUP_INVALID) {
update_status(task->status_fn, task->status_arg,
STATUS_ERROR,
- _("invalid signature configuration"));
- }
- else if (rc) {
- update_status(task->status_fn, task->status_arg,
- STATUS_ERROR, _("kexec load failed"));
+ _("Invalid signature configuration"));
}
no_sig_load:
if (!rc) {
update_status(task->status_fn, task->status_arg,
- STATUS_INFO, _("performing kexec reboot"));
+ STATUS_INFO, _("Performing kexec reboot"));
rc = kexec_reboot(task);
if (rc) {
if (!url)
return 0;
- *result = load_url_async(task, url, boot_process, task);
+ *result = load_url_async(task, url, boot_process, task, NULL,
+ task->status_arg);
if (!*result) {
update_status(task->status_fn, task->status_arg,
STATUS_ERROR, _("Error loading %s"), name);
boot_desc = _("(unknown)");
update_status(status_fn, status_arg, STATUS_INFO,
- _("Booting %s."), boot_desc);
+ _("Booting %s"), boot_desc);
if (cmd && cmd->boot_image_file) {
image = pb_url_parse(opt, cmd->boot_image_file);
}
/* start async loads for boot resources */
- rc = start_url_load(boot_task, "kernel image", image, &boot_task->image)
- || start_url_load(boot_task, "initrd", initrd, &boot_task->initrd)
- || start_url_load(boot_task, "dtb", dtb, &boot_task->dtb);
+ rc = start_url_load(boot_task, _("kernel image"),
+ image, &boot_task->image)
+ || start_url_load(boot_task, _("initrd"), initrd, &boot_task->initrd)
+ || start_url_load(boot_task, _("dtb"), dtb, &boot_task->dtb);
if (boot_task->verify_signature) {
/* Generate names of associated signature files and load */
if (image) {
image_sig = gpg_get_signature_url(ctx, image);
rc |= start_url_load(boot_task,
- "kernel image signature", image_sig,
+ _("kernel image signature"), image_sig,
&boot_task->image_signature);
}
if (initrd) {
initrd_sig = gpg_get_signature_url(ctx, initrd);
- rc |= start_url_load(boot_task, "initrd signature",
+ rc |= start_url_load(boot_task, _("initrd signature"),
initrd_sig, &boot_task->initrd_signature);
}
if (dtb) {
dtb_sig = gpg_get_signature_url(ctx, dtb);
- rc |= start_url_load(boot_task, "dtb signature",
+ rc |= start_url_load(boot_task, _("dtb signature"),
dtb_sig, &boot_task->dtb_signature);
}
}
if (boot_task->verify_signature || boot_task->decrypt_files) {
rc |= start_url_load(boot_task,
- "kernel command line signature", cmdline_sig,
+ _("kernel command line signature"), cmdline_sig,
&boot_task->cmdline_signature);
}