From: Michael Chang via Grub-devel <grub-devel@gnu.org>
To: The development of GNU GRUB <grub-devel@gnu.org>
Cc: Michael Chang <mchang@suse.com>, Neal Gompa <ngompa13@gmail.com>,
Marta Lewandowska <mlewando@redhat.com>
Subject: [PATCH v2 4/9] util/grub-editenv: wire set_variables to optional fs_envblk
Date: Mon, 15 Sep 2025 17:08:43 +0800 [thread overview]
Message-ID: <20250915090848.131937-5-mchang@suse.com> (raw)
In-Reply-To: <20250915090848.131937-1-mchang@suse.com>
This patch changes set_variables so that it can use an external
environment block when one is present. The variable next_entry is
written into the external block, env_block is treated as read only, and
all other variables are written into the normal file based envblk.
A cleanup step is added to handle cases where GRUB at runtime writes
variables into the external block because file based updates are not
safe on a copy on write filesystem such as Btrfs. For example, the
savedefault command can update saved_entry, and on Btrfs GRUB will place
that update in the external block instead of the file envblk. If an
older copy remains in the external block, it would override the newer
value from the file envblk when GRUB first loads the file and then
applies the external block on top of it. To avoid this, whenever a
variable is updated in the file envblk, any same named key in the
external block is deleted.
Signed-off-by: Michael Chang <mchang@suse.com>
---
util/grub-editenv.c | 55 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 53 insertions(+), 2 deletions(-)
diff --git a/util/grub-editenv.c b/util/grub-editenv.c
index 26a81d2d0..d47adeb5e 100644
--- a/util/grub-editenv.c
+++ b/util/grub-editenv.c
@@ -394,12 +394,33 @@ fs_envblk_write (grub_envblk_t envblk)
fclose (fp);
}
+struct var_lookup_ctx {
+ const char *varname;
+ bool found;
+};
+
+static int
+var_lookup_iter (const char *varname, const char *value __attribute__ ((unused)), void *hook_data)
+{
+ struct var_lookup_ctx *ctx = (struct var_lookup_ctx *)hook_data;
+ if (grub_strcmp (ctx->varname, varname) == 0)
+ {
+ ctx->found = true;
+ return 1;
+ }
+ return 0;
+}
+
static void
set_variables (const char *name, int argc, char *argv[])
{
grub_envblk_t envblk;
+ grub_envblk_t envblk_fs = NULL;
envblk = open_envblk_file (name);
+ if (fs_envblk != NULL)
+ envblk_fs = fs_envblk->ops->open (envblk);
+
while (argc)
{
char *p;
@@ -410,8 +431,32 @@ set_variables (const char *name, int argc, char *argv[])
*(p++) = 0;
- if (! grub_envblk_set (envblk, argv[0], p))
- grub_util_error ("%s", _("environment block too small"));
+ if ((strcmp (argv[0], "next_entry") == 0) && envblk_fs)
+ {
+ if (! grub_envblk_set (envblk_fs, argv[0], p))
+ grub_util_error ("%s", _("environment block too small"));
+ }
+ else if (strcmp (argv[0], "env_block") == 0)
+ {
+ grub_util_warn (_("can't set env_block as it's read-only"));
+ }
+ else
+ {
+ if (! grub_envblk_set (envblk, argv[0], p))
+ grub_util_error ("%s", _("environment block too small"));
+
+ if (envblk_fs)
+ {
+ struct var_lookup_ctx ctx = {
+ .varname = argv[0],
+ .found = false
+ };
+
+ grub_envblk_iterate (envblk_fs, &ctx, var_lookup_iter);
+ if (ctx.found == true)
+ grub_envblk_delete (envblk_fs, argv[0]);
+ }
+ }
argc--;
argv++;
@@ -419,6 +464,12 @@ set_variables (const char *name, int argc, char *argv[])
write_envblk (name, envblk);
grub_envblk_close (envblk);
+
+ if (envblk_fs != NULL)
+ {
+ fs_envblk->ops->write (envblk_fs);
+ grub_envblk_close (envblk_fs);
+ }
}
static void
--
2.51.0
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
next prev parent reply other threads:[~2025-09-15 9:10 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-15 9:08 [PATCH v2 0/9] Add support for external environment block on Btrfs Michael Chang via Grub-devel
2025-09-15 9:08 ` [PATCH v2 1/9] util/grub-editenv: add basic structures and probe call for external envblk Michael Chang via Grub-devel
2025-09-15 9:08 ` [PATCH v2 2/9] util/grub-editenv: add fs_envblk open helper Michael Chang via Grub-devel
2025-09-15 9:08 ` [PATCH v2 3/9] util/grub-editenv: add fs_envblk write helper Michael Chang via Grub-devel
2025-09-15 9:08 ` Michael Chang via Grub-devel [this message]
2025-09-15 9:08 ` [PATCH v2 5/9] util/grub-editenv: wire unset_variables to optional fs_envblk Michael Chang via Grub-devel
2025-09-15 9:08 ` [PATCH v2 6/9] util/grub-editenv: wire list_variables " Michael Chang via Grub-devel
2025-09-17 15:16 ` Sudhakar Kuppusamy
2025-09-15 9:08 ` [PATCH v2 7/9] btrfs: add environment block to reserved header area Michael Chang via Grub-devel
2025-09-15 9:08 ` [PATCH v2 8/9] 00_header.in: wire grub.cfg to use env_block when present Michael Chang via Grub-devel
2025-09-15 9:08 ` [PATCH v2 9/9] docs: add Btrfs env block and special env vars Michael Chang via Grub-devel
2025-09-16 12:05 ` [PATCH v2 0/9] Add support for external environment block on Btrfs Neal Gompa
[not found] <mailman.4164.1757927381.1199.grub-devel@gnu.org>
2025-09-17 17:08 ` [PATCH v2 4/9] util/grub-editenv: wire set_variables to optional fs_envblk Avnish Chouhan
2025-09-24 2:29 ` Michael Chang via Grub-devel
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=20250915090848.131937-5-mchang@suse.com \
--to=grub-devel@gnu.org \
--cc=mchang@suse.com \
--cc=mlewando@redhat.com \
--cc=ngompa13@gmail.com \
/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;
as well as URLs for NNTP newsgroup(s).