aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwiktor w brodlo <wiktor@brodlo.net>2011-06-15 16:59:54 +0000
committerwiktor w brodlo <wiktor@brodlo.net>2011-06-15 16:59:54 +0000
commit2590d96369d0217e31dc2812690dde61dac417b5 (patch)
tree82276f787b08a28548e342c7921486f1acefab9f /bootloader.py
parentfirst commit (diff)
downloadanaconda-2590d96369d0217e31dc2812690dde61dac417b5.tar.gz
anaconda-2590d96369d0217e31dc2812690dde61dac417b5.tar.bz2
anaconda-2590d96369d0217e31dc2812690dde61dac417b5.zip
Initial import from Sabayon (ver 0.9.9.56)
Diffstat (limited to 'bootloader.py')
-rw-r--r--bootloader.py241
1 files changed, 241 insertions, 0 deletions
diff --git a/bootloader.py b/bootloader.py
new file mode 100644
index 0000000..e2b06a8
--- /dev/null
+++ b/bootloader.py
@@ -0,0 +1,241 @@
+#
+# bootloader.py: anaconda bootloader shims
+#
+# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
+# All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Erik Troan <ewt@redhat.com>
+# Jeremy Katz <katzj@redhat.com>
+#
+
+import isys
+import parted
+import os, sys
+import iutil
+import string
+from flags import flags
+from constants import *
+from storage.devices import devicePathToName
+from storage import getReleaseString
+from booty.util import getDiskPart
+
+import gettext
+_ = lambda x: gettext.ldgettext("anaconda", x)
+
+import logging
+log = logging.getLogger("anaconda")
+
+import booty
+from booty import bootloaderInfo, checkbootloader
+
+def isEfiSystemPartition(part):
+ if not part.active:
+ return False
+ return (part.disk.type == "gpt" and
+ part.name == "EFI System Partition" and
+ part.getFlag(parted.PARTITION_BOOT) and
+ part.fileSystem.type in ("fat16", "fat32") and
+ isys.readFSLabel(part.getDeviceNodeName()) != "ANACONDA")
+
+def bootloaderSetupChoices(anaconda):
+ if anaconda.dir == DISPATCH_BACK:
+ rc = anaconda.intf.messageWindow(_("Warning"),
+ _("Filesystems have already been activated. You "
+ "cannot go back past this point.\n\nWould you like to "
+ "continue with the installation?"),
+ type="custom", custom_icon=["error","error"],
+ custom_buttons=[_("_Exit installer"), _("_Continue")])
+
+ if rc == 0:
+ sys.exit(0)
+ return DISPATCH_FORWARD
+
+ if anaconda.ksdata and anaconda.ksdata.bootloader.driveorder:
+ anaconda.bootloader.updateDriveList(anaconda.ksdata.bootloader.driveorder)
+ else:
+ #We want the selected bootloader drive to be preferred
+ pref = anaconda.bootloader.drivelist[:1]
+ anaconda.bootloader.updateDriveList(pref)
+
+ if iutil.isEfi() and not anaconda.bootloader.device:
+ bootPart = None
+ partitions = anaconda.storage.partitions
+ for part in partitions:
+ if part.partedPartition.active and isEfiSystemPartition(part.partedPartition):
+ bootPart = part.name
+ break
+ if bootPart:
+ anaconda.bootloader.setDevice(bootPart)
+
+# iSeries bootloader on upgrades
+ if iutil.getPPCMachine() == "iSeries" and not anaconda.bootloader.device:
+ bootPart = None
+ partitions = anaconda.storage.partitions
+ for part in partitions:
+ if part.partedPartition.active and \
+ part.partedPartition.getFlag(parted.PARTITION_PREP):
+ bootPart = part.name
+ break
+ if bootPart:
+ anaconda.bootloader.setDevice(bootPart)
+
+ choices = anaconda.platform.bootloaderChoices(anaconda.bootloader)
+ if not choices and iutil.getPPCMachine() != "iSeries":
+ anaconda.dispatch.skipStep("instbootloader")
+ else:
+ anaconda.dispatch.skipStep("instbootloader", skip = 0)
+
+ # FIXME: ...
+ anaconda.bootloader.images.setup(anaconda.storage)
+
+ if anaconda.bootloader.defaultDevice != None and choices:
+ keys = choices.keys()
+ # there are only two possible things that can be in the keys
+ # mbr and boot. boot is ALWAYS present. so if the dev isn't
+ # listed, it was mbr and we should nicely fall back to boot
+ if anaconda.bootloader.defaultDevice not in keys:
+ log.warning("MBR not suitable as boot device; installing to partition")
+ anaconda.bootloader.defaultDevice = "boot"
+ anaconda.bootloader.setDevice(choices[anaconda.bootloader.defaultDevice][0])
+ elif choices and iutil.isMactel() and choices.has_key("boot"): # haccckkkk
+ anaconda.bootloader.setDevice(choices["boot"][0])
+ elif choices and choices.has_key("mbr"):
+ anaconda.bootloader.setDevice(choices["mbr"][0])
+ elif choices and choices.has_key("boot"):
+ anaconda.bootloader.setDevice(choices["boot"][0])
+
+def fixedMdraidGrubTarget(anaconda, grubTarget):
+ # handle change made in F12 - before F12 mdX used to mean installation
+ # into mbrs of mdX members' disks
+ fixedGrubTarget = grubTarget
+ (product, version) = getReleaseString(anaconda.rootPath)
+ try:
+ if float(version) < 12:
+ stage1Devs = anaconda.bootloader.getPhysicalDevices(grubTarget)
+ fixedGrubTarget = getDiskPart(stage1Devs[0], anaconda.storage)[0]
+ log.info("Mdraid grub upgrade: %s -> %s" % (grubTarget,
+ fixedGrubTarget))
+ except ValueError:
+ log.warning("Can't decide mdraid grub upgrade fix, product: %s, version: %s" % (product, version))
+
+ return fixedGrubTarget
+
+def writeBootloader(anaconda):
+ def dosync():
+ isys.sync()
+ isys.sync()
+ isys.sync()
+
+ if anaconda.bootloader.defaultDevice == -1:
+ return
+
+ if anaconda.bootloader.doUpgradeOnly:
+ (bootType, theDev) = checkbootloader.getBootloaderTypeAndBoot(anaconda.rootPath, storage=anaconda.storage)
+
+ anaconda.bootloader.doUpgradeonly = 1
+ if bootType == "GRUB":
+ if theDev.startswith('/dev/md'):
+ theDev = fixedMdraidGrubTarget(anaconda,
+ devicePathToName(theDev))
+ anaconda.bootloader.useGrubVal = 1
+ anaconda.bootloader.setDevice(devicePathToName(theDev))
+ else:
+ anaconda.bootloader.doUpgradeOnly = 0
+
+ w = anaconda.intf.waitWindow(_("Bootloader"), _("Installing bootloader."))
+
+ kernelList = []
+ otherList = []
+ # getDefault needs to return a device, but that's too invasive for now.
+ rootDev = anaconda.storage.rootDevice
+
+ if not anaconda.bootloader.images.getDefault():
+ defaultDev = None
+ else:
+ defaultDev = anaconda.storage.devicetree.getDeviceByName(anaconda.bootloader.images.getDefault())
+
+ kernelLabel = None
+ kernelLongLabel = None
+
+ for (dev, (label, longlabel, type)) in anaconda.bootloader.images.getImages().items():
+ if (rootDev is None and kernelLabel is None) or (dev == rootDev.name):
+ kernelLabel = label
+ kernelLongLabel = longlabel
+ elif (not defaultDev and not dev) or (defaultDev and dev == defaultDev.name):
+ otherList = [(label, longlabel, dev)] + otherList
+ else:
+ otherList.append((label, longlabel, dev))
+
+ if kernelLabel is None:
+ log.error("unable to find default image, bailing")
+ w.pop()
+ return
+
+ plainLabelUsed = 0
+ defkern = "kernel"
+ for (version, arch, nick) in \
+ anaconda.backend.kernelVersionList(anaconda.rootPath):
+ if plainLabelUsed:
+ kernelList.append(("%s-%s" %(kernelLabel, nick),
+ "%s-%s" %(kernelLongLabel, nick),
+ version))
+ else:
+ kernelList.append((kernelLabel, kernelLongLabel, version))
+ if nick != "base":
+ defkern = "kernel-%s" %(nick,)
+ plainLabelUsed = 1
+
+ f = open(anaconda.rootPath + "/etc/sysconfig/kernel", "w+")
+ f.write("# UPDATEDEFAULT specifies if new-kernel-pkg should make\n"
+ "# new kernels the default\n")
+ # only update the default if we're setting the default to linux (#156678)
+ if (not defaultDev and not rootDev) or (defaultDev and rootDev.name == defaultDev.name):
+ f.write("UPDATEDEFAULT=yes\n")
+ else:
+ f.write("UPDATEDEFAULT=no\n")
+ f.write("\n")
+ f.write("# DEFAULTKERNEL specifies the default kernel package type\n")
+ f.write("DEFAULTKERNEL=%s\n" %(defkern,))
+ f.close()
+
+ dosync()
+ try:
+ rc = anaconda.bootloader.write(anaconda.rootPath, anaconda.bootloader,
+ kernelList, otherList, defaultDev)
+ w.pop()
+
+ if rc and anaconda.intf:
+ anaconda.intf.messageWindow(_("Warning"),
+ _("There was an error installing the bootloader. "
+ "The system may not be bootable."))
+ except booty.BootyNoKernelWarning:
+ w.pop()
+ if anaconda.intf:
+ anaconda.intf.messageWindow(_("Warning"),
+ _("No kernel packages were installed on the "
+ "system. Bootloader configuration "
+ "will not be changed."))
+
+ dosync()
+
+def hasWindows(bl):
+ foundWindows = False
+ for (k,v) in bl.images.getImages().iteritems():
+ if v[0].lower() == 'other' and v[2] in bootloaderInfo.dosFilesystems:
+ foundWindows = True
+ break
+
+ return foundWindows