summaryrefslogtreecommitdiffstats
path: root/isys
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
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')
-rw-r--r--isys/eddsupport.c33
-rwxr-xr-xisys/isys.py27
2 files changed, 48 insertions, 12 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++;
+ }
}
}
diff --git a/isys/isys.py b/isys/isys.py
index d5ae22325..88bfaf13e 100755
--- a/isys/isys.py
+++ b/isys/isys.py
@@ -308,14 +308,23 @@ def doGetBiosDisk(mbrSig):
handleSegv = _isys.handleSegv
-biosdisks = {}
-for d in range(80, 80 + 15):
- disk = doGetBiosDisk("%d" %(d,))
- #print("biosdisk of %s is %s" %(d, disk))
- if disk is not None:
- biosdisks[disk] = d
def compareDrives(first, second):
+ from storage.devicelibs.dm import dm_node_from_name
+
+ biosdisks = {}
+ for d in range(80, 80 + 15):
+ disk = doGetBiosDisk("%d" %(d,))
+ #print("biosdisk of %s is %s" %(d, disk))
+ if disk is not None:
+ biosdisks[disk] = d
+
+ # convert /dev/mapper/foo -> /dev/dm-#, as that is what is in biosdisks
+ if os.access("/dev/mapper/%s" % first, os.F_OK):
+ first = dm_node_from_name(first)
+ if os.access("/dev/mapper/%s" % second, os.F_OK):
+ second = dm_node_from_name(second)
+
if biosdisks.has_key(first) and biosdisks.has_key(second):
one = biosdisks[first]
two = biosdisks[second]
@@ -324,6 +333,12 @@ def compareDrives(first, second):
elif (one > two):
return 1
+ # if one is in the BIOS and the other not prefer the one in the BIOS
+ if biosdisks.has_key(first):
+ return -1
+ if biosdisks.has_key(second):
+ return 1
+
if first.startswith("hd"):
type1 = 0
elif first.startswith("sd"):