Debrand for AlmaLinux

This commit is contained in:
Eduard Abdullin 2026-08-24 13:13:24 +00:00 committed by root
commit 4725caf9ee
14 changed files with 1931 additions and 6 deletions

View File

@ -0,0 +1,130 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Josue Hernandez <josherna@redhat.com>
Date: Thu, 28 May 2026 16:26:40 -0600
Subject: [PATCH] Change login error message
Login error message shows the line of code where it was called
which is not user friendly, This proposal adds better and more
human log messages when authentication fails
Resolves: #RHEL-180631
Signed-off-by: Josue Hernandez <josherna@redhat.com>
---
grub-core/commands/password.c | 2 +-
grub-core/commands/password_pbkdf2.c | 2 +-
grub-core/kern/err.c | 14 ++++++++++++++
grub-core/normal/auth.c | 17 +++++++++++++----
include/grub/err.h | 2 ++
5 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/grub-core/commands/password.c b/grub-core/commands/password.c
index 6d42c9b02..607ee6435 100644
--- a/grub-core/commands/password.c
+++ b/grub-core/commands/password.c
@@ -35,7 +35,7 @@ check_password (const char *user, const char *entered,
void *password)
{
if (grub_crypto_memcmp (entered, password, GRUB_AUTH_MAX_PASSLEN) != 0)
- return GRUB_ACCESS_DENIED;
+ grub_user_error(GRUB_ERR_ACCESS_DENIED, N_("Authentication error"));
grub_auth_authenticate (user);
diff --git a/grub-core/commands/password_pbkdf2.c b/grub-core/commands/password_pbkdf2.c
index ab845d25e..17dffcd44 100644
--- a/grub-core/commands/password_pbkdf2.c
+++ b/grub-core/commands/password_pbkdf2.c
@@ -58,7 +58,7 @@ check_password (const char *user, const char *entered, void *pin)
if (err)
ret = grub_crypto_gcry_error (err);
else if (grub_crypto_memcmp (buf, pass->expected, pass->buflen) != 0)
- ret = GRUB_ACCESS_DENIED;
+ ret = grub_user_error(GRUB_ERR_ACCESS_DENIED, N_("Authentication error"));
else
{
grub_auth_authenticate (user);
diff --git a/grub-core/kern/err.c b/grub-core/kern/err.c
index aebfe0cf8..d386e094f 100644
--- a/grub-core/kern/err.c
+++ b/grub-core/kern/err.c
@@ -37,6 +37,20 @@ static int grub_error_stack_assert;
#undef grub_error
#endif
+grub_err_t
+grub_user_error (grub_err_t n, const char *fmt, ...)
+{
+ va_list ap;
+
+ grub_errno = n;
+
+ va_start (ap, fmt);
+ grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap);
+ va_end (ap);
+
+ return n;
+}
+
grub_err_t
grub_error (grub_err_t n, const char *file, const int line, const char *fmt, ...)
{
diff --git a/grub-core/normal/auth.c b/grub-core/normal/auth.c
index 075aba452..a7ed80a19 100644
--- a/grub-core/normal/auth.c
+++ b/grub-core/normal/auth.c
@@ -253,12 +253,18 @@ grub_auth_check_authentication (const char *userlist)
grub_puts_ (N_("Enter username: "));
if (!grub_username_get (login, sizeof (login) - 1))
- goto access_denied;
+ {
+ grub_user_error(GRUB_ERR_ACCESS_DENIED, N_("Error getting user"));
+ goto access_denied;
+ }
grub_puts_ (N_("Enter password: "));
if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN))
- goto access_denied;
+ {
+ grub_user_error(GRUB_ERR_ACCESS_DENIED, N_("Error getting password"));
+ goto access_denied;
+ }
FOR_LIST_ELEMENTS (user, users)
{
@@ -267,7 +273,10 @@ grub_auth_check_authentication (const char *userlist)
}
if (!cur || ! cur->callback)
- goto access_denied;
+ {
+ grub_user_error(GRUB_ERR_ACCESS_DENIED, N_("Authentication error"));
+ goto access_denied;
+ }
cur->callback (login, entered, cur->arg);
if (is_authenticated (userlist))
@@ -282,7 +291,7 @@ grub_auth_check_authentication (const char *userlist)
if (punishment_delay < GRUB_ULONG_MAX / 2)
punishment_delay *= 2;
- return GRUB_ACCESS_DENIED;
+ return GRUB_ERR_ACCESS_DENIED;
}
static grub_err_t
diff --git a/include/grub/err.h b/include/grub/err.h
index 4703cb33c..547dda478 100644
--- a/include/grub/err.h
+++ b/include/grub/err.h
@@ -91,6 +91,8 @@ extern char EXPORT_VAR(grub_errmsg)[GRUB_MAX_ERRMSG];
grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *file, const int line, const char *fmt, ...)
__attribute__ ((format (GNU_PRINTF, 4, 5)));
+grub_err_t EXPORT_FUNC(grub_user_error) (grub_err_t n, const char *fmt, ...)
+ __attribute__ ((format (GNU_PRINTF, 2, 3)));
#define grub_error(n, fmt, ...) grub_error (n, __FILE__, __LINE__, fmt, ##__VA_ARGS__)

View File

@ -0,0 +1,120 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Avnish Chouhan <avnish@linux.ibm.com>
Date: Thu, 18 Jun 2026 10:49:54 +0200
Subject: [PATCH] ieee1275/powerpc: implements fibre channel discovery for
ofpathname
grub-ofpathname doesn't work with fibre channel because there is no
function currently implemented for it.
This patch enables it by prividing a function that looks for the port
name, building the entire path for OF devices.
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/146>
---
grub-core/osdep/linux/ofpath.c | 58 +++++++++++++++++++++---------------------
1 file changed, 29 insertions(+), 29 deletions(-)
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
index cc849d9c94c3..9ba1db74aadf 100644
--- a/grub-core/osdep/linux/ofpath.c
+++ b/grub-core/osdep/linux/ofpath.c
@@ -351,36 +351,36 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi
return ret;
}
-
+#define BNAME_SIZE 150
static void
-of_fc_port_name(const char *path, const char *subpath, char *port_name)
+of_fc_port_name (const char *path, const char *subpath, char *port_name)
{
char *bname, *basepath, *p;
int fd;
- bname = xmalloc(sizeof(char)*150);
- basepath = xmalloc(strlen(path));
+ bname = xmalloc (sizeof (char) * BNAME_SIZE);
+ basepath = xmalloc (strlen (path));
/* Generate the path to get port name information from the drive */
- strncpy(basepath,path,subpath-path);
- basepath[subpath-path-1] = '\0';
- p = get_basename(basepath);
- snprintf(bname,sizeof(char)*150,"%s/fc_transport/%s/port_name",basepath,p);
+ strncpy (basepath, path, subpath-path);
+ basepath[subpath-path - 1] = '\0';
+ p = get_basename (basepath);
+ snprintf (bname, sizeof (char) * BNAME_SIZE, "%s/fc_transport/%s/port_name", basepath, p);
/* Read the information from the port name */
fd = open (bname, O_RDONLY);
if (fd < 0)
grub_util_error (_("cannot open `%s': %s"), bname, strerror (errno));
- if (read(fd,port_name,sizeof(char)*19) < 0)
+ if (read (fd, port_name, sizeof (char) *19) < 0)
grub_util_error (_("cannot read `%s': %s"), bname, strerror (errno));
- sscanf(port_name,"0x%s",port_name);
-
- close(fd);
+ sscanf (port_name, "0x%s", port_name);
- free(bname);
- free(basepath);
+ close (fd);
+
+ free (bname);
+ free (basepath);
}
#ifdef __sparc__
@@ -610,16 +610,16 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
digit_string = trailing_digits (device);
if (strncmp (of_path, "/vdevice/", sizeof ("/vdevice/") - 1) == 0)
{
- if(strstr(of_path,"vfc-client"))
- {
- char * port_name = xmalloc(sizeof(char)*17);
- of_fc_port_name(sysfs_path, p, port_name);
-
- snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name);
- free(port_name);
- }
+ if (strstr (of_path, "vfc-client"))
+ {
+ char * port_name = xmalloc (sizeof (char) * 17);
+ of_fc_port_name (sysfs_path, p, port_name);
+
+ snprintf (disk, sizeof (disk), "/%s@%s", disk_name, port_name);
+ free (port_name);
+ }
else
- {
+ {
unsigned long id = 0x8000 | (tgt << 8) | (bus << 5) | lun;
if (*digit_string == '\0')
{
@@ -634,12 +634,12 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
"/%s@%04lx000000000000:%c", disk_name, id, 'a' + (part - 1));
}
}
- } else if (strstr(of_path,"fibre-channel")||(strstr(of_path,"vfc-client"))){
- char * port_name = xmalloc(sizeof(char)*17);
- of_fc_port_name(sysfs_path, p, port_name);
-
- snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name);
- free(port_name);
+ } else if (strstr (of_path, "fibre-channel") || (strstr (of_path, "vfc-client"))){
+ char * port_name = xmalloc (sizeof (char) * 17);
+ of_fc_port_name (sysfs_path, p, port_name);
+
+ snprintf (disk, sizeof (disk), "/%s@%s", disk_name, port_name);
+ free (port_name);
}
else
{

View File

@ -0,0 +1,143 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Avnish Chouhan <avnish@linux.ibm.com>
Date: Mon, 23 Feb 2026 19:14:07 +0530
Subject: [PATCH] ieee1275: implement FCP methods for WWPN and LUNs
This patch enables the fcp-targets and fcp-luns methods which are
responsible to get WWPNs and LUNs for fibre channel devices.
Those methods are specially necessary if the boot directory and grub
installation are in different FCP disks, allowing the dev_iterate()
to find the WWPNs and LUNs when called by searchfs.uuid tool.
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/146>
---
grub-core/disk/ieee1275/ofdisk.c | 111 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 110 insertions(+), 1 deletion(-)
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
index abb5082cdbfc..a16300a94745 100644
--- a/grub-core/disk/ieee1275/ofdisk.c
+++ b/grub-core/disk/ieee1275/ofdisk.c
@@ -223,7 +223,116 @@ dev_iterate_real (const char *name, const char *path)
static void
dev_iterate (const struct grub_ieee1275_devalias *alias)
{
- if (grub_strcmp (alias->type, "vscsi") == 0)
+ if (grub_strcmp (alias->type, "fcp") == 0)
+ {
+ /*
+ * If we are dealing with fcp devices, we need
+ * to find the WWPNs and LUNs to iterate them
+ */
+ grub_ieee1275_ihandle_t ihandle;
+ grub_uint64_t *ptr_targets, *ptr_luns, k, l;
+ unsigned int i, j, pos;
+ char *buf, *bufptr;
+ struct set_fcp_targets_args
+ {
+ struct grub_ieee1275_common_hdr common;
+ grub_ieee1275_cell_t method;
+ grub_ieee1275_cell_t ihandle;
+ grub_ieee1275_cell_t catch_result;
+ grub_ieee1275_cell_t nentries;
+ grub_ieee1275_cell_t table;
+ } args_targets;
+
+ struct set_fcp_luns_args
+ {
+ struct grub_ieee1275_common_hdr common;
+ grub_ieee1275_cell_t method;
+ grub_ieee1275_cell_t ihandle;
+ grub_ieee1275_cell_t wwpn_h;
+ grub_ieee1275_cell_t wwpn_l;
+ grub_ieee1275_cell_t catch_result;
+ grub_ieee1275_cell_t nentries;
+ grub_ieee1275_cell_t table;
+ } args_luns;
+
+ struct args_ret
+ {
+ grub_uint64_t addr;
+ grub_uint64_t len;
+ };
+
+ if (grub_ieee1275_open (alias->path, &ihandle))
+ {
+ grub_dprintf ("disk", "failed to open the disk while iterating FCP disk path=%s\n", alias->path);
+ return;
+ }
+
+ /* Setup the fcp-targets method to call via pfw*/
+ INIT_IEEE1275_COMMON (&args_targets.common, "call-method", 2, 3);
+ args_targets.method = (grub_ieee1275_cell_t) "fcp-targets";
+ args_targets.ihandle = ihandle;
+
+ /* Setup the fcp-luns method to call via pfw */
+ INIT_IEEE1275_COMMON (&args_luns.common, "call-method", 4, 3);
+ args_luns.method = (grub_ieee1275_cell_t) "fcp-luns";
+ args_luns.ihandle = ihandle;
+ if (IEEE1275_CALL_ENTRY_FN (&args_targets) == -1)
+ {
+ grub_dprintf ("disk", "failed to get the targets while iterating FCP disk path=%s\n", alias->path);
+ grub_ieee1275_close (ihandle);
+ return;
+ }
+ buf = grub_malloc (grub_strlen (alias->path) + 32 + 32);
+ if (!buf)
+ {
+ grub_ieee1275_close (ihandle);
+ return;
+ }
+ bufptr = grub_stpcpy (buf, alias->path);
+
+ /*
+ * Iterate over entries returned by pfw. Each entry contains a
+ * pointer to wwpn table and his length.
+ */
+ struct args_ret *targets_table = (struct args_ret *) (args_targets.table);
+ for (i = 0; i < args_targets.nentries; i++)
+ {
+ ptr_targets = (grub_uint64_t*) targets_table[i].addr;
+ /* Iterate over all wwpns in given table */
+ for(k = 0; k < targets_table[i].len; k++)
+ {
+ args_luns.wwpn_l = (grub_ieee1275_cell_t) (*ptr_targets);
+ args_luns.wwpn_h = (grub_ieee1275_cell_t) (*ptr_targets >> 32);
+ pos = grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T,
+ grub_get_unaligned64 (*ptr_targets++));
+ /* Get the luns for given wwpn target */
+ if (IEEE1275_CALL_ENTRY_FN (&args_luns) == -1)
+ {
+ grub_dprintf ("disk", "failed to get the LUNS while iterating FCP disk path=%s\n", buf);
+ grub_ieee1275_close (ihandle);
+ grub_free (buf);
+ return;
+ }
+ struct args_ret *luns_table = (struct args_ret *) (args_luns.table);
+
+ /* Iterate over all LUNs */
+ for(j = 0; j < args_luns.nentries; j++)
+ {
+ ptr_luns = (grub_uint64_t*) luns_table[j].addr;
+ for(l = 0; l < luns_table[j].len; l++)
+ {
+ grub_snprintf (&bufptr[pos], 30, ",%" PRIxGRUB_UINT64_T,
+ grub_get_unaligned64 (*ptr_luns++));
+ dev_iterate_real (buf, buf);
+ }
+ }
+ }
+ }
+ grub_ieee1275_close (ihandle);
+ grub_free (buf);
+ return;
+ }
+ else if (grub_strcmp (alias->type, "vscsi") == 0)
{
static grub_ieee1275_ihandle_t ihandle;
struct set_color_args

View File

@ -0,0 +1,63 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Avnish Chouhan <avnish@linux.ibm.com>
Date: Mon, 23 Feb 2026 19:14:08 +0530
Subject: [PATCH] ieee1275: change the logic of ieee1275_get_devargs()
Usually grub will parse the PFW arguments by searching for the first occurence of the character ':'.
However, we can have this char more than once on NQN.
This patch changes the logic to find the last occurence of this char so we can get the proper values
for NVMeoFC
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/146>
---
grub-core/kern/ieee1275/openfw.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c
index 0278054c61e6..de0b8c299285 100644
--- a/grub-core/kern/ieee1275/openfw.c
+++ b/grub-core/kern/ieee1275/openfw.c
@@ -324,7 +324,7 @@ grub_claimmap (grub_addr_t addr, grub_size_t size)
static char *
grub_ieee1275_get_devargs (const char *path)
{
- char *colon = grub_strchr (path, ':');
+ char *colon = grub_strrchr (path, ':');
if (! colon)
return 0;
@@ -339,6 +339,21 @@ grub_ieee1275_get_devname (const char *path)
char *colon = grub_strchr (path, ':');
int pathlen = grub_strlen (path);
struct grub_ieee1275_devalias curalias;
+
+ /* Check some special cases */
+ if (grub_strstr (path, "nvme-of"))
+ {
+ char *namespace_split = grub_strstr (path, "/namespace@");
+ if (namespace_split)
+ {
+ colon = grub_strchr (namespace_split, ':');
+ }
+ else
+ {
+ colon = NULL;
+ }
+ }
+
if (colon)
pathlen = (int)(colon - path);
@@ -579,7 +594,7 @@ grub_ieee1275_get_boot_dev (void)
return NULL;
}
- bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64);
+ bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64 + 256);
if (! bootpath)
{
grub_print_error ();

View File

@ -0,0 +1,547 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Avnish Chouhan <avnish@linux.ibm.com>
Date: Mon, 23 Feb 2026 19:14:10 +0530
Subject: [PATCH] ieee1275: ofpath enable NVMeoF logical device translate
This patch adds code to enable the translation of logical devices to the of NVMeoFC paths.
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/146>
---
grub-core/osdep/linux/ofpath.c | 431 ++++++++++++++++++++++++++++++++++++++++-
include/grub/util/ofpath.h | 28 +++
2 files changed, 450 insertions(+), 9 deletions(-)
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
index 9ba1db74aadf..54094a87576b 100644
--- a/grub-core/osdep/linux/ofpath.c
+++ b/grub-core/osdep/linux/ofpath.c
@@ -137,7 +137,7 @@ trim_newline (char *path)
*end-- = '\0';
}
-#define MAX_DISK_CAT 64
+#define MAX_DISK_CAT 512
static char *
find_obppath (const char *sysfs_path_orig)
@@ -313,6 +313,91 @@ get_basename(char *p)
return ret;
}
+int
+add_filename_to_pile (char *filename, struct ofpath_files_list_root* root)
+{
+ struct ofpath_files_list_node* file;
+
+ file = malloc (sizeof (struct ofpath_files_list_node));
+ if (!file)
+ return -1;
+
+ file->filename = malloc (sizeof (char) * 1024);
+ if (!file->filename)
+ {
+ free (file);
+ return -1;
+ }
+
+ grub_strcpy (file->filename, filename);
+ if (root->first == NULL)
+ {
+ root->items = 1;
+ root->first = file;
+ file->next = NULL;
+ }
+ else
+ {
+ root->items++;
+ file->next = root->first;
+ root->first = file;
+ }
+
+ return 0;
+}
+
+void
+find_file (char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth)
+{
+ struct dirent *ep;
+ struct stat statbuf;
+ DIR *dp;
+ int ret_val=0;
+ char* full_path;
+
+ if (depth > max_depth)
+ {
+ return;
+ }
+
+ if ((dp = opendir (directory)) == NULL)
+ {
+ return;
+ }
+
+ full_path = malloc (1024 * sizeof (char));
+ if (!full_path)
+ return;
+
+ while ((ep = readdir(dp)) != NULL)
+ {
+ snprintf (full_path, 1024, "%s/%s", directory, ep->d_name);
+ lstat (full_path, &statbuf);
+
+ if (S_ISLNK (statbuf.st_mode))
+ {
+ continue;
+ }
+
+ if (!strcmp (ep->d_name, ".") || !strcmp(ep->d_name, ".."))
+ {
+ continue;
+ }
+
+ if (!strcmp (ep->d_name, filename))
+ {
+ ret_val = add_filename_to_pile (full_path, root);
+ if (ret_val == -1)
+ continue;
+ }
+
+ find_file (filename, full_path, root, max_depth, depth+1);
+ }
+
+ free (full_path);
+ closedir (dp);
+}
+
static char *
of_path_of_vdisk(const char *sys_devname __attribute__((unused)),
const char *device,
@@ -383,7 +468,257 @@ of_fc_port_name (const char *path, const char *subpath, char *port_name)
free (basepath);
}
-#ifdef __sparc__
+void
+free_ofpath_files_list (struct ofpath_files_list_root* root)
+{
+ struct ofpath_files_list_node* node = root->first;
+ struct ofpath_files_list_node* next;
+
+ while (node!=NULL)
+ {
+ next = node->next;
+ free (node->filename);
+ free (node);
+ node = next;
+ }
+
+ free (root);
+ return;
+}
+
+char*
+of_find_fc_host (char* host_wwpn)
+{
+ FILE* fp;
+ char *buf;
+ char *ret_val;
+ char portname_filename[sizeof ("port_name")] = "port_name";
+ char devices_path[sizeof ("/sys/devices")] = "/sys/devices";
+ struct ofpath_files_list_root* portnames_file_list;
+ struct ofpath_files_list_node* node;
+
+ ret_val = malloc (sizeof (char) * 1024);
+ if (!ret_val)
+ return NULL;
+
+ portnames_file_list = malloc (sizeof (struct ofpath_files_list_root));
+ if (!portnames_file_list)
+ {
+ free (ret_val);
+ return NULL;
+ }
+
+ portnames_file_list->items = 0;
+ portnames_file_list->first = NULL;
+ find_file (portname_filename, devices_path, portnames_file_list, 10, 0);
+ node = portnames_file_list->first;
+
+ while (node != NULL)
+ {
+ fp = fopen(node->filename, "r");
+ if (!fp)
+ {
+ node = node->next;
+ continue;
+ }
+
+ buf = malloc (sizeof (char) * 512);
+ if (!buf)
+ break;
+
+ fscanf (fp, "%s", buf);
+ fclose (fp);
+
+ if ((strcmp (buf, host_wwpn) == 0) && grub_strstr (node->filename, "fc_host"))
+ {
+ free (buf);
+ grub_strcpy (ret_val, node->filename);
+ free_ofpath_files_list (portnames_file_list);
+ return ret_val;
+ }
+
+ node = node->next;
+ free (buf);
+ }
+ free_ofpath_files_list (portnames_file_list);
+ free (ret_val);
+ return NULL;
+}
+
+int
+of_path_get_nvmeof_adapter_info (char* sysfs_path,
+ struct ofpath_nvmeof_info* nvmeof_info)
+{
+ FILE *fp;
+ char *buf, *buf2, *buf3;
+
+ nvmeof_info->host_wwpn = malloc (sizeof (char) * 256);
+ nvmeof_info->target_wwpn = malloc (sizeof (char) * 256);
+ nvmeof_info->nqn = malloc (sizeof (char) * 256);
+
+ if (nvmeof_info->host_wwpn == NULL || nvmeof_info->target_wwpn == NULL || nvmeof_info->nqn == NULL)
+ {
+ free (nvmeof_info->host_wwpn);
+ free (nvmeof_info->target_wwpn);
+ free (nvmeof_info->nqn);
+ return -1;
+ }
+
+ buf = malloc (sizeof (char) * 512);
+ if (!buf)
+ {
+ free (nvmeof_info->host_wwpn);
+ free (nvmeof_info->target_wwpn);
+ free (nvmeof_info->nqn);
+ return -1;
+ }
+
+ snprintf (buf, 512, "%s/subsysnqn", sysfs_path);
+ if (! (fp = fopen (buf, "r")) ||
+ fscanf (fp, "%s", nvmeof_info->nqn) != 1)
+ {
+ if (fp)
+ fclose (fp);
+ free (nvmeof_info->host_wwpn);
+ free (nvmeof_info->target_wwpn);
+ free (nvmeof_info->nqn);
+ free (buf);
+ return -1;
+ }
+ fclose (fp);
+
+ snprintf (buf, 512, "%s/cntlid", sysfs_path);
+ if (! (fp = fopen (buf, "r")) ||
+ fscanf (fp, "%u", &(nvmeof_info->cntlid)) != 1)
+ {
+ if (fp)
+ fclose (fp);
+ free (nvmeof_info->host_wwpn);
+ free (nvmeof_info->target_wwpn);
+ free (nvmeof_info->nqn);
+ free (buf);
+ return -1;
+ }
+ fclose (fp);
+
+ snprintf (buf, 512, "%s/address", sysfs_path);
+ buf2 = NULL;
+ fp = NULL;
+ if (! (buf2 = malloc (sizeof (char) * 512)) ||
+ ! (fp = fopen (buf, "r")) ||
+ fscanf (fp, "%s", buf2) != 1)
+ {
+ if (fp)
+ fclose (fp);
+ free (nvmeof_info->host_wwpn);
+ free (nvmeof_info->target_wwpn);
+ free (nvmeof_info->nqn);
+ free (buf);
+ free (buf2);
+ return -1;
+ }
+
+ fclose (fp);
+
+ if (! (buf3 = strrchr (buf2, '-')))
+ {
+ free (nvmeof_info->host_wwpn);
+ free (nvmeof_info->target_wwpn);
+ free (nvmeof_info->nqn);
+ free (buf);
+ free (buf2);
+ return -1;
+ }
+ grub_memcpy (nvmeof_info->host_wwpn, buf3 + 1, 256);
+ if (! (buf3 = strchr (buf2, '-')) ||
+ ! (buf3 = strchr (buf3 + 1, '-')) ||
+ ! (buf3 = strchr (buf3 + 1, 'x')))
+ {
+ free (nvmeof_info->host_wwpn);
+ free (nvmeof_info->target_wwpn);
+ free (nvmeof_info->nqn);
+ free (buf);
+ free (buf2);
+ return -1;
+ }
+ grub_memcpy (nvmeof_info->target_wwpn, buf3 + 1, 256);
+ buf3 = strchr (nvmeof_info->target_wwpn, ',');
+ if (buf3)
+ *buf3 = '\0';
+ free (buf);
+ free (buf2);
+ return 0;
+}
+
+#define OFPATH_MAX_UINT_HEX_DIGITS 8
+#define OFPATH_MAX_INT_DIGITS 10
+
+static char *
+of_path_get_nvme_controller_name_node (const char* devname)
+{
+ char *controller_node, *end;
+
+ controller_node = xstrdup (devname);
+ end = grub_strchr (controller_node + 1, 'n');
+ if (end != NULL)
+ {
+ *end = '\0';
+ }
+
+ return controller_node;
+}
+
+unsigned int
+of_path_get_nvme_nsid (const char* devname)
+{
+ unsigned int nsid;
+ char *sysfs_path, *buf;
+ FILE *fp;
+
+ buf = malloc (sizeof(char) * 512);
+ if (!buf)
+ return 0;
+
+ sysfs_path = block_device_get_sysfs_path_and_link (devname);
+ snprintf (buf, 512, "%s/%s/nsid", sysfs_path, devname);
+ fp = fopen(buf, "r");
+ if (!fp)
+ {
+ free (sysfs_path);
+ free (buf);
+ return 0;
+ }
+
+ fscanf (fp, "%u", &(nsid));
+ fclose (fp);
+
+ free (sysfs_path);
+ free (buf);
+ return nsid;
+}
+
+static char *
+nvme_get_syspath (const char *nvmedev)
+{
+ char *sysfs_path;
+
+ sysfs_path = block_device_get_sysfs_path_and_link (nvmedev);
+ if (strstr (sysfs_path, "nvme-subsystem"))
+ {
+ char *controller_node = of_path_get_nvme_controller_name_node (nvmedev);
+ char *buf = xmalloc (strlen (sysfs_path) + strlen ("/") + strlen (controller_node) + 1);
+ strcpy (buf, sysfs_path);
+ strcat (buf, "/");
+ strcat (buf, controller_node);
+ free (sysfs_path);
+ free (controller_node);
+ sysfs_path = xrealpath (buf);
+ free (buf);
+ }
+
+ return sysfs_path;
+}
+
static char *
of_path_of_nvme(const char *sys_devname __attribute__((unused)),
const char *device,
@@ -392,6 +727,8 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
{
char *sysfs_path, *of_path, disk[MAX_DISK_CAT];
const char *digit_string, *part_end;
+ int chars_written, ret_val;
+ struct ofpath_nvmeof_info* nvmeof_info;
digit_string = trailing_digits (device);
part_end = devicenode + strlen (devicenode) - 1;
@@ -411,15 +748,94 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
/* Remove the p. */
*end = '\0';
sscanf (digit_string, "%d", &part);
- snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1));
- sysfs_path = block_device_get_sysfs_path_and_link (nvmedev);
+ sysfs_path = nvme_get_syspath (nvmedev);
+
+ /* If is a NVMeoF */
+ if (strstr (sysfs_path, "nvme-fabrics"))
+ {
+ nvmeof_info = malloc (sizeof (struct ofpath_nvmeof_info));
+ if (!nvmeof_info)
+ {
+ free (nvmedev);
+ return NULL;
+ }
+
+ ret_val = of_path_get_nvmeof_adapter_info (sysfs_path, nvmeof_info);
+ if (ret_val == -1)
+ {
+ free (nvmedev);
+ free (nvmeof_info);
+ return NULL;
+ }
+
+ free (sysfs_path);
+ sysfs_path = of_find_fc_host (nvmeof_info->host_wwpn);
+ if (!sysfs_path)
+ {
+ free (nvmedev);
+ free (nvmeof_info->host_wwpn);
+ free (nvmeof_info->target_wwpn);
+ free (nvmeof_info->nqn);
+ free (nvmeof_info);
+ return NULL;
+ }
+
+ chars_written = snprintf (disk,sizeof(disk), "/nvme-of/controller@%s,%x:nqn=%s",
+ nvmeof_info->target_wwpn,0xffff,
+ nvmeof_info->nqn);
+ unsigned int nsid = of_path_get_nvme_nsid (nvmedev);
+ if (nsid)
+ {
+ snprintf (disk+chars_written, sizeof("/namespace@") + OFPATH_MAX_UINT_HEX_DIGITS + OFPATH_MAX_INT_DIGITS,
+ "/namespace@%x:%d", nsid, part);
+ }
+ free (nvmeof_info);
+ }
+ else
+ {
+ snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1));
+ }
free (nvmedev);
}
else
{
/* We do not have the parition. */
- snprintf (disk, sizeof (disk), "/disk@1");
- sysfs_path = block_device_get_sysfs_path_and_link (device);
+ sysfs_path = nvme_get_syspath (device);
+ if (strstr (sysfs_path, "nvme-fabrics"))
+ {
+ nvmeof_info = malloc (sizeof (struct ofpath_nvmeof_info));
+ if (!nvmeof_info)
+ return NULL;
+
+ ret_val = of_path_get_nvmeof_adapter_info (sysfs_path, nvmeof_info);
+ if (ret_val == -1)
+ {
+ free (nvmeof_info);
+ return NULL;
+ }
+
+ sysfs_path = of_find_fc_host (nvmeof_info->host_wwpn);
+ if (!sysfs_path)
+ {
+ free (nvmeof_info);
+ return NULL;
+ }
+
+ chars_written = snprintf (disk,sizeof(disk), "/nvme-of/controller@%s,%x:nqn=%s",
+ nvmeof_info->target_wwpn, 0xffff,
+ nvmeof_info->nqn);
+ unsigned int nsid = of_path_get_nvme_nsid (device);
+ if (nsid)
+ {
+ snprintf (disk+chars_written,sizeof("/namespace@") + sizeof(char) * OFPATH_MAX_UINT_HEX_DIGITS,
+ "/namespace@%x", nsid);
+ }
+ free (nvmeof_info);
+ }
+ else
+ {
+ snprintf (disk, sizeof (disk), "/disk@1");
+ }
}
of_path = find_obppath (sysfs_path);
@@ -430,7 +846,6 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
free (sysfs_path);
return of_path;
}
-#endif
static int
vendor_is_ATA(const char *path)
@@ -841,11 +1256,9 @@ grub_util_devname_to_ofpath (const char *sys_devname)
/* All the models I've seen have a devalias "floppy".
New models have no floppy at all. */
ofpath = xstrdup ("floppy");
-#ifdef __sparc__
else if (device[0] == 'n' && device[1] == 'v' && device[2] == 'm'
&& device[3] == 'e')
ofpath = of_path_of_nvme (name_buf, device, devnode, devicenode);
-#endif
else
{
grub_util_warn (_("unknown device type %s"), device);
diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h
index b43c523cb267..7ab377c7cc43 100644
--- a/include/grub/util/ofpath.h
+++ b/include/grub/util/ofpath.h
@@ -3,4 +3,32 @@
char *grub_util_devname_to_ofpath (const char *devname);
+struct ofpath_files_list_node
+{
+ char* filename;
+ struct ofpath_files_list_node* next;
+};
+
+struct ofpath_files_list_root
+{
+ int items;
+ struct ofpath_files_list_node* first;
+};
+
+struct ofpath_nvmeof_info
+{
+ char* host_wwpn;
+ char* target_wwpn;
+ char* nqn;
+ int cntlid;
+ int nsid;
+};
+
+int of_path_get_nvmeof_adapter_info (char* sysfs_path, struct ofpath_nvmeof_info* nvmeof_info);
+unsigned int of_path_get_nvme_nsid (const char* devname);
+int add_filename_to_pile (char *filename, struct ofpath_files_list_root* root);
+void find_file (char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth);
+char* of_find_fc_host (char* host_wwpn);
+void free_ofpath_files_list (struct ofpath_files_list_root* root);
+
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */

View File

@ -0,0 +1,218 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Avnish Chouhan <avnish@linux.ibm.com>
Date: Mon, 23 Feb 2026 19:14:11 +0530
Subject: [PATCH] ieee1275: support added for multiple nvme bootpaths
This patch sets mupltiple NVMe boot-devices for more robust boot.
Scenario where NVMe multipaths are available, all the available bootpaths (Max 5)
will be added as the boot-device.
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/146>
---
grub-core/osdep/linux/ofpath.c | 4 +-
grub-core/osdep/unix/platform.c | 122 +++++++++++++++++++++++++++++++++++++++-
include/grub/util/install.h | 3 +
include/grub/util/ofpath.h | 4 ++
4 files changed, 130 insertions(+), 3 deletions(-)
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
index 54094a87576b..46b23820c8b8 100644
--- a/grub-core/osdep/linux/ofpath.c
+++ b/grub-core/osdep/linux/ofpath.c
@@ -209,7 +209,7 @@ find_obppath (const char *sysfs_path_orig)
}
}
-static char *
+char *
xrealpath (const char *in)
{
char *out;
@@ -697,7 +697,7 @@ of_path_get_nvme_nsid (const char* devname)
return nsid;
}
-static char *
+char *
nvme_get_syspath (const char *nvmedev)
{
char *sysfs_path;
diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
index 55b8f4016248..8ca94e3ee0fe 100644
--- a/grub-core/osdep/unix/platform.c
+++ b/grub-core/osdep/unix/platform.c
@@ -28,6 +28,10 @@
#include <dirent.h>
#include <string.h>
#include <errno.h>
+#include <grub/util/ofpath.h>
+#include <stdbool.h>
+
+#define BOOTDEV_BUFFER 1000
static char *
get_ofpathname (const char *dev)
@@ -176,6 +180,111 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
return ret;
}
+
+char *
+add_multiple_nvme_bootdevices (const char *install_device)
+{
+ char *sysfs_path, *nvme_ns, *ptr, *non_splitter_path;
+ unsigned int nsid;
+ char *multipath_boot, *ofpath, *ext_dir;
+ struct dirent *ep, *splitter_ep;
+ DIR *dp, *splitter_dp;
+ char *cntl_id, *dirR1, *dirR2, *splitter_info_path;
+ bool is_FC = false, is_splitter = false;
+
+ nvme_ns = grub_strstr (install_device, "nvme");
+ nsid = of_path_get_nvme_nsid (nvme_ns);
+ if (nsid == 0)
+ return NULL;
+
+ sysfs_path = nvme_get_syspath (nvme_ns);
+ ofpath = xasprintf ("%s", get_ofpathname (nvme_ns));
+
+ if (grub_strstr (ofpath, "fibre-channel"))
+ {
+ char *tmp = xasprintf ("%s/device", sysfs_path);
+ free (sysfs_path);
+ sysfs_path = tmp;
+ is_FC = true;
+ }
+ else
+ {
+ char *tmp = xasprintf ("%s/subsystem", sysfs_path);
+ free (sysfs_path);
+ sysfs_path = tmp;
+ is_FC = false;
+ }
+ if (is_FC == false)
+ {
+ cntl_id = grub_strstr (nvme_ns, "e");
+ dirR1 = xasprintf ("nvme%c",cntl_id[1]);
+
+ splitter_info_path = xasprintf ("/sys/block/%s/device", nvme_ns);
+ splitter_dp = opendir (splitter_info_path);
+ if (!splitter_dp)
+ return NULL;
+
+ while ((splitter_ep = readdir (splitter_dp)) != NULL)
+ {
+ if (grub_strstr (splitter_ep->d_name, "nvme"))
+ {
+ if (grub_strstr (splitter_ep->d_name, dirR1))
+ continue;
+
+ ext_dir = grub_strchr (splitter_ep->d_name, 'e');
+ if (grub_strchr (ext_dir, 'n') == NULL)
+ {
+ dirR2 = xasprintf("%s", splitter_ep->d_name);
+ is_splitter = true;
+ break;
+ }
+ }
+ }
+ closedir (splitter_dp);
+ }
+ sysfs_path = xrealpath (sysfs_path);
+ dp = opendir (sysfs_path);
+ if (!dp)
+ return NULL;
+
+ ptr = multipath_boot = xmalloc (BOOTDEV_BUFFER);
+ if (is_splitter == false && is_FC == false)
+ {
+ non_splitter_path = xasprintf ("%s/namespace@%x:1 ", get_ofpathname (dirR1), nsid);
+ strncpy (ptr, non_splitter_path, strlen (non_splitter_path));
+ ptr += strlen (non_splitter_path);
+ free (non_splitter_path);
+ }
+ else
+ {
+ while ((ep = readdir (dp)) != NULL)
+ {
+ char *path;
+
+ if (grub_strstr (ep->d_name, "nvme") != NULL)
+ {
+ if (is_FC == false && grub_strstr (ep->d_name, dirR1) == NULL &&
+ grub_strstr (ep->d_name, dirR2) == NULL)
+ continue;
+ path = xasprintf ("%s/namespace@%x ", get_ofpathname (ep->d_name), nsid);
+ if ((strlen (multipath_boot) + strlen (path)) > BOOTDEV_BUFFER)
+ {
+ grub_util_warn (_("Maximum five entries are allowed in the bootlist"));
+ free (path);
+ break;
+ }
+ strncpy (ptr, path, strlen (path));
+ ptr += strlen (path);
+ free (path);
+ }
+ }
+ }
+ *--ptr = '\0';
+ closedir (dp);
+
+ return multipath_boot;
+}
+
void
grub_install_register_ieee1275 (int is_prep, const char *install_device,
int partno, const char *relpath)
@@ -215,8 +324,19 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
}
*ptr = '\0';
}
+ else if (grub_strstr (install_device, "nvme"))
+ {
+ boot_device = add_multiple_nvme_bootdevices (install_device);
+ }
else
- boot_device = get_ofpathname (install_device);
+ {
+ boot_device = get_ofpathname (install_device);
+ if (grub_strstr (boot_device, "nvme-of"))
+ {
+ free (boot_device);
+ boot_device = add_multiple_nvme_bootdevices (install_device);
+ }
+ }
if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
boot_device, NULL }))
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
index ccf799ff7169..5b4513904889 100644
--- a/include/grub/util/install.h
+++ b/include/grub/util/install.h
@@ -238,6 +238,9 @@ grub_install_register_efi (grub_device_t efidir_grub_dev,
const char *efifile_path,
const char *efi_distributor);
+char *
+add_multiple_nvme_bootdevices (const char *install_device);
+
void
grub_install_register_ieee1275 (int is_prep, const char *install_device,
int partno, const char *relpath);
diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h
index 7ab377c7cc43..9f9a753dcebb 100644
--- a/include/grub/util/ofpath.h
+++ b/include/grub/util/ofpath.h
@@ -30,5 +30,9 @@ int add_filename_to_pile (char *filename, struct ofpath_files_list_root* root);
void find_file (char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth);
char* of_find_fc_host (char* host_wwpn);
void free_ofpath_files_list (struct ofpath_files_list_root* root);
+char* nvme_get_syspath (const char *nvmedev);
+unsigned int of_path_get_nvme_nsid (const char* devname);
+char* xrealpath (const char *in);
+
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */

View File

@ -0,0 +1,457 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Avnish Chouhan <avnish@linux.ibm.com>
Date: Mon, 23 Feb 2026 19:14:09 +0530
Subject: [PATCH] ieee1275: add support for NVMeoFC
This patch implements the functions to scan and discovery of NVMeoFC.
Signed-off-by: Diego Domingos <diegodo@br.ibm.com>
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
Reviewed-by: Leo Sandoval <lsandova@redhat.com>
Reviewed-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
Part-of: <https://gitlab.freedesktop.org/gnu-grub/grub/-/merge_requests/146>
---
grub-core/disk/ieee1275/ofdisk.c | 418 +++++++++++++++++++++++++++++----------
1 file changed, 312 insertions(+), 106 deletions(-)
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
index a16300a94745..cf0f003f90da 100644
--- a/grub-core/disk/ieee1275/ofdisk.c
+++ b/grub-core/disk/ieee1275/ofdisk.c
@@ -26,6 +26,10 @@
#include <grub/time.h>
#include <grub/safemath.h>
+#define EXTEND_PATH_64 64
+#define EXTEND_PATH_512 512
+#define TABLE_SIZE 256
+
static char *last_devpath;
static grub_ieee1275_ihandle_t last_ihandle;
@@ -220,117 +224,319 @@ dev_iterate_real (const char *name, const char *path)
return;
}
+static void
+dev_iterate_fcp_disks (const struct grub_ieee1275_devalias *alias)
+ {
+ /*
+ * If we are dealing with fcp devices, we need
+ * to find the WWPNs and LUNs to iterate them
+ */
+ grub_ieee1275_ihandle_t ihandle;
+ grub_uint64_t *ptr_targets, *ptr_luns, k, l;
+ unsigned int i, j, pos;
+ char *buf, *bufptr;
+ struct set_fcp_targets_args
+ {
+ struct grub_ieee1275_common_hdr common;
+ grub_ieee1275_cell_t method;
+ grub_ieee1275_cell_t ihandle;
+ grub_ieee1275_cell_t catch_result;
+ grub_ieee1275_cell_t nentries;
+ grub_ieee1275_cell_t table;
+ } args_targets;
+
+ struct set_fcp_luns_args
+ {
+ struct grub_ieee1275_common_hdr common;
+ grub_ieee1275_cell_t method;
+ grub_ieee1275_cell_t ihandle;
+ grub_ieee1275_cell_t wwpn_h;
+ grub_ieee1275_cell_t wwpn_l;
+ grub_ieee1275_cell_t catch_result;
+ grub_ieee1275_cell_t nentries;
+ grub_ieee1275_cell_t table;
+ } args_luns;
+
+ struct args_ret
+ {
+ grub_uint64_t addr;
+ grub_uint64_t len;
+ };
+ struct args_ret *targets_table;
+ struct args_ret *luns_table;
+
+ if (grub_ieee1275_open (alias->path, &ihandle))
+ {
+ grub_dprintf ("disk", "failed to open the disk while iterating FCP disk path=%s\n", alias->path);
+ return;
+ }
+
+ /* Setup the fcp-targets method to call via pfw*/
+ INIT_IEEE1275_COMMON (&args_targets.common, "call-method", 2, 3);
+ args_targets.method = (grub_ieee1275_cell_t) "fcp-targets";
+ args_targets.ihandle = ihandle;
+
+ /* Setup the fcp-luns method to call via pfw */
+ INIT_IEEE1275_COMMON (&args_luns.common, "call-method", 4, 3);
+ args_luns.method = (grub_ieee1275_cell_t) "fcp-luns";
+ args_luns.ihandle = ihandle;
+ if (IEEE1275_CALL_ENTRY_FN (&args_targets) == -1)
+ {
+ grub_dprintf ("disk", "failed to get the targets while iterating FCP disk path=%s\n", alias->path);
+ grub_ieee1275_close (ihandle);
+ return;
+ }
+ /* Allocate memory for building the path */
+ buf = grub_malloc (grub_strlen (alias->path) + EXTEND_PATH_64);
+ if (!buf)
+ {
+ grub_ieee1275_close (ihandle);
+ return;
+ }
+ bufptr = grub_stpcpy (buf, alias->path);
+
+ /*
+ * Iterate over entries returned by pfw. Each entry contains a
+ * pointer to wwpn table and his length.
+ */
+ targets_table = (struct args_ret *) (args_targets.table);
+ for (i = 0; i < args_targets.nentries; i++)
+ {
+ ptr_targets = (grub_uint64_t*) (grub_addr_t) targets_table[i].addr;
+ /* Iterate over all wwpns in given table */
+ for (k = 0; k < targets_table[i].len; k++)
+ {
+ args_luns.wwpn_l = (grub_ieee1275_cell_t) (*ptr_targets);
+ args_luns.wwpn_h = (grub_ieee1275_cell_t) (*ptr_targets >> 32);
+ pos = grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T,
+ grub_get_unaligned64 ((const void *) ptr_targets));
+ ptr_targets++;
+ /* Get the luns for given wwpn target */
+ if (IEEE1275_CALL_ENTRY_FN (&args_luns) == -1)
+ {
+ grub_dprintf ("disk", "failed to get the LUNS while iterating FCP disk path=%s\n", buf);
+ grub_ieee1275_close (ihandle);
+ grub_free (buf);
+ return;
+ }
+ luns_table = (struct args_ret *) (args_luns.table);
+
+ /* Iterate over all LUNs */
+ for (j = 0; j < args_luns.nentries; j++)
+ {
+ ptr_luns = (grub_uint64_t*) (grub_addr_t) luns_table[j].addr;
+ for (l = 0; l < luns_table[j].len; l++)
+ {
+ grub_snprintf (&bufptr[pos], 30, ",%" PRIxGRUB_UINT64_T,
+ grub_get_unaligned64 ((const void *) ptr_luns));
+ ptr_luns++;
+ dev_iterate_real (buf, buf);
+ }
+ }
+ }
+ }
+ grub_ieee1275_close (ihandle);
+ grub_free (buf);
+ return;
+}
+
+static void
+dev_iterate_fcp_nvmeof (const struct grub_ieee1275_devalias *alias)
+{
+ char *bufptr;
+ grub_ieee1275_ihandle_t ihandle;
+
+ /* Create the structs for the parameters passing to PFW */
+ struct nvme_args
+ {
+ struct grub_ieee1275_common_hdr common;
+ grub_ieee1275_cell_t method;
+ grub_ieee1275_cell_t ihandle;
+ grub_ieee1275_cell_t catch_result;
+ grub_ieee1275_cell_t nentries;
+ grub_ieee1275_cell_t table;
+ } nvme_discovery_controllers_args, nvme_controllers_args, nvme_namespaces_args;
+
+ /* Create the structs for the results from PFW */
+ struct discovery_controllers_table_struct
+ {
+ grub_uint64_t table[TABLE_SIZE];
+ grub_uint32_t len;
+ } discovery_controllers_table;
+
+ /*
+ * struct nvme_controllers_table_entry
+ * this the return of nvme-controllers method tables, containing:
+ * - 2-byte controller ID
+ * - 256-byte transport address string
+ * - 256-byte field containing null-terminated NVM subsystem NQN string up to 223 characters
+ */
+ struct nvme_controllers_table_entry
+ {
+ grub_uint16_t id;
+ char wwpn[TABLE_SIZE];
+ char nqn[TABLE_SIZE];
+ };
+
+ struct nvme_controllers_table_entry_real
+ {
+ grub_uint16_t id;
+ char wwpn[TABLE_SIZE];
+ char nqn[TABLE_SIZE];
+ };
+
+ struct nvme_controllers_table_entry* nvme_controllers_table;
+ grub_uint32_t nvme_controllers_table_entries;
+ char *buf;
+ unsigned int i = 0;
+ int current_buffer_index;
+ int nvme_controller_index;
+ int bufptr_pos2;
+ grub_uint32_t namespace_index = 0;
+ struct nvme_controllers_table_entry* nvme_controllers_table_buf;
+
+ nvme_controllers_table = grub_malloc (sizeof (struct nvme_controllers_table_entry) * TABLE_SIZE);
+ /* Allocate memory for building the NVMeoF path */
+ buf = grub_malloc (grub_strlen (alias->path) + EXTEND_PATH_512);
+
+ if (!buf || !nvme_controllers_table)
+ {
+ grub_free (nvme_controllers_table);
+ grub_free (buf);
+ return;
+ }
+
+ /* Copy the alias->path to buf so we can work with */
+ bufptr = grub_stpcpy (buf, alias->path);
+ grub_snprintf (bufptr, 32, "/nvme-of");
+
+ /*
+ * Open the nvme-of layer
+ * Ex. /pci@bus/fibre-channel@@dev,func/nvme-of
+ */
+ if (grub_ieee1275_open (buf, &ihandle))
+ {
+ grub_dprintf ("disk", "failed to open the disk while iterating FCP disk path=%s\n", buf);
+ grub_free (nvme_controllers_table);
+ grub_free (buf);
+ return;
+ }
+
+ /*
+ * Call to nvme-discovery-controllers method from the nvme-of layer
+ * to get a list of the NVMe discovery controllers per the binding
+ */
+ INIT_IEEE1275_COMMON (&nvme_discovery_controllers_args.common, "call-method", 2, 2);
+ nvme_discovery_controllers_args.method = (grub_ieee1275_cell_t) "nvme-discovery-controllers";
+ nvme_discovery_controllers_args.ihandle = ihandle;
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_discovery_controllers_args) == -1)
+ {
+ grub_dprintf ("disk", "failed to get the targets while iterating FCP disk path=%s\n", buf);
+ grub_free (nvme_controllers_table);
+ grub_free (buf);
+ grub_ieee1275_close (ihandle);
+ return;
+ }
+
+ /* After closing the device, the info is lost. So lets copy each buffer in the buffers table */
+ discovery_controllers_table.len = (grub_uint32_t) nvme_discovery_controllers_args.nentries;
+
+ for (i = 0; i < discovery_controllers_table.len; i++)
+ {
+ discovery_controllers_table.table[i] = ((grub_uint64_t*) nvme_discovery_controllers_args.table)[i];
+ }
+ grub_ieee1275_close (ihandle);
+ grub_dprintf ("ofdisk","NVMeoF: Found %d discovery controllers\n", discovery_controllers_table.len);
+
+ /* For each nvme discovery controller */
+ for (current_buffer_index = 0; current_buffer_index < (int) discovery_controllers_table.len; current_buffer_index++)
+ {
+ grub_snprintf (bufptr, 64, "/nvme-of/controller@%" PRIxGRUB_UINT64_T ",ffff",
+ discovery_controllers_table.table[current_buffer_index]);
+ grub_dprintf ("ofdisk", "nvmeof controller=%s\n", buf);
+ if (grub_ieee1275_open (buf, &ihandle))
+ {
+ grub_dprintf ("ofdisk", "failed to open the disk while getting nvme-controllers path=%s\n", buf);
+ continue;
+ }
+ INIT_IEEE1275_COMMON (&nvme_controllers_args.common, "call-method", 2, 2);
+ nvme_controllers_args.method = (grub_ieee1275_cell_t) "nvme-controllers";
+ nvme_controllers_args.ihandle = ihandle;
+ nvme_controllers_args.catch_result = 0;
+
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_controllers_args) == -1)
+ {
+ grub_dprintf ("ofdisk", "failed to get the nvme-controllers while iterating FCP disk path\n");
+ grub_ieee1275_close (ihandle);
+ continue;
+ }
+
+ /* Copy the buffer list to nvme_controllers_table */
+ nvme_controllers_table_entries = ((grub_uint32_t) nvme_controllers_args.nentries);
+ nvme_controllers_table_buf = (struct nvme_controllers_table_entry*) nvme_controllers_args.table;
+ for (i = 0; i < nvme_controllers_table_entries; i++)
+ {
+ nvme_controllers_table[i].id = (grub_uint16_t) nvme_controllers_table_buf[i].id;
+ grub_strcpy (nvme_controllers_table[i].wwpn, nvme_controllers_table_buf[i].wwpn);
+ grub_strcpy (nvme_controllers_table[i].nqn, nvme_controllers_table_buf[i].nqn);
+ }
+ grub_ieee1275_close (ihandle);
+ grub_dprintf ("ofdisk", "NVMeoF: found %d nvme controllers\n", (int) nvme_controllers_args.nentries);
+
+ /* For each nvme controller */
+ for (nvme_controller_index = 0; nvme_controller_index < (int) nvme_controllers_args.nentries; nvme_controller_index++)
+ {
+ /*
+ * Open the nvme controller
+ * /pci@bus/fibre-channel@dev,func/nvme-of/controller@transport-addr,ctlr-id:nqn=tgt-subsystem-nqn
+ */
+ bufptr_pos2 = grub_snprintf (bufptr, 512, "/nvme-of/controller@%s,ffff:nqn=%s",
+ nvme_controllers_table[nvme_controller_index].wwpn,
+ nvme_controllers_table[nvme_controller_index].nqn);
+ grub_dprintf ("ofdisk", "NVMeoF: nvmeof controller=%s\n", buf);
+ if (grub_ieee1275_open (buf, &ihandle))
+ {
+ grub_dprintf ("ofdisk", "failed to open the path=%s\n", buf);
+ continue;
+ }
+ INIT_IEEE1275_COMMON (&nvme_namespaces_args.common, "call-method", 2, 2);
+ nvme_namespaces_args.method = (grub_ieee1275_cell_t) "get-namespace-list";
+ nvme_namespaces_args.ihandle = ihandle;
+ nvme_namespaces_args.catch_result = 0;
+
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_namespaces_args) == -1)
+ {
+ grub_dprintf ("ofdisk", "failed to get the nvme-namespace-list while iterating FCP disk path\n");
+ grub_ieee1275_close (ihandle);
+ continue;
+ }
+ grub_uint32_t *namespaces = (grub_uint32_t*) nvme_namespaces_args.table;
+ grub_dprintf ("ofdisk", "NVMeoF: found %d namespaces\n", (int)nvme_namespaces_args.nentries);
+ grub_ieee1275_close (ihandle);
+ namespace_index = 0;
+ for (namespace_index=0; namespace_index < nvme_namespaces_args.nentries; namespace_index++)
+ {
+ grub_snprintf (bufptr+bufptr_pos2, 512, "/namespace@%"PRIxGRUB_UINT32_T, namespaces[namespace_index]);
+ grub_dprintf ("ofdisk", "NVMeoF: namespace=%s\n", buf);
+ dev_iterate_real (buf, buf);
+ }
+ dev_iterate_real (buf, buf);
+ }
+ }
+ grub_free (buf);
+ grub_free (nvme_controllers_table);
+ return;
+}
+
static void
dev_iterate (const struct grub_ieee1275_devalias *alias)
{
if (grub_strcmp (alias->type, "fcp") == 0)
{
- /*
- * If we are dealing with fcp devices, we need
- * to find the WWPNs and LUNs to iterate them
- */
- grub_ieee1275_ihandle_t ihandle;
- grub_uint64_t *ptr_targets, *ptr_luns, k, l;
- unsigned int i, j, pos;
- char *buf, *bufptr;
- struct set_fcp_targets_args
- {
- struct grub_ieee1275_common_hdr common;
- grub_ieee1275_cell_t method;
- grub_ieee1275_cell_t ihandle;
- grub_ieee1275_cell_t catch_result;
- grub_ieee1275_cell_t nentries;
- grub_ieee1275_cell_t table;
- } args_targets;
-
- struct set_fcp_luns_args
- {
- struct grub_ieee1275_common_hdr common;
- grub_ieee1275_cell_t method;
- grub_ieee1275_cell_t ihandle;
- grub_ieee1275_cell_t wwpn_h;
- grub_ieee1275_cell_t wwpn_l;
- grub_ieee1275_cell_t catch_result;
- grub_ieee1275_cell_t nentries;
- grub_ieee1275_cell_t table;
- } args_luns;
-
- struct args_ret
- {
- grub_uint64_t addr;
- grub_uint64_t len;
- };
-
- if (grub_ieee1275_open (alias->path, &ihandle))
- {
- grub_dprintf ("disk", "failed to open the disk while iterating FCP disk path=%s\n", alias->path);
- return;
- }
-
- /* Setup the fcp-targets method to call via pfw*/
- INIT_IEEE1275_COMMON (&args_targets.common, "call-method", 2, 3);
- args_targets.method = (grub_ieee1275_cell_t) "fcp-targets";
- args_targets.ihandle = ihandle;
-
- /* Setup the fcp-luns method to call via pfw */
- INIT_IEEE1275_COMMON (&args_luns.common, "call-method", 4, 3);
- args_luns.method = (grub_ieee1275_cell_t) "fcp-luns";
- args_luns.ihandle = ihandle;
- if (IEEE1275_CALL_ENTRY_FN (&args_targets) == -1)
- {
- grub_dprintf ("disk", "failed to get the targets while iterating FCP disk path=%s\n", alias->path);
- grub_ieee1275_close (ihandle);
- return;
- }
- buf = grub_malloc (grub_strlen (alias->path) + 32 + 32);
- if (!buf)
- {
- grub_ieee1275_close (ihandle);
- return;
- }
- bufptr = grub_stpcpy (buf, alias->path);
-
- /*
- * Iterate over entries returned by pfw. Each entry contains a
- * pointer to wwpn table and his length.
- */
- struct args_ret *targets_table = (struct args_ret *) (args_targets.table);
- for (i = 0; i < args_targets.nentries; i++)
- {
- ptr_targets = (grub_uint64_t*) targets_table[i].addr;
- /* Iterate over all wwpns in given table */
- for(k = 0; k < targets_table[i].len; k++)
- {
- args_luns.wwpn_l = (grub_ieee1275_cell_t) (*ptr_targets);
- args_luns.wwpn_h = (grub_ieee1275_cell_t) (*ptr_targets >> 32);
- pos = grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T,
- grub_get_unaligned64 (*ptr_targets++));
- /* Get the luns for given wwpn target */
- if (IEEE1275_CALL_ENTRY_FN (&args_luns) == -1)
- {
- grub_dprintf ("disk", "failed to get the LUNS while iterating FCP disk path=%s\n", buf);
- grub_ieee1275_close (ihandle);
- grub_free (buf);
- return;
- }
- struct args_ret *luns_table = (struct args_ret *) (args_luns.table);
-
- /* Iterate over all LUNs */
- for(j = 0; j < args_luns.nentries; j++)
- {
- ptr_luns = (grub_uint64_t*) luns_table[j].addr;
- for(l = 0; l < luns_table[j].len; l++)
- {
- grub_snprintf (&bufptr[pos], 30, ",%" PRIxGRUB_UINT64_T,
- grub_get_unaligned64 (*ptr_luns++));
- dev_iterate_real (buf, buf);
- }
- }
- }
- }
- grub_ieee1275_close (ihandle);
- grub_free (buf);
- return;
+ /* Iterate disks */
+ dev_iterate_fcp_disks (alias);
+ /* Iterate NVMeoF */
+ dev_iterate_fcp_nvmeof (alias);
}
else if (grub_strcmp (alias->type, "vscsi") == 0)
{

View File

@ -0,0 +1,47 @@
From 3d5fd0d7c5984338902f651882c76ec122e450ff Mon Sep 17 00:00:00 2001
From: Rolv Apneseth <rolv.apneseth@gmail.com>
Date: Mon, 18 May 2026 09:58:18 +0100
Subject: [PATCH] mdraid: fix metadata 1.0 detection in userspace utilities on
IEEE1275
The powerpc guard in grub_mdraid_detect skips metadata 1.0 to avoid a
firmware block issue, but also ends up applying to userspace utilities
where reads will be going through the kernel. Extend the conditional
with !defined(GRUB_UTIL) so utilities like grub-install can detect
metadata 1.0 arrays.
Signed-off-by: Rolv Apneseth <rolv.apneseth@gmail.com>
---
grub-core/disk/mdraid1x_linux.c | 2 +-
grub-core/disk/mdraid_linux.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/disk/mdraid1x_linux.c b/grub-core/disk/mdraid1x_linux.c
index 08c57ae..09f1065 100644
--- a/grub-core/disk/mdraid1x_linux.c
+++ b/grub-core/disk/mdraid1x_linux.c
@@ -130,7 +130,7 @@ grub_mdraid_detect (grub_disk_t disk,
struct grub_diskfilter_vg *array;
char *uuid;
-#ifdef __powerpc__
+#if defined(__powerpc__) && !defined(GRUB_UTIL)
/* Firmware will yell at us for reading too far. */
if (minor_version == 0)
continue;
diff --git a/grub-core/disk/mdraid_linux.c b/grub-core/disk/mdraid_linux.c
index 98fcfb1..79145f8 100644
--- a/grub-core/disk/mdraid_linux.c
+++ b/grub-core/disk/mdraid_linux.c
@@ -189,7 +189,7 @@ grub_mdraid_detect (grub_disk_t disk,
grub_uint32_t level;
struct grub_diskfilter_vg *ret;
-#ifdef __powerpc__
+#if defined(__powerpc__) && !defined(GRUB_UTIL)
/* Firmware will yell at us for reading too far. */
return NULL;
#endif
--
2.54.0

View File

@ -0,0 +1,39 @@
From df2f1f23de0b79c156c70a72667ab98d85a29050 Mon Sep 17 00:00:00 2001
From: Rolv Apneseth <rolv.apneseth@gmail.com>
Date: Mon, 18 May 2026 10:07:03 +0100
Subject: [PATCH] grub-install: use search.fs_uuid for RAID1 on IEEE1275
On IEEE1275, grub-install hardcodes an mduuid prefix for RAID
abstractions, requiring array assembly at boot. This fails on metadata
1.0 partitions because detection is skipped due to a firmware issue.
Since RAID1 mirrors are individually readable, use search.fs_uuid on
IEEE1275 to find the boot filesystem on any member partition and avoid
requiring array assembly.
Signed-off-by: Rolv Apneseth <rolv.apneseth@gmail.com>
---
util/grub-install.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/util/grub-install.c b/util/grub-install.c
index 162162b..c5cf20a 100644
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -1385,7 +1385,12 @@ main (int argc, char *argv[])
}
}
- if (!have_abstractions)
+ int is_ieee1275_raid1 = have_abstractions
+ && (platform == GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275)
+ && grub_dev->disk
+ && probe_raid_level (grub_dev->disk) == 1;
+
+ if (!have_abstractions || is_ieee1275_raid1)
{
if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0)
|| grub_drives[1]
--
2.54.0

View File

@ -153,7 +153,7 @@ case "$COMMAND" in
fi
fi
if [ -n "$NEWDEFAULT" ]; then
grub2-editenv - set "saved_entry=${NEWDEFAULT}"
grub2-editenv - set "tmp_saved_entry=${NEWDEFAULT}"
fi
# this probably isn't the best place to do this, but it will do for now.

View File

@ -0,0 +1,44 @@
#!/bin/bash
[[ -f /etc/default/grub ]] && . /etc/default/grub
[[ -f /etc/os-release ]] && . /etc/os-release
COMMAND="$1"
KERNEL_VERSION="$2"
BOOT_DIR_ABS="$3"
KERNEL_IMAGE="$4"
case "$COMMAND" in
add)
if [[ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]] || [[ ! -f /sbin/new-kernel-pkg ]]; then
entry=$(grub2-editenv list | grep tmp_saved_entry)
if [ -n "$entry" ]; then
BLS_ID=${entry##tmp_saved_entry=}
BLS_DIR="/boot/loader/entries"
BLS_TARGET="${BLS_DIR}/${BLS_ID}.conf"
LINUX="$(grep '^linux[ \t]' "${BLS_TARGET}" | sed -e 's,^linux[ \t]*,,' | awk '{print $1}')"
INITRD="$(grep '^initrd[ \t]' "${BLS_TARGET}" | sed -e 's,^initrd[ \t]*,,' | awk '{print $1}')"
ROOTPREFIX=""
[ -z "$(grub2-mkrelpath /boot)" ] && ROOTPREFIX="/boot"
if [ -e "${ROOTPREFIX}${LINUX}" -a -n "${INITRD}" ]; then
if [ ! -e "${ROOTPREFIX}${INITRD}" ]; then
echo "Error: ${ROOTPREFIX}${INITRD} not found."
exit 1
fi
if ! lsinitrd ${ROOTPREFIX}${INITRD} > /dev/null; then
echo "Error: ${ROOTPREFIX}${INITRD} appears to be corrupt."
exit 1
fi
fi
grub2-editenv - unset "tmp_saved_entry"
grub2-editenv - set "saved_entry=$BLS_ID"
fi
fi
;;
*)
;;
esac

View File

@ -591,7 +591,6 @@ cp docs/grub-dev.info \\\
$RPM_BUILD_ROOT%{_infodir}/%{name}-dev.info \
install -d -m 0700 ${RPM_BUILD_ROOT}%{efi_esp_dir}/ \
install -d -m 0700 ${RPM_BUILD_ROOT}/boot/%{name}/ \
install -d -m 0700 ${RPM_BUILD_ROOT}/boot/loader/entries \
install -d -m 0700 ${RPM_BUILD_ROOT}/boot/%{name}/themes/system \
install -d -m 0700 ${RPM_BUILD_ROOT}%{_sysconfdir}/default \
install -d -m 0700 ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig \
@ -609,7 +608,6 @@ ln -s ../boot/%{name}/grub.cfg \\\
%defattr(-,root,root,-) \
%config(noreplace) %{_sysconfdir}/%{name}.cfg \
%ghost %config(noreplace) %attr(0600,root,root)/boot/%{name}/grub.cfg \
%dir %attr(0700,root,root)/boot/loader/entries \
%attr(0644,root,root) %config(noreplace) /etc/dnf/protected.d/%{name}-%{1}.conf \
%ifarch ppc64le \
%dir %{_libdir}/grub/%{2}/ \
@ -643,7 +641,6 @@ ln -s ../boot/%{name}/grub.cfg \\\
%endif \
%attr(0700,root,root)/boot/%{name}/fonts \
%attr(0700,root,root)/usr/bin/gen_grub_cfgstub \
%dir %attr(0700,root,root)/boot/loader/entries \
%ghost %config(noreplace) %attr(0600,root,root)/boot/%{name}/grub.cfg \
%ghost %config(noreplace) %verify(not mtime) %attr(0700,root,root)%{efi_esp_dir}/grub.cfg \
%config(noreplace) %verify(not size mode md5 mtime) /boot/%{name}/grubenv \

View File

@ -533,3 +533,12 @@ Patch0533: 0533-commands-usbtest-Ensure-string-length-is-sufficient-.patch
Patch0534: 0534-util-grub-mkimagexx-Stop-generating-unaligned-append.patch
Patch0535: 0535-grub-mkimage-Do-not-generate-empty-SBAT-metadata.patch
Patch0536: 0536-kern-efi-mm-Change-grub_efi_mm_add_regions-to-keep-t.patch
Patch0537: 0537-Change-login-error-message.patch
Patch0538: 0538-ieee1275-powerpc-implements-fibre-channel-discovery-.patch
Patch0539: 0539-ieee1275-implement-FCP-methods-for-WWPN-and-LUNs.patch
Patch0540: 0540-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch
Patch0541: 0541-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch
Patch0542: 0542-ieee1275-support-added-for-multiple-nvme-bootpaths.patch
Patch0543: 0543-ieee1275-add-support-for-NVMeoFC.patch
Patch0544: 0544-mdraid-fix-metadata-1.0-detection-in-userspace-utils-on-IEEE1275.patch
Patch0545: 0545-grub-install-use-search.fs_uuid-for-RAID1-on-IEEE1275.patch

View File

@ -16,7 +16,7 @@
Name: grub2
Epoch: 1
Version: 2.06
Release: 126%{?dist}.alma.1
Release: 134%{?dist}.alma.1
Summary: Bootloader with support for Linux, Multiboot and more
License: GPLv3+
URL: http://www.gnu.org/software/grub/
@ -36,6 +36,7 @@ Source11: grub.patches
Source12: sbat.csv.in
Source13: gen_grub_cfgstub
Source14: sbat.ppc.csv
Source15: 95-set-boot-entry.install
%include %{SOURCE1}
@ -255,6 +256,7 @@ rm -vf ${RPM_BUILD_ROOT}/%{_sbindir}/%{name}-macbless
# Install kernel-install scripts
install -d -m 0755 %{buildroot}%{_prefix}/lib/kernel/install.d/
install -D -m 0755 -t %{buildroot}%{_prefix}/lib/kernel/install.d/ %{SOURCE10}
install -D -m 0755 -t %{buildroot}%{_prefix}/lib/kernel/install.d/ %{SOURCE15}
install -D -m 0755 -t %{buildroot}%{_prefix}/lib/kernel/install.d/ %{SOURCE3}
install -d -m 0755 %{buildroot}%{_sysconfdir}/kernel/install.d/
# Install systemd user service to set the boot_success flag
@ -293,6 +295,12 @@ ln -s ../%{name}-systemd-integration.service \
%undefine buildsubdir
%check
%if 0%{with_efi_arch}
pesigcheck -i $RPM_BUILD_ROOT%{efi_esp_dir}/%{grubefiname} -n0 -c %{sb_cer}
pesigcheck -i $RPM_BUILD_ROOT%{efi_esp_dir}/%{grubeficdname} -n0 -c %{sb_cer}
%endif
%pre tools
if [ -f /boot/%{name}/user.cfg ]; then
if grep -q '^GRUB_PASSWORD=' /boot/%{name}/user.cfg ; then
@ -365,11 +373,81 @@ if test -f ${EFI_HOME}/grubenv; then
mv --force ${EFI_HOME}/grubenv ${GRUB_HOME}/grubenv
fi
%if "%{platform}" == "pc"
%posttrans pc
set -eu
set -o pipefail
SYS_FIRMWARE_EFI_DIR=/sys/firmware/efi
BOOT_DIR=/boot
find_grub_devices() {
local boot_device
local component_devs=()
local block_devs=()
# Exit if UEFI system running
if test -d $SYS_FIRMWARE_EFI_DIR ; then
exit 0
fi
# grub2-probe is required for device finding
if ! command -v grub2-probe &>/dev/null; then
exit 0;
fi
# Get block devices where GRUB is located. We assume GRUB is on the same device
# as /boot partition is. In case that device is an md (Multiple Device) device, all
# of the component devices of such a device are considered.
boot_device=$(grub2-probe --target=device $BOOT_DIR)
# Check if a given device is an md (Multiple Device) device
# It is expected that the "mdadm" command is available,
# if it's not it is assumed the device is not an md device.
if command -v mdadm &>/dev/null && \
mdadm --detail --verbose --brief "$boot_device" &> /dev/null; then
out=$(mdadm --detail --verbose --brief "$boot_device")
# output would look like:
# ARRAY /dev/md0 level=raid1 num-devices=2 metadata=1.2 name=localhost.localdomain:0 UUID=c4acea6e:d56e1598:91822e3f:fb26832c disable=line-too-long devices=/dev/vda1,/dev/vdb1
for d in $(echo "$out" | sed -n -e 's/.* devices=\([^ ]*\).*/\1/p' | sed 's/,/ /g'); do
component_devs+=("$d")
done
else
component_devs+=("$boot_device")
fi
# Get blocks from partitions
for d in "${component_devs[@]}"; do
block_devs+=("$(lsblk -spnlo name "$d" | tail -1)")
done
# Filter those GRUB blocks
for d in "${block_devs[@]}"; do
if dd if="$d" bs=446 count=1 status=none | grep -aq "GRUB"; then
echo "$d"
fi
done
}
grub_install () {
if ! command -v grub2-install &>/dev/null; then
exit 0
fi
for d in $(find_grub_devices); do
echo "Installing on $d" >&2
grub2-install "$d"
done
}
grub_install || :
%endif
%files common -f grub.lang
%dir %{_libdir}/grub/
%dir %{_datarootdir}/grub/
%attr(0700,root,root) %dir %{_sysconfdir}/grub.d
%{_prefix}/lib/kernel/install.d/20-grub.install
%{_prefix}/lib/kernel/install.d/95-set-boot-entry.install
%{_prefix}/lib/kernel/install.d/99-grub-mkconfig.install
%dir %{_datarootdir}/grub
%exclude %{_datarootdir}/grub/*
@ -534,9 +612,42 @@ fi
%endif
%changelog
* Mon Mar 30 2026 Eduard Abdullin <eabdullin@almalinux.org> - 1:2.06-126.alma.1
* Mon Aug 24 2026 Eduard Abdullin <eabdullin@almalinux.org> - 1:2.06-134.alma.1
- Debrand for AlmaLinux
* Wed Jul 29 2026 Marta Lewandowska <mlewando@redhat.com> 2.06-134
- Add pesigcheck to check for correct SB signature on UEFI
- Resolves: RHEL-188360
* Fri Jul 24 2026 Leo Sandoval <lsandova@redhat.com> - 2.06-133
- Run grub2-install automatically on grub2-pc posttrans
- Resolves: #RHEL-216339
* Mon Jul 21 2026 Josue Hernandez <josherna@redhat.com> - 2.06-132
- Remove creation of /boot/loader/entries
- Resolves: #RHEL-212729
* Mon Jul 06 2026 Rolv Apneseth <rapneset@redhat.com> - 2.06-131
- mdraid: fix metadata 1.0 detection in userspace utilities on IEEE1275
- grub-install: use search.fs_uuid for RAID1 on IEEE1275
- Resolves: #RHEL-186902
* Wed Jul 01 2026 Josue Hernandez <josherna@redhat.com> 2.06-130
- Wait for initrmafs and kernel to be installed before set default kernel
- Resolves: #RHEL-191464
* Thu Jun 18 2026 Nicolas Frayer <nfrayer@redhat.com> 2.06-129
- ieee1275/powerpc: implements fibre channel discovery for ofpathname
- Resolves: #RHEL-53369
* Fri Jun 05 2026 Nicolas Frayer <nfrayer@redhat.com> 2.06-128
- CentOS: Sign grub with 802
- Resolves: #RHEL-182487
* Fri May 29 2026 Josue Hernandez <josherna@redhat.com> 2.06-127
- Change login error message for more user frienly version
- resolves: #RHEL-180631
* Mon Mar 09 2026 Josue Hernandez <josherna@redhat.com> 2.06-126
- kern/efi/mm: Change grub_efi_mm_add_regions() to keep track of map allocation size
- Resolves: #RHEL-148310