ACC SHELL

Path : /usr/share/YaST2/modules/
File Upload :
Current File : //usr/share/YaST2/modules/BootSupportCheck.ycp

/**
 * File:
 *      modules/BootSupportCheck.ycp
 *
 * Module:
 *      Bootloader installation and configuration
 *
 * Summary:
 *      Check whether the current system setup is a supported configuration
 *
 * Authors:
 *      Jiri Srain <jsrain@suse.cz>
 *
 * $Id: BootCommon.ycp 49686 2008-08-05 10:04:46Z juhliarik $
 *
 */

{
module "BootSupportCheck";

textdomain "bootloader";

import "Bootloader";
import "Arch";
import "Storage";
import "Region";
import "BootCommon";
import "BootStorage";
import "FileUtils";

/**
 * List of problems found during last check
 */
list<string> detected_problems = [];

/**
 * Add a new problem description to the list of found problems
 */
void AddNewProblem (string description) {
    detected_problems = add (detected_problems, description);
}

/**
 * List detected problems
 * Always run SystemSupported before calling this function
 * @return boolean a list of problems, empty if no was found
 */
global list<string> DetectedProblems () {
    return detected_problems;
}


/**
 * Formated string of detected problems
 * Always run SystemSupported before calling this function
 * @return boolean a list of problems, empty if no was found
 */
global string StringProblems () {

	string ret = "";
	if (size(detected_problems) > 0)
	{
		foreach(string s, detected_problems,
		{
			ret = ret + s + "\n";	
		});
	}

	return ret;
}


/**
 * Check that bootloader is known and supported
 */
boolean KnownLoader () {
    if (! contains (["grub", "elilo", "ppc", "zipl", "none"], Bootloader::getLoaderType ()))
    {

	if (Bootloader::getLoaderType () != "lilo")
        {
	   y2error ("Unknown bootloader: %1", Bootloader::getLoaderType ());
	   AddNewProblem (sformat (_("Unknown bootloader: %1"), Bootloader::getLoaderType ()));
	} else {
	   y2error ("LILO bootloader: %1", Bootloader::getLoaderType ());
	   AddNewProblem (_("LILO bootloader is not supported"));
	}
	return false;
    }
    return true;
}

/**
 * Check if elilo is supported
 */
boolean checkElilo()
{
    string cmd = "modprobe efivars 2>/dev/null";
    map ret = (map)SCR::Execute (.target.bash_output, cmd);
    // bnc#581213 - x86-64/UEFI: "Unsupported combination of hardware platform x86_64 and bootloader elilo"
    if (FileUtils::Exists("/sys/firmware/efi/systab"))
	return true;
    else
	return false;
}



/**
 * Check that bootloader matches current hardware
 */
boolean CorrectLoaderType () {
    string lt = Bootloader::getLoaderType ();
    if (lt == "none")
	return true;

    if (Arch::s390() && lt == "zipl")
	return true;
    if (Arch::ppc() && lt == "ppc")
	return true;
    if (Arch::ia64() && lt == "elilo")
	return true;
    if (Arch::i386() || Arch::x86_64()) {
	if (checkElilo()) {
	    if (lt == "elilo")
		return true;
	} else {
	    if ((lt == "grub") || (lt == "lilo"))
		return true;
	}
    }
    y2error ("Unsupported combination of hardware platform %1 and bootloader %2", Arch::architecture(), lt);
    AddNewProblem (sformat (_("Unsupported combination of hardware platform %1 and bootloader %2"), Arch::architecture(), lt));
    return false;
}

/**
 * Checks for GPT partition table
 // FIXME adapt for ELILO if needed
 */
boolean GptPartitionTable () {
    boolean ret = true;
    map tm = Storage::GetTargetMap ();
    list<string> devices = [ BootStorage::BootPartitionDevice ];
    // TODO add more devices
    foreach (string dev, devices, {
	map p_dev = Storage::GetDiskPartition (dev);
        integer num = BootCommon::myToInteger( p_dev["nr"]:nil );
        string mbr_dev = p_dev["disk"]:"";
	string label = tm[mbr_dev,"label"]:"";
	y2milestone ("Label: %1", label);
	y2internal ("Num: %1", num);
	if (label == "gpt")
	{
	    if (num > 3)
	    {
		y2error ("Partition number > 3 is being used for booting with GPT partition table");
		AddNewProblem (_("Partition number > 3 is being used for booting with GPT partition table"));
		ret = false;
	    }
	}
    });
    return ret;
}


/**
 * Check if boot partition exist
 * check if not on raid0
 *
 * @return boolean true on success
 */


global boolean check_BootDevice()
{
    boolean result = true;
    string boot_device = "";

    map<string,map> devices = (map<string,map>)Storage::GetTargetMap();

    boot_device = BootCommon::getBootPartition();

    string boot_disk = BootCommon::getBootDisk();
    // if (BootStorage::BootPartitionDevice == BootStorage::RootPartitionDevice)
    // AddNewProblem (_("Doesn't exist separete /boot partition"));

    boolean found_boot = false;
    // check if boot device is on raid0
    if (boot_device != "")
    {
	foreach (string k, map v, devices, 
	{
	    // check if boot disk is iscsi disk
	    // bnc#393928: Installing root system on iscsi disk makes the system useless
	    if (k == boot_disk)
	    {
		// if "iscsi" is true
		if (v["iscsi"]:false)
		{
		    AddNewProblem (sformat(_("The boot device is on iSCSI disk: %1. System may not boot."),
				 k));
		    y2error("The boot partition: %1 is on iscsi disk: %2", boot_device,  k);
		    result = false;
		}
	    }
	    foreach (map p, (list<map>)(v["partitions"]:[]), 
	    {
		if (p["device"]:"" == boot_device)
		{
		    if ((p["raid_type"]:"" != "raid1") && (p["type"]:nil ==`sw_raid))
		    {
			AddNewProblem (sformat(_("The boot device is on raid type: %1. System will not boot."),
				 p["raid_type"]:""));
			y2error("The boot device: %1 is on raid type: %2", boot_device,  p["raid_type"]:"");
			result = false;
			break;
		    } else {
			// bnc#501043 added check for valid configuration 
			if ((p["raid_type"]:"" == "raid1") && (p["type"]:nil ==`sw_raid))
			{
			    if ((tolower(p["fstype"]:"") == "md raid") && 
			       (BootCommon::globals["boot_mbr"]:"false" != "true"))
			    {
				AddNewProblem (_("The boot device is on software RAID1. Select other bootloader location, e.g. Master Boot Record"));
				y2error("Booting from soft-raid: %1 and bootloader setting are not valid: %2",
					p, BootCommon::globals);
				result = false;
				break;
			    } else {
				found_boot = true;
				y2milestone("Valid configuration for soft-raid");
			    }
 
			} else {
			    found_boot = true;
			    y2milestone("The boot device: %1 is on raid: %2", boot_device, p["raid_type"]:"");
			}
		    }
		    if (p["used_fs"]:nil == `xfs) 
		    {
			AddNewProblem (_("The /boot directory is on an XFS filesystem. System may not boot."));
			y2error ("The /boot directory is on an XFS filesystem");
			result = false;
			break;
		    } else {
			found_boot = true;
			y2milestone ("/boot filesystem is OK");
			break;
		    }

		}
	    });
	    if ((!result) || (found_boot))
		break;
	});
    }
   return result;
}

/**
 * Check if there is bios_id
 * if not show warning
 *
 * @return boolean true on success
 */

boolean CheckBios_ID()
{
	boolean ret = true;
	if (BootStorage::bois_id_missing)
	{
		AddNewProblem (_("It was not possible to determine the exact order of disks for device map. The order of disks can be changed in \"Boot Loader Installation Details\""));
		ret = false;
	}
	return ret;
}


/**
 * Check that the root partition is reachable
 */
boolean RootPartition () {
    return true;
}

/**
 * GRUB-related check
 */
global boolean GRUB () {
    boolean ret = GptPartitionTable ();
    if (ret)
	ret = check_BootDevice();
    if (ret)
	ret = CheckBios_ID();
    return  ret;
}

/**
 * ELILO related check
 */
boolean ELILO () {
    return true;
}

/**
 * ZIPL related check
 */
boolean ZIPL () {
    return true;
}

/**
 * PPC related check
 */
boolean PPC () {
    return true;
}

/**
 * Check if the system configuraiton is supported
 * Also sets the founds problems into internal variable
 * Always run this function before calling DetectedProblems()
 * @return boolean true if supported
 */
global boolean SystemSupported () {
    detected_problems = [];

    // check if the bootloader is known and supported
    boolean supported = KnownLoader ();

    string lt = Bootloader::getLoaderType ();
    if (lt == "none")
	return true;

    // detect correct bootloader type
    supported = CorrectLoaderType () && supported;

    // check whether root partition can be reached
    supported = RootPartition () && supported;

    // check specifics for individual loaders
    if (lt == "grub")
	supported = GRUB () && supported;
    else if (lt == "elilo")
	supported = ELILO () && supported;
    else if (lt == "ppc")
	supported = PPC () && supported;
    else if (lt == "zipl")
	supported = ZIPL () && supported;

    y2milestone ("Configuration supported: %1", supported);
    return supported;
}


global integer EndOfBootOrRootPartition()
{
    map part = Storage::GetEntryForMountpoint("/boot");
    if (isempty(part))
	part = Storage::GetEntryForMountpoint("/");

    string device = part["device"]:"";
    y2milestone("device:%1", device);

    integer end_cyl = Region::End(part["region"]:[]);

    integer cyl_size = 82252800;
    map<string, map> target_map = Storage::GetTargetMap();
    foreach (string dev, map disk, target_map, {
	if (find (map p, disk["partitions"]:[], { return p["device"]:"" == device; }) != nil)
	    cyl_size = disk["cyl_size"]:82252800;
    });

    integer ret = end_cyl * cyl_size;

    y2milestone("end_cyl:%1 cyl_size:%2 end:%3", end_cyl, cyl_size, ret);
    return ret;
}


} // EOF

ACC SHELL 2018