Hi Avnish,

On Thu, Oct 09, 2025 at 02:13:00PM +0530, Avnish Chouhan wrote:
> On 2025-10-09 12:50, [email protected] wrote:
> 
> Reviewed-by: Avnish Chouhan <[email protected]>

Many thanks for your help in reviewing the patches. I'll add your
Reviewed-by tag in next version.

Regards,
Michael

> 
> > Message: 3
> > Date: Thu,  9 Oct 2025 15:18:40 +0800
> > From: Michael Chang <[email protected]>
> > To: The development of GNU GRUB <[email protected]>
> > Cc: Neal Gompa <[email protected]>,        Marta Lewandowska
> >     <[email protected]>
> > Subject: [PATCH v4 07/12] util/grub-editenv: wire set_variables to
> >     optional fs_envblk
> > Message-ID: <[email protected]>
> > 
> > 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 <[email protected]>
> > Reviewed-by: Neal Gompa <[email protected]>
> > ---
> >  util/grub-editenv.c | 58 +++++++++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 56 insertions(+), 2 deletions(-)
> > 
> > diff --git a/util/grub-editenv.c b/util/grub-editenv.c
> > index 42a0c63f8..beb2dd4fc 100644
> > --- a/util/grub-editenv.c
> > +++ b/util/grub-editenv.c
> > @@ -402,12 +402,35 @@ fs_envblk_write (grub_envblk_t envblk)
> >    fclose (fp);
> >  }
> > 
> > +struct var_lookup_ctx {
> > +  const char *varname;
> > +  bool found;
> > +};
> > +typedef struct var_lookup_ctx var_lookup_ctx_t;
> > +
> > +static int
> > +var_lookup_iter (const char *varname, const char *value __attribute__
> > ((unused)), void *hook_data)
> > +{
> > +  var_lookup_ctx_t *ctx = (var_lookup_ctx_t *) 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_on_block = NULL;
> > 
> >    envblk = open_envblk_file (name);
> > +  if (fs_envblk != NULL)
> > +    envblk_on_block = fs_envblk->ops->open (envblk);
> > +
> >    while (argc)
> >      {
> >        char *p;
> > @@ -418,15 +441,46 @@ 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_on_block !=
> > NULL)
> > +   {
> > +     if (grub_envblk_set (envblk_on_block, argv[0], p) == 0)
> > +       grub_util_error ("%s", _("environment block too small"));
> > +     goto next;
> > +   }
> > +
> > +      if (strcmp (argv[0], "env_block") == 0)
> > +   {
> > +     grub_util_warn (_("can't set env_block as it's read-only"));
> > +     goto next;
> > +   }
> > +
> > +      if (grub_envblk_set (envblk, argv[0], p) == 0)
> > +   grub_util_error ("%s", _("environment block too small"));
> > 
> > +      if (envblk_on_block != NULL)
> > +   {
> > +     var_lookup_ctx_t ctx = {
> > +       .varname = argv[0],
> > +       .found = false
> > +     };
> > +
> > +     grub_envblk_iterate (envblk_on_block, &ctx, var_lookup_iter);
> > +     if (ctx.found == true)
> > +       grub_envblk_delete (envblk_on_block, argv[0]);
> > +   }
> > + next:
> >        argc--;
> >        argv++;
> >      }
> > 
> >    write_envblk (name, envblk);
> >    grub_envblk_close (envblk);
> > +
> > +  if (envblk_on_block != NULL)
> > +    {
> > +      fs_envblk->ops->write (envblk_on_block);
> > +      grub_envblk_close (envblk_on_block);
> > +    }
> >  }
> > 
> >  static void
> > --
> > 2.51.0

_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to