home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
boot
/
i386
/
root
/
usr
/
share
/
YaST2
/
modules
/
BootPOWERLILO.ycp
< prev
next >
Wrap
Text File
|
2006-11-29
|
33KB
|
1,096 lines
/**
* File:
* modules/BootPOWERLILO.ycp
*
* Module:
* Bootloader installation and configuration
*
* Summary:
* Module containing specific functions for POWERLILO configuration
* and installation
*
* Authors:
* Jiri Srain <jsrain@suse.cz>
* Joachim Plack <jplack@suse.de>
* Olaf Dabrunz <od@suse.de>
*
* $Id: BootPOWERLILO.ycp 34587 2006-11-24 16:02:55Z odabrunz $
*
*/
{
module "BootPOWERLILO";
textdomain "bootloader";
import "Arch";
import "BootArch";
import "BootCommon";
import "Kernel";
import "Mode";
import "Pkg";
import "Stage";
import "Storage";
/*
* This whole code is a big mess. To have a solution at all I included and
* adapted copies of the code from the old BootPPC.ycp, from common code in
* lilolike.ycp and others.
*
* od - February and March 2006
*/
// change the OpenFirmware variable 'boot-device' on CHRP or new PowerMacs
global boolean of_defaultdevice = true;
// partition number for the bootloader (either 41PReP boot or Apple_HFS)
// start with disabled value and let the partition scanner find a match.
global string prep_boot_partition = "";
// map available of 41 PReP partitions, used on iSeries and CHRP
global list<string> prep_boot_partitions = [];
// PReP boot partitions that were proposed by partitioner to install BL
global list<string> install_prep_boot_partitions = [];
// saved ID of the base installation source
global integer base_source = -1;
// iSeries specific global settings
// filename for the iSeries kernel, for streamfile *STMF booting
global string iseries_streamfile = "/boot/suse_linux_bootfile";
// write the install kernel to slot A, for rescue purpose
global boolean iseries_write_slot_a = false;
// write the kernel to slot B
global boolean iseries_write_slot_b = false;
// write the kernel to an 41 PReP boot partition
global boolean iseries_write_prepboot = false;
// write the kernel to file, this must be transfered to OS/400
global boolean iseries_write_streamfile = false;
// current board attribs
global boolean prep_only_active = true;
global boolean prep_only_iseries_vd = true;
global boolean prep_only_primary = true;
global boolean prep_same_disk_as_root = true;
global list table_items = [];
global string boot_device = "";
string board_type = nil;
global define string getBoardType ();
global define void setBoardType (string board);
global define void currentBoardInit ();
include "bootloader/ppc/misc.ycp";
include "bootloader/ppc/prep.ycp";
include "bootloader/ppc/chrp.ycp";
include "bootloader/ppc/iseries.ycp";
/*
* include ppc specific help messages
*/
include "bootloader/ppc/helps.ycp";
/*
* read my dialogs
*/
include "bootloader/routines/popups.ycp"; // define confirmSectionDeletePopup
include "bootloader/generic/dialogs.ycp";
// misc. functions
global define void initBoardType () {
if (Arch::board_iseries ())
{
board_type = "iseries";
}
else if (Arch::board_prep ())
{
board_type = "prep";
}
else if (Arch::board_chrp ())
{
board_type = "chrp";
}
else if (Arch::board_mac_new ())
{
board_type = "mac_new";
}
else if (Arch::board_mac_old ())
{
board_type = "mac_old";
}
else
{
board_type = "unknown";
}
y2milestone ("setting board type to: %1", board_type);
}
global define string getBoardType () {
if (board_type == nil)
initBoardType ();
return board_type;
}
global define void setBoardType (string board) {
board_type = board;
currentBoardInit ();
}
/**
* Initialize the attribute of currently used board type
*/
global define void currentBoardInit () {
if (getBoardType () == "iseries")
{
iSeriesInit ();
}
else if (getBoardType () == "prep")
{
PRePInit ();
}
else if (getBoardType () == "chrp")
{
CHRPInit ();
}
// TODO other boards
}
/**
* Create section for bootable image
* @param title string the section name to create (untranslated)
* @return map describes the section
*/
map<string,any> CreateImageSection (string title) {
// FIXME: This really should be a function and not be duplicated in
// BootCommon.ycp (although that code there also handles wildcard
// entries for lilo)
// FIXME:
// This only works in the installed system (problem with GetFinalKernel))),
// in all other cases we use the symlinks.
string image_fn = "";
string initrd_fn = "";
if (Mode::normal ()) {
// Find out the file names of the "real" kernel and initrd files, with
// version etc. pp. whatever (currently version-flavor) attached.
//
// First, get the file names in the "selected" kernel package,
string kernel_package = Kernel::GetFinalKernel();
list<string> files = Pkg::PkgGetFilelist( kernel_package, `any );
y2milestone ("kernel package %1 has these files: %2", kernel_package, files);
// then find the first file that matches the arch-dependent kernel file
// name prefix and the initrd filename prefix.
string kernel_prefix = "/boot/" + Kernel::GetBinary ();
string initrd_prefix = "/boot/initrd";
list<string> files_filtered = filter (string file, files, {
return ( substring(file, 0, size(kernel_prefix)) == kernel_prefix );
});
image_fn = files_filtered[0]:"";
files_filtered = filter (string file, files, {
return substring(file, 0, size(initrd_prefix)) == initrd_prefix ;
});
initrd_fn = files_filtered[0]:"";
} else {
// code removed: no wildcard entries possible on ppc (yaboot)
image_fn = "/boot/" + Kernel::GetBinary ();
initrd_fn = "/boot/initrd";
}
// done: image_fn and initrd_fn are the results
y2milestone ("image_fn: %1 initrd_fn: %2", image_fn, initrd_fn);
map<string,any> ret = $[
"type" : "image",
"name" : title,
"original_name" : title,
"image" : image_fn,
"initrd" : initrd_fn,
"root" : BootCommon::RootPartitionDevice,
// "": do not include resume parameter on ppc
"append" : BootArch::DefaultKernelParams (""),
"__auto" : true,
"__changed" : false,
"__devs" : [BootCommon::BootPartitionDevice, BootCommon::RootPartitionDevice],
];
return ret;
}
/**
* Choose a boot partition on pmac
* type == Apple_HFS|Apple_Bootstrap && size < 20 cyl
* @return string device name of pmac boot partition
*/
string GoodPmacBootPartition() {
y2milestone ("Detecting pmac boot partition");
map<string,map> targetMap = (map<string,map>)Storage::GetTargetMap ();
y2milestone ("TargetMap: %1", targetMap);
list<string> boot_partitions = [];
string selected_boot_partition = "";
foreach (string dname, map ddata, targetMap, ``{
list<map> partitions = ddata["partitions"]:[];
y2milestone ("Partitions: %1", partitions);
// does this device contain the root partition?
boolean hasrootdev = ( find (map p, partitions, ``(
(! p["delete"]:false)
&& p["device"]:"" == BootCommon::RootPartitionDevice
&& !contains( [`lvm, `evms, `sw_raid], p["type"]:`primary )
)) != nil );
// find possible boot partitions
partitions = filter (map p, partitions, ``(
(! p["delete"]:false)
&& is (p["fsid"]:nil, integer)
// both partition types Apple_Bootstrap and Apple_HFS can be
// handled by PPC lilo; yast2-storage maps both to fsid 258
&& (p["fsid"]:nil == 258)
// the partition should be smaller than 20 cylinders (PPC lilo
// takes that size as well); estimating the kiBytes:
// 255 heads * 63 sectors * 20 cylinders * 512 bytes / 1024 bytes =
// 160650 kiBytes
&& (p["size_k"]:0 < 160650)
&& !contains( [`lvm, `evms, `sw_raid], p["type"]:`primary )
));
y2milestone ("Filtered existing partitions: %1", partitions);
// found a boot partition on the same device as the root partition?
if (hasrootdev && size (partitions) > 0
&& selected_boot_partition == "")
{
y2milestone ("Selected pmac boot partition %1 on device with root partition %2",
partitions[0, "device"]:"", BootCommon::RootPartitionDevice);
selected_boot_partition = partitions[0, "device"]:"";
}
// collect found boot partitions
boot_partitions = (list<string>)merge (boot_partitions,
(list<string>)maplist (map p, partitions, ``(
p["device"]:""
))
);
});
y2milestone ("Detected pmac boot partitions: %1", boot_partitions);
if (selected_boot_partition == "")
{
selected_boot_partition = boot_partitions[0]:"";
}
y2milestone ("Selected pmac boot partition: %1", selected_boot_partition);
return selected_boot_partition;
}
/**
* Propose the location of the root device on disk and the boot device (if
* any), according to the subarchitecture.
* Results are stored in global variables.
*
*/
global void LocationProposal () {
BootCommon::DetectDisks ();
// del_parts is used by FixSections() in lilolike.ycp (imported by BootCommon.ycp)
BootCommon::del_parts = BootCommon::getPartitionList (`deleted);
boolean disks_changed = BootCommon::RefreshDisks();
if (updatePrepBootPartitions () || prep_boot_partition == "")
{
// TODO warning to user
choosePrepBootPartition ();
}
/* FIXME: remove this code (it was a simple proposal)
// get map of lists: mountpoint -> [partitionName, fsid, targetdevice, raid_type]
map mp = Storage::GetMountPoints();
y2milestone( "mountPoints %1", mp );
BootCommon::RootPartitionDevice = mp["/", 0]:"";
if (BootCommon::RootPartitionDevice == "")
y2error ("No mountpoint for / !!");
else
y2milestone("Root partition is %1", BootCommon::RootPartitionDevice);
*/
string arch = BootCommon::exports["arch"]:"chrp";
if ( arch == "chrp" ) {
/* FIXME: remove this code (it was a simple proposal)
// FIXME: really detect the boot partition (instead of leaving this to
// lilo), see /lib/lilo/lilo-chrp.lib:76 (ie. GoodPrepOrFatPartition()
// functionality)
BootCommon::BootPartitionDevice =
regexpsub (BootCommon::RootPartitionDevice, "^(.*[^0-9])[0-9]*", "\\1");
if (BootCommon::BootPartitionDevice == nil)
BootCommon::BootPartitionDevice = BootCommon::RootPartitionDevice;
*/
BootCommon::BootPartitionDevice = prep_boot_partition;
// also set as default value in widget
BootCommon::change_widget_default_value("boot_chrp_custom", prep_boot_partition);
}
else if ( arch == "prep" ) {
BootCommon::BootPartitionDevice = prep_boot_partition;
BootCommon::change_widget_default_value("boot_prep_custom", prep_boot_partition);
}
else if ( arch == "iseries" ) {
BootCommon::BootPartitionDevice = prep_boot_partition;
BootCommon::change_widget_default_value("boot_iseries_custom", prep_boot_partition);
}
else if ( arch == "pmac" ) {
BootCommon::BootPartitionDevice = GoodPmacBootPartition();
BootCommon::change_widget_default_value("boot_pmac_custom", BootCommon::BootPartitionDevice);
}
// These need to be set, for POWERLILO probably only to interface with
// autoyast, others base subsequent decisions on this.
// See ConfigureLocation() in lilolike.ycp.
//
// Mini-discussion: If autoyast is mainly used to clone configs, the
// loader_device and repl_mbr interface is enough, because loader_device
// simply contains the name of the device (partition, disk MBR, RAID
// device) to use for the bootloader.
// But if autoyast some day is used to transport configurations to less
// similar machines and setups, or to specify some sort of generic setup
// with special settings that will work on most machines, it may (or may
// not) be helpful to be able to specify boot_* variables in the autoyast
// file. This may apply better to the boot_* variables in BootGRUB.ycp
// though.
BootCommon::loader_device = BootCommon::BootPartitionDevice;
BootCommon::activate = true;
y2milestone("Boot partition is %1", BootCommon::loader_device);
}
/**
* Propose sections to bootloader menu
* modifies internal sreuctures
*/
global void CreateSections () {
map<string,any> linux = CreateImageSection ("linux");
// FIXME: I hate that i386 crap!!
if (haskey(linux, "kernel")) {
linux["image"] = linux["kernel"]:"/boot/vmlinux";
linux = remove(linux, "kernel");
};
// FIXME: create an 'other' section for MACs to boot MacOS
BootCommon::sections = [ linux, ];
}
/**
* Propose global options of bootloader
* modifies internal structures
*/
global void CreateGlobals () {
// FIXME: for iseries there are typically more than one boot option;
// boot = B
// boot = /dev/iseries/vda1
// boot = /boot/suse_linux_bootfile
BootCommon::globals = $[
"activate": "true",
"default" : BootCommon::sections[0, "name"]:"",
"timeout" : "80",
];
string arch = BootCommon::exports["arch"]:"chrp";
map<string, string> boot_map = $[];
y2milestone("RootPartDevice is %1",BootCommon::RootPartitionDevice);
if ( arch == "chrp" ) {
boot_map = $[
"boot_chrp_custom" : BootCommon::BootPartitionDevice,
];
}
else if ( arch == "prep" ) {
boot_map = $[
"boot_prep_custom" : BootCommon::BootPartitionDevice,
];
}
else if ( arch == "pmac" ) {
boot_map = $[
"boot_pmac_custom" : BootCommon::BootPartitionDevice,
];
}
else if ( arch == "iseries" ) {
boot_map = $[
"boot_slot" : "B",
// FIXME: what file should be used here?
"boot_file" : "/tmp/suse_linux_image",
// GoodPRePPartitionOnVDisk(BootCommon::RootPartitionDevice)
];
// If we have an empty BootPartitionDevice on iseries, this means:
// do not boot from BootPartitionDevice but from some other place.
// Do not pass down to perl-Bootloader, lilo fails on an empty "boot =" line.
if (BootCommon::BootPartitionDevice != nil &&
BootCommon::BootPartitionDevice != "") {
boot_map["boot_iseries_custom"] = BootCommon::BootPartitionDevice;
}
}
// Finally merge results into "globals": new values replace old ones
BootCommon::globals = (map<string, string>) union(BootCommon::globals, boot_map);
}
/**
* Save the ID of the base installation source
* modifies internal variable
*/
global void SaveInstSourceId () {
base_source = -1;
// Find the source ID of the base product:
// list all products
list<map<string,any> > products =
Pkg::ResolvableProperties ("", `product, "");
y2internal ("products: %1", products);
// filter products to be installed
products = filter (map<string,any> p, products, {
return p["source"]:-1 != -1;
});
// get base products
list<map<string,any> > base_products =
filter (map<string,any> p, products, {
return p["category"]:"" == "base";
});
if (size (base_products) == 0)
base_products = products; // just to be safe in case of a bug...
list<integer> sources = maplist (map<string,any> p, base_products, {
return p["source"]:-1;
});
y2internal ("remaining products: %1, sources: %2",
products, sources);
sources = sort (sources);
base_source = sources[0]:-1;
y2milestone ("Base source: %1", base_source);
}
// general functions
/**
* Propose bootloader settings
*/
global define void Propose () {
y2debug ("Started propose: Glob: %1, Sec: %2",
BootCommon::globals, BootCommon::sections);
// Need to remember inst source ID now to get the ISERIES64 file from the
// inst source later on (see Bug #165497, Comment #16). This won't work
// later during inst_finish, so we need to do it earlier -- only the
// proposal is a possible place.
SaveInstSourceId();
// FIXME: make modern code out of these conditionals
// - comments
// - simplify
// - check validity
boolean initial_propose = true;
if (BootCommon::was_proposed)
{
// FIXME: autoyast settings are simply Import()ed and was_proposed is
// set to true. The settings for the current board still need to be
// initialized though. We do this every time the bootloader proposal is
// called, because it also does not harm (results for the board
// detection are cached both in Arch.ycp and in our variable
// board_type.) To fix: make the "where does the information come
// from", when, more clear and obvious (in the code and/or in docs).
if (Mode::autoinst ())
{
currentBoardInit ();
}
initial_propose = false;
}
else
{
currentBoardInit ();
}
y2milestone ("board type is: %1", board_type);
// Get root and boot partition (if any)
LocationProposal();
if (BootCommon::sections == nil || size (BootCommon::sections) == 0)
{
CreateSections (); // make an initial proposal for at least one section
BootCommon::kernelCmdLine = Kernel::GetCmdLine ();
}
else
{
if (Mode::autoinst ())
{
y2debug ("Nothing to do in AI mode if sections exist");
}
else
BootCommon::FixSections (BootPOWERLILO::CreateSections);
}
if (BootCommon::globals == nil ||
// consider globals empty even if lines_cache_id is present
size (filter(string key, any v, BootCommon::globals, {
return key != "lines_cache_id";
})) == 0)
{
CreateGlobals ();
}
else
{
if (Mode::autoinst ())
{
y2debug ("Nothing to do in AI mode if globals are defined");
}
else
BootCommon::FixGlobals ();
}
y2milestone ("Proposed sections: %1", BootCommon::sections);
y2milestone ("Proposed globals: %1", BootCommon::globals);
}
/**
* Propose bootloader settings
*
global define void Propose () {
boolean initial_propose = true;
if (BootCommon::was_proposed)
{
initial_propose = false;
}
else
{
currentBoardInit ();
}
BootCommon::DetectDisks ();
BootCommon::del_parts = BootCommon::getPartitionList (`deleted);
boolean disks_changed = BootCommon::RefreshDisks();
if (updatePrepBootPartitions () || prep_boot_partition == "")
{
// TODO warning to user
choosePrepBootPartition ();
}
if ( getBoardType () == "iseries" )
{
iSeriesPropose (initial_propose);
}
else if ( getBoardType () == "prep" )
{
PRePPropose (initial_propose);
}
else if ( getBoardType () == "chrp" )
{
CHRPPropose (initial_propose);
}
if (BootCommon::sections == nil || size (BootCommon::sections) == 0)
{
createSections ();
BootCommon::kernelCmdLine = Kernel::GetCmdLine ();
}
else
{
if (Mode::autoinst ())
{
y2debug ("nothing to to in AI mode if sections exist");
// TODO whatever will be needed
}
else
fixSections (disks_changed);
}
if (BootCommon::globals == nil || size (BootCommon::globals) == 0)
{
createGlobals ();
}
else
{
if (Mode::autoinst ())
{
y2debug ("nothing to to in AI mode if globals are defined");
// TODO whatever will be needed
}
else
fixGlobals (disks_changed);
}
}
*/
/**
* Export bootloader settings to a map
* @return bootloader settings
*/
global define map Export () {
map exp = $[
"global": BootCommon::globals,
"sections" : BootCommon::sections,
"activate" : BootCommon::activate,
];
return exp;
}
/**
* Import settings from a map
* @param settings map of bootloader settings
* @return boolean true on success
*/
global define boolean Import (map settings) {
BootCommon::globals = settings["global"]:$[];
BootCommon::sections = settings["sections"]:[];
BootCommon::activate = settings["activate"]:false;
return true;
}
/**
* Read settings from disk
* @return boolean true on success
*/
global boolean Read (boolean reread) {
BootCommon::InitializeLibrary (reread, "ppc");
if (reread) {
BootCommon::ReadFiles ();
}
// Do we have to detect disks ?
// in /src/routines/lilolike.ycp is usesless for PPC (calls FindMBRDisk)
// BootCommon::DetectDisks ();
boolean ret = BootCommon::Read (false);
y2milestone (":: Read globals: %1", BootCommon::globals);
importMetaData();
return ret;
}
/**
* Reset bootloader settings
*/
global define void Reset (boolean init) {
// Reset global variables to default values
prep_boot_partition = "";
prep_boot_partitions = [];
install_prep_boot_partitions = [];
BootCommon::Reset (init);
}
/**
* Save all bootloader configuration files to the cache of the PlugLib
* PlugLib must be initialized properly !!!
* @param clean boolean true if settings should be cleaned up (checking their
* correctness, supposing all files are on the disk
* @param init boolean true to init the library
* @param flush boolean true to flush settings to the disk
* @return boolean true if success
*/
global boolean Save (boolean clean, boolean init, boolean flush) {
boolean ret = true;
// FIXME: this is currently a copy from BootCommon::Save
if (clean)
{
BootCommon::RemoveUnexistentSections ("", "");
// FIXME: this is not needed, unclear code
// BootCommon::UpdateInitrdLine ();
BootCommon::UpdateAppend ();
}
if (! BootCommon::InitializeLibrary (init, "ppc"))
// send current disk/partition information to perl-Bootloader
BootCommon::SetDiskInfo ();
// Sanity check the sections list: we can only pass strings
// through the perl interface
list<map<string,string> > sects = maplist (map<string,any> s, BootCommon::sections, {
return (map<string,string>)
filter (string k, any v, s, { return is (v, string); });
});
// convert root device names in sections to the device names indicated by
// "mountby"
sects = maplist (map<string,string> s, sects, {
s["root"] = BootCommon::Dev2MountByDev(s["root"]:"");
return s;
});
// FIXME: remove all mountpoints of type 'boot/boot' through some Storage::<func>
// FIXME: set one mountpoint 'boot/boot' for every boot target means all
// partitions in 'boot_<arch>_custom' and 'clone' (chrp)
// ret = ret && BootCommon::SetDeviceMap (device_mapping);
ret = ret && BootCommon::SetSections (sects);
ret = ret && BootCommon::SetGlobal (BootCommon::globals);
if (flush)
ret = ret && BootCommon::CommitSettings ();
return ret;
}
/**
* Display bootloader summary
* @return a list of summary lines
*/
global define list<string> Summary () {
list<string> result = [];
// FIXME:
// - evaluate and use the text from iSeriesSummary(), PRePSummary() and
// CHRPSummary()
// - add the cases for mac_old and mac_new (see BootPPC::Summary())
// summary text, %1 is bootloader name
result = add(
result,
sformat(
_("Boot loader type: %1"),
BootCommon::getLoaderName (BootCommon::getLoaderType (false), `summary)
)
);
// summary text for boot loader locations, sum up all locations to one string
string boot_loader_locations =
mergestring(
filter( string bll,
maplist( string key, any value, BootCommon::global_options, {
return (substring(key,0,5) == "boot_")
? BootCommon::globals[key]:"" : "";
}),
{ return bll != ""; }
),
", "
);
result = add (result, sformat (_("Location: %1"), boot_loader_locations));
list<string> sects = [];
foreach (map<string,any> s, BootCommon::sections, {
string title = s["name"]:"";
// section name "suffix" for default section
string def = (title == BootCommon::globals["default"]:"")
? _(" (default)")
: "";
sects = add (sects, sformat ("%1%2", title, def));
});
// summary text. %1 is list of bootloader sections
result = add (result, sformat (_("Sections: %1"),
String::EscapeTags (mergestring (sects, ", "))));
// FIXME: does the following code make any sense for ppc? (see also #163387)
// It seems not. (We do not do this, cf. jplack.) Keeping the code cadaver
// around until finally ready for removal.
// if (BootCommon::loader_device == "/dev/null")
// // summary text
// result = add (result,
// _("Do not install boot loader; just create configuration files"));
return result;
}
/**
* Update read settings to new version of configuration files
*/
global void Update () {
/**
* Firstly update sections of bootloader configuration and modify internal
* structures as needed. This means right now:
*
* - no change of "resume=" parameter in append entry, not used on ppc yet
* - delete console= parameters as console autodetection now works
*/
// This function has been copied from lilolike.ycp::UpdateSections and
// adapted to conform with the image parameter
// BootPOWERLILO.ycp/perl-Bootloader uses. Some unneeded code has been
// removed.
// FIXME: SLES9 -> SLES10 update: check loader_type = lilo in
// /etc/sysconfig/bootloader
// take current sections as starting point
list<map<string,any> > updated_sections = BootCommon::sections;
boolean linux_resume_added = false;
map<string,any> default_sect = CreateImageSection("linux");
string default_name = default_sect["name"]:"";
// assumption is that all of the following section names ar "good" names
// meaning that we will return a valid section description from
// CreateImageSection for them.
list<string> sections_to_recreate = ["linux"];
updated_sections = maplist (map<string,any> s, updated_sections, {
string name = s["name"]:"";
string oname = s["original_name"]:name;
// if we find a section that looks like it has been initially proposed
// from the installer, replace with the actual "good" proposal
if (contains(sections_to_recreate, oname)) {
sections_to_recreate = filter (string this_name,
sections_to_recreate, ``(this_name != oname)
);
// check for a new global default if oname != name
if ( name == BootCommon::globals["default"]:"" ) {
// we assume that the new name produced by CreateImageSection
// will be oname
BootCommon::globals["default"] = oname;
}
return CreateImageSection(oname);
}
// else adjust the entries of the found section according to some
// fancy rules
foreach (string key, ["image", "initrd"], {
string value = s[key]:"";
// FIXME: check whether this is code for update from SLES8?
// then we would delete it.
if (regexpmatch (value, "^.*\.shipped.*$"))
{
value = regexpsub (value,
"^(.*)\.shipped(.*)$", "\\1\\2");
}
else if (regexpmatch (value, "^.*\.suse.*$"))
{
value = regexpsub (value,
"^(.*)\.suse(.*)$", "\\1\\2");
}
s[key] = value;
});
// update root= entry in selected sections as the device naming
// changes in the linux kernel from time to time ...
if (contains (BootCommon::update_section_types, oname) && haskey(s, "root"))
{
y2milestone ("Updating root device of section %1", name);
s["root"] = BootCommon::UpdateDevice (s["root"]:"");
}
// handle the append line
string append = s["append"]:"";
// FIXME: how should we handle root= entries in append= lines?
// add additional kernel parameters to the end of the append entry
// of special image section 'linux'
//
if (oname == "linux") {
foreach (string o, BootCommon::ListAdditionalKernelParams (), {
append = BootCommon::setKernelParamToLine (append, o, "false");
});
append = append + " " + BootCommon::GetAdditionalKernelParams ();
if (BootCommon::getKernelParamFromLine (append, "splash") == "false")
append = BootCommon::setKernelParamToLine (append, "splash", "silent");
}
// remove console= entries from kernel parameters, console auto
// detection now works. For special sections take what's given on boot
// command line
string console = "false"; // false means delete to 'setKernelParamToLine'
if (contains (BootCommon::update_section_types, oname))
{
console = BootCommon::getKernelParamFromLine (Kernel::GetCmdLine(), "console") ;
}
append = BootCommon::setKernelParamToLine (append, "console", console);
// finally append entry is written back
if (append != "")
s["append"] = append;
else
s = remove(s, "append");
return s;
});
// if there was no original section matching the sections we want to
// recreate, so do prepend or append newly created sections to the list of
// updated sections
foreach (string section_name, sections_to_recreate, {
map<string,any> new_section = CreateImageSection(section_name);
if (section_name == "linux")
updated_sections = prepend (updated_sections, new_section);
else
updated_sections = add (updated_sections, new_section);
});
BootCommon::sections = updated_sections;
y2milestone("finished updating sections: %1", updated_sections);
// End of UpdateSections ();
/**
* Secondly update global settings of bootloader configuration:
*
* - no change of 'activate'
* - no change of 'timeout'
* - no change of default section
* - no change of default initrd
* - update device names that might have changed in as needed
* - delete console= parameters as console autodetection now works
*/
BootCommon::loader_device
= BootCommon::UpdateDevice (BootCommon::loader_device);
// update device naming of default root and boot_* entries
foreach (string key, ["root", "boot_prep_custom", "boot_chrp_custom",
"boot_iseries_custom","boot_pmac_custom", "clone"], {
if (haskey(BootCommon::globals, key)) {
y2milestone ("Updating global %1= setting, currently %2",
key, BootCommon::globals[key]:"");
BootCommon::globals[key] =
BootCommon::UpdateDevice (BootCommon::globals[key]:"");
}
});
// remove console= entries from globals, console auto detection now works
if (haskey (BootCommon::globals, "append")) {
string append = BootCommon::globals["append"]:"";
append = BootCommon::setKernelParamToLine (append, "console", "false");
if (append != "")
BootCommon::globals["append"] = append;
else
BootCommon::globals = remove(BootCommon::globals, "append");
}
}
/**
* Write bootloader settings to disk
* @return boolean true on success
*/
global define boolean Write () {
if (getBoardType () == "iseries")
{
iSeriesWrite ();
}
boolean ret = BootCommon::UpdateBootloader ();
ret = ret && BootCommon::InitializeBootloader ();
return ret;
}
global symbol WizardSequenzer() {
/*
blMainSequence () {
map functions = getFunctions (BootCommon::getLoaderType (false));
symbol () toEval = (symbol ())functions["wizard_sequencer"]:nil;
if (toEval != nil)
return toEval ();
else
return `generic;
*/
y2milestone("Call generic WizardSequenzer");
return `generic_new;
}
global map<string,symbol()> Dialogs () {
// PPC definitly needs other text modules
return $[
"loader" : genericBootLoaderOptionsDialog,
// "installation" : ppcInstallDetailsDialog,
];
}
/**
* Return map of provided functions
* @return map map of functions (eg. $["write":BootPOWERLILO::Write])
*/
global map<string, any> GetFunctions () {
return $[
"export" : Export,
"import" : Import,
"read" : Read,
"reset" : Reset,
"propose" : Propose,
"save" : Save,
"summary" : Summary,
"update" : Update,
"write" : Write,
"widgets" : genericWidgets,
"wizard_sequencer" : WizardSequenzer,
"dialogs" : Dialogs,
"section_types" : section_types,
];
}
/**
* Initializer of PowerLILO bootloader
*/
global void Initializer () {
y2milestone ("Called PowerLILO initializer");
BootCommon::current_bootloader_attribs = $[
"propose" : true,
"read" : true,
"scratch" : true,
"bootloader_on_disk" : true,
];
BootCommon::help_messages = (map<string,string>)
union(BootCommon::help_messages,
mapmap(string key, string val, ppc_help_messages,
{ return $[ "ppc_" + key : val ]; }
)
);
y2debug("Initialized help_messages to %1", BootCommon::help_messages);
BootCommon::descriptions = (map<string,string>)
union(BootCommon::descriptions,
mapmap(string key, string val, ppc_descriptions,
{ return $[ "ppc_" + key : val ]; }
)
);
y2debug("Initialized help_messages to %1", BootCommon::help_messages);
BootCommon::InitializeLibrary (false, "ppc");
importMetaData();
}
/**
* Constructor
*/
global void BootPOWERLILO () {
BootCommon::bootloader_attribs["ppc"] = $[
"required_packages" : ["lilo"],
"loader_name" : "ppc",
"initializer" : BootPOWERLILO::Initializer,
];
}
}
/*
* Local variables:
* mode: ycp
* mode: font-lock
* mode: auto-fill
* indent-level: 4
* fill-column: 78
* End:
*/