diff -Nur -x '*.orig' -x '*.rej' booty-0.44.4/bootloaderInfo.py mezzanine_patched_booty-0.44.4/bootloaderInfo.py --- booty-0.44.4/bootloaderInfo.py 2006-04-19 14:37:24.000000000 -0600 +++ mezzanine_patched_booty-0.44.4/bootloaderInfo.py 2007-05-17 22:24:05.000000000 -0600 @@ -16,6 +16,7 @@ # import os, sys +import isys import crypt import whrandom import butil @@ -419,6 +420,7 @@ return args args.append("--location=%s" % (self.defaultDevice,)) + args.append("--driveorder=%s" % (",".join(self.drivelist))) if self.args.get(): args.append("--append=\"%s\"" %(self.args.get())) @@ -642,6 +644,28 @@ def setUseGrub(self, val): self.useGrubVal = val + def getPhysicalDevices(self, device): + # This finds a list of devices on which the given device name resides. + # Accepted values for "device" are raid1 md devices (i.e. "md0"), + # physical disks ("hda"), and real partitions on physical disks + # ("hda1"). Volume groups/logical volumes are not accepted. + # + # XXX this has internal anaconda-ish knowledge. ick. + import isys + import lvm + + if string.split(device, '/', 1)[0] in map (lambda vg: vg[0], + lvm.vglist()): + return [] + + if device.startswith('md'): + bootable = 0 + parts = checkbootloader.getRaidDisks(device, 1, stripPart=0) + parts.sort() + return parts + + return [device] + def writeGrub(self, instRoot, fsset, bl, langs, kernelList, chainList, defaultDev, justConfigFile): if len(kernelList) < 1: @@ -663,10 +687,12 @@ instRoot + cf + '.rpmsave') grubTarget = bl.getDevice() - # XXX wouldn't it be nice if grub really understood raid? :) - if grubTarget.startswith('md'): - ent = fsset.getEntryByDeviceName(grubTarget) - grubTarget = ent.device.members[0] + target = "mbr" + if (grubTarget.startswith('rd/') or grubTarget.startswith('ida/') or grubTarget.startswith('cciss/')): + if grubTarget[-2] == 'p' or grubTarget[-3] == 'p': + target = "partition" + elif grubTarget[-1].isdigit() and not grubTarget.startswith('md'): + target = "partition" f = open(instRoot + cf, "w+") @@ -692,9 +718,10 @@ f.write("# all kernel and initrd paths are relative " "to /boot/, eg.\n") - bootDev = bootDev.device.getDevice(asBoot = 1) + bootDevs = self.getPhysicalDevices(bootDev.device.getDevice()) + bootDev = bootDev.device.getDevice() - f.write('# root %s\n' % self.grubbyPartitionName(bootDev)) + f.write('# root %s\n' % self.grubbyPartitionName(bootDevs[0])) f.write("# kernel %svmlinuz-version ro " "root=/dev/%s\n" % (cfPath, rootDev)) f.write("# initrd %sinitrd-version.img\n" % (cfPath)) @@ -741,11 +768,11 @@ # we only want splashimage if they're not using a serial console if os.access("%s/boot/grub/splash.xpm.gz" %(instRoot,), os.R_OK): f.write('splashimage=%s%sgrub/splash.xpm.gz\n' - % (self.grubbyPartitionName(bootDev), cfPath)) + % (self.grubbyPartitionName(bootDevs[0]), cfPath)) f.write("hiddenmenu\n") - usedDevs[bootDev] = 1 - usedDevs[grubTarget] = 1 + for dev in self.getPhysicalDevices(grubTarget): + usedDevs[dev] = 1 if self.password: f.write('password --md5 %s\n' %(self.password)) @@ -757,7 +784,7 @@ initrd = booty.makeInitrd (kernelTag, instRoot) f.write('title %s (%s)\n' % (longlabel, version)) - f.write('\troot %s\n' % self.grubbyPartitionName(bootDev)) + f.write('\troot %s\n' % self.grubbyPartitionName(bootDevs[0])) realroot = getRootDevName(initrd, fsset, rootDev, instRoot) realroot = " root=%s" %(realroot,) @@ -801,21 +828,31 @@ except: pass + for dev in self.getPhysicalDevices(rootDev): + usedDevs[dev] = 1 + + for dev in bootDevs: + usedDevs[dev] = 1 if not os.access(instRoot + "/boot/grub/device.map", os.R_OK): f = open(instRoot + "/boot/grub/device.map", "w+") f.write("# this device map was generated by anaconda\n") f.write("(fd0) /dev/fd0\n") devs = usedDevs.keys() - devs.sort() usedDevs = {} for dev in devs: drive = getDiskPart(dev)[0] if usedDevs.has_key(drive): continue - f.write("(%s) /dev/%s\n" % (self.grubbyDiskName(drive), - drive)) usedDevs[drive] = 1 + devs = usedDevs.keys() + devs.sort() + for drive in devs: + # XXX hack city. If they're not the sort of thing that'll + # be in the device map, they shouldn't still be in the list. + if not drive.startswith('md'): + f.write("(%s) /dev/%s\n" % (self.grubbyDiskName(drive), + drive)) f.close() args = "--stage2=/boot/grub/stage2 " @@ -840,14 +877,22 @@ f.write("forcelba=0\n") f.close() - part = self.grubbyPartitionName(bootDev) - prefix = "%s/%s" % (self.grubbyPartitionName(bootDev), grubPath) - cmd = "root %s\ninstall %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" % \ - (part, args, grubPath, self.grubbyPartitionName(grubTarget), - grubPath, part, grubPath) + cmds = [] + for bootDev in bootDevs: + gtDisk = self.grubbyPartitionName(getDiskPart(bootDev)[0]) + bPart = self.grubbyPartitionName(bootDev) + + stage1Target = gtDisk + if target == "partition": + stage1Target = self.grubbyPartitionName(bootDev) + + cmd = "root %s\nsetup %s" % (bPart, stage1Target) + cmds.append(cmd) if not justConfigFile: - log("GRUB command %s", cmd) + log("GRUB commands:") + for cmd in cmds: + log("\t%s\n", cmd) # copy the stage files over into /boot rhpl.executil.execWithRedirect( "/sbin/grub-install", @@ -865,7 +910,8 @@ # really install the bootloader p = os.pipe() - os.write(p[1], cmd + '\n') + for cmd in cmds: + os.write(p[1], cmd + '\n') os.close(p[1]) rhpl.executil.execWithRedirect('/sbin/grub' , [ "grub", "--batch", "--no-floppy", @@ -1044,41 +1090,64 @@ bootDev = fsset.getEntryByMountPoint("/") grubPath = "/boot/grub" cfPath = "/boot/" - bootDev = bootDev.device.getDevice(asBoot = 1) - part = self.grubbyPartitionName(bootDev) - prefix = "%s/%s" % (self.grubbyPartitionName(bootDev), grubPath) - args = "--stage2=/boot/grub/stage2 " - cmd = "root %s\ninstall %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" % \ - (part, args, grubPath, self.grubbyPartitionName(theDev[5:]), - grubPath, part, grubPath) - - if not justConfigFile: - log("GRUB command %s", cmd) + masterBootDev = bootDev.device.getDevice(asBoot = 0) + if masterBootDev[0:2] == 'md': + rootDevs = checkbootloader.getRaidDisks(masterBootDev, raidLevel=1, + stripPart = 0) + else: + rootDevs = [masterBootDev] - # copy the stage files over into /boot - rhpl.executil.execWithRedirect( "/sbin/grub-install", + if theDev[5:7] == 'md': + stage1Devs = checkbootloader.getRaidDisks(theDev[5:], raidLevel=1) + else: + stage1Devs = [theDev[5:]] + + for stage1Dev in stage1Devs: + # cross fingers; if we can't find a root device on the same + # hardware as this boot device, we just blindly hope the first + # thing in the list works. + + grubbyStage1Dev = self.grubbyPartitionName(stage1Dev) + + grubbyRootPart = self.grubbyPartitionName(rootDevs[0]) + + for rootDev in rootDevs: + testGrubbyRootDev = getDiskPart(rootDev)[0] + testGrubbyRootDev = self.grubbyPartitionName(testGrubbyRootDev) + + if grubbyStage1Dev == testGrubbyRootDev: + grubbyRootPart = self.grubbyPartitionName(rootDev) + break + + cmd = "root %s\nsetup %s" % (grubbyRootPart, grubbyStage1Dev) + + if not justConfigFile: + log("GRUB command %s", cmd) + + # copy the stage files over into /boot + rhpl.executil.execWithRedirect( "/sbin/grub-install", ["/sbin/grub-install", "--just-copy"], stdout = "/dev/tty5", stderr = "/dev/tty5", root = instRoot) - # get the stage files synced to disk - import isys - isys.sync() - isys.sync() - isys.sync() + # get the stage files synced to disk + import isys + isys.sync() + isys.sync() + isys.sync() - # really install the bootloader - p = os.pipe() - os.write(p[1], cmd + '\n') - os.close(p[1]) - rhpl.executil.execWithRedirect('/sbin/grub' , + # really install the bootloader + p = os.pipe() + os.write(p[1], cmd + '\n') + os.close(p[1]) + rhpl.executil.execWithRedirect('/sbin/grub' , [ "grub", "--batch", "--no-floppy", "--device-map=/boot/grub/device.map" ], stdin = p[0], stdout = "/dev/tty5", stderr = "/dev/tty5", root = instRoot) - os.close(p[0]) + os.close(p[0]) return "" diff -Nur -x '*.orig' -x '*.rej' booty-0.44.4/checkbootloader.py mezzanine_patched_booty-0.44.4/checkbootloader.py --- booty-0.44.4/checkbootloader.py 2003-03-04 17:11:48.000000000 -0700 +++ mezzanine_patched_booty-0.44.4/checkbootloader.py 2007-05-17 22:23:10.000000000 -0600 @@ -56,8 +56,13 @@ return (name, partNum) -def getRaidDisks(raidDevice): +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") @@ -69,14 +74,19 @@ 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 - disk = getDiskPart(dev)[0] - rc.append(disk) + if stripPart: + disk = getDiskPart(dev)[0] + rc.append(disk) + else: + rc.append(dev) return rc