diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2016-08-24 12:22:40 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2016-09-22 11:44:23 +0200 |
commit | cc532a3f733718526898c14f8137118b7d76a5bc (patch) | |
tree | 2addc58100c74b55f6477012f1d2f4df27de0c99 /commands | |
parent | 6d8beeaad1e1133ae48664223793394310b1db46 (diff) | |
download | barebox-cc532a3f733718526898c14f8137118b7d76a5bc.tar.gz barebox-cc532a3f733718526898c14f8137118b7d76a5bc.tar.xz |
boot: add framework for redundant boot scenarios
There are several use cases where a redundant Linux system is needed. The
barebox bootchooser framework provides the building blocks to model different
use cases without the need to start from the scratch over and over again.
The bootchooser works on abstract boot targets, each with a set of properties
and implements an algorithm which selects the highest priority target to boot.
See the documentation contained in this patch for more information.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'commands')
-rw-r--r-- | commands/Kconfig | 5 | ||||
-rw-r--r-- | commands/Makefile | 1 | ||||
-rw-r--r-- | commands/bootchooser.c | 148 |
3 files changed, 154 insertions, 0 deletions
diff --git a/commands/Kconfig b/commands/Kconfig index 3c79831d99..21d921268f 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -2097,6 +2097,11 @@ config CMD_STATE depends on STATE prompt "state" +config CMD_BOOTCHOOSER + tristate + depends on BOOTCHOOSER + prompt "bootchooser" + config CMD_DHRYSTONE bool prompt "dhrystone" diff --git a/commands/Makefile b/commands/Makefile index 7abd6dd406..601f15fc38 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -115,6 +115,7 @@ obj-$(CONFIG_CMD_NV) += nv.o obj-$(CONFIG_CMD_DEFAULTENV) += defaultenv.o obj-$(CONFIG_CMD_STATE) += state.o obj-$(CONFIG_CMD_DHCP) += dhcp.o +obj-$(CONFIG_CMD_BOOTCHOOSER) += bootchooser.o obj-$(CONFIG_CMD_DHRYSTONE) += dhrystone.o obj-$(CONFIG_CMD_SPD_DECODE) += spd_decode.o obj-$(CONFIG_CMD_MMC_EXTCSD) += mmc_extcsd.o diff --git a/commands/bootchooser.c b/commands/bootchooser.c new file mode 100644 index 0000000000..91938fe551 --- /dev/null +++ b/commands/bootchooser.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2012 Jan Luebbe <j.luebbe@pengutronix.de> + * Copyright (C) 2015 Marc Kleine-Budde <mkl@pengutronix.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <bootchooser.h> +#include <globalvar.h> +#include <command.h> +#include <common.h> +#include <getopt.h> +#include <malloc.h> +#include <stdio.h> + +#define DONTTOUCH -2 +#define DEFAULT -1 + +static void target_reset(struct bootchooser_target *target, int priority, int attempts) +{ + printf("Resetting target %s to ", bootchooser_target_name(target)); + + if (priority >= 0) + printf("priority %d", priority); + else if (priority == DEFAULT) + printf("default priority"); + + if (priority > DONTTOUCH && attempts > DONTTOUCH) + printf(", "); + + if (attempts >= 0) + printf("%d attempts", attempts); + else if (attempts == DEFAULT) + printf("default attempts"); + + printf("\n"); + + if (priority > DONTTOUCH) + bootchooser_target_set_priority(target, priority); + if (attempts > DONTTOUCH) + bootchooser_target_set_attempts(target, attempts); +} + +static int do_bootchooser(int argc, char *argv[]) +{ + int opt, ret = 0, i; + struct bootchooser *bootchooser; + struct bootchooser_target *target; + int attempts = DONTTOUCH; + int priority = DONTTOUCH; + int info = 0; + bool done_something = false; + bool last_boot_successful = false; + + while ((opt = getopt(argc, argv, "a:p:is")) > 0) { + switch (opt) { + case 'a': + if (!strcmp(optarg, "default")) + attempts = DEFAULT; + else + attempts = simple_strtoul(optarg, NULL, 0); + break; + case 'p': + if (!strcmp(optarg, "default")) + priority = DEFAULT; + else + priority = simple_strtoul(optarg, NULL, 0); + break; + case 'i': + info = 1; + break; + case 's': + last_boot_successful = true; + break; + default: + return COMMAND_ERROR_USAGE; + } + } + + bootchooser = bootchooser_get(); + if (IS_ERR(bootchooser)) { + printf("No bootchooser found\n"); + return COMMAND_ERROR; + } + + if (last_boot_successful) { + bootchooser_last_boot_successful(); + done_something = true; + } + + if (attempts != DONTTOUCH || priority != DONTTOUCH) { + if (optind < argc) { + for (i = optind; i < argc; i++) { + target = bootchooser_target_by_name(bootchooser, argv[i]); + if (!target) { + printf("No such target: %s\n", argv[i]); + ret = COMMAND_ERROR; + goto out; + } + + target_reset(target, priority, attempts); + } + } else { + bootchooser_for_each_target(bootchooser, target) + target_reset(target, priority, attempts); + } + done_something = true; + } + + if (info) { + bootchooser_info(bootchooser); + done_something = true; + } + + if (!done_something) { + printf("Nothing to do\n"); + ret = COMMAND_ERROR_USAGE; + } +out: + bootchooser_put(bootchooser); + + return ret; +} + +BAREBOX_CMD_HELP_START(bootchooser) +BAREBOX_CMD_HELP_TEXT("Control misc behaviour of the bootchooser") +BAREBOX_CMD_HELP_TEXT("") +BAREBOX_CMD_HELP_TEXT("Options:") +BAREBOX_CMD_HELP_OPT ("-a <n|default> [TARGETS]", "set priority of given targets to 'n' or the default priority") +BAREBOX_CMD_HELP_OPT ("-p <n|default> [TARGETS]", "set remaining attempts of given targets to 'n' or the default attempts") +BAREBOX_CMD_HELP_OPT ("-i", "Show information about the bootchooser") +BAREBOX_CMD_HELP_OPT ("-s", "Mark the last boot successful") +BAREBOX_CMD_HELP_END + +BAREBOX_CMD_START(bootchooser) + .cmd = do_bootchooser, + BAREBOX_CMD_DESC("bootchooser control") + BAREBOX_CMD_GROUP(CMD_GRP_MISC) + BAREBOX_CMD_HELP(cmd_bootchooser_help) +BAREBOX_CMD_END |