+ run_boot_hooks(task);
+
+ update_status(task->status_fn, task->status_arg, BOOT_STATUS_INFO,
+ "performing kexec_load");
+
+ rc = kexec_load(task);
+ if (rc) {
+ update_status(task->status_fn, task->status_arg,
+ BOOT_STATUS_ERROR, "kexec load failed");
+ }
+
+no_load:
+ cleanup_load(task->image);
+ cleanup_load(task->initrd);
+ cleanup_load(task->dtb);
+
+ if (!rc) {
+ update_status(task->status_fn, task->status_arg,
+ BOOT_STATUS_INFO,
+ "performing kexec reboot");
+
+ rc = kexec_reboot(task);
+ if (rc) {
+ update_status(task->status_fn, task->status_arg,
+ BOOT_STATUS_ERROR,
+ "kexec reboot failed");
+ }
+ }
+}
+
+static int start_url_load(struct boot_task *task, const char *name,
+ struct pb_url *url, struct load_url_result **result)
+{
+ if (!url)
+ return 0;
+
+ *result = load_url_async(task, url, boot_process, task);
+ if (!*result) {
+ update_status(task->status_fn, task->status_arg,
+ BOOT_STATUS_ERROR,
+ "Error loading %s", name);
+ return -1;
+ }
+ return 0;
+}
+
+struct boot_task *boot(void *ctx, struct discover_boot_option *opt,
+ struct boot_command *cmd, int dry_run,
+ boot_status_fn status_fn, void *status_arg)
+{
+ struct pb_url *image = NULL, *initrd = NULL, *dtb = NULL;
+ struct boot_task *boot_task;
+ const char *boot_desc;
+ int rc;
+
+ if (opt && opt->option->name)
+ boot_desc = opt->option->name;
+ else if (cmd && cmd->boot_image_file)
+ boot_desc = cmd->boot_image_file;
+ else
+ boot_desc = "(unknown)";
+
+ update_status(status_fn, status_arg, BOOT_STATUS_INFO,
+ "Booting %s.", boot_desc);