While doing some in-depth testing came across a few more issues. The
second one really threw me for a loop. The LVM wouldn't come up because
it couldn't find some of the raid arrays but when I hexdumped the raid
arrays it showed the correct uuid. Applies on top of previous patch.
- Ignore spare and faulty drives
- Set a dynamic array->number. It's used for the disk->id and is important
for the cache subsystem that it be unique.
=== modified file 'disk/mdraid_linux.c'
--- disk/mdraid_linux.c 2010-07-23 05:25:00 +0000
+++ disk/mdraid_linux.c 2010-07-24 05:53:53 +0000
@@ -363,6 +363,19 @@
return grub_error (GRUB_ERR_OUT_OF_RANGE, "csum invalid");
}
+ if (grub_le_to_cpu32 (real_sb->dev_number) <
+ grub_le_to_cpu32 (real_sb->max_dev))
+ array->index = grub_le_to_cpu16
+ (real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]);
+ else
+ array->index = 0xffff; /* disk will be later not used! */
+
+ if (array->index == 0xffff || array->index == 0xfffe)
+ {
+ grub_free (real_sb);
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "spare or faulty drive");
+ }
+
array->name = grub_strdup (real_sb->set_name);
if (! array->name)
{
@@ -375,14 +388,11 @@
array->layout = grub_le_to_cpu32 (real_sb->layout);
array->total_devs = grub_le_to_cpu32 (real_sb->raid_disks);
array->disk_size = grub_le_to_cpu64 (real_sb->size);
+ if (!array->disk_size)
+ /* Level 0 doesn't seem to set sb->size */
+ array->disk_size = grub_le_to_cpu64 (real_sb->data_size);
array->chunk_size = grub_le_to_cpu32 (real_sb->chunksize);
array->freshness = grub_le_to_cpu32(real_sb->events);
- if (grub_le_to_cpu32 (real_sb->dev_number) <
- grub_le_to_cpu32 (real_sb->max_dev))
- array->index = grub_le_to_cpu16
- (real_sb->dev_roles[grub_le_to_cpu32 (real_sb->dev_number)]);
- else
- array->index = 0xffff; /* disk will be later not used! */
array->uuid_len = 16;
array->uuid = grub_malloc (16);
if (!array->uuid)
=== modified file 'disk/raid.c'
--- disk/raid.c 2010-07-23 05:25:00 +0000
+++ disk/raid.c 2010-07-24 09:57:05 +0000
@@ -555,25 +555,28 @@
grub_memset (&array->device, 0, sizeof (array->device));
grub_memset (&array->start_sector, 0, sizeof (array->start_sector));
+ /* mdraid 1.x superblocks don't have a number but we need a unique id
+ for the cache system. Start numbering down from the top. */
if (array->name)
- goto skip_duplicate_check;
+ array->number = -1;
+
/* Check whether we don't have multiple arrays with the same number. */
for (p = array_list; p != NULL; p = p->next)
{
- if (! p->name && p->number == array->number)
+ if (p->number == array->number)
break;
}
if (p)
{
/* The number is already in use, so we need to find a new one. */
- int i = 0;
+ int i = array->name ? -2 : 0;
while (1)
{
for (p = array_list; p != NULL; p = p->next)
{
- if (! p->name && p->number == i)
+ if (p->number == i)
break;
}
@@ -584,10 +587,10 @@
break;
}
- i++;
+ i += array->name ? -1 : 1;
}
}
- skip_duplicate_check:
+
/* mdraid 1.x superblocks have only a name stored not a number.
Use it directly as GRUB device. */
if (! array->name)
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel