mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Sascha Hauer <s.hauer@pengutronix.de>
To: BAREBOX <barebox@lists.infradead.org>
Subject: [PATCH 03/10] boot: revert globalvar changes after each boot entry
Date: Fri, 30 Oct 2026 11:54:01 +0100	[thread overview]
Message-ID: <20261030-boot-globalvar-stack-v1-3-a03803e1100c@pengutronix.de> (raw)
In-Reply-To: <20261030-boot-globalvar-stack-v1-0-a03803e1100c@pengutronix.de>

Boot entries, especially boot scripts, configure the boot by setting
global.bootm.* and global.linux.bootargs.* variables. To keep these from
leaking into the boot entries tried afterwards, there are currently two
mechanisms:

 - bootscript_boot() saves the global.bootm.* variables that are part of
   struct bootm_data and restores them afterwards. Variables not part of
   this struct, like global.bootm.tee, are not restored, and empty load
   addresses come back as the hex values of UIMAGE_SOME_ADDRESS resp.
   UIMAGE_INVALID_ADDRESS.
 - Kernel command line options have to be put into
   global.linux.bootargs.dyn.*, which boot_entry() clears after each boot
   entry. Options set by a boot entry in any other variable stay.

Replace both with a globalvar scope around the boot entry in
boot_entry(). This reverts all changes to the globalvars covered by
boot_globalvar_scope_push(), whatever the variable, and also restores
values that were set before the boot entry instead of clearing them.
This includes global.boot.watchdog_timeout, which boot_entry() reads
before running the boot entry, so a value set by a boot entry so far only
took effect for the following ones.

global.linux.bootargs.dyn.* still works as before for boot entries, but
values set in this namespace before calling boot are now kept instead of
being cleared once the first boot entry returns.

bootm_data_restore_defaults() has no users anymore, so remove it.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 Documentation/user/booting-linux.rst | 20 ++++++++++++++------
 Documentation/user/devboot.rst       |  4 ++--
 common/boot.c                        | 35 ++++++++---------------------------
 common/bootm.c                       | 21 ---------------------
 include/bootm.h                      |  1 -
 5 files changed, 24 insertions(+), 57 deletions(-)

diff --git a/Documentation/user/booting-linux.rst b/Documentation/user/booting-linux.rst
index afc705ac86..0fbdc52c68 100644
--- a/Documentation/user/booting-linux.rst
+++ b/Documentation/user/booting-linux.rst
@@ -164,16 +164,24 @@ A simple boot entry in ``/env/boot/mmc`` could look like this:
   global.bootm.image=/mnt/mmc1/zImage
   global.bootm.oftree=/env/oftree
 
-  global linux.bootargs.dyn.root="root=PARTUUID=deadbeef:01"
+  global linux.bootargs.root="root=PARTUUID=deadbeef:01"
 
 This takes the kernel from ``/mnt/mmc1/zImage`` (which could be an
 :ref:`automount` path registered earlier). The devicetree will be used from
 ``/env/oftree``. The Kernel gets the command line
-``root=PARTUUID=deadbeef:01``. Note the ``.dyn`` in the bootargs variable name.
-boot entries should always add Kernel command line parameters to variables with
-``.dyn`` in it. These will be cleared before booting different boot entries.
-This is done so that following boot entries do not leak command line
-parameters from the previous boot entries.
+``root=PARTUUID=deadbeef:01``.
+
+All changes a boot entry makes to ``global.bootm.*``, ``global.linux.*``,
+``global.of.*`` and
+:ref:`global.boot.watchdog_timeout <magicvar_global_boot_watchdog_timeout>`
+are reverted when the boot entry returns:
+modified variables get their previous value back, variables created by
+the boot entry are removed and variables it removed are created again.
+This way a boot entry that fails to boot doesn't leak its settings into
+the following boot entries. Older boot entries put their Kernel command
+line parameters into ``global.linux.bootargs.dyn.*`` for this reason,
+which still works, but is no longer necessary. Settings meant for all
+boot entries belong into an init script or an nv variable instead.
 
 This entry can be booted with ``boot mmc``. It can also be made the default by
 setting the :ref:`global.boot.default <magicvar_global_boot_default>` variable
diff --git a/Documentation/user/devboot.rst b/Documentation/user/devboot.rst
index e319636994..62cc357c3a 100644
--- a/Documentation/user/devboot.rst
+++ b/Documentation/user/devboot.rst
@@ -191,8 +191,8 @@ when ``CONFIG_BOOTM_OFTREE_FALLBACK`` is enabled), and appends the
 contains.
 
 Kernel command line fragments set by the script should use the
-``global.linux.bootargs.devboot.`` namespace. Unlike
-``global.linux.bootargs.dyn.``, which is cleared whenever a boot entry
+``global.linux.bootargs.devboot.`` namespace. Unlike variables set
+by the boot entries themselves, which are reverted whenever a boot entry
 returns, it survives falling through to the next boot target, e.g. for
 ``devboot system0 system1``. The ``devboot`` command removes the
 namespace after the boot command returns, so a subsequent plain
diff --git a/common/boot.c b/common/boot.c
index 1d8768b864..eaeff7796e 100644
--- a/common/boot.c
+++ b/common/boot.c
@@ -97,7 +97,7 @@ static int bootscript_boot(struct bootentry *entry, int verbose, int dryrun)
 	int bootm_nattempts;
 	int ret;
 
-	struct bootm_data backup = {}, data = {};
+	struct bootm_data data = {};
 
 	if (dryrun == 1) {
 		printf("Would run %s%s%s\n", bs->entry.path,
@@ -105,18 +105,6 @@ static int bootscript_boot(struct bootentry *entry, int verbose, int dryrun)
 		return 0;
 	}
 
-	bootm_data_init_defaults(&backup);
-
-	/*
-	 * The strings point to the globalvars' current values, which the
-	 * script frees when it assigns new ones. Keep our own copies.
-	 */
-	backup.os_file = xstrdup(backup.os_file);
-	backup.initrd_file = xstrdup(backup.initrd_file);
-	backup.oftree_file = xstrdup(backup.oftree_file);
-	backup.root_dev = xstrdup(backup.root_dev);
-	backup.root_param = xstrdup(backup.root_param);
-
 	globalvar_add_simple("linux.bootargs.dyn.ip", NULL);
 	globalvar_add_simple("linux.bootargs.dyn.root", NULL);
 
@@ -129,12 +117,12 @@ static int bootscript_boot(struct bootentry *entry, int verbose, int dryrun)
 	ret = execute_binfmt(bs->args ? 2 : 1, argv);
 	if (ret) {
 		pr_err("Running script '%s' failed: %s\n", bs->entry.path, strerror(-ret));
-		goto out;
+		return ret;
 	}
 
 	/* No point in repeating bootm if script already called it */
 	if (bootm_nattempts != bootm_command_attempts())
-		goto out;
+		return 0;
 
 	bootm_data_init_defaults(&data);
 
@@ -143,17 +131,7 @@ static int bootscript_boot(struct bootentry *entry, int verbose, int dryrun)
 	if (dryrun >= 2)
 		data.dryrun = dryrun - 1;
 
-	ret = bootm_entry(entry, &data);
-out:
-	bootm_data_restore_defaults(&backup);
-
-	free_const(backup.os_file);
-	free_const(backup.initrd_file);
-	free_const(backup.oftree_file);
-	free_const(backup.root_dev);
-	free_const(backup.root_param);
-
-	return ret;
+	return bootm_entry(entry, &data);
 }
 
 static unsigned int boot_watchdog_timeout;
@@ -210,6 +188,7 @@ BAREBOX_MAGICVAR(global.user,
 
 int boot_entry(struct bootentry *be, int verbose, int dryrun)
 {
+	struct globalvar_scope *scope;
 	int ret;
 
 	pr_info("Booting entry '%s'\n", be->title);
@@ -224,11 +203,13 @@ int boot_entry(struct bootentry *be, int verbose, int dryrun)
 		}
 	}
 
+	scope = boot_globalvar_scope_push();
+
 	ret = be->boot(be, verbose, dryrun);
 	if (ret && ret != -ENOMEDIUM)
 		pr_err("Booting entry '%s' failed: %pe\n", be->title, ERR_PTR(ret));
 
-	globalvar_set_match("linux.bootargs.dyn.", "");
+	globalvar_scope_pop(scope);
 
 	return ret;
 }
diff --git a/common/bootm.c b/common/bootm.c
index 22f2ca4081..2ad8c34bb4 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -101,27 +101,6 @@ void bootm_data_init_defaults(struct bootm_data *data)
 	data->efi_boot = bootm_efi_mode;
 }
 
-void bootm_data_restore_defaults(const struct bootm_data *data)
-{
-	globalvar_set("bootm.oftree", data->oftree_file);
-	globalvar_set("bootm.image", data->os_file);
-	pr_setenv("global.bootm.image.loadaddr", "0x%lx", data->os_address);
-	if (IS_ENABLED(CONFIG_BOOTM_INITRD)) {
-		pr_setenv("global.bootm.initrd.loadaddr", "0x%lx", data->initrd_address);
-		globalvar_set("bootm.initrd", data->initrd_file);
-	}
-	globalvar_set("bootm.root_dev", data->root_dev);
-	globalvar_set("bootm.root_param", data->root_param);
-	bootm_set_verify_mode(data->verify);
-	bootm_appendroot = data->appendroot;
-	bootm_provide_machine_id = data->provide_machine_id;
-	bootm_provide_hostname = data->provide_hostname;
-	bootm_provide_policy = data->provide_policy;
-	bootm_verbosity = data->verbose;
-	bootm_dryrun = data->dryrun;
-	bootm_efi_mode = data->efi_boot;
-}
-
 static enum bootm_verify bootm_verify_mode = BOOTM_VERIFY_AVAILABLE;
 
 enum bootm_verify bootm_get_verify_mode(void)
diff --git a/include/bootm.h b/include/bootm.h
index bbdbb8e69d..06eb90c5ed 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -196,7 +196,6 @@ static inline int bootm_verbose(struct image_data *data)
 #endif
 
 void bootm_data_init_defaults(struct bootm_data *data);
-void bootm_data_restore_defaults(const struct bootm_data *data);
 
 const struct resource *
 bootm_load_os(struct image_data *data,

-- 
2.47.3




  parent reply	other threads:[~2026-10-30 10:55 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-30 10:53 [PATCH 00/10] boot: revert boot related globalvars after booting Sascha Hauer
2026-10-30 10:53 ` [PATCH 01/10] globalvar: add scopes to snapshot and restore globalvars Sascha Hauer
2026-10-30 10:54 ` [PATCH 02/10] bootm: revert globalvar changes in bootm_boot_cleanup() Sascha Hauer
2026-10-30 10:54 ` Sascha Hauer [this message]
2026-10-30 10:54 ` [PATCH 04/10] bootchooser: use a globalvar scope for its bootargs Sascha Hauer
2026-10-30 10:54 ` [PATCH 05/10] test: py: add test for reverting globalvars after boot Sascha Hauer
2026-10-30 10:54 ` [PATCH 06/10] bootargs: remove unused linux_bootargs_overwrite() Sascha Hauer
2026-10-30 10:54 ` [PATCH 07/10] of: add watchdog bootarg directly instead of via a globalvar Sascha Hauer
2026-10-30 10:54 ` [PATCH 08/10] boot: drop the dyn infix from the bootentries bootargs variable Sascha Hauer
2026-10-30 10:54 ` [PATCH 09/10] defaultenv: don't use global.linux.bootargs.dyn.* in boot entries Sascha Hauer
2026-10-30 10:54 ` [PATCH 10/10] Documentation: migration-guides: describe reverting boot globalvars Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261030-boot-globalvar-stack-v1-3-a03803e1100c@pengutronix.de \
    --to=s.hauer@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox