summaryrefslogtreecommitdiffstats
path: root/booty/checkbootloader.py
diff options
context:
space:
mode:
authorChris Lumens <clumens@redhat.com>2009-02-18 14:16:04 -0500
committerChris Lumens <clumens@redhat.com>2009-03-04 15:37:03 -0500
commit9276f6795674a776f29ccbaa4ebb0ed2b5b2e25f (patch)
tree1ab506a889a7c1c565d7bec43ff6ccba97460ecf /booty/checkbootloader.py
parentf6ccb426af374f745efe53cfbb1df1175e550de7 (diff)
downloadanaconda-9276f6795674a776f29ccbaa4ebb0ed2b5b2e25f.tar.gz
anaconda-9276f6795674a776f29ccbaa4ebb0ed2b5b2e25f.tar.xz
anaconda-9276f6795674a776f29ccbaa4ebb0ed2b5b2e25f.zip
Add the existing booty back into anaconda.
Welcome back, booty. We missed you.
Diffstat (limited to 'booty/checkbootloader.py')
-rw-r--r--booty/checkbootloader.py270
1 files changed, 270 insertions, 0 deletions
diff --git a/booty/checkbootloader.py b/booty/checkbootloader.py
new file mode 100644
index 000000000..38cb8255d
--- /dev/null
+++ b/booty/checkbootloader.py
@@ -0,0 +1,270 @@
+#!/usr/bin/python
+#
+# Check to see whether it looks like GRUB or LILO is the boot loader
+# being used on the system.
+#
+# Jeremy Katz <katzj@redhat.com>
+# Peter Jones <pjones@redhat.com>
+#
+# Copyright 2001,2005 Red Hat, Inc.
+#
+# This software may be freely redistributed under the terms of the GNU
+# library public license.
+#
+# You should have received a copy of the GNU Library Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+import os
+import string
+import rhpl
+
+grubConfigFile = "/etc/grub.conf"
+liloConfigFile = "/etc/lilo.conf"
+yabootConfigFile = "/etc/yaboot.conf"
+siloConfigFile = "/etc/silo.conf"
+
+
+# XXX: this is cut and pasted directly from booty/bootloaderInfo.py
+# should eventually just go from there
+def getDiskPart(dev):
+ """Return (disk, partition number) tuple for dev"""
+ cut = len(dev)
+ if (dev[:3] == "rd/" or dev[:4] == "ida/" or
+ dev[:6] == "cciss/"):
+ if dev[-2] == 'p':
+ cut = -1
+ elif dev[-3] == 'p':
+ cut = -2
+ else:
+ if dev[-2] in string.digits:
+ cut = -2
+ elif dev[-1] in string.digits:
+ cut = -1
+
+ name = dev[:cut]
+
+ # hack off the trailing 'p' from /dev/cciss/*, for example
+ if name[-1] == 'p':
+ for letter in name:
+ if letter not in string.letters and letter != "/":
+ name = name[:-1]
+ break
+
+ if cut < 0:
+ partNum = int(dev[cut:]) - 1
+ else:
+ partNum = None
+
+ return (name, partNum)
+
+
+def getRaidDisks(raidDevice, raidLevel=None, stripPart=1):
+ rc = []
+ if raidLevel is not None:
+ try:
+ raidLevel = "raid%d" % (int(raidLevel),)
+ except ValueError:
+ pass
+
+ try:
+ f = open("/proc/mdstat", "r")
+ lines = f.readlines()
+ f.close()
+ except:
+ return rc
+
+ for line in lines:
+ fields = string.split(line, ' ')
+ if fields[0] == raidDevice:
+ if raidLevel is not None and fields[3] != raidLevel:
+ continue
+ for field in fields[4:]:
+ if string.find(field, "[") == -1:
+ continue
+ dev = string.split(field, '[')[0]
+ if len(dev) == 0:
+ continue
+ if stripPart:
+ disk = getDiskPart(dev)[0]
+ rc.append(disk)
+ else:
+ rc.append(dev)
+
+ return rc
+
+
+def getBootBlock(bootDev, instRoot, seekBlocks=0):
+ """Get the boot block from bootDev. Return a 512 byte string."""
+ block = " " * 512
+ if bootDev is None:
+ return block
+
+ # get the devices in the raid device
+ if bootDev[5:7] == "md":
+ bootDevs = getRaidDisks(bootDev[5:])
+ bootDevs.sort()
+ else:
+ bootDevs = [ bootDev[5:] ]
+
+ # FIXME: this is kind of a hack
+ # look at all of the devs in the raid device until we can read the
+ # boot block for one of them. should do this better at some point
+ # by looking at all of the drives properly
+ for dev in bootDevs:
+ try:
+ fd = os.open("%s/dev/%s" % (instRoot, dev), os.O_RDONLY)
+ if seekBlocks > 0:
+ os.lseek(fd, seekBlocks * 512, 0)
+ block = os.read(fd, 512)
+ os.close(fd)
+ return block
+ except:
+ pass
+ return block
+
+# takes a line like #boot=/dev/hda and returns /dev/hda
+# also handles cases like quoted versions and other nonsense
+def getBootDevString(line):
+ dev = string.split(line, '=')[1]
+ dev = string.strip(dev)
+ dev = string.replace(dev, '"', '')
+ dev = string.replace(dev, "'", "")
+ return dev
+
+def getBootDevList(line):
+ devs = string.split(line, '=')[1]
+ rets = []
+ for dev in devs:
+ dev = getBootDevString("=%s" % (dev,))
+ rets.append(dev)
+ return string.join(rets)
+
+efi = None
+## Determine if the hardware supports EFI.
+# @return True if so, False otherwise.
+def isEfi():
+ global efi
+ if efi is not None:
+ return efi
+
+ efi = False
+ if rhpl.getArch() in ("ia64", "i386", "x86_64"):
+ # XXX need to make sure efivars is loaded...
+ if os.path.exists("/sys/firmware/efi"):
+ efi = True
+
+ return efi
+
+def getBootloaderTypeAndBoot(instRoot = "/"):
+ haveGrubConf = 1
+ haveLiloConf = 1
+ haveYabootConf = 1
+ haveSiloConf = 1
+
+ bootDev = None
+
+ # make sure they have the config file, otherwise we definitely can't
+ # use that bootloader
+ if not os.access(instRoot + grubConfigFile, os.R_OK):
+ haveGrubConf = 0
+ if not os.access(instRoot + liloConfigFile, os.R_OK):
+ haveLiloConf = 0
+ if not os.access(instRoot + yabootConfigFile, os.R_OK):
+ haveYabootConf = 0
+ if not os.access(instRoot + siloConfigFile, os.R_OK):
+ haveSiloConf = 0
+
+ if haveGrubConf:
+ bootDev = None
+ for (fn, stanza) in [ ("/etc/sysconfig/grub", "boot="),
+ (grubConfigFile, "#boot=") ]:
+ try:
+ f = open(instRoot + fn, "r")
+ except:
+ continue
+
+ # the following bits of code are straight from checkbootloader.py
+ lines = f.readlines()
+ f.close()
+ for line in lines:
+ if line.startswith(stanza):
+ bootDev = getBootDevString(line)
+ break
+ if bootDev is not None:
+ break
+
+ if isEfi():
+ return ("GRUB", bootDev)
+
+ if bootDev is not None:
+ block = getBootBlock(bootDev, instRoot)
+ # XXX I don't like this, but it's what the maintainer suggested :(
+ if string.find(block, "GRUB") >= 0:
+ return ("GRUB", bootDev)
+
+ if haveLiloConf:
+ f = open(instRoot + liloConfigFile, "r")
+ lines = f.readlines()
+ for line in lines:
+ if line[0:5] == "boot=":
+ bootDev = getBootDevString(line)
+ break
+
+ block = getBootBlock(bootDev, instRoot)
+ # this at least is well-defined
+ if block[6:10] == "LILO":
+ return ("LILO", bootDev)
+
+ if haveYabootConf:
+ f = open(instRoot + yabootConfigFile, "r")
+ lines = f.readlines()
+ for line in lines:
+ if line[0:5] == "boot=":
+ bootDev = getBootDevList(line)
+
+ if bootDev:
+ return ("YABOOT", bootDev)
+
+ if haveSiloConf:
+ bootDev = None
+ # We've never done the /etc/sysconfig/silo thing, but maybe
+ # we should start...
+ for (fn, stanza) in [ ("/etc/sysconfig/silo", "boot="),
+ (grubConfigFile, "#boot=") ]:
+ try:
+ f = open(instRoot + fn, "r")
+ except:
+ continue
+
+ lines = f.readlines()
+ f.close()
+ for line in lines:
+ if line.startswith(stanza):
+ bootDev = getBootDevString(line)
+ break
+ if bootDev is not None:
+ break
+
+ if bootDev is not None:
+ # XXX SILO sucks just like grub.
+ if getDiskPart(bootDev)[1] != 3:
+ block = getBootBlock(bootDev, instRoot, 1)
+ if block[24:28] == "SILO":
+ return ("SILO", bootDev)
+
+ return (None, None)
+
+def whichBootLoader(instRoot = "/"):
+ ret = getBootloaderTypeAndBoot(instRoot)
+ if not ret:
+ return None
+ else:
+ return ret[0]
+
+if __name__ == "__main__":
+ bootloader = whichBootLoader()
+ if bootloader:
+ print "Found %s." % (bootloader)
+ else:
+ print "Unable to determine boot loader."