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 boot_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)
{
unsetenv("boot_initrd");
unsetenv("boot_dtb");
unsetenv("boot_args");
- unsetenv("boot_tty");
+ unsetenv("boot_console");
setenv("boot_image", task->local_image, 1);
if (task->local_initrd)
setenv("boot_dtb", task->local_dtb, 1);
if (task->args)
setenv("boot_args", task->args, 1);
- if (task->boot_tty)
- setenv("boot_tty", task->boot_tty, 1);
+ if (task->boot_console)
+ setenv("boot_console", task->boot_console, 1);
}
static int hook_filter(const struct dirent *dirent)
if (n < 1)
return;
- update_status(task->status_fn, task->status_arg, BOOT_STATUS_INFO,
- _("running boot hooks"));
+ update_status(task->status_fn, task->status_arg, STATUS_INFO,
+ _("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,
- BOOT_STATUS_ERROR,
- _("Couldn't load %s"), name);
+ STATUS_ERROR,
+ _("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, BOOT_STATUS_INFO,
- _("performing kexec_load"));
+ update_status(task->status_fn, task->status_arg, STATUS_INFO,
+ _("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,
- BOOT_STATUS_ERROR, _("decryption failed"));
+ STATUS_ERROR, _("Decryption failed"));
}
else if (rc == KEXEC_LOAD_SIGNATURE_FAILURE) {
update_status(task->status_fn, task->status_arg,
- BOOT_STATUS_ERROR,
- _("signature verification failed"));
+ STATUS_ERROR,
+ _("Signature verification failed"));
}
else if (rc == KEXEC_LOAD_SIG_SETUP_INVALID) {
update_status(task->status_fn, task->status_arg,
- BOOT_STATUS_ERROR,
- _("invalid signature configuration"));
- }
- else if (rc) {
- update_status(task->status_fn, task->status_arg,
- BOOT_STATUS_ERROR,
- _("kexec load failed"));
+ STATUS_ERROR,
+ _("Invalid signature configuration"));
}
no_sig_load:
if (!rc) {
update_status(task->status_fn, task->status_arg,
- BOOT_STATUS_INFO,
- _("performing kexec reboot"));
+ STATUS_INFO, _("Performing kexec reboot"));
rc = kexec_reboot(task);
if (rc) {
update_status(task->status_fn, task->status_arg,
- BOOT_STATUS_ERROR,
+ STATUS_ERROR,
_("kexec reboot failed"));
}
}
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,
- BOOT_STATUS_ERROR,
- _("Error loading %s"), name);
+ STATUS_ERROR, _("Error loading %s"), name);
return -1;
}
return 0;
struct pb_url *image = NULL, *initrd = NULL, *dtb = NULL;
struct pb_url *image_sig = NULL, *initrd_sig = NULL, *dtb_sig = NULL,
*cmdline_sig = NULL;
- const struct config *config;
+ const struct config *config = config_get();
struct boot_task *boot_task;
const char *boot_desc;
int rc;
else
boot_desc = _("(unknown)");
- update_status(status_fn, status_arg, BOOT_STATUS_INFO,
- _("Booting %s."), boot_desc);
+ update_status(status_fn, status_arg, STATUS_INFO,
+ _("Booting %s"), boot_desc);
if (cmd && cmd->boot_image_file) {
image = pb_url_parse(opt, cmd->boot_image_file);
image = opt->boot_image->url;
} else {
pb_log("%s: no image specified\n", __func__);
- update_status(status_fn, status_arg, BOOT_STATUS_INFO,
+ update_status(status_fn, status_arg, STATUS_INFO,
_("Boot failed: no image specified"));
return NULL;
}
boot_task->args = NULL;
}
- if (cmd && cmd->tty)
- boot_task->boot_tty = talloc_strdup(boot_task, cmd->tty);
- else {
- config = config_get();
- boot_task->boot_tty = config ? config->boot_tty : NULL;
- }
+ if (cmd && cmd->console && !config->manual_console)
+ boot_task->boot_console = talloc_strdup(boot_task, cmd->console);
+ else
+ boot_task->boot_console = config ? config->boot_console : NULL;
if (boot_task->verify_signature || boot_task->decrypt_files) {
if (cmd && cmd->args_sig_file) {
} else {
pb_log("%s: no command line signature file"
" specified\n", __func__);
- update_status(status_fn, status_arg, BOOT_STATUS_INFO,
+ update_status(status_fn, status_arg, STATUS_INFO,
_("Boot failed: no command line"
" signature file specified"));
talloc_free(boot_task);
}
/* 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);
}
{
task->cancelled = true;
- update_status(task->status_fn, task->status_arg, BOOT_STATUS_INFO,
+ update_status(task->status_fn, task->status_arg, STATUS_INFO,
_("Boot cancelled"));
cleanup_cancellations(task, NULL);