diff options
author | Hans de Goede <hdegoede@redhat.com> | 2009-04-07 21:05:36 +0200 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2009-04-08 10:48:45 +0200 |
commit | b4ed339a8ae0e33310b1302493823c079139f24a (patch) | |
tree | 1c628f030ead556b19bac9e22f6dfbc4c95dfb0b /isys/eddsupport.c | |
parent | 5a08c2bd0504f2a8c4a35251ecadcd7505e9303d (diff) | |
download | anaconda-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.c | 33 |
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, ¤tSig)) < 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++; + } } } |