Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package grub2 for openSUSE:Factory checked 
in at 2022-03-08 20:31:17
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/grub2 (Old)
 and      /work/SRC/openSUSE:Factory/.grub2.new.2349 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "grub2"

Tue Mar  8 20:31:17 2022 rev:260 rq:959763 version:2.06

Changes:
--------
--- /work/SRC/openSUSE:Factory/grub2/grub2.changes      2022-02-15 
23:57:02.496172974 +0100
+++ /work/SRC/openSUSE:Factory/.grub2.new.2349/grub2.changes    2022-03-11 
11:43:55.418786429 +0100
@@ -1,0 +2,18 @@
+Fri Mar  4 03:37:40 UTC 2022 - Michael Chang <mch...@suse.com>
+
+- Support saving grub environment for POWER signed grub images (jsc#SLE-23854)
+  * 0001-Add-grub_envblk_buf-helper-function.patch
+  * 0002-Add-grub_disk_write_tail-helper-function.patch
+  * 0003-grub-install-support-prep-environment-block.patch
+  * 0004-Introduce-prep_load_env-command.patch
+  * 0005-export-environment-at-start-up.patch
+- Use enviroment variable in early boot config to looking up root device 
+  * grub2.spec
+
+-------------------------------------------------------------------
+Tue Mar  1 08:55:57 UTC 2022 - Michal Suchanek <msucha...@suse.com>
+
+- Remove obsolete openSUSE 12.2 conditionals in spec file
+- Clean up powerpc certificate handling.
+
+-------------------------------------------------------------------

New:
----
  0001-Add-grub_envblk_buf-helper-function.patch
  0002-Add-grub_disk_write_tail-helper-function.patch
  0003-grub-install-support-prep-environment-block.patch
  0004-Introduce-prep_load_env-command.patch
  0005-export-environment-at-start-up.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ grub2.spec ++++++
--- /var/tmp/diff_new_pack.BGjWvK/_old  2022-03-11 11:43:57.490788753 +0100
+++ /var/tmp/diff_new_pack.BGjWvK/_new  2022-03-11 11:43:57.494788757 +0100
@@ -53,11 +53,9 @@
 %endif
 BuildRequires:  xz-devel
 %ifarch x86_64 aarch64 ppc ppc64 ppc64le
-%if 0%{?suse_version} >= 1230 || 0%{?suse_version} == 1110
 BuildRequires:  openssl >= 0.9.8
 BuildRequires:  pesign-obs-integration
 %endif
-%endif
 %if 0%{?suse_version} >= 1210
 # Package systemd services files grub2-once.service
 BuildRequires:  systemd-rpm-macros
@@ -353,6 +351,11 @@
 Patch834:       0022-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch
 Patch835:       0023-x509-allow-Digitial-Signature-plus-other-Key-Usages.patch
 Patch836:       0001-grub-install-Add-SUSE-signed-image-support-for-power.patch
+Patch837:       0001-Add-grub_envblk_buf-helper-function.patch
+Patch838:       0002-Add-grub_disk_write_tail-helper-function.patch
+Patch839:       0003-grub-install-support-prep-environment-block.patch
+Patch840:       0004-Introduce-prep_load_env-command.patch
+Patch841:       0005-export-environment-at-start-up.patch
 
 Requires:       gettext-runtime
 %if 0%{?suse_version} >= 1140
@@ -638,7 +641,7 @@
 
 GRUB_MODULES="${CD_MODULES} ${FS_MODULES} ${PXE_MODULES} ${CRYPTO_MODULES} 
mdraid09 mdraid1x lvm serial"
 %ifarch ppc ppc64 ppc64le
-GRUB_MODULES="${GRUB_MODULES} appendedsig memdisk tar regexp"
+GRUB_MODULES="${GRUB_MODULES} appendedsig memdisk tar regexp prep_loadenv"
 %endif
 
 %ifarch %{efi}
@@ -675,7 +678,6 @@
 %endif
 
 %ifarch x86_64 aarch64
-%if 0%{?suse_version} >= 1230 || 0%{?suse_version} == 1110
 if test -e %{_sourcedir}/_projectcert.crt ; then
     prjsubject=$(openssl x509 -in %{_sourcedir}/_projectcert.crt -noout 
-subject_hash)
     prjissuer=$(openssl x509 -in %{_sourcedir}/_projectcert.crt -noout 
-issuer_hash)
@@ -698,7 +700,6 @@
 
 openssl x509 -in $cert -outform DER -out grub.der
 %endif
-%endif
 
 cd ..
 %endif
@@ -729,8 +730,11 @@
 make %{?_smp_mflags}
 
 if [ "%{platform}" = "ieee1275" ]; then
-        cert="%{_sourcedir}/_projectcert.crt"
-        openssl x509 -in "$cert" -outform DER -out grub.der
+        # So far neither OpenFirmware nor grub support CA chain, only 
certificate pinning
+        # Use project certificate always in the shipped informational file and
+        # for kernel verification
+        projectcert="%{_sourcedir}/_projectcert.crt"
+        openssl x509 -in "$projectcert" -outform DER -out grub.der
         cat > %{platform}-config <<'EOF'
 set root=memdisk
 set prefix=($root)/
@@ -744,39 +748,76 @@
 echo "bpart=$bpart"
 echo "bpath=$bpath"
 
+if [ "$btrfs_relative_path" = xy ]; then
+  btrfs_relative_path=1
+fi
+
 if [ "$bdev" -a "$bpart" -a "$bpath" ]; then
-  hints="--hint $bdev$bpart"
-  cfg_dir="$bpath"
+  set hints="--hint $bdev$bpart"
+  set cfg_dir="$bpath"
 elif [ "$bdev" -a "$bpart" ]; then
-  hints="--hint $bdev$bpart"
-  cfg_dir="/boot/grub2 /grub2"
+  set hints="--hint $bdev$bpart"
+  set cfg_dir="/boot/grub2 /grub2"
+  set btrfs_relative_path=1
 elif [ "$bdev" ]; then
-  hints="--hint ${bdev},"
-  cfg_dir="/boot/grub2 /grub2"
+  if [ "$ENV_HINT" ]; then
+    set hints="--hint $ENV_HINT"
+  else
+    set hints="--hint ${bdev},"
+  fi
+  if [ "$ENV_GRUB_DIR" ]; then
+    set cfg_dir="$ENV_GRUB_DIR"
+  else
+    set cfg_dir="/boot/grub2 /grub2"
+    set btrfs_relative_path=1
+  fi
 else
-  hints=""
-  cfg_dir="/boot/grub2 /grub2"
+  set hints=""
+  set cfg_dir="/boot/grub2 /grub2"
+  set btrfs_relative_path=1
 fi
 
 set prefix=""
 set root=""
 set cfg="grub.cfg"
+
+if [ "$ENV_CRYPTO_UUID" ]; then
+  cryptomount -u "$ENV_CRYPTO_UUID"
+fi
+
+if [ "$ENV_FS_UUID" ]; then
+  echo "searching for $ENV_FS_UUID with $hints"
+  if search --fs-uuid --set=root "$ENV_FS_UUID" $hints; then
+    echo "$ENV_FS_UUID is on $root"
+  fi
+fi
+
 for d in ${cfg_dir}; do
-  set btrfs_relative_path=1
-  echo "start searching for $d/${cfg} with $hints"
+  if [ -z "$root" ]; then
+    echo "searching for ${d}/${cfg}"
   if search --file --set=root "${d}/${cfg}" $hints; then
     echo "${d}/${cfg} is on $root"
-    set btrfs_relative_path=0
+      prefix="($root)${d}"
+    fi
+  elif [ -f "${d}/${cfg}" ]; then
+    echo "${d}/${cfg} is on $root"
+    prefix="($root)${d}"
+  else
+    echo "${d}/${cfg} not found in $root"
+  fi
+
+  if [ "$prefix" -a x"$btrfs_relative_path" = x1 ]; then
+    btrfs_relative_path=0
     if [ -f /@"${d}"/powerpc-ieee1275/command.lst ]; then
-      set btrfs_relative_path=1
+      btrfs_relative_path=1
       echo "mounting subvolume @${d}/powerpc-ieee1275 on ${d}/powerpc-ieee1275"
       btrfs-mount-subvol ($root) "${d}"/powerpc-ieee1275 
@"${d}"/powerpc-ieee1275
     fi
-    set btrfs_relative_path=1
-    set prefix="($root)${d}"
+    btrfs_relative_path=1
     break
   fi
 done
+
 echo "prefix=$prefix root=$root"
 if [ -n "$prefix" ]; then
   source "${prefix}/${cfg}"
@@ -835,14 +876,12 @@
 %endif
 
 %ifarch x86_64 aarch64
-%if 0%{?suse_version} >= 1230 || 0%{?suse_version} == 1110
 export BRP_PESIGN_FILES="%{_datadir}/%{name}/%{grubefiarch}/grub.efi"
 %ifarch x86_64
 BRP_PESIGN_FILES="${BRP_PESIGN_FILES} 
%{_datadir}/%{name}/%{grubefiarch}/grub-tpm.efi"
 %endif
 install -m 444 grub.der %{buildroot}/%{sysefidir}/
 %endif
-%endif
 
 cd ..
 %endif
@@ -1285,10 +1324,8 @@
 %endif
 
 %ifarch x86_64 aarch64
-%if 0%{?suse_version} >= 1230 || 0%{?suse_version} == 1110
 %{sysefidir}/grub.der
 %endif
-%endif
 
 %files %{grubefiarch}-debug
 %defattr(-,root,root,-)

++++++ 0001-Add-grub_envblk_buf-helper-function.patch ++++++
>From a326e486bdcf99e6be973ba54c0abfb6d2d95b73 Mon Sep 17 00:00:00 2001
From: Michael Chang <mch...@suse.com>
Date: Mon, 17 Jan 2022 17:45:00 +0800
Subject: [PATCH 1/5] Add grub_envblk_buf helper function

This helps in creation and initialization of memory buffer for
environment block of given size.

Signed-off-by: Michael Chang <mch...@suse.com>
---
 grub-core/lib/envblk.c    | 12 ++++++++++++
 include/grub/lib/envblk.h |  1 +
 util/grub-editenv.c       |  4 +---
 3 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/grub-core/lib/envblk.c b/grub-core/lib/envblk.c
index 2e4e78b132..24efbe7ffa 100644
--- a/grub-core/lib/envblk.c
+++ b/grub-core/lib/envblk.c
@@ -23,6 +23,18 @@
 #include <grub/mm.h>
 #include <grub/lib/envblk.h>
 
+char *
+grub_envblk_buf (grub_size_t size)
+{
+  char *buf;
+
+  buf = grub_malloc (size);
+  grub_memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
+  grub_memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', size - sizeof 
(GRUB_ENVBLK_SIGNATURE) + 1);
+
+  return buf;
+}
+
 grub_envblk_t
 grub_envblk_open (char *buf, grub_size_t size)
 {
diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h
index c3e6559217..83f3fcf841 100644
--- a/include/grub/lib/envblk.h
+++ b/include/grub/lib/envblk.h
@@ -31,6 +31,7 @@ struct grub_envblk
 };
 typedef struct grub_envblk *grub_envblk_t;
 
+char *grub_envblk_buf (grub_size_t size);
 grub_envblk_t grub_envblk_open (char *buf, grub_size_t size);
 int grub_envblk_set (grub_envblk_t envblk, const char *name, const char 
*value);
 void grub_envblk_delete (grub_envblk_t envblk, const char *name);
diff --git a/util/grub-editenv.c b/util/grub-editenv.c
index b8219335f7..a02d3f2a63 100644
--- a/util/grub-editenv.c
+++ b/util/grub-editenv.c
@@ -210,9 +210,7 @@ create_envblk_fs (void)
   if (! fp)
     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);
+  buf = grub_envblk_buf (size);
 
   if (fseek (fp, offset, SEEK_SET) < 0)
     grub_util_error (_("cannot seek `%s': %s"), device, strerror (errno));
-- 
2.34.1


++++++ 0002-Add-grub_disk_write_tail-helper-function.patch ++++++
>From c0d00403a297d6023eab6189ba87dc8a3f6d1e85 Mon Sep 17 00:00:00 2001
From: Michael Chang <mch...@suse.com>
Date: Mon, 7 Feb 2022 20:44:40 +0800
Subject: [PATCH 2/5] Add grub_disk_write_tail helper function

This helps in writing data to partition where the end of buffer is
aligned to end of partition.

Signed-off-by: Michael Chang <mch...@suse.com>
---
 grub-core/lib/disk.c | 18 ++++++++++++++++++
 include/grub/disk.h  |  3 +++
 2 files changed, 21 insertions(+)

diff --git a/grub-core/lib/disk.c b/grub-core/lib/disk.c
index b4eb064a81..08e24485f0 100644
--- a/grub-core/lib/disk.c
+++ b/grub-core/lib/disk.c
@@ -51,6 +51,24 @@ grub_disk_cache_invalidate (unsigned long dev_id, unsigned 
long disk_id,
     }
 }
 
+grub_err_t
+grub_disk_write_tail (grub_disk_t disk, grub_size_t size, const void *buf)
+{
+  grub_partition_t part;
+  grub_disk_addr_t sector;
+  grub_off_t offset;
+
+  if (!disk->partition)
+    return GRUB_ERR_NONE;
+
+  part = disk->partition;
+  sector = part->len;
+  sector -= (size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS;
+  offset = size & (GRUB_DISK_SECTOR_SIZE - 1);
+
+  return grub_disk_write (disk, sector, offset, size, buf);
+}
+
 grub_err_t
 grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector,
                 grub_off_t offset, grub_size_t size, const void *buf)
diff --git a/include/grub/disk.h b/include/grub/disk.h
index f95aca929a..6d656c4315 100644
--- a/include/grub/disk.h
+++ b/include/grub/disk.h
@@ -232,6 +232,9 @@ grub_err_t EXPORT_FUNC(grub_disk_read) (grub_disk_t disk,
                                        grub_off_t offset,
                                        grub_size_t size,
                                        void *buf);
+grub_err_t grub_disk_write_tail (grub_disk_t disk,
+                              grub_size_t size,
+                              const void *buf);
 grub_err_t grub_disk_write (grub_disk_t disk,
                            grub_disk_addr_t sector,
                            grub_off_t offset,
-- 
2.34.1


++++++ 0003-grub-install-support-prep-environment-block.patch ++++++
>From c31fc5aa0ded9ce1e774d0a3526cfee19be1b77f Mon Sep 17 00:00:00 2001
From: Michael Chang <mch...@suse.com>
Date: Mon, 7 Feb 2022 20:49:01 +0800
Subject: [PATCH 3/5] grub-install: support prep environment block

The grub-install can be instructed to create environment block at end of
PReP paritition with probed device identities and properties in
variables to facilitate root device discovery. So far these variables
are defined for this purpose:

ENV_FS_UUID - The filesystem uuid for the grub root device
ENV_CRYPTO_UUID - The crytodisk uuid for the grub root device
ENV_GRUB_DIR - The path to grub prefix directory
ENV_HINT - The recommended hint string for searching root device

The size of environment block is defined in GRUB_ENVBLK_PREP_SIZE which
is 4096 bytes and can be extended in the future.

Signed-off-by: Michael Chang <mch...@suse.com>
---
 include/grub/lib/envblk.h |  3 +++
 util/grub-install.c       | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h
index 83f3fcf841..d01927bcf7 100644
--- a/include/grub/lib/envblk.h
+++ b/include/grub/lib/envblk.h
@@ -24,6 +24,9 @@
 
 #ifndef ASM_FILE
 
+#include <grub/disk.h>
+#define GRUB_ENVBLK_PREP_SIZE (GRUB_DISK_SECTOR_SIZE << 3)
+
 struct grub_envblk
 {
   char *buf;
diff --git a/util/grub-install.c b/util/grub-install.c
index 8fb5ea616b..7bc5f84378 100644
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -43,6 +43,7 @@
 #include <grub/util/ofpath.h>
 #include <grub/hfsplus.h>
 #include <grub/time.h>
+#include <grub/lib/envblk.h>
 
 #include <string.h>
 
@@ -2112,6 +2113,43 @@ main (int argc, char *argv[])
            {
              grub_util_error ("%s", _("failed to copy Grub to the PReP 
partition"));
            }
+
+         if ((signed_grub_mode >= SIGNED_GRUB_FORCE) || ((signed_grub_mode == 
SIGNED_GRUB_AUTO) && (ppc_sb_state > 0)))
+           {
+             char *uuid = NULL;
+             const char *cryptouuid = NULL;
+             grub_envblk_t envblk = NULL;
+             char *buf;
+
+             /* TODO: Add LVM/RAID on encrypted partitions */
+             if (grub_dev->disk && grub_dev->disk->dev->id == 
GRUB_DISK_DEVICE_CRYPTODISK_ID)
+               cryptouuid = grub_util_cryptodisk_get_uuid (grub_dev->disk);
+             if (grub_fs->fs_uuid && grub_fs->fs_uuid (grub_dev, &uuid))
+               {
+                 grub_print_error ();
+                 grub_errno = 0;
+                 uuid = NULL;
+               }
+             buf = grub_envblk_buf (GRUB_ENVBLK_PREP_SIZE);
+             envblk = grub_envblk_open (buf, GRUB_ENVBLK_PREP_SIZE);
+             if (uuid)
+               grub_envblk_set (envblk, "ENV_FS_UUID", uuid);
+             if (cryptouuid)
+               grub_envblk_set (envblk, "ENV_CRYPTO_UUID", cryptouuid);
+             if (relative_grubdir)
+               grub_envblk_set (envblk, "ENV_GRUB_DIR", relative_grubdir);
+             if (have_abstractions)
+               grub_envblk_set (envblk, "ENV_HINT", grub_dev->disk->name);
+             if (use_relative_path_on_btrfs)
+               grub_envblk_set (envblk, "btrfs_relative_path", "1");
+             if (envblk)
+               {
+                 fprintf (stderr, _("Write environment block to PReP.\n"));
+                 if (grub_disk_write_tail (ins_dev->disk, envblk->size, 
envblk->buf))
+                   grub_util_error ("%s", _("failed to write environment block 
to the PReP partition"));
+               }
+             grub_envblk_close (envblk);
+           }
          grub_device_close (ins_dev);
          if (update_nvram)
            grub_install_register_ieee1275 (1, grub_util_get_os_disk 
(install_device),
-- 
2.34.1


++++++ 0004-Introduce-prep_load_env-command.patch ++++++
>From 3cf4fdf8d17423dea4e5913ab14fb6305f3c2571 Mon Sep 17 00:00:00 2001
From: Michael Chang <mch...@suse.com>
Date: Fri, 18 Feb 2022 21:43:38 +0800
Subject: [PATCH 4/5] Introduce prep_load_env command

This command will accept grub disk device and perform load_env for
environment block located at end of PReP partition which belongs to that
input disk device. All variables read from that environment block are
exported to grub as environment variables.

Please note there's no support for whitelist variables and also
--skip-sig option compared to ordinary load_env command.

Signed-off-by: Michael Chang <mch...@suse.com>
---
 grub-core/Makefile.core.def       |   5 +
 grub-core/commands/prep_loadenv.c | 227 ++++++++++++++++++++++++++++++
 2 files changed, 232 insertions(+)
 create mode 100644 grub-core/commands/prep_loadenv.c

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 49bdb63b69..4d529859be 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2624,3 +2624,8 @@ module = {
   common = lib/libtasn1_wrap/tests/Test_strings.c;
   common = lib/libtasn1_wrap/wrap_tests.c;
 };
+
+module = {
+  name = prep_loadenv;
+  common = commands/prep_loadenv.c;
+};
diff --git a/grub-core/commands/prep_loadenv.c 
b/grub-core/commands/prep_loadenv.c
new file mode 100644
index 0000000000..f4bb270a2b
--- /dev/null
+++ b/grub-core/commands/prep_loadenv.c
@@ -0,0 +1,227 @@
+#include <grub/dl.h>
+#include <grub/mm.h>
+#include <grub/file.h>
+#include <grub/disk.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/env.h>
+#include <grub/partition.h>
+#include <grub/lib/envblk.h>
+#include <grub/extcmd.h>
+#include <grub/i18n.h>
+#include <grub/gpt_partition.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static char *
+match_substr (regmatch_t *match, const char *str)
+{
+  if (match->rm_so != -1)
+    {
+      char *substr;
+      regoff_t sz = match->rm_eo - match->rm_so;
+
+      if (!sz)
+       return NULL;
+      substr = grub_malloc (1 + sz);
+      if (!substr)
+       {
+         grub_print_error ();
+         return NULL;
+       }
+      grub_memcpy (substr, str + match->rm_so, sz);
+      substr[sz] = '\0';
+      return substr;
+    }
+
+  return NULL;
+}
+
+static int
+is_prep_partition (grub_device_t dev)
+{
+  if (!dev->disk)
+    return 0;
+  if (!dev->disk->partition)
+    return 0;
+  if (grub_strcmp (dev->disk->partition->partmap->name, "msdos") == 0)
+    return (dev->disk->partition->msdostype == 0x41);
+
+  if (grub_strcmp (dev->disk->partition->partmap->name, "gpt") == 0)
+    {
+      struct grub_gpt_partentry gptdata;
+      grub_partition_t p = dev->disk->partition;
+      int ret = 0;
+      dev->disk->partition = dev->disk->partition->parent;
+
+      if (grub_disk_read (dev->disk, p->offset, p->index,
+                         sizeof (gptdata), &gptdata) == 0)
+       {
+         const grub_gpt_part_guid_t template = {
+           grub_cpu_to_le32_compile_time (0x9e1a2d38),
+           grub_cpu_to_le16_compile_time (0xc612),
+           grub_cpu_to_le16_compile_time (0x4316),
+           { 0xaa, 0x26, 0x8b, 0x49, 0x52, 0x1e, 0x5a, 0x8b }
+         };
+
+         ret = grub_memcmp (&template, &gptdata.type,
+                            sizeof (template)) == 0;
+       }
+      dev->disk->partition = p;
+      return ret;
+    }
+
+  return 0;
+}
+
+static int
+part_hook (grub_disk_t disk, const grub_partition_t partition, void *data)
+{
+  char **ret = data;
+  char *partition_name, *devname;
+  grub_device_t dev;
+
+  partition_name = grub_partition_get_name (partition);
+  if (! partition_name)
+    return 2;
+
+  devname = grub_xasprintf ("%s,%s", disk->name, partition_name);
+  grub_free (partition_name);
+  if (!devname)
+    return 2;
+
+  dev = grub_device_open (devname);
+  if (!dev)
+    {
+      grub_free (devname);
+      return 2;
+    }
+  if (is_prep_partition (dev))
+    {
+      *ret = devname;
+      return 1;
+    }
+  grub_free (devname);
+  grub_device_close (dev);
+  return 0;
+}
+
+static int
+set_var (const char *name, const char *value,
+        void *hook_data __attribute__ ((unused)))
+{
+  grub_env_set (name, value);
+  grub_env_export (name);
+  return 0;
+}
+
+static grub_err_t
+prep_read_envblk (const char *devname)
+{
+  char *buf = NULL;
+  grub_device_t dev = NULL;
+  grub_envblk_t envblk = NULL;
+
+  dev = grub_device_open (devname);
+  if (!dev)
+    return grub_errno;
+
+  if (!dev->disk || !dev->disk->partition)
+    {
+      grub_error (GRUB_ERR_BAD_DEVICE, "disk device required");
+      goto fail;
+    }
+
+  buf = grub_malloc (GRUB_ENVBLK_PREP_SIZE);
+  if (!buf)
+    goto fail;
+
+  if (grub_disk_read (dev->disk, dev->disk->partition->len - 
(GRUB_ENVBLK_PREP_SIZE >> GRUB_DISK_SECTOR_BITS), 0, GRUB_ENVBLK_PREP_SIZE, 
buf))
+    goto fail;
+
+  envblk = grub_envblk_open (buf, GRUB_ENVBLK_PREP_SIZE);
+  if (!envblk)
+    {
+      grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
+      goto fail;
+    }
+  grub_envblk_iterate (envblk, NULL, set_var);
+
+ fail:
+  if (envblk)
+    grub_envblk_close (envblk);
+  else
+    grub_free (buf);
+  if (dev)
+    grub_device_close (dev);
+  return grub_errno;
+}
+
+static grub_err_t
+prep_partname (const char *devname, char **prep)
+{
+  grub_device_t dev = NULL;
+  grub_err_t err;
+  int ret;
+
+  dev = grub_device_open (devname);
+  if (!dev)
+    return grub_errno;
+
+  ret = grub_partition_iterate (dev->disk, part_hook, prep);
+  if (ret == 1 && *prep)
+    {
+      err = GRUB_ERR_NONE;
+      goto out;
+    }
+  else if (ret == 0 && grub_errno == GRUB_ERR_NONE)
+    err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "no prep partition");
+  else
+    err = grub_errno;
+
+ out:
+  grub_device_close (dev);
+  return err;
+}
+
+static grub_err_t
+grub_cmd_prep_loadenv (grub_command_t cmd __attribute__ ((unused)),
+                      int argc,
+                      char **argv)
+{
+  char *devname, *prep = NULL;
+  grub_err_t err;
+
+  if (argc < 1)
+    return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
+
+  devname = grub_file_get_device_name(argv[0]);
+  if (!devname)
+    return grub_errno;
+
+  err = prep_partname (devname, &prep);
+  if (prep == NULL || err != GRUB_ERR_NONE)
+    goto out;
+
+  err = prep_read_envblk (prep);
+
+ out:
+  grub_free (devname);
+  grub_free (prep);
+  return err;
+}
+
+static grub_command_t cmd_prep_load;
+
+GRUB_MOD_INIT(prep_loadenv)
+{
+  cmd_prep_load =
+    grub_register_command("prep_load_env", grub_cmd_prep_loadenv,
+                         "DEVICE",
+                         N_("Load variables from environment block file."));
+}
+
+GRUB_MOD_FINI(prep_loadenv)
+{
+  grub_unregister_command (cmd_prep_load);
+}
-- 
2.34.1


++++++ 0005-export-environment-at-start-up.patch ++++++
>From 496b6b20cbce3fc27228d1d8290089fb7107b8de Mon Sep 17 00:00:00 2001
From: Michael Chang <mch...@suse.com>
Date: Fri, 18 Feb 2022 21:51:16 +0800
Subject: [PATCH 5/5] export environment at start up

If the prep_loadenv module is built into the core image, it will read
the environment block automatically during start up and export all
variables. The will ease integration with those without early scripts to
running the command.

Signed-off-by: Michael Chang <mch...@suse.com>
---
 grub-core/Makefile.core.def       |  2 +
 grub-core/commands/prep_loadenv.c | 77 +++++++++++++++++++++++++++++++
 grub-core/kern/env.c              |  2 +
 grub-core/kern/main.c             |  3 ++
 include/grub/env.h                |  1 +
 5 files changed, 85 insertions(+)

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 4d529859be..f3140815b8 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2628,4 +2628,6 @@ module = {
 module = {
   name = prep_loadenv;
   common = commands/prep_loadenv.c;
+  cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
+  cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)';
 };
diff --git a/grub-core/commands/prep_loadenv.c 
b/grub-core/commands/prep_loadenv.c
index f4bb270a2b..4f40f7e41a 100644
--- a/grub-core/commands/prep_loadenv.c
+++ b/grub-core/commands/prep_loadenv.c
@@ -10,6 +10,7 @@
 #include <grub/extcmd.h>
 #include <grub/i18n.h>
 #include <grub/gpt_partition.h>
+#include <regex.h>
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
@@ -184,6 +185,65 @@ prep_partname (const char *devname, char **prep)
   return err;
 }
 
+static grub_err_t
+boot_disk_prep_partname (char **name)
+{
+  regex_t regex;
+  int ret;
+  grub_size_t s;
+  char *comperr;
+  const char *cmdpath;
+  regmatch_t *matches = NULL;
+  grub_err_t err = GRUB_ERR_NONE;
+
+  *name = NULL;
+
+  cmdpath = grub_env_get ("cmdpath");
+  if (!cmdpath)
+    return GRUB_ERR_NONE;
+
+  ret = regcomp (&regex, "\\(([^,]+)(,?.*)?\\)(.*)", REG_EXTENDED);
+  if (ret)
+    goto fail;
+
+  matches = grub_calloc (regex.re_nsub + 1, sizeof (*matches));
+  if (! matches)
+    goto fail;
+
+  ret = regexec (&regex, cmdpath, regex.re_nsub + 1, matches, 0);
+  if (!ret)
+    {
+      char *devname = devname = match_substr (matches + 1, cmdpath);
+      if (!devname)
+       {
+         err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "%s contains no disk 
name", cmdpath);
+         goto out;
+       }
+
+      err = prep_partname (devname, name);
+ out:
+      grub_free (devname);
+      regfree (&regex);
+      grub_free (matches);
+      return err;
+    }
+
+ fail:
+  grub_free (matches);
+  s = regerror (ret, &regex, 0, 0);
+  comperr = grub_malloc (s);
+  if (!comperr)
+    {
+      regfree (&regex);
+      return grub_errno;
+    }
+  regerror (ret, &regex, comperr, s);
+  err = grub_error (GRUB_ERR_TEST_FAILURE, "%s", comperr);
+  regfree (&regex);
+  grub_free (comperr);
+  return err;
+}
+
 static grub_err_t
 grub_cmd_prep_loadenv (grub_command_t cmd __attribute__ ((unused)),
                       int argc,
@@ -211,10 +271,27 @@ grub_cmd_prep_loadenv (grub_command_t cmd __attribute__ 
((unused)),
   return err;
 }
 
+static void
+early_prep_loadenv (void)
+{
+  grub_err_t err;
+  char *prep;
+
+  err = boot_disk_prep_partname (&prep);
+  if (err == GRUB_ERR_NONE && prep)
+    err = prep_read_envblk (prep);
+  if (err == GRUB_ERR_BAD_FILE_TYPE || err == GRUB_ERR_FILE_NOT_FOUND)
+    grub_error_pop ();
+  if (err != GRUB_ERR_NONE)
+    grub_print_error ();
+  grub_free (prep);
+}
+
 static grub_command_t cmd_prep_load;
 
 GRUB_MOD_INIT(prep_loadenv)
 {
+  early_env_hook = early_prep_loadenv;
   cmd_prep_load =
     grub_register_command("prep_load_env", grub_cmd_prep_loadenv,
                          "DEVICE",
diff --git a/grub-core/kern/env.c b/grub-core/kern/env.c
index c408626423..ec0d268905 100644
--- a/grub-core/kern/env.c
+++ b/grub-core/kern/env.c
@@ -28,6 +28,8 @@ static struct grub_env_context initial_context;
 /* The current context.  */
 struct grub_env_context *grub_current_context = &initial_context;
 
+void (*early_env_hook) (void) = NULL;
+
 /* Return the hash representation of the string S.  */
 static unsigned int
 grub_env_hashval (const char *s)
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
index c7c6d2d0b8..42ea96e39e 100644
--- a/grub-core/kern/main.c
+++ b/grub-core/kern/main.c
@@ -310,6 +310,9 @@ grub_main (void)
 
   grub_boot_time ("Before execution of embedded config.");
 
+  if (early_env_hook != NULL)
+    early_env_hook ();
+
   if (load_config)
     grub_parser_execute (load_config);
 
diff --git a/include/grub/env.h b/include/grub/env.h
index 76f832eb94..636e190a21 100644
--- a/include/grub/env.h
+++ b/include/grub/env.h
@@ -68,5 +68,6 @@ grub_env_extractor_open (int source);
 grub_err_t
 grub_env_extractor_close (int source);
 
+extern void (*EXPORT_VAR (early_env_hook)) (void);
 
 #endif /* ! GRUB_ENV_HEADER */
-- 
2.34.1

Reply via email to