ACC SHELL

Path : /usr/share/YaST2/include/bootloader/routines/
File Upload :
Current File : //usr/share/YaST2/include/bootloader/routines/i386.ycp

/**
 * File:
 *      include/bootloader/routines/i386.ycp
 *
 * Module:
 *      Bootloader installation and configuration
 *
 * Summary:
 *      Functions for i386 architecture
 *
 * Authors:
 *      Jiri Srain <jsrain@suse.cz>
 *
 * $Id: i386.ycp 57010 2009-04-28 14:39:07Z juhliarik $
 *
 */
{

textdomain "bootloader";

// general MBR reading cache

/**
 * The last disk that was checked for the sequence
 */
string _old_mbr_disk = nil;

/**
 * Contents of the last read MBR
 */
string _old_mbr = nil;

// info about ThinkPad

/**
 * Does MBR contain special thinkpadd stuff?
 */
boolean _thinkpad_mbr = nil;

/**
 * The last disk that was checked for the sequence
 */
string _old_thinkpad_disk = nil;

// Info about keeping MBR contents

/**
 * Keep the MBR contents?
 */
boolean _keep_mbr = nil;

/**
 * Sequence specific for IBM ThinkPad laptops, see bug 86762
 */
string thinkpad_seq = "50e46124108ae0e461241038e074f8e2f458c332edb80103ba8000cd13c3be05068a04240cc0e802c3";

/**
 * Get the contents of the MBR of a disk
 * @param disk string the disk to be checked
 * @return strign the contents of the MBR of the disk in hexa form
 */
string GetMBRContents (string disk) {
    if (_old_mbr == nil || disk != _old_mbr_disk)
    {
	_old_mbr_disk = disk;
	map out = (map)SCR::Execute (.target.bash_output, sformat (
	    "dd if=%1 bs=512 count=1 | od -v -t x1 -", disk));
	if (out["exit"]:0 != 0)
	{
	    y2error ("Reading MBR contents failed");
	    return nil;
	}
	string mbr = out["stdout"]:"";
	list<string> mbrl = splitstring (mbr, "\n");
	mbrl = maplist (string s, mbrl, {
	    list<string> l = splitstring (s, " ");
	    l[0] = "";
	    return mergestring (l, "");
	});
	mbr = mergestring (mbrl, "");
	y2debug ("MBR contents: %1", mbr);
	_old_mbr = mbr;
    }
    return _old_mbr;
}

/**
 * Does MBR of the disk contain special IBM ThinkPad stuff?
 * @param disk string the disk to be checked
 * @return boolean true if it is MBR
 */
global boolean ThinkPadMBR (string disk) {
    if (_thinkpad_mbr == nil || disk != _old_thinkpad_disk)
    {
	_old_thinkpad_disk = disk;
	string mbr = GetMBRContents (disk);
	integer x02 = tointeger ("0x" + substring (mbr, 4, 2));
	integer x03 = tointeger ("0x" + substring (mbr, 6, 2));
	string x0e = substring (mbr, 28, 2);
	string x0f = substring (mbr, 30, 2);
	y2internal ("Data: %1 %2 %3 %4", x02, x03, x0e, x0f);
	_thinkpad_mbr = (2 <= x02 && x02 <= tointeger ("0x63") && 2 <= x03 && x03 <= tointeger ("0x63") &&
	    tolower (x0e) == "4e" && tolower (x0f) == "50");
    }
    y2milestone ("MBR of %1 contains ThinkPad sequence: %2",
	disk, _thinkpad_mbr);
    return _thinkpad_mbr;

}

/**
 * Keep the MBR contents on the specified disk? Check whether the contents
 * should be kept because ot contains vendor-specific data
 * @param disk string the disk to be checked
 * @return boolean true to keep the contents
 */
global boolean KeepMBR (string disk) {

    // FIXME: see bug #464485 there is problem with detection of
    // MBR the 3rd byte is 0 after recovery thinkpad notebook with
    // recovery CD, next missing cooperate with Lenovo there also
    // missing any specification about Lenovo's changes in MBR

    y2milestone("Skip checking of MBR for thinkpad sequence");

    return false;
}

/**
 * Add the partition holding firmware to bootloader?
 * @param disk string the disk to be checked
 * @return boolean true if firmware partition is to be added
 */
global boolean AddFirmwareToBootloader (string disk) {
    return ! ThinkPadMBR (disk);
}

/**
 * Display bootloader summary
 * @return a list of summary lines
 */
global list<string> i386Summary () {
    list<string> ret = Summary ();
    string order_sum = DiskOrderSummary ();
    if (order_sum != nil)
	ret = add (ret, order_sum);
    return ret;
}

/**
 * Propose the boot loader location for i386 (and similar) platform
 */
global void i386LocationProposal () {
    if (! was_proposed)
    {
	DetectDisks ();
	del_parts = BootStorage::getPartitionList (`deleted, getLoaderType(false));
	// check whether edd is loaded; if not: load it
	string lsmod_command = "lsmod | grep edd";
	y2milestone ("Running command %1", lsmod_command);
	map lsmod_out = (map)SCR::Execute (.target.bash_output, lsmod_command);
	y2milestone ("Command output: %1", lsmod_out);
	boolean edd_loaded = lsmod_out["exit"]:0 == 0;
	if (! edd_loaded)
	{
	    string command = "/sbin/modprobe edd";
	    y2milestone ("Loading EDD module, running %1", command);
	    map out = (map)SCR::Execute (.target.bash_output, command);
	    y2milestone ("Command output: %1", out);
	}
    }

    // refresh device map
    if ((BootStorage::device_mapping == nil
	|| size (BootStorage::device_mapping) == 0)
	&& (getLoaderType(false) == "grub"))
    {
	BootStorage::ProposeDeviceMap ();
    }

    if (DisksChanged () && ! Mode::autoinst ()) {
        if (askLocationResetPopup (loader_device)) {
	    selected_location = nil;
	    loader_device = nil;
	    y2milestone ("Reconfiguring locations");
	    DetectDisks ();
	}
    }
}


/**
 * Do updates of MBR after the bootloader is installed
 * @return boolean true on success
 */
global boolean PostUpdateMBR () {
    boolean ret = true;
    if (ThinkPadMBR (mbrDisk))
    {
	if (loader_device != mbrDisk)
	{
	    string command = sformat
		("/usr/lib/YaST2/bin/tp_mbr %1", mbrDisk);
	    y2milestone ("Running command %1", command);
	    map out = (map)SCR::Execute (.target.bash_output, command);
	    integer exit = out["exit"]:0;
	    y2milestone ("Command output: %1", out);
	    ret = ret && (0 == exit);
	}
    }

    return ret;
}

} // EOF

ACC SHELL 2018