[yast-commit] r42703 - in /trunk/bootloader: package/yast2-bootloader.changes src/grub/misc.ycp src/routines/lilolike.ycp
Author: jsrain Date: Wed Dec 5 12:37:52 2007 New Revision: 42703 URL: http://svn.opensuse.org/viewcvs/yast?rev=42703&view=rev Log: fixed the device map proposal if USB stick is present (F#302075) Modified: trunk/bootloader/package/yast2-bootloader.changes trunk/bootloader/src/grub/misc.ycp trunk/bootloader/src/routines/lilolike.ycp Modified: trunk/bootloader/package/yast2-bootloader.changes URL: http://svn.opensuse.org/viewcvs/yast/trunk/bootloader/package/yast2-bootloader.changes?rev=42703&r1=42702&r2=42703&view=diff ============================================================================== --- trunk/bootloader/package/yast2-bootloader.changes (original) +++ trunk/bootloader/package/yast2-bootloader.changes Wed Dec 5 12:37:52 2007 @@ -1,4 +1,9 @@ ------------------------------------------------------------------- +Wed Dec 5 12:36:32 CET 2007 - jsrain@suse.cz + +- fixed the device map proposal if USB stick is present (F#302075) + +------------------------------------------------------------------- Wed Oct 31 14:32:59 CET 2007 - dfiser@suse.cz - Adapted to change of StorageDevices API. Modified: trunk/bootloader/src/grub/misc.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/bootloader/src/grub/misc.ycp?rev=42703&r1=42702&r2=42703&view=diff ============================================================================== --- trunk/bootloader/src/grub/misc.ycp (original) +++ trunk/bootloader/src/grub/misc.ycp Wed Dec 5 12:37:52 2007 @@ -415,102 +415,7 @@ // copied from src/routines/lilolike.ycp; should be removed there when it is // not needed there any more (by DisksOrder()), as it is grub only global void grub_ProposeDeviceMap () { - BootCommon::device_mapping = $[]; - - map<string,map> targetMap = $[]; - if (Mode::config ()) - y2milestone ("Skipping device map proposing in Config mode"); - else - targetMap = (map<string,map>)Storage::GetTargetMap(); - -//FIXME: This is not the final solution, we must be able to handle both, -//FakeRAIDs _and_ single disks. - - // Search in complete target map for "CT_DMRAID" types - map <string, map> DMTargetMap = filter (string k, map v, targetMap, { - return v["type"]:`CT_UNKNOWN==`CT_DMRAID; - }); - - // If no dmraids are present, search in complete target map for "CT_DISK" - // types. This should be the "normal" case. - if ( size(DMTargetMap) == 0 ) { - targetMap = filter (string k, map v, targetMap, { - return v["type"]:`CT_UNKNOWN==`CT_DISK; - }); - } else { - // If dmraid(s) are found, only use them - - // Get all available dmraids in the proper BIOS order - map out = (map) SCR::Execute (.target.bash_output, "dmraid -s -c"); - - if ( out["exit"]:0 == 0 && out["stdout"]:"" != "" ) { - list<string> DMRaid_devices_in_BIOS_order = - splitstring (out["stdout"]:"", "\n"); - - // Remove last list entry (because it is empty) - integer index_empty = size(DMRaid_devices_in_BIOS_order) - 1; - DMRaid_devices_in_BIOS_order = - remove(DMRaid_devices_in_BIOS_order, index_empty); - - integer DMRaidBiosID = 128; - - // FIXME: This code only work when YaST2-Storage either assigns - // BIOS-IDs to all available DMRaid devices or to none of them. - // Probably it's best to throw this code away once YaST2-Storage - // assigns BIOS-IDs to all available DMRaid devices. - - // Assign BIOS-IDs to DMRaid devices in the Target Map in BIOS - // order - DMTargetMap = listmap (string DMRaidDevice, DMRaid_devices_in_BIOS_order, { - DMRaidDevice = "/dev/mapper/" + DMRaidDevice; - if (haskey(DMTargetMap, DMRaidDevice)) { - if ( !haskey(DMTargetMap[DMRaidDevice]:$[], "bios_id") ) { - DMTargetMap[DMRaidDevice, "bios_id"] = tohexstring(DMRaidBiosID); - DMRaidBiosID = DMRaidBiosID + 1; - } - return $[ DMRaidDevice : DMTargetMap[DMRaidDevice]:$[] ]; - } - }); - y2milestone("sorted (according to BIOS) DMTargetMap: %1", DMTargetMap); - } else { - y2error ("Command: \"dmraid -s -c\" failed, no sorting of DMTargetMap."); - } - - targetMap = DMTargetMap; - } - - y2milestone ("Target map: %1", targetMap); - - // add devices with known bios_id - // collect BIOS IDs which are used - map ids = $[]; - foreach (string target_dev, map target, targetMap, { - string bios_id = target["bios_id"]:""; - if (bios_id != "") - { - integer index = tointeger (bios_id) - tointeger ("0x80"); - string grub_dev = sformat ("hd%1", index); - BootCommon::device_mapping[target_dev] = grub_dev; - ids[index] = true; - } - }); - // and guess other devices - // don't use already used BIOS IDs - foreach (string target_dev, map target, targetMap, { - string bios_id = target["bios_id"]:""; - if (bios_id == "") - { - integer index = 0; - while (ids[index]:false) - index = index + 1; - string grub_dev = sformat ("hd%1", index); - BootCommon::device_mapping[target_dev] = grub_dev; - ids[index] = true; - } - }); - if (StorageDevices::FloppyPresent()) - BootCommon::device_mapping[StorageDevices::FloppyDevice()] = "fd0"; - y2milestone ("Detected device mapping: %1", BootCommon::device_mapping); + BootCommon::ProposeDeviceMap(); } /** Modified: trunk/bootloader/src/routines/lilolike.ycp URL: http://svn.opensuse.org/viewcvs/yast/trunk/bootloader/src/routines/lilolike.ycp?rev=42703&r1=42702&r2=42703&view=diff ============================================================================== --- trunk/bootloader/src/routines/lilolike.ycp (original) +++ trunk/bootloader/src/routines/lilolike.ycp Wed Dec 5 12:37:52 2007 @@ -1143,12 +1143,139 @@ } + +/*** helper functions for ProposeDeviceMap: ***/ +/** + * Returns true if any device from list devices is in device_mapping + * marked as hd0. + */ +boolean isHd0(list<string> devices) +{ + boolean ret = false; + + foreach (string value, devices, + { + if (device_mapping[value]:"" == "hd0"){ + ret = true; + } + }); + + return ret; +} + +/** + * Returns first key from mapping associated with value. + * Example: + * map = $[ "a" : "1", + * "b" : "2", + * "c" : "3", + * "d" : "2"]; + * getDeviceFromMapping("1", map) -> "a" + * getDeviceFromMapping("2", map) -> "b" + */ +string getKey(string value, map<string, string> mapping) +{ + string ret = ""; + + foreach (string key, string val, mapping, + { + if (value == val){ + ret = key; + return; + } + }); + + return ret; +} + /** - * Generate device map proposal, store it in internal variables + * This function changes order of devices in device_mapping. + * All devices listed in bad_devices are maped to "hdN" are moved to the end + * (with changed number N). And second step is putting device with boot partition + * on top (i.e. device_mapping[dev_with_boot] = "hd0"). + * + * Example: + * device_mapping = $[ "/dev/sda" : "hd0", + * "/dev/sdb" : "hd1", + * "/dev/sdc" : "hd2", + * "/dev/sdd" : "hd3", + * "/dev/sde" : "hd4" ]; + * bad_devices = [ "/dev/sda", "/dev/sdc" ]; + * + * changeOrderInDeviceMapping(bad_devices); + * // after call, device_mapping is: + * device_mapping -> $[ "/dev/sda" : "hd3", + * "/dev/sdb" : "hd0", + * "/dev/sdc" : "hd4", + * "/dev/sdd" : "hd1", + * "/dev/sde" : "hd2" ]; + */ +void changeOrderInDeviceMapping(list<string> bad_devices) +{ + integer cur_id = 0; + list keys = []; + string value = ""; + string tmp = ""; + string tmp2 = ""; + + // get keys from device_mapping, it's not possible to use foreach over keys and values + // of device_mapping directly, because during the loop device_mapping is changing. + foreach (string key, string value, device_mapping, { keys = add(keys, key); }); + + // put bad_devices at bottom + foreach (string key, (list<string>)keys, + { + value = device_mapping[key]:""; + + // if device is mapped on hdX and this device is _not_ in bad_devices + if (substring(value, 0, 2) == "hd" + && !contains(bad_devices, key)){ + // get device name of mapped on "hd"+cur_id + tmp = getKey("hd" + tostring(cur_id), device_mapping); + + // swap tmp and key devices (swap their mapping) + device_mapping[tmp] = value; + device_mapping[key] = "hd" + tostring(cur_id); + + cur_id = cur_id + 1; + } + }); + + // put device with boot partition on the top: + tmp = (regexptokenize(BootCommon::BootPartitionDevice, "([a-z/]+)[0-9]*"))[0]:""; + if (haskey(device_mapping, tmp) && device_mapping[tmp]:"" != "hd0"){ + y2debug("Putting device with boot partition (%1) on the top.", tmp); + + tmp2 = getKey("hd0", device_mapping); + device_mapping[tmp2] = device_mapping[tmp]:""; + device_mapping[tmp] = "hd0"; + } +} +/*** helper functions END ***/ + +/** + * Generate device map proposal, store it in internal variables. + * + * FATE #302075: + * When user is installing from USB media or any non IDE disk or bios simply + * set any non IDE disk as first and user is not installing on this removable + * (non IDE) disk, the order of disks proposed by bios must be changed because + * of future remove of USB disk. + * This function must find right place for bootloader (which is most probably + * boot sector of boot partition (where /boot dir is located)) and change the + * order of disks in device map. + * This method is only heuristic because order of disks after remove of usb + * disk can't be determined by any method. + * + * Algorithm for solving problem with usb disk propsed by bios as hd0: + * if usbDiskDevice == hd0 && BootDevice != usbDiskDevice: + * change order of disks in device_mappings to have BootDevice as hd0 */ // FIXME: remove that function from here, as it is grub only // NOTE: there is a local copy in routines/grub/misc.ycp now global void ProposeDeviceMap () { + list<string> usb_disks = []; // contains those usb removable disks + device_mapping = $[]; map<string,map> targetMap = $[]; @@ -1242,8 +1369,34 @@ ids[index] = true; } }); + + // Fill usb_disks list with usb removable devices. + // + // It's not easy to determine how to identify removable usb devices. Now + // it tests if driver of device is usb-storage. If you find better + // algorithm how to find removable usb devices, put it here into foreach + // to apply this algorithm on all devices. + foreach (string target_dev, map target, targetMap, + { + string driver = target["driver"]:""; + if (driver == "usb-storage"){ + usb_disks = add(usb_disks, target_dev); + } + }); + y2milestone("Found usb discs: %1", usb_disks); + + // change order in device_mapping if usb disk is hd0 + // (FATE #302075) + if (isHd0(usb_disks) + && BootCommon::BootPartitionDevice != getKey("hd0", device_mapping)){ + y2milestone ("Detected device mapping: %1", device_mapping); + y2milestone("Changing order in device mapping needed..."); + changeOrderInDeviceMapping(usb_disks); + } + if (StorageDevices::FloppyPresent()) device_mapping[StorageDevices::FloppyDevice()] = "fd0"; + y2milestone ("Detected device mapping: %1", device_mapping); } -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org
participants (1)
-
jsrain@svn.opensuse.org