Here are a couple more patches to cleanup the raid user interface a
little.
The first detects if there are actually partitions on the disk. Only
kicks in if we open the whole disk and the underlying subsystem says
there might be partitions. Slight semantic change is that has_partitions
now really means it has partitions rather then might have partitions.
This cleans up the tab completion of devices that may have partitions
but we're using the full disk (i.e. usually raid devices, lvms, etc.)
The second expands the 'ls -l' output to include raid information.
Previously depending on the raid metadata layout, it was possible to
detect the filesystem on the underlying raid partition. So now it checks
for raid devices first and if detected prints out the raid info. This
probably requires the previous patches for raid that have been posted in
the last few days. Holler if you want a roll-up patch.
Partition ide1,apple9: RAID6, md/1 - Disk 2/4, UUID
5c991134-a98c-2396-7204-9d6b077d2840
The last patch fixes a small error I had in the calculation of ofdisk
sizes and also prints the device with the seek/read error.
Doug
=== modified file 'include/grub/partition.h'
--- include/grub/partition.h 2010-07-14 09:26:17 +0000
+++ include/grub/partition.h 2010-07-29 01:03:11 +0000
@@ -72,6 +72,7 @@
int EXPORT_FUNC(grub_partition_iterate) (struct grub_disk *disk,
int (*hook) (struct grub_disk *disk,
const grub_partition_t
partition));
+int EXPORT_FUNC(grub_partition_detect) (struct grub_disk *disk);
char *EXPORT_FUNC(grub_partition_get_name) (const grub_partition_t partition);
=== modified file 'kern/disk.c'
--- kern/disk.c 2010-02-07 00:48:38 +0000
+++ kern/disk.c 2010-07-29 01:13:07 +0000
@@ -298,6 +298,10 @@
goto fail;
}
}
+ else if (disk->has_partitions)
+ {
+ disk->has_partitions = grub_partition_detect(disk);
+ }
/* The cache will be invalidated about 2 seconds after a device was
closed. */
=== modified file 'kern/partition.c'
--- kern/partition.c 2010-07-16 23:55:01 +0000
+++ kern/partition.c 2010-07-29 01:07:42 +0000
@@ -219,6 +219,35 @@
return ret;
}
+int
+grub_partition_detect (struct grub_disk *disk)
+{
+ const struct grub_partition_map *partmap;
+ int found = 0;
+
+ auto int part_iterate (grub_disk_t dsk, const grub_partition_t p);
+
+ int part_iterate (grub_disk_t dsk __attribute((unused)),
+ const grub_partition_t partition __attribute((unused)))
+ {
+ found = 1;
+ /* It's not really an error, just want to short-circut the interation */
+ return grub_error(GRUB_ERR_TEST_FAILURE, "Partition found");
+ }
+
+ FOR_PARTITION_MAPS(partmap)
+ {
+ grub_err_t err;
+ err = partmap->iterate (disk, part_iterate);
+ if (err)
+ grub_errno = GRUB_ERR_NONE;
+ if (found)
+ break;
+ }
+
+ return found;
+}
+
char *
grub_partition_get_name (const grub_partition_t partition)
{
=== modified file 'disk/dmraid_nvidia.c'
--- disk/dmraid_nvidia.c 2010-07-23 05:25:00 +0000
+++ disk/dmraid_nvidia.c 2010-07-29 02:36:07 +0000
@@ -156,6 +156,7 @@
{
.name = "dmraid_nv",
.detect = grub_dmraid_nv_detect,
+ .uuid = 0,
.next = 0
};
=== modified file 'disk/mdraid_linux.c'
--- disk/mdraid_linux.c 2010-07-28 03:18:33 +0000
+++ disk/mdraid_linux.c 2010-07-29 02:38:44 +0000
@@ -475,9 +475,32 @@
return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid");
}
+static char *
+grub_mdraid_uuid (struct grub_raid_array *array)
+{
+ char *uuid;
+ grub_uint16_t *data;
+
+ if (!array || !array->uuid_len || !array->uuid)
+ return 0;
+
+ data = (grub_uint16_t *)array->uuid;
+ uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
+ grub_be_to_cpu16 (data[0]),
+ grub_be_to_cpu16 (data[1]),
+ grub_be_to_cpu16 (data[2]),
+ grub_be_to_cpu16 (data[3]),
+ grub_be_to_cpu16 (data[4]),
+ grub_be_to_cpu16 (data[5]),
+ grub_be_to_cpu16 (data[6]),
+ grub_be_to_cpu16 (data[7]));
+ return uuid;
+}
+
static struct grub_raid grub_mdraid_dev = {
.name = "mdraid",
.detect = grub_mdraid_detect,
+ .uuid = grub_mdraid_uuid,
.next = 0
};
=== modified file 'disk/raid.c'
--- disk/raid.c 2010-07-28 07:55:56 +0000
+++ disk/raid.c 2010-07-29 02:20:47 +0000
@@ -726,6 +726,40 @@
}
}
+struct grub_raid_array *
+grub_raid_probe(grub_device_t dev, int *index, char **uuid)
+{
+ struct grub_raid *p;
+
+ if (!dev->disk)
+ return 0;
+
+ for (p = grub_raid_list; p; p = p->next)
+ {
+ struct grub_raid_array array;
+
+ if (p->detect && !p->detect(dev->disk, &array, 0))
+ {
+ struct grub_raid_array *a;
+
+ for (a = array_list; a != NULL; a = a->next)
+ if ((a->uuid_len == array.uuid_len) &&
+ (! grub_memcmp (a->uuid, array.uuid, a->uuid_len)))
+ {
+ if (index)
+ *index = array.index;
+ if (uuid && p->uuid)
+ *uuid = p->uuid(a);
+ return a;
+ }
+ }
+
+ grub_errno = 0;
+ }
+
+ return 0;
+}
+
static struct grub_disk_dev grub_raid_dev =
{
.name = "raid",
=== modified file 'include/grub/raid.h'
--- include/grub/raid.h 2010-07-23 05:25:00 +0000
+++ include/grub/raid.h 2010-07-29 02:17:04 +0000
@@ -64,6 +64,7 @@
grub_err_t (*detect) (grub_disk_t disk, struct grub_raid_array *array,
grub_disk_addr_t *start_sector);
+ char * (*uuid) (struct grub_raid_array *array);
struct grub_raid *next;
};
@@ -74,6 +75,8 @@
void grub_raid_block_xor (char *buf1, const char *buf2, int size);
+struct grub_raid_array * grub_raid_probe(grub_device_t dev, int *index, char
**uuid);
+
typedef grub_err_t (*grub_raid5_recover_func_t) (struct grub_raid_array *array,
int disknr, char *buf,
grub_disk_addr_t sector,
=== modified file 'normal/misc.c'
--- normal/misc.c 2010-03-15 10:49:27 +0000
+++ normal/misc.c 2010-07-29 02:37:44 +0000
@@ -26,6 +26,7 @@
#include <grub/datetime.h>
#include <grub/term.h>
#include <grub/i18n.h>
+#include <grub/raid.h>
/* Print the information on the device NAME. */
grub_err_t
@@ -53,12 +54,30 @@
else if (dev->disk)
{
grub_fs_t fs;
-
- fs = grub_fs_probe (dev);
- /* Ignore all errors. */
- grub_errno = 0;
-
- if (fs)
+ struct grub_raid_array *array;
+ int disk_index;
+ char *array_uuid = 0;
+
+ array = grub_raid_probe(dev, &disk_index, &array_uuid);
+ if (!array)
+ {
+ fs = grub_fs_probe (dev);
+ /* Ignore all errors. */
+ grub_errno = 0;
+ }
+
+ if (array)
+ {
+ grub_printf ("RAID%u %s - Disk %u/%u",
+ array->level, array->name,
+ disk_index, array->total_devs);
+ if (array_uuid)
+ {
+ grub_printf (", UUID %s", array_uuid);
+ grub_free (array_uuid);
+ }
+ }
+ else if (fs)
{
grub_printf_ (N_("Filesystem type %s"), fs->name);
if (fs->label)
=== modified file 'disk/ieee1275/ofdisk.c'
--- disk/ieee1275/ofdisk.c 2010-07-28 07:55:56 +0000
+++ disk/ieee1275/ofdisk.c 2010-07-29 03:58:16 +0000
@@ -264,7 +264,7 @@
}
- if (size > 1024)
+ if (curr > 1024 && size == 512)
disk->total_sectors = curr / 512;
op->size = disk->total_sectors;
}
@@ -303,13 +303,13 @@
pos, &status);
if (status < 0)
return grub_error (GRUB_ERR_READ_ERROR,
- "seek error, can't seek block %llu",
- (long long) sector);
+ "seek error, can't seek on '%s' at block %llu",
+ disk->name, (long long) sector);
grub_ieee1275_read ((grub_ieee1275_ihandle_t) (unsigned long) disk->data,
buf, size * 512UL, &actual);
if (actual != (grub_ssize_t) (size * 512UL))
- return grub_error (GRUB_ERR_READ_ERROR, "read error on block: %llu",
- (long long) sector);
+ return grub_error (GRUB_ERR_READ_ERROR, "read error on '%s' at block:
%llu",
+ disk->name, (long long) sector);
return 0;
}
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel