merge with mainline
This commit is contained in:
commit
16c7cb32c8
80 changed files with 5101 additions and 1687 deletions
|
@ -1,7 +1,7 @@
|
|||
/* raid.c - module to read RAID arrays. */
|
||||
/*
|
||||
* GRUB -- GRand Unified Bootloader
|
||||
* Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
|
||||
*
|
||||
* GRUB is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -254,7 +254,8 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
err = grub_disk_read (array->device[k],
|
||||
read_sector + j * far_ofs + b,
|
||||
array->start_sector[k] +
|
||||
read_sector + j * far_ofs + b,
|
||||
0,
|
||||
read_size << GRUB_DISK_SECTOR_BITS,
|
||||
buf);
|
||||
|
@ -366,7 +367,8 @@ grub_raid_read (grub_disk_t disk, grub_disk_addr_t sector,
|
|||
grub_errno = GRUB_ERR_NONE;
|
||||
|
||||
err = grub_disk_read (array->device[disknr],
|
||||
read_sector + b, 0,
|
||||
array->start_sector[disknr] +
|
||||
read_sector + b, 0,
|
||||
read_size << GRUB_DISK_SECTOR_BITS,
|
||||
buf);
|
||||
|
||||
|
@ -475,12 +477,12 @@ grub_raid_write (grub_disk_t disk __attribute ((unused)),
|
|||
|
||||
static grub_err_t
|
||||
insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
|
||||
const char *scanner_name)
|
||||
grub_disk_addr_t start_sector, const char *scanner_name)
|
||||
{
|
||||
struct grub_raid_array *array = 0, *p;
|
||||
|
||||
/* See whether the device is part of an array we have already seen a
|
||||
device from. */
|
||||
device from. */
|
||||
for (p = array_list; p != NULL; p = p->next)
|
||||
if ((p->uuid_len == new_array->uuid_len) &&
|
||||
(! grub_memcmp (p->uuid, new_array->uuid, p->uuid_len)))
|
||||
|
@ -491,7 +493,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
|
|||
/* Do some checks before adding the device to the array. */
|
||||
|
||||
/* FIXME: Check whether the update time of the superblocks are
|
||||
the same. */
|
||||
the same. */
|
||||
|
||||
if (array->total_devs == array->nr_devs)
|
||||
/* We found more members of the array than the array
|
||||
|
@ -502,7 +504,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
|
|||
|
||||
if (array->device[new_array->index] != NULL)
|
||||
/* We found multiple devices with the same number. Again,
|
||||
this shouldn't happen.*/
|
||||
this shouldn't happen. */
|
||||
grub_dprintf ("raid", "Found two disks with the number %d?!?",
|
||||
new_array->number);
|
||||
|
||||
|
@ -524,46 +526,75 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
|
|||
*array = *new_array;
|
||||
array->nr_devs = 0;
|
||||
grub_memset (&array->device, 0, sizeof (array->device));
|
||||
grub_memset (&array->start_sector, 0, sizeof (array->start_sector));
|
||||
|
||||
/* Check whether we don't have multiple arrays with the same number. */
|
||||
for (p = array_list; p != NULL; p = p->next)
|
||||
{
|
||||
if (p->number == array->number)
|
||||
break;
|
||||
}
|
||||
|
||||
if (p)
|
||||
{
|
||||
/* The number is already in use, so we need to find an new number. */
|
||||
int i = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
for (p = array_list; p != NULL; p = p->next)
|
||||
{
|
||||
if (p->number == i)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!p)
|
||||
{
|
||||
/* We found an unused number. */
|
||||
array->number = i;
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
array->name = grub_xasprintf ("md%d", array->number);
|
||||
if (! array->name)
|
||||
{
|
||||
grub_free (array->uuid);
|
||||
grub_free (array);
|
||||
{
|
||||
for (p = array_list; p != NULL; p = p->next)
|
||||
{
|
||||
if (! p->name && p->number == array->number)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
if (array->name || p)
|
||||
{
|
||||
/* The number is already in use, so we need to find a new one.
|
||||
(Or, in the case of named arrays, the array doesn't have its
|
||||
own number, but we need one that doesn't clash for use as a key
|
||||
in the disk cache. */
|
||||
int i = array->name ? 0x40000000 : 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
for (p = array_list; p != NULL; p = p->next)
|
||||
{
|
||||
if (p->number == i)
|
||||
break;
|
||||
}
|
||||
|
||||
if (! p)
|
||||
{
|
||||
/* We found an unused number. */
|
||||
array->number = i;
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/* mdraid 1.x superblocks have only a name stored not a number.
|
||||
Use it directly as GRUB device. */
|
||||
if (! array->name)
|
||||
{
|
||||
array->name = grub_xasprintf ("md%d", array->number);
|
||||
if (! array->name)
|
||||
{
|
||||
grub_free (array->uuid);
|
||||
grub_free (array);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Strip off the homehost if present. */
|
||||
char *colon = grub_strchr (array->name, ':');
|
||||
char *new_name = grub_xasprintf ("md/%s",
|
||||
colon ? colon + 1 : array->name);
|
||||
|
||||
if (! new_name)
|
||||
{
|
||||
grub_free (array->uuid);
|
||||
grub_free (array);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
grub_free (array->name);
|
||||
array->name = new_name;
|
||||
}
|
||||
|
||||
grub_dprintf ("raid", "Found array %s (%s)\n", array->name,
|
||||
scanner_name);
|
||||
|
@ -580,6 +611,7 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
|
|||
|
||||
/* Add the device to the array. */
|
||||
array->device[new_array->index] = disk;
|
||||
array->start_sector[new_array->index] = start_sector;
|
||||
array->nr_devs++;
|
||||
|
||||
return 0;
|
||||
|
@ -621,6 +653,7 @@ grub_raid_register (grub_raid_t raid)
|
|||
{
|
||||
grub_disk_t disk;
|
||||
struct grub_raid_array array;
|
||||
grub_disk_addr_t start_sector;
|
||||
|
||||
grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name);
|
||||
|
||||
|
@ -629,8 +662,8 @@ grub_raid_register (grub_raid_t raid)
|
|||
return 0;
|
||||
|
||||
if ((disk->total_sectors != GRUB_ULONG_MAX) &&
|
||||
(! grub_raid_list->detect (disk, &array)) &&
|
||||
(! insert_array (disk, &array, grub_raid_list->name)))
|
||||
(! grub_raid_list->detect (disk, &array, &start_sector)) &&
|
||||
(! insert_array (disk, &array, start_sector, grub_raid_list->name)))
|
||||
return 0;
|
||||
|
||||
/* This error usually means it's not raid, no need to display
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue