grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
From: Avnish Chouhan <avnish@linux.ibm.com>
To: mchang@suse.com
Cc: grub-devel@gnu.org, ngompa13@gmail.com, mlewando@redhat.com
Subject: Re: [PATCH v2 2/9] util/grub-editenv: add fs_envblk open helper
Date: Wed, 17 Sep 2025 16:13:21 +0530	[thread overview]
Message-ID: <87c0dd8f4b1f0f2841099548ebc8863a@linux.ibm.com> (raw)
In-Reply-To: <mailman.4306.1757927367.1200.grub-devel@gnu.org>

On 2025-09-15 14:39, grub-devel-request@gnu.org wrote:
> Message: 3
> Date: Mon, 15 Sep 2025 17:08:41 +0800
> From: Michael Chang <mchang@suse.com>
> To: The development of GNU GRUB <grub-devel@gnu.org>
> Cc: Neal Gompa <ngompa13@gmail.com>,	Marta Lewandowska
> 	<mlewando@redhat.com>
> Subject: [PATCH v2 2/9] util/grub-editenv: add fs_envblk open helper
> Message-ID: <20250915090848.131937-3-mchang@suse.com>
> 
> This patch adds the logic to locate and open an environment block that
> is stored in a reserved area on the device. It introduces the function
> fs_envblk_open together with helper routines to read the block pointed
> to by the env_block variable, and to create the block on disk when it
> does not yet exist. When a block is created, the code records its
> location inside the file based envblk by setting env_block in block 
> list
> syntax of offset plus size in sectors.
> 
> The env_block variable acts as a link from the file envblk to the raw
> disk region so that later runs of grub editenv can follow it and access
> the external block. The helper is exposed through a small ops table
> attached to fs_envblk so that later patches can call
> fs_envblk->ops->open without touching core code again. At this stage
> variables are still stored in the file envblk and no redirection has
> been applied.
> 
> Signed-off-by: Michael Chang <mchang@suse.com>
> ---
>  util/grub-editenv.c | 128 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 128 insertions(+)
> 
> diff --git a/util/grub-editenv.c b/util/grub-editenv.c
> index 2302a6acf..4e5dffa86 100644
> --- a/util/grub-editenv.c
> +++ b/util/grub-editenv.c
> @@ -130,12 +130,23 @@ struct fs_envblk_spec {
>  };
>  typedef struct fs_envblk_spec *fs_envblk_spec_t;
> 
> +static grub_envblk_t fs_envblk_open (grub_envblk_t envblk);
> +
> +struct fs_envblk_ops {
> +  grub_envblk_t (*open) (grub_envblk_t);
> +};
> +
>  struct fs_envblk {
>    struct fs_envblk_spec *spec;
> +  struct fs_envblk_ops *ops;
>    const char *dev;
>  };
>  typedef struct fs_envblk *fs_envblk_t;
> 
> +static struct fs_envblk_ops fs_envblk_ops = {
> +  .open = fs_envblk_open
> +};
> +
>  static struct fs_envblk_spec fs_envblk_spec[] = {
>    { "btrfs", ENV_BTRFS_OFFSET, GRUB_DISK_SECTOR_SIZE },
>    { NULL, 0, 0 }
> @@ -143,6 +154,122 @@ static struct fs_envblk_spec fs_envblk_spec[] = {
> 
>  static fs_envblk_t fs_envblk = NULL;
> 
> +static int
> +read_envblk_fs (const char *varname, const char *value, void 
> *hook_data)
> +{
> +  grub_envblk_t *p_envblk = (grub_envblk_t *)hook_data;
> +  off_t off;
> +  size_t sz;
> +  char *p, *buf;
> +  FILE *fp;
> +
> +  if (p_envblk == NULL || fs_envblk == NULL)
> +    return 1;
> +
> +  if (strcmp (varname, "env_block") != 0)
> +    return 0;
> +
> +  off = strtol (value, &p, 10);
> +  if (*p == '+')
> +    sz = strtol (p+1, &p, 10);
> +  else
> +    return 0;
> +
> +  if (*p != '\0' || sz == 0)
> +    return 0;
> +
> +  off <<= GRUB_DISK_SECTOR_BITS;
> +  sz <<= GRUB_DISK_SECTOR_BITS;
> +
> +  fp = grub_util_fopen (fs_envblk->dev, "rb");
> +  if (! fp)

Hi Michael,

(fp == NULL) would be better here!

> +    grub_util_error (_("cannot open `%s': %s"), fs_envblk->dev,
> +			strerror (errno));
> +
> +  if (fseek (fp, off, SEEK_SET) < 0)

fclose (fp) seems missing here.

> +    grub_util_error (_("cannot seek `%s': %s"), fs_envblk->dev,
> +			strerror (errno));
> +
> +  buf = xmalloc (sz);
> +  if ((fread (buf, 1, sz, fp)) != sz)

fclose (fp) seems missing as well as grub_free (buf).

> +    grub_util_error (_("cannot read `%s': %s"), fs_envblk->dev,
> +			strerror (errno));
> +
> +  fclose (fp);
> +
> +  *p_envblk = grub_envblk_open (buf, sz);
> +
> +  return 1;
> +}
> +
> +static void
> +create_envblk_fs (void)
> +{
> +  FILE *fp;
> +  char *buf;
> +  const char *device;
> +  off_t offset;
> +  size_t size;
> +
> +  if (fs_envblk == NULL)
> +    return;
> +
> +  device = fs_envblk->dev;
> +  offset = fs_envblk->spec->offset;
> +  size = fs_envblk->spec->size;
> +
> +  fp = grub_util_fopen (device, "r+b");
> +  if (fp == NULL)
> +    grub_util_error (_("cannot open `%s': %s"), device, strerror 
> (errno));
> +
> +  buf = xmalloc (size);
> +  memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 
> 1);
> +  memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', size -
> sizeof (GRUB_ENVBLK_SIGNATURE) + 1);
> +
> +  if (fseek (fp, offset, SEEK_SET) < 0)

fclose (fp) seems missing as well as grub_free (buf).

> +    grub_util_error (_("cannot seek `%s': %s"), device, strerror 
> (errno));
> +
> +  if (fwrite (buf, 1, size, fp) != size)

fclose (fp) seems missing as well as grub_free (buf).

> +    grub_util_error (_("cannot write to `%s': %s"), device, strerror 
> (errno));
> +
> +  grub_util_file_sync (fp);
> +  free (buf);
> +  fclose (fp);
> +}
> +
> +static grub_envblk_t
> +fs_envblk_open (grub_envblk_t envblk)
> +{
> +  grub_envblk_t envblk_fs = NULL;
> +  char *val;
> +  off_t offset;
> +  size_t size;
> +
> +  if (envblk == NULL)
> +    return NULL;
> +
> +  offset = fs_envblk->spec->offset;
> +  size = fs_envblk->spec->size;
> +
> +  grub_envblk_iterate (envblk, &envblk_fs, read_envblk_fs);
> +
> +  if (envblk_fs && grub_envblk_size (envblk_fs) == size)
> +    return envblk_fs;
> +
> +  create_envblk_fs ();
> +
> +  offset = offset >> GRUB_DISK_SECTOR_BITS;
> +  size =  (size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS;
> +
> +  val = xasprintf ("%ld+%lu", offset, size);
> +  if (! grub_envblk_set (envblk, "env_block", val))

grub_free (val) missing here.

Thank you!

Regards,
Avnish Chouhan

> +    grub_util_error ("%s", _("environment block too small"));
> +  grub_envblk_iterate (envblk, &envblk_fs, read_envblk_fs);
> +  free (val);
> +
> +  return envblk_fs;
> +}
> +
>  static grub_envblk_t
>  open_envblk_file (const char *name)
>  {
> @@ -392,6 +519,7 @@ probe_fs_envblk (fs_envblk_spec_t spec)
>  	  fs_envblk = xmalloc (sizeof (fs_envblk_t));
>  	  fs_envblk->spec = p;
>  	  fs_envblk->dev = devname;
> +	  fs_envblk->ops = &fs_envblk_ops;
>  	  return fs_envblk;
>  	}
>      }
> --
> 2.51.0

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

  parent reply	other threads:[~2025-09-17 10:44 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <mailman.4306.1757927367.1200.grub-devel@gnu.org>
2025-09-15 13:07 ` [PATCH v2 1/9] util/grub-editenv: add basic structures and probe call for external envblk Avnish Chouhan
2025-09-16  4:58   ` Michael Chang via Grub-devel
2025-09-16 17:06     ` Avnish Chouhan
2025-09-17 10:43 ` Avnish Chouhan [this message]
2025-10-02  5:44   ` [PATCH v2 2/9] util/grub-editenv: add fs_envblk open helper Michael Chang via Grub-devel
2025-10-07  5:24     ` Avnish Chouhan
2025-09-17 11:04 ` [PATCH v2 3/9] util/grub-editenv: add fs_envblk write helper Avnish Chouhan
2025-10-02  5:53   ` Michael Chang via Grub-devel
2025-10-07  5:22     ` Avnish Chouhan
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 2/9] util/grub-editenv: add fs_envblk open helper 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=87c0dd8f4b1f0f2841099548ebc8863a@linux.ibm.com \
    --to=avnish@linux.ibm.com \
    --cc=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).