2009-07-31 Bean <bean123ch@gmail.com>
* disk/lvm.c (grub_lvm_scan_device): Ignore extra copy of metadata. Don't change pv->disk if it's already set. * disk/raid.c (grub_raid_scan_device): Merge this function into ... (grub_raid_register): ... here. (grub_raid_rescan): Removed. * include/grub/raid.h (grub_raid_rescan): Removed. * util/grub-fstest.c: Remove include file <grub/raid.h>. (fstest): Replace grub_raid_rescan with module fini function followed by init function. * util/grub-probe.c: Add include file <grub/raid.h>. (probe_raid_level): New function. (probe): Detect abstraction by walking the disk device, support two level of abstraction (LVM on RAID) when detecting partition map.
This commit is contained in:
parent
24443b5a47
commit
f45d6cfc48
6 changed files with 139 additions and 93 deletions
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
|||
2009-07-31 Bean <bean123ch@gmail.com>
|
||||
|
||||
* disk/lvm.c (grub_lvm_scan_device): Ignore extra copy of metadata.
|
||||
Don't change pv->disk if it's already set.
|
||||
|
||||
* disk/raid.c (grub_raid_scan_device): Merge this function into ...
|
||||
(grub_raid_register): ... here.
|
||||
(grub_raid_rescan): Removed.
|
||||
|
||||
* include/grub/raid.h (grub_raid_rescan): Removed.
|
||||
|
||||
* util/grub-fstest.c: Remove include file <grub/raid.h>.
|
||||
(fstest): Replace grub_raid_rescan with module fini function followed
|
||||
by init function.
|
||||
|
||||
* util/grub-probe.c: Add include file <grub/raid.h>.
|
||||
(probe_raid_level): New function.
|
||||
(probe): Detect abstraction by walking the disk device, support two
|
||||
level of abstraction (LVM on RAID) when detecting partition map.
|
||||
|
||||
2009-07-31 Pavel Roskin <proski@gnu.org>
|
||||
|
||||
* disk/raid5_recover.c (grub_raid5_recover): Revert conversion
|
||||
|
|
15
disk/lvm.c
15
disk/lvm.c
|
@ -271,15 +271,9 @@ grub_lvm_scan_device (const char *name)
|
|||
dlocn++;
|
||||
mda_offset = grub_le_to_cpu64 (dlocn->offset);
|
||||
mda_size = grub_le_to_cpu64 (dlocn->size);
|
||||
dlocn++;
|
||||
|
||||
if (dlocn->offset)
|
||||
{
|
||||
grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
"We don't support multiple LVM metadata areas");
|
||||
|
||||
goto fail;
|
||||
}
|
||||
/* It's possible to have multiple copies of metadata areas, we just use the
|
||||
first one. */
|
||||
|
||||
/* Allocate buffer space for the circular worst-case scenario. */
|
||||
metadatabuf = grub_malloc (2 * mda_size);
|
||||
|
@ -564,7 +558,10 @@ grub_lvm_scan_device (const char *name)
|
|||
{
|
||||
if (! grub_memcmp (pv->id, pv_id, GRUB_LVM_ID_STRLEN))
|
||||
{
|
||||
pv->disk = grub_disk_open (name);
|
||||
/* This could happen to LVM on RAID, pv->disk points to the
|
||||
raid device, we shouldn't change it. */
|
||||
if (! pv->disk)
|
||||
pv->disk = grub_disk_open (name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
88
disk/raid.c
88
disk/raid.c
|
@ -589,56 +589,6 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
|
|||
|
||||
static grub_raid_t grub_raid_list;
|
||||
|
||||
static void
|
||||
grub_raid_scan_device (int head_only)
|
||||
{
|
||||
auto int hook (const char *name);
|
||||
int hook (const char *name)
|
||||
{
|
||||
grub_disk_t disk;
|
||||
struct grub_raid_array array;
|
||||
struct grub_raid *p;
|
||||
|
||||
grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name);
|
||||
|
||||
disk = grub_disk_open (name);
|
||||
if (!disk)
|
||||
return 0;
|
||||
|
||||
if (disk->total_sectors == GRUB_ULONG_MAX)
|
||||
{
|
||||
grub_disk_close (disk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (p = grub_raid_list; p; p = p->next)
|
||||
{
|
||||
if (! p->detect (disk, &array))
|
||||
{
|
||||
if (! insert_array (disk, &array, p->name))
|
||||
return 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* This error usually means it's not raid, no need to display
|
||||
it. */
|
||||
if (grub_errno != GRUB_ERR_OUT_OF_RANGE)
|
||||
grub_print_error ();
|
||||
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
if (head_only)
|
||||
break;
|
||||
}
|
||||
|
||||
grub_disk_close (disk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
grub_device_iterate (&hook);
|
||||
}
|
||||
|
||||
static void
|
||||
free_array (void)
|
||||
{
|
||||
|
@ -668,9 +618,38 @@ free_array (void)
|
|||
void
|
||||
grub_raid_register (grub_raid_t raid)
|
||||
{
|
||||
auto int hook (const char *name);
|
||||
int hook (const char *name)
|
||||
{
|
||||
grub_disk_t disk;
|
||||
struct grub_raid_array array;
|
||||
|
||||
grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name);
|
||||
|
||||
disk = grub_disk_open (name);
|
||||
if (!disk)
|
||||
return 0;
|
||||
|
||||
if ((disk->total_sectors != GRUB_ULONG_MAX) &&
|
||||
(! grub_raid_list->detect (disk, &array)) &&
|
||||
(! insert_array (disk, &array, grub_raid_list->name)))
|
||||
return 0;
|
||||
|
||||
/* This error usually means it's not raid, no need to display
|
||||
it. */
|
||||
if (grub_errno != GRUB_ERR_OUT_OF_RANGE)
|
||||
grub_print_error ();
|
||||
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
grub_disk_close (disk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
raid->next = grub_raid_list;
|
||||
grub_raid_list = raid;
|
||||
grub_raid_scan_device (1);
|
||||
grub_device_iterate (&hook);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -686,13 +665,6 @@ grub_raid_unregister (grub_raid_t raid)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
grub_raid_rescan (void)
|
||||
{
|
||||
free_array ();
|
||||
grub_raid_scan_device (0);
|
||||
}
|
||||
|
||||
static struct grub_disk_dev grub_raid_dev =
|
||||
{
|
||||
.name = "raid",
|
||||
|
|
|
@ -67,7 +67,6 @@ typedef struct grub_raid *grub_raid_t;
|
|||
void grub_raid_register (grub_raid_t raid);
|
||||
void grub_raid_unregister (grub_raid_t raid);
|
||||
|
||||
void grub_raid_rescan (void);
|
||||
void grub_raid_block_xor (char *buf1, const char *buf2, int size);
|
||||
|
||||
typedef grub_err_t (*grub_raid5_recover_func_t) (struct grub_raid_array *array,
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <grub/env.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/raid.h>
|
||||
#include <grub/lib/hexdump.h>
|
||||
#include <grub/lib/crc.h>
|
||||
#include <grub/command.h>
|
||||
|
@ -293,7 +292,13 @@ fstest (char **images, int num_disks, int cmd, int n, char **args)
|
|||
grub_util_error ("loopback command fails.");
|
||||
}
|
||||
|
||||
grub_raid_rescan ();
|
||||
grub_lvm_fini ();
|
||||
grub_mdraid_fini ();
|
||||
grub_raid_fini ();
|
||||
grub_raid_init ();
|
||||
grub_mdraid_init ();
|
||||
grub_lvm_init ();
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case CMD_LS:
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <grub/util/getroot.h>
|
||||
#include <grub/term.h>
|
||||
#include <grub/env.h>
|
||||
#include <grub/raid.h>
|
||||
|
||||
#include <grub_probe_init.h>
|
||||
|
||||
|
@ -100,13 +101,21 @@ probe_partmap (grub_disk_t disk)
|
|||
free (name);
|
||||
}
|
||||
|
||||
static int
|
||||
probe_raid_level (grub_disk_t disk)
|
||||
{
|
||||
if (disk->dev->id != GRUB_DISK_DEVICE_RAID_ID)
|
||||
return -1;
|
||||
|
||||
return ((struct grub_raid_array *) disk->data)->level;
|
||||
}
|
||||
|
||||
static void
|
||||
probe (const char *path, char *device_name)
|
||||
{
|
||||
char *drive_name = NULL;
|
||||
char *grub_path = NULL;
|
||||
char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL;
|
||||
int abstraction_type;
|
||||
grub_device_t dev = NULL;
|
||||
grub_fs_t fs;
|
||||
|
||||
|
@ -132,28 +141,6 @@ probe (const char *path, char *device_name)
|
|||
goto end;
|
||||
}
|
||||
|
||||
abstraction_type = grub_util_get_dev_abstraction (device_name);
|
||||
/* No need to check for errors; lack of abstraction is permissible. */
|
||||
|
||||
if (print == PRINT_ABSTRACTION)
|
||||
{
|
||||
char *abstraction_name;
|
||||
switch (abstraction_type)
|
||||
{
|
||||
case GRUB_DEV_ABSTRACTION_LVM:
|
||||
abstraction_name = "lvm";
|
||||
break;
|
||||
case GRUB_DEV_ABSTRACTION_RAID:
|
||||
abstraction_name = "raid mdraid";
|
||||
break;
|
||||
default:
|
||||
grub_util_info ("did not find LVM/RAID in %s, assuming raw device", device_name);
|
||||
goto end;
|
||||
}
|
||||
printf ("%s\n", abstraction_name);
|
||||
goto end;
|
||||
}
|
||||
|
||||
drive_name = grub_util_get_grub_dev (device_name);
|
||||
if (! drive_name)
|
||||
grub_util_error ("Cannot find a GRUB drive for %s. Check your device.map.\n", device_name);
|
||||
|
@ -169,6 +156,58 @@ probe (const char *path, char *device_name)
|
|||
if (! dev)
|
||||
grub_util_error ("%s", grub_errmsg);
|
||||
|
||||
if (print == PRINT_ABSTRACTION)
|
||||
{
|
||||
grub_disk_memberlist_t list = NULL, tmp;
|
||||
const int is_lvm = (dev->disk->dev->id == GRUB_DISK_DEVICE_LVM_ID);
|
||||
int is_raid = 0;
|
||||
int is_raid5 = 0;
|
||||
int is_raid6 = 0;
|
||||
int raid_level;
|
||||
|
||||
raid_level = probe_raid_level (dev->disk);
|
||||
if (raid_level >= 0)
|
||||
{
|
||||
is_raid = 1;
|
||||
is_raid5 |= (raid_level == 5);
|
||||
is_raid6 |= (raid_level == 6);
|
||||
}
|
||||
|
||||
if ((is_lvm) && (dev->disk->dev->memberlist))
|
||||
list = dev->disk->dev->memberlist (dev->disk);
|
||||
while (list)
|
||||
{
|
||||
raid_level = probe_raid_level (list->disk);
|
||||
if (raid_level >= 0)
|
||||
{
|
||||
is_raid = 1;
|
||||
is_raid5 |= (raid_level == 5);
|
||||
is_raid6 |= (raid_level == 6);
|
||||
}
|
||||
|
||||
tmp = list->next;
|
||||
free (list);
|
||||
list = tmp;
|
||||
}
|
||||
|
||||
if (is_raid)
|
||||
{
|
||||
printf ("raid ");
|
||||
if (is_raid5)
|
||||
printf ("raid5rec ");
|
||||
if (is_raid6)
|
||||
printf ("raid6rec ");
|
||||
printf ("mdraid ");
|
||||
}
|
||||
|
||||
if (is_lvm)
|
||||
printf ("lvm ");
|
||||
|
||||
printf ("\n");
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (print == PRINT_PARTMAP)
|
||||
{
|
||||
grub_disk_memberlist_t list = NULL, tmp;
|
||||
|
@ -182,6 +221,20 @@ probe (const char *path, char *device_name)
|
|||
while (list)
|
||||
{
|
||||
probe_partmap (list->disk);
|
||||
/* LVM on RAID */
|
||||
if (list->disk->dev->memberlist)
|
||||
{
|
||||
grub_disk_memberlist_t sub_list;
|
||||
|
||||
sub_list = list->disk->dev->memberlist (list->disk);
|
||||
while (sub_list)
|
||||
{
|
||||
probe_partmap (sub_list->disk);
|
||||
tmp = sub_list->next;
|
||||
free (sub_list);
|
||||
sub_list = tmp;
|
||||
}
|
||||
}
|
||||
tmp = list->next;
|
||||
free (list);
|
||||
list = tmp;
|
||||
|
|
Loading…
Reference in a new issue