summaryrefslogtreecommitdiffstats
path: root/isys/eddsupport.c
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2009-04-07 21:05:36 +0200
committerHans de Goede <hdegoede@redhat.com>2009-04-08 10:48:45 +0200
commitb4ed339a8ae0e33310b1302493823c079139f24a (patch)
tree1c628f030ead556b19bac9e22f6dfbc4c95dfb0b /isys/eddsupport.c
parent5a08c2bd0504f2a8c4a35251ecadcd7505e9303d (diff)
downloadanaconda-b4ed339a8ae0e33310b1302493823c079139f24a.tar.gz
anaconda-b4ed339a8ae0e33310b1302493823c079139f24a.tar.xz
anaconda-b4ed339a8ae0e33310b1302493823c079139f24a.zip
Fix EDD BIOS disk order detection in general and make it work with dmraid
Our C-code isys EDD BIOS disk order detection is broken in 2 ways atm: 1) It tries to open "sda" instead of "/dev/sda" 2) It tries to open floppies and when it fails, it aborts further device scanning Besides that it didn't work with dmraid setups due to the following issues: 3) The C-code will not identify a device by the mbr signature from the EDD BIOS info, if multiple devices match the signature, however if we have a fakeraid mirror for example we will have 3 matching devices both the 2 raw disks and the device mapper device. 4) The python code was using /dev/mapper/longName names where as the C-code uses /dev/dm-# 5) The python code was calling the C-code (which builds a cache) before it setup the dmraid sets, so those were not known to the C-code
Diffstat (limited to 'isys/eddsupport.c')
-rw-r--r--isys/eddsupport.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/isys/eddsupport.c b/isys/eddsupport.c
index ae974c565..5356491b3 100644
--- a/isys/eddsupport.c
+++ b/isys/eddsupport.c
@@ -106,8 +106,10 @@ static struct device ** createDiskList(){
static int readDiskSig(char *device, uint32_t *disksig) {
int fd, rc;
+ char devnodeName[64];
- fd = open(device, O_RDONLY);
+ snprintf(devnodeName, sizeof(devnodeName), "/dev/%s", device);
+ fd = open(devnodeName, O_RDONLY);
if (fd < 0) {
#ifdef STANDALONE
fprintf(stderr, "Error opening device %s: %s\n ", device,
@@ -147,7 +149,7 @@ static int mapBiosDisks(struct device** devices,const char *path) {
char * sigFileName;
uint32_t mbrSig, biosNum, currentSig;
struct device **currentDev, **foundDisk;
- int i, rc, ret;
+ int i, rc, ret, dm_nr, highest_dm;
dirHandle = opendir(path);
if(!dirHandle){
@@ -176,22 +178,41 @@ static int mapBiosDisks(struct device** devices,const char *path) {
sigFileName = malloc(strlen(path) + strlen(entry->d_name) + 20);
sprintf(sigFileName, "%s/%s/%s", path, entry->d_name, SIG_FILE);
if (readMbrSig(sigFileName, &mbrSig) == 0) {
- for (currentDev = devices, i = 0, foundDisk=NULL;
- (*currentDev) != NULL && i<2;
+ for (currentDev = devices, i = 0, foundDisk=NULL, highest_dm=-1;
+ (*currentDev) != NULL;
currentDev++) {
if (!(*currentDev)->device)
continue;
if ((rc=readDiskSig((*currentDev)->device, &currentSig)) < 0) {
- if (rc == -ENOMEDIUM)
+ if (rc == -ENOMEDIUM || rc == -ENXIO)
continue;
closedir(dirHandle);
return 0;
}
if (mbrSig == currentSig) {
- foundDisk=currentDev;
+ /* When we have a fakeraid setup we will find multiple hits
+ a number for the raw disks (1 when striping, 2 when
+ mirroring, more with raid on raid like raid 01 or 10)
+ and a number for the dm devices (normally only one dm
+ device will match, but more with raid on raid).
+ Since with raid on raid the last dm device created
+ will be the top layer raid, we want the highest matching
+ dm device. */
+ if (!strncmp((*currentDev)->device, "dm-", 3) &&
+ sscanf((*currentDev)->device+3, "%d", &dm_nr) == 1) {
+ if (dm_nr > highest_dm) {
+ highest_dm = dm_nr;
+ foundDisk=currentDev;
+ i = 1;
+ }
+ } else if (!foundDisk ||
+ strncmp((*foundDisk)->device, "dm-", 3)) {
+ printf("using non dm device %s\n", (*currentDev)->device);
+ foundDisk=currentDev;
i++;
+ }
}
}