Author: jsrain
Date: Wed Dec 5 12:39:12 2007
New Revision: 42704
URL: http://svn.opensuse.org/viewcvs/yast?rev=42704&view=rev
Log:
fixed the device map proposal if USB stick is present (F#302075)
Modified:
branches/SuSE-SLE-10-SP2-Branch/bootloader/package/yast2-bootloader.changes
branches/SuSE-SLE-10-SP2-Branch/bootloader/src/grub/misc.ycp
branches/SuSE-SLE-10-SP2-Branch/bootloader/src/routines/lilolike.ycp
Modified: branches/SuSE-SLE-10-SP2-Branch/bootloader/package/yast2-bootloader.changes
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-SLE-10-SP2-Branch/bootloader/package/yast2-bootloader.changes?rev=42704&r1=42703&r2=42704&view=diff
==============================================================================
--- branches/SuSE-SLE-10-SP2-Branch/bootloader/package/yast2-bootloader.changes (original)
+++ branches/SuSE-SLE-10-SP2-Branch/bootloader/package/yast2-bootloader.changes Wed Dec 5 12:39:12 2007
@@ -1,4 +1,10 @@
-------------------------------------------------------------------
+Wed Dec 5 11:15:12 CET 2007 - jsrain@suse.cz
+
+- fixed the device map proposal if USB stick is present (F#302075)
+- 2.13.148
+
+-------------------------------------------------------------------
Thu Sep 27 18:55:34 CEST 2007 - od@suse.de
- do not install bootloader in XEN paravirtualized DomU (#308451)
Modified: branches/SuSE-SLE-10-SP2-Branch/bootloader/src/grub/misc.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-SLE-10-SP2-Branch/bootloader/src/grub/misc.ycp?rev=42704&r1=42703&r2=42704&view=diff
==============================================================================
--- branches/SuSE-SLE-10-SP2-Branch/bootloader/src/grub/misc.ycp (original)
+++ branches/SuSE-SLE-10-SP2-Branch/bootloader/src/grub/misc.ycp Wed Dec 5 12:39:12 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 targetMap = $[];
- if (Mode::config ())
- y2milestone ("Skipping device map proposing in Config mode");
- else
- targetMap = (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 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: branches/SuSE-SLE-10-SP2-Branch/bootloader/src/routines/lilolike.ycp
URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-SLE-10-SP2-Branch/bootloader/src/routines/lilolike.ycp?rev=42704&r1=42703&r2=42704&view=diff
==============================================================================
--- branches/SuSE-SLE-10-SP2-Branch/bootloader/src/routines/lilolike.ycp (original)
+++ branches/SuSE-SLE-10-SP2-Branch/bootloader/src/routines/lilolike.ycp Wed Dec 5 12:39:12 2007
@@ -962,12 +962,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;
+}
+
/**
- * Generate device map proposal, store it in internal variables
+ * 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 mapping)
+{
+ string ret = "";
+
+ foreach (string key, string val, mapping,
+ {
+ if (value == val){
+ ret = key;
+ return;
+ }
+ });
+
+ return ret;
+}
+
+/**
+ * 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 targetMap = $[];
@@ -1061,8 +1188,35 @@
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