static const char *translate_runlevel(int runlevel, bool *isolate) { static const struct { const int runlevel; const char *special; bool isolate; } table[] = { { '0', SPECIAL_POWEROFF_TARGET, false }, { '1', SPECIAL_RESCUE_TARGET, true }, { 's', SPECIAL_RESCUE_TARGET, true }, { 'S', SPECIAL_RESCUE_TARGET, true }, { '2', SPECIAL_MULTI_USER_TARGET, true }, { '3', SPECIAL_MULTI_USER_TARGET, true }, { '4', SPECIAL_MULTI_USER_TARGET, true }, { '5', SPECIAL_GRAPHICAL_TARGET, true }, { '6', SPECIAL_REBOOT_TARGET, false }, }; unsigned i; assert(isolate); for (i = 0; i < ELEMENTSOF(table); i++) if (table[i].runlevel == runlevel) { *isolate = table[i].isolate; if (runlevel == '6' && kexec_loaded()) return SPECIAL_KEXEC_TARGET; return table[i].special; } return NULL; }
int main(int argc, char *argv[]) { int do_load = 1; int do_exec = 0; int do_shutdown = 1; int do_sync = 1; int do_ifdown = 0; int do_unload = 0; int do_reuse_initrd = 0; unsigned long kexec_flags = 0; char *type = 0; char *endptr; int opt; int result = 0; int fileind; static const struct option options[] = { KEXEC_ARCH_OPTIONS { 0, 0, 0, 0}, }; static const char short_options[] = KEXEC_OPT_STR; opterr = 0; /* Don't complain about unrecognized options here */ while ((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { switch(opt) { case OPT_HELP: usage(); return 0; case OPT_VERSION: version(); return 0; case OPT_NOIFDOWN: do_ifdown = 0; break; case OPT_FORCE: do_load = 1; do_shutdown = 0; do_sync = 1; do_ifdown = 1; do_exec = 1; break; case OPT_LOAD: do_load = 1; do_exec = 0; do_shutdown = 0; break; case OPT_UNLOAD: do_load = 0; do_shutdown = 0; do_sync = 0; do_unload = 1; break; case OPT_EXEC: do_load = 0; do_shutdown = 0; do_sync = 1; do_ifdown = 1; do_exec = 1; break; case OPT_TYPE: type = optarg; break; case OPT_PANIC: do_load = 1; do_exec = 0; do_shutdown = 0; do_sync = 0; kexec_flags = KEXEC_ON_CRASH; break; case OPT_MEM_MIN: mem_min = strtoul(optarg, &endptr, 0); if (*endptr) { fprintf(stderr, "Bad option value in --mem-min=%s\n", optarg); usage(); return 1; } break; case OPT_MEM_MAX: mem_max = strtoul(optarg, &endptr, 0); if (*endptr) { fprintf(stderr, "Bad option value in --mem-max=%s\n", optarg); usage(); return 1; } break; case OPT_REUSE_INITRD: do_reuse_initrd = 1; break; default: break; } } if ((kexec_flags & KEXEC_ON_CRASH) && !is_crashkernel_mem_reserved()) { printf("Memory for crashkernel is not reserved\n"); printf("Please reserve memory by passing "); printf("\"crashkernel=X@Y\" parameter to the kernel\n"); die("Then try loading kdump kernel\n"); } fileind = optind; /* Reset getopt for the next pass; called in other source modules */ opterr = 1; optind = 1; result = arch_process_options(argc, argv); /* Check for bogus options */ if (!do_load) { while((opt = getopt_long(argc, argv, short_options, options, 0)) != -1) { if ((opt == '?') || (opt >= OPT_ARCH_MAX)) { usage(); return 1; } } } if (do_reuse_initrd){ check_reuse_initrd(); arch_reuse_initrd(); } if (do_unload) { result = k_unload(kexec_flags); } if (do_load && (result == 0)) { result = my_load(type, fileind, argc, argv, kexec_flags); } /* Don't shutdown unless there is something to reboot to! */ if ((result == 0) && (do_shutdown || do_exec) && !kexec_loaded()) { die("Nothing has been loaded!\n"); } if ((result == 0) && do_shutdown) { result = my_shutdown(); } if ((result == 0) && do_sync) { sync(); } if ((result == 0) && do_ifdown) { extern int ifdown(void); (void)ifdown(); } if ((result == 0) && do_exec) { result = my_exec(); } fflush(stdout); fflush(stderr); return result; }