X-Git-Url: http://git.ozlabs.org/?p=petitboot;a=blobdiff_plain;f=discover%2Fboot.c;h=29aefa916a8e149b973c69baccbb52b6a6bef799;hp=02618cce1251fd070e3baec29c27bac762141c45;hb=556e622653c72de9b3eda70995e9f8619ee1c9a1;hpb=3ea411971ea7db66c44527aa720d82567b7a1a5a diff --git a/discover/boot.c b/discover/boot.c index 02618cc..29aefa9 100644 --- a/discover/boot.c +++ b/discover/boot.c @@ -5,9 +5,12 @@ #include #include #include +#include +#include "device-handler.h" #include "boot.h" #include "paths.h" +#include "resource.h" /** * kexec_load - kexec load helper. @@ -91,58 +94,105 @@ static int kexec_reboot(int dry_run) if (result) pb_log("%s: failed: (%d)\n", __func__, result); + /* okay, kexec -e -f */ + if (result) { + p = argv; + *p++ = pb_system_apps.kexec; /* 1 */ + *p++ = "-e"; /* 2 */ + *p++ = "-f"; /* 3 */ + *p++ = NULL; /* 4 */ + + result = pb_run_cmd(argv, 1, 0); + } + + if (result) + pb_log("%s: failed: (%d)\n", __func__, result); + + return result; } -int boot(void *ctx, struct boot_option *opt, struct boot_command *cmd, - int dry_run) +static void update_status(boot_status_fn fn, void *arg, int type, + char *message) +{ + struct boot_status status; + + status.type = type; + status.message = message; + status.progress = -1; + status.detail = NULL; + + fn(arg, &status); +} + +int boot(void *ctx, struct discover_boot_option *opt, struct boot_command *cmd, + int dry_run, boot_status_fn status_fn, void *status_arg) { char *local_image, *local_initrd; unsigned int clean_image = 0; unsigned int clean_initrd = 0; - char *image, *initrd, *args; + struct pb_url *image, *initrd; + char *args; int result; + local_initrd = NULL; image = NULL; initrd = NULL; args = NULL; if (cmd->boot_image_file) { - image = talloc_strdup(ctx, cmd->boot_image_file); - } else if (opt && opt->boot_image_file) { - image = talloc_strdup(ctx, opt->boot_image_file); + image = pb_url_parse(opt, cmd->boot_image_file); + } else if (opt && opt->boot_image) { + image = opt->boot_image->url; } else { pb_log("%s: no image specified", __func__); return -1; } if (cmd->initrd_file) { - initrd = talloc_strdup(ctx, cmd->initrd_file); - } else if (opt && opt->initrd_file) { - initrd = talloc_strdup(ctx, opt->initrd_file); + initrd = pb_url_parse(opt, cmd->initrd_file); + } else if (opt && opt->initrd) { + initrd = opt->initrd->url; } if (cmd->boot_args) { args = talloc_strdup(ctx, cmd->boot_args); - } else if (opt && opt->boot_args) { - args = talloc_strdup(ctx, opt->boot_args); + } else if (opt && opt->option->boot_args) { + args = talloc_strdup(ctx, opt->option->boot_args); } result = -1; - local_image = load_file(NULL, image, &clean_image); - if (!local_image) + update_status(status_fn, status_arg, BOOT_STATUS_INFO, + "loading kernel"); + local_image = load_url(NULL, image, &clean_image); + if (!local_image) { + update_status(status_fn, status_arg, BOOT_STATUS_ERROR, + "Couldn't load kernel image"); goto no_load; + } - local_initrd = NULL; if (initrd) { - local_initrd = load_file(NULL, initrd, &clean_initrd); - if (!local_initrd) + update_status(status_fn, status_arg, BOOT_STATUS_INFO, + "loading initrd"); + local_initrd = load_url(NULL, initrd, &clean_initrd); + if (!local_initrd) { + update_status(status_fn, status_arg, BOOT_STATUS_ERROR, + "Couldn't load initrd image"); goto no_load; + } } + update_status(status_fn, status_arg, BOOT_STATUS_INFO, + "performing kexec_load"); + result = kexec_load(local_image, local_initrd, args, dry_run); + if (result) { + update_status(status_fn, status_arg, BOOT_STATUS_ERROR, + "kexec load failed"); + } + no_load: if (clean_image) unlink(local_image); @@ -152,8 +202,17 @@ no_load: talloc_free(local_image); talloc_free(local_initrd); - if (!result) + if (!result) { + update_status(status_fn, status_arg, BOOT_STATUS_INFO, + "performing kexec reboot"); + result = kexec_reboot(dry_run); + if (result) { + update_status(status_fn, status_arg, BOOT_STATUS_ERROR, + "kexec reboot failed"); + } + } + return result; }