grub-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] ZFS/other CoW FS save_env support


From: Daniel Kiper
Subject: Re: [PATCH] ZFS/other CoW FS save_env support
Date: Mon, 24 Feb 2020 12:02:47 +0100
User-agent: NeoMutt/20170113 (1.7.2)

On Tue, Feb 18, 2020 at 11:10:07AM -0800, Paul Dagnelie wrote:
> Hey all, I previously discussed my concept for this patch in my email
> https://lists.gnu.org/archive/html/grub-devel/2020-01/msg00004.html .
> I'm pleased to announce that I've gotten it into a working state and
> it is ready to review.  There are a number of changes here, which I
> will break down below.
>
> First, the concept of "special files" is introduced into grub. These
> are files that are manipulated using different functions from the
> remainder of the filesystem. A filesystem advertises its support for
> these files by filling in new entries in the grub_fs struct.
>
> Second, the loadenv command was modified to use the special file
> functions of the root filesystem if they are detected. If that
> happens, these functions are used to open, read, and write to the
> loadenv file instead of the normal grub file functions.  A variable
> was also added that allows the user to force a file to be used instead
> of the special files, or vice versa.
>
> Third, the grub-editenv command was modified to teach it to probe the
> root filesystem and then check in an array of structures that contain

Why "root" not "boot"?

> functions that will read and modify the filesystem's special file in
> userland. These functions are very similar to normal read and write
> functions, and so don't result in a very different code flow.
>
> Finally, the GRUB ZFS logic was modified to have new special_file
> functions. These functions manipulate the pad2 area of the ZFS label,
> which was previously unused. It now stores a version number, the raw
> contents of the grubenv file, and an embedded checksum for integrity
> purposes. GRUB was taught to read and verify these areas, and also to
> modify them, computing the embeddded checksum appropriately.  In
> addition, if GRUB is build with libzfs support, an entry is added to
> the grub-editenv table that points GRUB to the appropriate libzfs
> functions, and init and fini functions are built into grub-editenv
> itself.
>
> Future work:
> * In the ZFS code could store a packed nvlist instead of a raw file,
> but this would involve further changes to the grub environment file
> code and was deferred for when it would be more useful and important.
> * For the special files code, there is only one special file allowed
> per filesystem, but a specification interface (using either an enum or
> a set of names) could be added in the future.
> * Other filesystem support was not built into this change, but
> extensibility was a primary goal, so adding support for btrfs or other
> filesystems should be relatively straightforward.
> * I did not implement the proposed UEFI variable support, but I did
> develop this with that future in mind, so adding it should be a
> relatively simple extension of these changes.
>
> This patch has been tested on systems with and without ZFS as the boot
> filesystem, and built with and without ZFS libraries installed. It
> worked in each case I tried, including with manual corruption applied
> to the ZFS labels to force GRUB to read from the other label.  This
> was tested in conjunction with
> https://github.com/zfsonlinux/zfs/pull/10009 , the ZoL patch that
> enables ZFS to read from and write to the padding areas we reserved
> for the data.
>
> Let me know if you have any feedback, I'm sure there's some stuff I'm
> doing wrong or in a non-idiomatic fashion.  In addition, if you'd like
> this patch divided into multiple smaller patches, I would also be
> happy to oblige.

Yes, please split the patch into smaller patches. Please do one logical
change per patch.

I quickly went through the patch and pointed things which I spotted at
first sight. I will provide more comments when you split the patch into
separate patches.

Next time please CC following people too: address@hidden,
address@hidden and address@hidden.

>   grub-core/commands/loadenv.c | 122 +++++++++++++++++---
>  grub-core/fs/zfs/zfs.c       | 131 +++++++++++++++++++--
>  grub-core/kern/file.c        |  74 ++++++++----
>  grub-core/lib/envblk.c       |   2 +-
>  include/grub/file.h          |  10 ++
>  include/grub/fs.h            |  12 +-
>  include/grub/lib/envblk.h    |   2 +
>  include/grub/util/install.h  |   3 +
>  include/grub/util/libzfs.h   |   5 +
>  include/grub/zfs/vdev_impl.h |  33 +++---
>  util/editenv.c               |  26 +++--
>  util/grub-editenv.c          | 267 
> +++++++++++++++++++++++++++++++++++++++++--
>  12 files changed, 603 insertions(+), 84 deletions(-)
>
> diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c
> index 3fd664aac..3553c2f94 100644
> --- a/grub-core/commands/loadenv.c
> +++ b/grub-core/commands/loadenv.c
> @@ -79,6 +79,94 @@ open_envblk_file (char *filename,
>    return file;
>  }
>
> +static grub_file_t
> +open_envblk_block (grub_fs_t fs, grub_device_t dev, enum grub_file_type type)
> +{
> +  if (!fs->fs_special_open)
> +    return NULL;
> +  return grub_file_special_open(fs, dev, type);

I think more natural would be...

   if (fs->fs_special_open)
     return grub_file_special_open (fs, dev, type);
   else
     return NULL;

...and it seems to me that "fs_special_open" name is too generic.
What about "fs_envblk_open" or "fs_ext_data_open" (extra data) or
something like that? Same for other functions...

> +}
> +
> +static grub_file_t
> +open_envblk (grub_extcmd_context_t ctxt, enum grub_file_type type)
> +{
> +  struct grub_arg_list *state = ctxt->state;
> +  grub_file_t file = NULL;
> +  grub_device_t device = NULL;
> +  const char *force;
> +  grub_fs_t fs = NULL;
> +  char *filename = (state[0].set) ? state[0].arg : 0;

I think that you can drop parenthesis here. And please use NULL instead of 0.

> +  force = grub_env_get ("grubenv_force");

"grubenv_src" instead of "grubenv_force"?

[...]

> diff --git a/include/grub/fs.h b/include/grub/fs.h
> index 302e48d4b..99a1bf71e 100644
> --- a/include/grub/fs.h
> +++ b/include/grub/fs.h
> @@ -65,7 +65,7 @@ struct grub_fs
>    grub_err_t (*fs_open) (struct grub_file *file, const char *name);
>
>    /* Read LEN bytes data from FILE into BUF.  */
> -  grub_ssize_t (*fs_read) (struct grub_file *file, char *buf, grub_size_t 
> len);
> +  grub_ssize_t (*fs_read) (struct grub_file *file, char *buf, grub_size_t 
> len);
>
>    /* Close the file FILE.  */
>    grub_err_t (*fs_close) (struct grub_file *file);
> @@ -96,6 +96,16 @@ struct grub_fs
>    /* Whether blocklist installs have a chance to work.  */
>    int blocklist_install;
>  #endif
> +
> +  /* The special file functions are defined on filesystems that need to
> +     handle grub-writable files in a special way. This is most commonly the
> +     case for CoW filesystems like btrfs and ZFS.  The normal read and close
> +     functions should detect that they are being called on a special file and
> +     act appropriately.  */

This comment is incorrectly formatted. Please read this [1].

Daniel

[1] https://www.gnu.org/software/grub/manual/grub-dev/grub-dev.html#Comments



reply via email to

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