grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] grub: add grub variable update functionality


From: Prarit Bhargava
Subject: Re: [PATCH] grub: add grub variable update functionality
Date: Fri, 11 Jan 2019 06:40:59 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1

Just re-pinging on this ...

P.

On 1/4/19 7:53 AM, Prarit Bhargava wrote:
> Please be aware I am NOT subscribed to grub-devel.
> 
> P.
> 
> ---8<---
> 
> Customers and users of the kernel are commenting that there is no way to 
> update
> a grub variable without copy and pasting the existing data.
> 
> For example,
> 
> [10:57 AM address@hidden grub-2.02]# ./grub-editenv list
> saved_entry=0
> next_entry=
> kernelopts=root=/dev/mapper/rhel_intel--wildcatpass--07-root ro 
> crashkernel=auto resume=/dev/mapper/rhel_intel--wildcatpass--07-swap 
> rd.lvm.lv=rhel_intel-wildcatpass-07/root 
> rd.lvm.lv=rhel_intel-wildcatpass-07/swap console=ttyS0,115200n81  
> ignore_loglevel
> [10:57 AM address@hidden grub-2.02]# ./grub-editenv - set 
> kernelopts="root=/dev/mapper/rhel_intel--wildcatpass--07-root ro 
> crashkernel=auto resume=/dev/mapper/rhel_intel--wildcatpass--07-swap 
> rd.lvm.lv=rhel_intel-wildcatpass-07/root 
> rd.lvm.lv=rhel_intel-wildcatpass-07/swap console=ttyS0,115200n81  
> ignore_loglevel newarg"
> [10:57 AM address@hidden grub-2.02]# ./grub-editenv list
> saved_entry=0
> next_entry=
> kernelopts=root=/dev/mapper/rhel_intel--wildcatpass--07-root ro 
> crashkernel=auto resume=/dev/mapper/rhel_intel--wildcatpass--07-swap 
> rd.lvm.lv=rhel_intel-wildcatpass-07/root 
> rd.lvm.lv=rhel_intel-wildcatpass-07/swap console=ttyS0,115200n81  
> ignore_loglevel newarg
> 
> which is cumbersome.
> 
> Add functionality to add to an existing variable.  For example,
> 
> [10:58 AM address@hidden grub-2.02]# ./grub-editenv list
> saved_entry=0
> next_entry=
> kernelopts=root=/dev/mapper/rhel_intel--wildcatpass--07-root ro 
> crashkernel=auto resume=/dev/mapper/rhel_intel--wildcatpass--07-swap 
> rd.lvm.lv=rhel_intel-wildcatpass-07/root 
> rd.lvm.lv=rhel_intel-wildcatpass-07/swap console=ttyS0,115200n81  
> ignore_loglevel
> [10:58 AM address@hidden grub-2.02]# ./grub-editenv - set kernelopts+="newarg"
> [10:59 AM address@hidden grub-2.02]# ./grub-editenv list
> saved_entry=0
> next_entry=
> kernelopts=root=/dev/mapper/rhel_intel--wildcatpass--07-root ro 
> crashkernel=auto resume=/dev/mapper/rhel_intel--wildcatpass--07-swap 
> rd.lvm.lv=rhel_intel-wildcatpass-07/root 
> rd.lvm.lv=rhel_intel-wildcatpass-07/swap console=ttyS0,115200n81  
> ignore_loglevel newarg
> 
> Signed-off-by: Prarit Bhargava <address@hidden>
> Cc: address@hidden
> Cc: address@hidden
> Cc: address@hidden
> Cc: address@hidden
> ---
>  grub-core/lib/envblk.c    | 61 +++++++++++++++++++++++++++++++++++++++
>  include/grub/lib/envblk.h |  1 +
>  util/grub-editenv.c       | 25 +++++++++++++++-
>  3 files changed, 86 insertions(+), 1 deletion(-)
> 
> diff --git a/grub-core/lib/envblk.c b/grub-core/lib/envblk.c
> index 230e0e9d9abe..8ddbe2e8267e 100644
> --- a/grub-core/lib/envblk.c
> +++ b/grub-core/lib/envblk.c
> @@ -295,3 +295,64 @@ grub_envblk_iterate (grub_envblk_t envblk,
>        p = find_next_line (p, pend);
>      }
>  }
> +
> +int
> +grub_envblk_add (grub_envblk_t envblk, const char *name, const char *add)
> +{
> +  char *current, *new, *ostart, *pstart, *pend;
> +  int newsize, ret = 1;
> +
> +  /* get a copy of the existing entry */
> +  pstart = envblk->buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1;
> +  pstart = grub_strstr (pstart, name);
> +  if (!pstart)
> +  {
> +     ret = -1; /* existing entry not found */
> +     goto out;
> +  }
> +  pend = grub_strchr (pstart, '\n');
> +  if (!pend || pend > (envblk->buf + envblk->size))
> +  {
> +     ret = -1; /* existing entry not found */
> +     goto out;
> +  }
> +
> +  current = grub_zalloc (pend - pstart + 1);
> +  if (!current)
> +  {
> +     ret = -2; /* out of memory */
> +     goto out;
> +  }
> +  grub_strncpy (current, pstart, (int)(pend - pstart));
> +
> +  ostart = grub_strchr (current, '=');
> +  ostart++;
> +
> +  /* create a buffer for the updated entry. */
> +  newsize = grub_strlen (ostart) + grub_strlen (add) + 2;
> +  new = grub_zalloc (newsize);
> +  if (!new)
> +    {
> +      return -2; /* out of memory */
> +      goto out;
> +    }
> +
> +  grub_strcpy (new, ostart);
> +  grub_memcpy (new + grub_strlen (new), " ", 1);
> +  grub_strcpy (new + grub_strlen (new), add);
> +
> +  /* erase the current entry */
> +  grub_envblk_delete (envblk, name);
> +  /* add the updated entry */
> +  if (!grub_envblk_set (envblk, name, new))
> +    {
> +      /* restore the original entry.  This should always work */
> +      grub_envblk_set (envblk, name, ostart);
> +      ret = 0;
> +    }
> +
> +out:
> +  grub_free(new);
> +  grub_free(current);
> +  return ret;
> +}
> diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h
> index c3e655921709..2a0f09e3435b 100644
> --- a/include/grub/lib/envblk.h
> +++ b/include/grub/lib/envblk.h
> @@ -37,6 +37,7 @@ void grub_envblk_delete (grub_envblk_t envblk, const char 
> *name);
>  void grub_envblk_iterate (grub_envblk_t envblk,
>                            void *hook_data,
>                            int hook (const char *name, const char *value, 
> void *hook_data));
> +int grub_envblk_add(grub_envblk_t envblk, const char *name, const char *add);
>  void grub_envblk_close (grub_envblk_t envblk);
>  
>  static inline char *
> diff --git a/util/grub-editenv.c b/util/grub-editenv.c
> index 118e89fe57fe..2df81a20b6bc 100644
> --- a/util/grub-editenv.c
> +++ b/util/grub-editenv.c
> @@ -210,15 +210,38 @@ set_variables (const char *name, int argc, char *argv[])
>    while (argc)
>      {
>        char *p;
> +      int add = 0;
>  
>        p = strchr (argv[0], '=');
>        if (! p)
>          grub_util_error (_("invalid parameter %s"), argv[0]);
>  
> +      if ( *(p - 1) == '+')
> +        {
> +          add = 1;
> +          *(p - 1) = 0;
> +        }
>        *(p++) = 0;
>  
> -      if (! grub_envblk_set (envblk, argv[0], p))
> +      if (!add && ! grub_envblk_set (envblk, argv[0], p))
>          grub_util_error ("%s", _("environment block too small"));
> +      else if (add) {
> +        int ret;
> +        ret = grub_envblk_add (envblk, argv[0], p);
> +        switch (ret) {
> +        case (0):
> +          grub_util_error ("%s", _("environment block too small"));
> +          break;
> +        case (-1):
> +          grub_util_error("%s", _("existing entry not found"));
> +          break;
> +        case (-2):
> +          grub_util_error("%s", _("out of memory error"));
> +          break;
> +        default:
> +          break;
> +        }
> +      }
>  
>        argc--;
>        argv++;
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]