Sometimes, when booting from a very busy SAN, the access to the disk can fail and then grub will eventually drop to grub prompt. This scenario is more frequent when deploying many machines at the same time using the same SAN. This patch aims to force the ofdisk module to retry the open or read function after it fails. We use MAX_RETRIES to specify the amount of times it will try to access the disk before it definitely fails.
--- grub-core/disk/ieee1275/ofdisk.c | 27 +++++++++++++++++++++------ include/grub/ieee1275/ofdisk.h | 8 ++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c index d887d4b..777ae63 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c @@ -225,7 +225,9 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) char *buf, *bufptr; unsigned i; - if (grub_ieee1275_open (alias->path, &ihandle)) + + RETRY_IEEE1275_OFDISK_OPEN(alias->path, &ihandle) + if (! ihandle) return; /* This method doesn't need memory allocation for the table. Open @@ -305,7 +307,9 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) return; } - if (grub_ieee1275_open (alias->path, &ihandle)) + RETRY_IEEE1275_OFDISK_OPEN(alias->path, &ihandle) + + if (! ihandle) { grub_free (buf); grub_free (table); @@ -555,7 +559,7 @@ grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector) last_ihandle = 0; last_devpath = NULL; - grub_ieee1275_open (disk->data, &last_ihandle); + RETRY_IEEE1275_OFDISK_OPEN(disk->data, &last_ihandle) if (! last_ihandle) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); last_devpath = disk->data; @@ -582,12 +586,23 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector, return err; grub_ieee1275_read (last_ihandle, buf, size << disk->log_sector_size, &actual); - if (actual != (grub_ssize_t) (size << disk->log_sector_size)) + int i = 0; + while(actual != (grub_ssize_t) (size << disk->log_sector_size)){ + if (i>10){ return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx " "from `%s'"), (unsigned long long) sector, disk->name); - + } + grub_dprintf("ofdisk","Read failed. Retrying...\n"); + last_devpath = NULL; + err = grub_ofdisk_prepare (disk, sector); + if (err) + return err; + grub_ieee1275_read (last_ihandle, buf, size << disk->log_sector_size, + &actual); + i++; + } return 0; } @@ -704,7 +719,7 @@ grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size, last_ihandle = 0; last_devpath = NULL; - grub_ieee1275_open (device, &last_ihandle); + RETRY_IEEE1275_OFDISK_OPEN (device, &last_ihandle) if (! last_ihandle) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); diff --git a/include/grub/ieee1275/ofdisk.h b/include/grub/ieee1275/ofdisk.h index 2f69e3f..124e297 100644 --- a/include/grub/ieee1275/ofdisk.h +++ b/include/grub/ieee1275/ofdisk.h @@ -22,4 +22,12 @@ extern void grub_ofdisk_init (void); extern void grub_ofdisk_fini (void); +#define MAX_RETRIES 20 + + +#define RETRY_IEEE1275_OFDISK_OPEN(device, last_ihandle) unsigned retry_i=0;for(retry_i=0; retry_i < MAX_RETRIES; retry_i++){ \ + if(!grub_ieee1275_open(device, last_ihandle)) \ + break; \ + grub_dprintf("ofdisk","Opening disk %s failed. Retrying...\n",device); } + #endif /* ! GRUB_INIT_HEADER */ -- 2.27.0 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel