|
|
ee2076 |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
ee2076 |
From: Peter Jones <pjones@redhat.com>
|
|
|
ee2076 |
Date: Thu, 4 Oct 2018 14:22:09 -0400
|
|
|
ee2076 |
Subject: [PATCH] Reimplement boot_counter
|
|
|
ee2076 |
|
|
|
ee2076 |
This adds "increment" and "decrement" commands, and uses them to maintain our
|
|
|
ee2076 |
variables in 01_fallback_counter. It also simplifies the counter logic, so
|
|
|
ee2076 |
that there are no nested tests that conflict with each other.
|
|
|
ee2076 |
|
|
|
ee2076 |
Apparently, this *really* wasn't tested well enough.
|
|
|
ee2076 |
|
|
|
ee2076 |
Resolves: rhbz#1614637
|
|
|
ee2076 |
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
|
ee2076 |
[lorbus: add comments and revert logic changes in 01_fallback_counting]
|
|
|
ee2076 |
Signed-off-by: Christian Glombek <lorbus@fedoraproject.org>
|
|
|
ee2076 |
---
|
|
|
ee2076 |
Makefile.util.def | 6 +++
|
|
|
ee2076 |
grub-core/Makefile.core.def | 5 ++
|
|
|
ee2076 |
grub-core/commands/increment.c | 105 ++++++++++++++++++++++++++++++++++++
|
|
|
ee2076 |
util/grub.d/01_fallback_counting.in | 22 ++++++++
|
|
|
ee2076 |
4 files changed, 138 insertions(+)
|
|
|
ee2076 |
create mode 100644 grub-core/commands/increment.c
|
|
|
ee2076 |
create mode 100644 util/grub.d/01_fallback_counting.in
|
|
|
ee2076 |
|
|
|
ee2076 |
diff --git a/Makefile.util.def b/Makefile.util.def
|
|
|
ee2076 |
index 08cc98ddb8b..eca3dfa753f 100644
|
|
|
ee2076 |
--- a/Makefile.util.def
|
|
|
ee2076 |
+++ b/Makefile.util.def
|
|
|
ee2076 |
@@ -448,6 +448,12 @@ script = {
|
|
|
ee2076 |
installdir = grubconf;
|
|
|
ee2076 |
};
|
|
|
ee2076 |
|
|
|
ee2076 |
+script = {
|
|
|
ee2076 |
+ name = '01_fallback_counting';
|
|
|
ee2076 |
+ common = util/grub.d/01_fallback_counting.in;
|
|
|
ee2076 |
+ installdir = grubconf;
|
|
|
ee2076 |
+};
|
|
|
ee2076 |
+
|
|
|
ee2076 |
script = {
|
|
|
ee2076 |
name = '01_menu_auto_hide';
|
|
|
ee2076 |
common = util/grub.d/01_menu_auto_hide.in;
|
|
|
ee2076 |
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
|
|
ee2076 |
index 6864e780fd4..c8a50b4fcfa 100644
|
|
|
ee2076 |
--- a/grub-core/Makefile.core.def
|
|
|
ee2076 |
+++ b/grub-core/Makefile.core.def
|
|
|
ee2076 |
@@ -362,6 +362,11 @@ kernel = {
|
|
|
ee2076 |
extra_dist = kern/mips/cache_flush.S;
|
|
|
ee2076 |
};
|
|
|
ee2076 |
|
|
|
ee2076 |
+module = {
|
|
|
ee2076 |
+ name = increment;
|
|
|
ee2076 |
+ common = commands/increment.c;
|
|
|
ee2076 |
+};
|
|
|
ee2076 |
+
|
|
|
ee2076 |
program = {
|
|
|
ee2076 |
name = grub-emu;
|
|
|
ee2076 |
mansection = 1;
|
|
|
ee2076 |
diff --git a/grub-core/commands/increment.c b/grub-core/commands/increment.c
|
|
|
ee2076 |
new file mode 100644
|
|
|
ee2076 |
index 00000000000..79cf137656c
|
|
|
ee2076 |
--- /dev/null
|
|
|
ee2076 |
+++ b/grub-core/commands/increment.c
|
|
|
ee2076 |
@@ -0,0 +1,105 @@
|
|
|
ee2076 |
+/* increment.c - Commands to increment and decrement variables. */
|
|
|
ee2076 |
+/*
|
|
|
ee2076 |
+ * GRUB -- GRand Unified Bootloader
|
|
|
ee2076 |
+ * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
|
|
|
ee2076 |
+ *
|
|
|
ee2076 |
+ * GRUB is free software: you can redistribute it and/or modify
|
|
|
ee2076 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
ee2076 |
+ * the Free Software Foundation, either version 3 of the License, or
|
|
|
ee2076 |
+ * (at your option) any later version.
|
|
|
ee2076 |
+ *
|
|
|
ee2076 |
+ * GRUB is distributed in the hope that it will be useful,
|
|
|
ee2076 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
ee2076 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
ee2076 |
+ * GNU General Public License for more details.
|
|
|
ee2076 |
+ *
|
|
|
ee2076 |
+ * You should have received a copy of the GNU General Public License
|
|
|
ee2076 |
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
|
|
ee2076 |
+ */
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+#include <grub/dl.h>
|
|
|
ee2076 |
+#include <grub/term.h>
|
|
|
ee2076 |
+#include <grub/time.h>
|
|
|
ee2076 |
+#include <grub/types.h>
|
|
|
ee2076 |
+#include <grub/misc.h>
|
|
|
ee2076 |
+#include <grub/extcmd.h>
|
|
|
ee2076 |
+#include <grub/i18n.h>
|
|
|
ee2076 |
+#include <grub/env.h>
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+GRUB_MOD_LICENSE ("GPLv3+");
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+typedef enum {
|
|
|
ee2076 |
+ INCREMENT,
|
|
|
ee2076 |
+ DECREMENT,
|
|
|
ee2076 |
+} operation;
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+static grub_err_t
|
|
|
ee2076 |
+incr_decr(operation op, int argc, char **args)
|
|
|
ee2076 |
+{
|
|
|
ee2076 |
+ const char *old;
|
|
|
ee2076 |
+ char *new;
|
|
|
ee2076 |
+ long value;
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+ if (argc < 1)
|
|
|
ee2076 |
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no variable specified"));
|
|
|
ee2076 |
+ if (argc > 1)
|
|
|
ee2076 |
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("too many arguments"));
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+ old = grub_env_get (*args);
|
|
|
ee2076 |
+ if (!old)
|
|
|
ee2076 |
+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("No such variable \"%s\""),
|
|
|
ee2076 |
+ *args);
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+ value = grub_strtol (old, NULL, 0);
|
|
|
ee2076 |
+ if (grub_errno != GRUB_ERR_NONE)
|
|
|
ee2076 |
+ return grub_errno;
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+ switch (op)
|
|
|
ee2076 |
+ {
|
|
|
ee2076 |
+ case INCREMENT:
|
|
|
ee2076 |
+ value += 1;
|
|
|
ee2076 |
+ break;
|
|
|
ee2076 |
+ case DECREMENT:
|
|
|
ee2076 |
+ value -= 1;
|
|
|
ee2076 |
+ break;
|
|
|
ee2076 |
+ }
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+ new = grub_xasprintf ("%ld", value);
|
|
|
ee2076 |
+ if (!new)
|
|
|
ee2076 |
+ return grub_errno;
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+ grub_env_set (*args, new);
|
|
|
ee2076 |
+ grub_free (new);
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+ return GRUB_ERR_NONE;
|
|
|
ee2076 |
+}
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+static grub_err_t
|
|
|
ee2076 |
+grub_cmd_incr(struct grub_command *cmd UNUSED,
|
|
|
ee2076 |
+ int argc, char **args)
|
|
|
ee2076 |
+{
|
|
|
ee2076 |
+ return incr_decr(INCREMENT, argc, args);
|
|
|
ee2076 |
+}
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+static grub_err_t
|
|
|
ee2076 |
+grub_cmd_decr(struct grub_command *cmd UNUSED,
|
|
|
ee2076 |
+ int argc, char **args)
|
|
|
ee2076 |
+{
|
|
|
ee2076 |
+ return incr_decr(DECREMENT, argc, args);
|
|
|
ee2076 |
+}
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+static grub_command_t cmd_incr, cmd_decr;
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+GRUB_MOD_INIT(increment)
|
|
|
ee2076 |
+{
|
|
|
ee2076 |
+ cmd_incr = grub_register_command ("increment", grub_cmd_incr, N_("VARIABLE"),
|
|
|
ee2076 |
+ N_("increment VARIABLE"));
|
|
|
ee2076 |
+ cmd_decr = grub_register_command ("decrement", grub_cmd_decr, N_("VARIABLE"),
|
|
|
ee2076 |
+ N_("decrement VARIABLE"));
|
|
|
ee2076 |
+}
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+GRUB_MOD_FINI(increment)
|
|
|
ee2076 |
+{
|
|
|
ee2076 |
+ grub_unregister_command (cmd_incr);
|
|
|
ee2076 |
+ grub_unregister_command (cmd_decr);
|
|
|
ee2076 |
+}
|
|
|
ee2076 |
diff --git a/util/grub.d/01_fallback_counting.in b/util/grub.d/01_fallback_counting.in
|
|
|
ee2076 |
new file mode 100644
|
|
|
ee2076 |
index 00000000000..be0e770ea82
|
|
|
ee2076 |
--- /dev/null
|
|
|
ee2076 |
+++ b/util/grub.d/01_fallback_counting.in
|
|
|
ee2076 |
@@ -0,0 +1,22 @@
|
|
|
ee2076 |
+#! /bin/sh -e
|
|
|
ee2076 |
+
|
|
|
ee2076 |
+# Boot Counting
|
|
|
ee2076 |
+# The boot_counter env var can be used to count down boot attempts after an
|
|
|
ee2076 |
+# OSTree upgrade and choose the rollback deployment when 0 is reached. Both
|
|
|
ee2076 |
+# boot_counter and boot_success need to be (re-)set from userspace.
|
|
|
ee2076 |
+cat << EOF
|
|
|
ee2076 |
+insmod increment
|
|
|
ee2076 |
+# Check if boot_counter exists and boot_success=0 to activate this behaviour.
|
|
|
ee2076 |
+if [ -n "\${boot_counter}" -a "\${boot_success}" = "0" ]; then
|
|
|
ee2076 |
+ # if countdown has ended, choose to boot rollback deployment (default=1 on
|
|
|
ee2076 |
+ # OSTree-based systems)
|
|
|
ee2076 |
+ if [ "\${boot_counter}" = "0" -o "\${boot_counter}" = "-1" ]; then
|
|
|
ee2076 |
+ set default=1
|
|
|
ee2076 |
+ set boot_counter=-1
|
|
|
ee2076 |
+ # otherwise decrement boot_counter
|
|
|
ee2076 |
+ else
|
|
|
ee2076 |
+ decrement boot_counter
|
|
|
ee2076 |
+ fi
|
|
|
ee2076 |
+ save_env boot_counter
|
|
|
ee2076 |
+fi
|
|
|
ee2076 |
+EOF
|