def getScreen(self, anaconda): self.dispatch = anaconda.dispatch self.bl = anaconda.bootloader self.intf = anaconda.intf self.driveorder = self.bl.drivelist if len(self.driveorder) == 0: partitioned = anaconda.storage.partitioned disks = anaconda.storage.disks self.driveorder = [d.name for d in disks if d in partitioned] if self.bl.getPassword(): self.usePass = 1 self.password = self.bl.getPassword() else: self.usePass = 0 self.password = None thebox = gtk.VBox (False, 12) thebox.set_border_width(18) # make sure we get a valid device to say we're installing to if self.bl.getDevice() is not None: self.bldev = self.bl.getDevice() else: # we don't know what it is yet... if mbr is possible, we want # it, else we want the boot dev choices = anaconda.platform.bootloaderChoices(self.bl) if choices.has_key('mbr'): self.bldev = choices['mbr'][0] else: self.bldev = choices['boot'][0] hb = gtk.HBox(False, 12) self.grubCB = gtk.CheckButton(_("_Install boot loader on /dev/%s.") % (self.bldev,)) self.grubCB.set_active(not self.dispatch.stepInSkipList("instbootloader")) self.grubCB.connect("toggled", self.bootloaderChanged) hb.pack_start(self.grubCB, False) # no "Change device" button on EFI systems, since there should only # be one EFI System Partition available/usable self.deviceButton = None if not iutil.isEfi(): self.deviceButton = gtk.Button(_("_Change device")) self.deviceButton.connect("clicked", self._deviceChange, anaconda) hb.pack_start(self.deviceButton, False) thebox.pack_start(hb, False) # control whether or not there's a boot loader password and what it is self.blpass = BootloaderPasswordWidget(anaconda, self.parent) thebox.pack_start(self.blpass.getWidget(), False) # configure the systems available to boot from the boot loader self.oslist = OSBootWidget(anaconda, self.parent) thebox.pack_end(self.oslist.getWidget(), True) self.bootloaderChanged() return thebox
def writeGrub(self, instRoot, bl, kernelList, chainList, defaultDev, upgrade=False): rootDev = self.storage.rootDevice grubTarget = bl.getDevice() try: bootDev = self.storage.mountpoints["/boot"] grubPath = "/grub" cfPath = "/" except KeyError: bootDev = rootDev grubPath = "/boot/grub" cfPath = "/boot/" if not upgrade and not iutil.isEfi(): self.writeGrubConf(instRoot, bootDev, rootDev, defaultDev, kernelList, chainList, grubTarget, grubPath, cfPath) # keep track of which devices are used for the device.map usedDevs = set() usedDevs.update( self.getPhysicalDevices( self.storage.devicetree.getDeviceByName(grubTarget))) usedDevs.update(self.getPhysicalDevices(bootDev)) usedDevs.update([ self.storage.devicetree.getDeviceByName(dev) for (label, longlabel, dev) in chainList if longlabel ]) if not upgrade: self.writeDeviceMap(instRoot, usedDevs, upgrade) self.writeSysconfig(instRoot, grubTarget, upgrade) ret = self.installGrub(instRoot, bootDev, grubTarget, grubPath, cfPath) if iutil.isEfi(): self.writeGrubConf(instRoot, bootDev, rootDev, defaultDev, kernelList, chainList, grubTarget, grubPath, cfPath) return ret
def writeGrub(self, instRoot, bl, kernelList, chainList, defaultDev, upgrade=False): rootDev = self.storage.rootDevice grubTarget = bl.getDevice() try: bootDev = self.storage.mountpoints["/boot"] grubPath = "/grub" cfPath = "/" except KeyError: bootDev = rootDev grubPath = "/boot/grub" cfPath = "/boot/" if not upgrade and not iutil.isEfi(): self.writeGrubConf(instRoot, bootDev, rootDev, defaultDev, kernelList, chainList, grubTarget, grubPath, cfPath) # keep track of which devices are used for the device.map usedDevs = set() usedDevs.update(self.getPhysicalDevices( self.storage.devicetree.getDeviceByName(grubTarget))) usedDevs.update(self.getPhysicalDevices(bootDev)) usedDevs.update([self.storage.devicetree.getDeviceByName(dev) for (label, longlabel, dev) in chainList if longlabel]) if not upgrade: self.writeDeviceMap(instRoot, usedDevs, upgrade) self.writeSysconfig(instRoot, grubTarget, upgrade) ret = self.installGrub(instRoot, bootDev, grubTarget, grubPath, cfPath) if iutil.isEfi(): self.writeGrubConf(instRoot, bootDev, rootDev, defaultDev, kernelList, chainList, grubTarget, grubPath, cfPath) return ret
def getScreen(self, anaconda): self.dispatch = anaconda.dispatch self.bl = anaconda.bootloader self.intf = anaconda.intf self.driveorder = [d.name for d in self.bl.drives] thebox = gtk.VBox (False, 12) thebox.set_border_width(18) # make sure we get a valid device to say we're installing to self.bldev = self.bl.stage1_device hb = gtk.HBox(False, 12) self.grubCB = gtk.CheckButton(_("_Install boot loader on %s.") % (self.bldev.path,)) self.grubCB.set_active(self.dispatch.step_enabled("instbootloader")) self.grubCB.connect("toggled", self.bootloaderChanged) hb.pack_start(self.grubCB, False) # no "Change device" button on EFI systems, since there should only # be one EFI System Partition available/usable self.deviceButton = None if not iutil.isEfi(): self.deviceButton = gtk.Button(_("_Change device")) self.deviceButton.connect("clicked", self._deviceChange, anaconda) hb.pack_start(self.deviceButton, False) thebox.pack_start(hb, False) # control whether or not there's a boot loader password and what it is self.blpass = BootloaderPasswordWidget(anaconda, self.parent) thebox.pack_start(self.blpass.getWidget(), False) # configure the systems available to boot from the boot loader self.oslist = OSBootWidget(anaconda, self.parent) if not self.bl.name == "GRUB2": # with grub2 we use os-prober to generate menu entries for all # other OS it finds without user interaction thebox.pack_end(self.oslist.getWidget(), True) self.bootloaderChanged() return thebox
def writeGrubConf(self, instRoot, bootDev, rootDev, defaultDev, kernelList, chainList, grubTarget, grubPath, cfPath): bootDevs = self.getPhysicalDevices(bootDev) # XXX old config file should be read here for upgrade cf = "%s%s" % (instRoot, self.configfile) self.perms = 0600 if os.access(cf, os.R_OK): self.perms = os.stat(cf)[0] & 0777 os.rename(cf, cf + '.rpmsave') f = open(cf, "w+") f.write("# grub.conf generated by anaconda\n") f.write("#\n") f.write("# Note that you do not have to rerun grub " "after making changes to this file\n") if grubPath == "/grub": f.write("# NOTICE: You have a /boot partition. This means " "that\n") f.write("# all kernel and initrd paths are relative " "to /boot/, eg.\n") else: f.write("# NOTICE: You do not have a /boot partition. " "This means that\n") f.write("# all kernel and initrd paths are relative " "to /, eg.\n") f.write('# root %s\n' % self.grubbyPartitionName(bootDevs[0])) f.write("# kernel %svmlinuz-version ro root=%s\n" % (cfPath, rootDev.path)) f.write("# initrd %sinitrd-[generic-]version.img\n" % (cfPath)) f.write("#boot=/dev/%s\n" % (grubTarget)) if iutil.isEfi(): from pyanaconda.product import productName # Map the target device to the full EFI path if self.getEfiProductPath(productName): (n, pn) = getDiskPart(bootDevs[0]) f.write("device (%s) %s\n" % (self.grubbyDiskName(n), self.getEfiProductPath(productName))) # get the default image to boot... we have to walk and find it # since grub indexes by where it is in the config file if defaultDev.name == rootDev.name: default = 0 else: # if the default isn't linux, it's the first thing in the # chain list default = len(kernelList) f.write('default=%s\n' % (default)) if self.serial == 1: # Set the global timeout in serial case f.write('timeout=%d\n' % (self.timeout or 5)) # grub the 0-based number of the serial console device unit = self.serialDevice[-1] # and we want to set the speed too speedend = 0 for char in self.serialOptions: if char not in string.digits: break speedend = speedend + 1 if speedend != 0: speed = self.serialOptions[:speedend] else: # reasonable default speed = "9600" f.write("serial --unit=%s --speed=%s\n" % (unit, speed)) f.write("terminal --timeout=%s serial console\n" % (self.timeout or 5)) else: # Default to 0 timeout in the non-serial case f.write('timeout=%d\n' % (self.timeout or 0)) # 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(bootDevs[0]), cfPath)) f.write("hiddenmenu\n") if self.password: f.write('password --encrypted %s\n' % (self.password)) for (label, longlabel, version) in kernelList: kernelTag = "-" + version kernelFile = "%svmlinuz%s" % (cfPath, kernelTag) initrd = self.makeInitrd(kernelTag, instRoot) f.write('title %s (%s)\n' % (longlabel, version)) f.write('\troot %s\n' % self.grubbyPartitionName(bootDevs[0])) realroot = " root=%s" % rootDev.fstabSpec if version.endswith("xen0") or (version.endswith("xen") and not os.path.exists("/proc/xen")): # hypervisor case sermap = { "ttyS0": "com1", "ttyS1": "com2", "ttyS2": "com3", "ttyS3": "com4" } if self.serial and sermap.has_key(self.serialDevice) and \ self.serialOptions: hvs = "%s=%s" % (sermap[self.serialDevice], self.serialOptions) else: hvs = "" if version.endswith("xen0"): hvFile = "%sxen.gz-%s %s" % ( cfPath, version.replace("xen0", ""), hvs) else: hvFile = "%sxen.gz-%s %s" % ( cfPath, version.replace("xen", ""), hvs) f.write('\tkernel %s\n' % (hvFile, )) f.write('\tmodule %s ro%s' % (kernelFile, realroot)) if self.args.get(): f.write(' %s' % self.args.get()) f.write('\n') if initrd: f.write('\tmodule %s%s\n' % (cfPath, initrd)) else: # normal kernel f.write('\tkernel %s ro%s' % (kernelFile, realroot)) if self.args.get(): f.write(' %s' % self.args.get()) f.write('\n') if initrd: f.write('\tinitrd %s%s\n' % (cfPath, initrd)) for (label, longlabel, device) in chainList: if ((not longlabel) or (longlabel == "")): continue f.write('title %s\n' % (longlabel)) f.write('\trootnoverify %s\n' % self.grubbyPartitionName( self.storage.devicetree.getDeviceByName(device))) # f.write('\tmakeactive\n') f.write('\tchainloader +1') f.write('\n') f.close() if not "/efi/" in cf: os.chmod(cf, self.perms) try: # make symlink for menu.lst (default config file name) menulst = "%s%s/menu.lst" % (instRoot, self.configdir) if os.access(menulst, os.R_OK): os.rename(menulst, menulst + ".rpmsave") os.symlink("./grub.conf", menulst) except: pass try: # make symlink for /etc/grub.conf (config files belong in /etc) etcgrub = "%s%s" % (instRoot, "/etc/grub.conf") if os.access(etcgrub, os.R_OK): os.rename(etcgrub, etcgrub + ".rpmsave") os.symlink(".." + self.configfile, etcgrub) except: pass
def installGrub(self, instRoot, bootDev, grubTarget, grubPath, cfPath): if iutil.isEfi(): return efiBootloaderInfo.installGrub(self, instRoot, bootDev, grubTarget, grubPath, cfPath) args = "--stage2=/boot/grub/stage2 " stage1Devs = self.getPhysicalDevices( self.storage.devicetree.getDeviceByName(grubTarget)) bootDevs = self.getPhysicalDevices(bootDev) installs = [(None, self.grubbyPartitionName(stage1Devs[0]), self.grubbyPartitionName(bootDevs[0]))] if bootDev.type == "mdarray": matches = self.matchingBootTargets(stage1Devs, bootDevs) # If the stage1 target disk contains member of boot raid array (mbr # case) or stage1 target partition is member of boot raid array # (partition case) if matches: # 1) install stage1 on target disk/partiton stage1Dev, mdMemberBootPart = matches[0] installs = [(None, self.grubbyPartitionName(stage1Dev), self.grubbyPartitionName(mdMemberBootPart))] firstMdMemberDiskGrubbyName = self.grubbyDiskName( getDiskPart(mdMemberBootPart)[0]) # 2) and install stage1 on other members' disks/partitions too # NOTES: # - the goal is to be able to boot after a members' disk removal # - so we have to use grub device names as if after removal # (i.e. the same disk name (e.g. (hd0)) for both member disks) # - if member partitions have different numbers only removal of # specific one of members will work because stage2 containing # reference to config file is shared and therefore can contain # only one value # if target is mbr, we want to install also to mbr of other # members, so extend the matching list matches = self.addMemberMbrs(matches, bootDevs) for stage1Target, mdMemberBootPart in matches[1:]: # prepare special device mapping corresponding to member removal mdMemberBootDisk = getDiskPart(mdMemberBootPart)[0] # It can happen due to ks --driveorder option, but is it ok? if not mdMemberBootDisk.name in self.drivelist: continue mdRaidDeviceRemap = (firstMdMemberDiskGrubbyName, mdMemberBootDisk.name) stage1TargetGrubbyName = self.grubbyPartitionName( stage1Target) rootPartGrubbyName = self.grubbyPartitionName( mdMemberBootPart) # now replace grub disk name part according to special device # mapping old = self.grubbyDiskName(mdMemberBootDisk).strip('() ') new = firstMdMemberDiskGrubbyName.strip('() ') rootPartGrubbyName = rootPartGrubbyName.replace(old, new) stage1TargetGrubbyName = stage1TargetGrubbyName.replace( old, new) installs.append((mdRaidDeviceRemap, stage1TargetGrubbyName, rootPartGrubbyName)) # This is needed for case when /boot member partitions have # different numbers. Shared stage2 can contain only one reference # to grub.conf file, so let's ensure that it is reference to partition # on disk which we will boot from - that is, install grub to # this disk as last so that its reference is not overwritten. installs.reverse() cmds = [] for mdRaidDeviceRemap, stage1Target, rootPart in installs: if mdRaidDeviceRemap: cmd = "device (%s) /dev/%s\n" % tuple(mdRaidDeviceRemap) else: cmd = '' cmd += "root %s\n" % (rootPart, ) cmd += "install %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" % \ (args, grubPath, stage1Target, grubPath, rootPart, grubPath) cmds.append(cmd) return self.runGrubInstall(instRoot, bootDev.name, cmds, cfPath)
def getBootloaderTypeAndBoot(instRoot, storage): 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 iutil.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. dev = storage.devicetree.getDeviceByName(bootDev) if getDiskPart(dev)[1] != 4: block = getBootBlock(bootDev, instRoot, 1) if block[24:28] == "SILO": return ("SILO", bootDev) return (None, None)
def mountptchangeCB(widget, fstypecombo): if iutil.isEfi() and widget.get_children()[0].get_text() == "/boot/efi": fstypecombo.set_active_text(getFormat("efi").name)
def createAlignedLabel(text): label = gtk.Label(text) label.set_alignment(0.0, 0.5) label.set_property("use-underline", True) return label defaultMountPoints = ['/', '/boot', '/home', '/tmp', '/var', '/usr/local', '/opt'] if iutil.isS390(): # Many s390 have 2G DASDs, we recomment putting /usr/share on its own DASD defaultMountPoints.insert(5, '/usr/share') if iutil.isEfi(): defaultMountPoints.insert(2, '/boot/efi') def createMountPointCombo(request, excludeMountPoints=[]): mountCombo = gtk.combo_box_entry_new_text() mntptlist = [] label = getattr(request.format, "label", None) if request.exists and label and label.startswith("/"): mntptlist.append(label) idx = 0 for p in defaultMountPoints: if p in excludeMountPoints: continue
def getBootloaderTypeAndBoot(instRoot, storage): 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 iutil.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. dev = storage.devicetree.getDeviceByName(bootDev) if getDiskPart(dev)[1] != 4: block = getBootBlock(bootDev, instRoot, 1) if block[24:28] == "SILO": return ("SILO", bootDev) return (None, None)
def mountptchangeCB(widget, fstypecombo): if iutil.isEfi() and widget.get_children()[0].get_text() == "/boot/efi": fstypecombo.set_active_text(getFormat("efi").name) if widget.get_children()[0].get_text() == "/boot": fstypecombo.set_active_text(get_default_filesystem_type(boot=True))
label = gtk.Label(text) label.set_alignment(0.0, 0.5) label.set_property("use-underline", True) return label defaultMountPoints = [ '/', '/boot', '/home', '/tmp', '/var', '/usr/local', '/opt' ] if iutil.isS390(): # Many s390 have 2G DASDs, we recomment putting /usr/share on its own DASD defaultMountPoints.insert(5, '/usr/share') if iutil.isEfi(): defaultMountPoints.insert(2, '/boot/efi') def createMountPointCombo(request, excludeMountPoints=[]): mountCombo = gtk.combo_box_entry_new_text() mntptlist = [] label = getattr(request.format, "label", None) if request.exists and label and label.startswith("/"): mntptlist.append(label) idx = 0 for p in defaultMountPoints: if p in excludeMountPoints: continue
def getScreen(self, anaconda): self.dispatch = anaconda.dispatch self.bl = anaconda.bootloader self.intf = anaconda.intf self.driveorder = self.bl.drivelist if len(self.driveorder) == 0: partitioned = anaconda.storage.partitioned disks = anaconda.storage.disks self.driveorder = [d.name for d in disks if d in partitioned] if self.bl.getPassword(): self.usePass = 1 self.password = self.bl.getPassword() else: self.usePass = 0 self.password = None thebox = gtk.VBox(False, 12) thebox.set_border_width(18) # make sure we get a valid device to say we're installing to if self.bl.getDevice() is not None: self.bldev = self.bl.getDevice() else: # we don't know what it is yet... if mbr is possible, we want # it, else we want the boot dev choices = anaconda.platform.bootloaderChoices(self.bl) if choices.has_key('mbr'): self.bldev = choices['mbr'][0] else: self.bldev = choices['boot'][0] hb = gtk.HBox(False, 12) self.grubCB = gtk.CheckButton( _("_Install boot loader on /dev/%s.") % (self.bldev, )) self.grubCB.set_active( not self.dispatch.stepInSkipList("instbootloader")) self.grubCB.connect("toggled", self.bootloaderChanged) hb.pack_start(self.grubCB, False) # no "Change device" button on EFI systems, since there should only # be one EFI System Partition available/usable self.deviceButton = None if not iutil.isEfi(): self.deviceButton = gtk.Button(_("_Change device")) self.deviceButton.connect("clicked", self._deviceChange, anaconda) hb.pack_start(self.deviceButton, False) thebox.pack_start(hb, False) # control whether or not there's a boot loader password and what it is self.blpass = BootloaderPasswordWidget(anaconda, self.parent) thebox.pack_start(self.blpass.getWidget(), False) # configure the systems available to boot from the boot loader self.oslist = OSBootWidget(anaconda, self.parent) thebox.pack_end(self.oslist.getWidget(), True) self.bootloaderChanged() return thebox
def writeGrubConf(self, instRoot, bootDev, rootDev, defaultDev, kernelList, chainList, grubTarget, grubPath, cfPath): bootDevs = self.getPhysicalDevices(bootDev) # XXX old config file should be read here for upgrade cf = "%s%s" % (instRoot, self.configfile) self.perms = 0600 if os.access (cf, os.R_OK): self.perms = os.stat(cf)[0] & 0777 os.rename(cf, cf + '.rpmsave') f = open(cf, "w+") f.write("# grub.conf generated by anaconda\n") f.write("#\n") f.write("# Note that you do not have to rerun grub " "after making changes to this file\n") if grubPath == "/grub": f.write("# NOTICE: You have a /boot partition. This means " "that\n") f.write("# all kernel and initrd paths are relative " "to /boot/, eg.\n") else: f.write("# NOTICE: You do not have a /boot partition. " "This means that\n") f.write("# all kernel and initrd paths are relative " "to /, eg.\n") f.write('# root %s\n' % self.grubbyPartitionName(bootDevs[0])) f.write("# kernel %svmlinuz-version ro root=%s\n" % (cfPath, rootDev.path)) f.write("# initrd %sinitrd-[generic-]version.img\n" % (cfPath)) f.write("#boot=/dev/%s\n" % (grubTarget)) if iutil.isEfi(): from pyanaconda.product import productName # Map the target device to the full EFI path if self.getEfiProductPath(productName): (n, pn) = getDiskPart(bootDevs[0]) f.write("device (%s) %s\n" % (self.grubbyDiskName(n), self.getEfiProductPath(productName))) # get the default image to boot... we have to walk and find it # since grub indexes by where it is in the config file if defaultDev.name == rootDev.name: default = 0 else: # if the default isn't linux, it's the first thing in the # chain list default = len(kernelList) f.write('default=%s\n' % (default)) if self.serial == 1: # Set the global timeout in serial case f.write('timeout=%d\n' % (self.timeout or 5)) # grub the 0-based number of the serial console device unit = self.serialDevice[-1] # and we want to set the speed too speedend = 0 for char in self.serialOptions: if char not in string.digits: break speedend = speedend + 1 if speedend != 0: speed = self.serialOptions[:speedend] else: # reasonable default speed = "9600" f.write("serial --unit=%s --speed=%s\n" %(unit, speed)) f.write("terminal --timeout=%s serial console\n" % (self.timeout or 5)) else: # Default to 0 timeout in the non-serial case f.write('timeout=%d\n' % (self.timeout or 0)) # 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(bootDevs[0]), cfPath)) f.write("hiddenmenu\n") if self.password: f.write('password --encrypted %s\n' %(self.password)) for (label, longlabel, version) in kernelList: kernelTag = "-" + version kernelFile = "%svmlinuz%s" % (cfPath, kernelTag) initrd = self.makeInitrd(kernelTag, instRoot) f.write('title %s (%s)\n' % (longlabel, version)) f.write('\troot %s\n' % self.grubbyPartitionName(bootDevs[0])) realroot = " root=%s" % rootDev.fstabSpec if version.endswith("xen0") or (version.endswith("xen") and not os.path.exists("/proc/xen")): # hypervisor case sermap = { "ttyS0": "com1", "ttyS1": "com2", "ttyS2": "com3", "ttyS3": "com4" } if self.serial and sermap.has_key(self.serialDevice) and \ self.serialOptions: hvs = "%s=%s" %(sermap[self.serialDevice], self.serialOptions) else: hvs = "" if version.endswith("xen0"): hvFile = "%sxen.gz-%s %s" %(cfPath, version.replace("xen0", ""), hvs) else: hvFile = "%sxen.gz-%s %s" %(cfPath, version.replace("xen", ""), hvs) f.write('\tkernel %s\n' %(hvFile,)) f.write('\tmodule %s ro%s' %(kernelFile, realroot)) if self.args.get(): f.write(' %s' % self.args.get()) f.write('\n') if initrd: f.write('\tmodule %s%s\n' % (cfPath, initrd)) else: # normal kernel f.write('\tkernel %s ro%s' % (kernelFile, realroot)) if self.args.get(): f.write(' %s' % self.args.get()) f.write('\n') if initrd: f.write('\tinitrd %s%s\n' % (cfPath, initrd)) for (label, longlabel, device) in chainList: if ((not longlabel) or (longlabel == "")): continue f.write('title %s\n' % (longlabel)) f.write('\trootnoverify %s\n' % self.grubbyPartitionName( self.storage.devicetree.getDeviceByName(device))) # f.write('\tmakeactive\n') f.write('\tchainloader +1') f.write('\n') f.close() if not "/efi/" in cf: os.chmod(cf, self.perms) try: # make symlink for menu.lst (default config file name) menulst = "%s%s/menu.lst" % (instRoot, self.configdir) if os.access (menulst, os.R_OK): os.rename(menulst, menulst + ".rpmsave") os.symlink("./grub.conf", menulst) except: pass try: # make symlink for /etc/grub.conf (config files belong in /etc) etcgrub = "%s%s" % (instRoot, "/etc/grub.conf") if os.access (etcgrub, os.R_OK): os.rename(etcgrub, etcgrub + ".rpmsave") os.symlink(".." + self.configfile, etcgrub) except: pass
def installGrub(self, instRoot, bootDev, grubTarget, grubPath, cfPath): if iutil.isEfi(): return efiBootloaderInfo.installGrub(self, instRoot, bootDev, grubTarget, grubPath, cfPath) args = "--stage2=/boot/grub/stage2 " stage1Devs = self.getPhysicalDevices( self.storage.devicetree.getDeviceByName(grubTarget)) bootDevs = self.getPhysicalDevices(bootDev) installs = [(None, self.grubbyPartitionName(stage1Devs[0]), self.grubbyPartitionName(bootDevs[0]))] if bootDev.type == "mdarray": matches = self.matchingBootTargets(stage1Devs, bootDevs) # If the stage1 target disk contains member of boot raid array (mbr # case) or stage1 target partition is member of boot raid array # (partition case) if matches: # 1) install stage1 on target disk/partiton stage1Dev, mdMemberBootPart = matches[0] installs = [(None, self.grubbyPartitionName(stage1Dev), self.grubbyPartitionName(mdMemberBootPart))] firstMdMemberDiskGrubbyName = self.grubbyDiskName( getDiskPart(mdMemberBootPart)[0]) # 2) and install stage1 on other members' disks/partitions too # NOTES: # - the goal is to be able to boot after a members' disk removal # - so we have to use grub device names as if after removal # (i.e. the same disk name (e.g. (hd0)) for both member disks) # - if member partitions have different numbers only removal of # specific one of members will work because stage2 containing # reference to config file is shared and therefore can contain # only one value # if target is mbr, we want to install also to mbr of other # members, so extend the matching list matches = self.addMemberMbrs(matches, bootDevs) for stage1Target, mdMemberBootPart in matches[1:]: # prepare special device mapping corresponding to member removal mdMemberBootDisk = getDiskPart(mdMemberBootPart)[0] # It can happen due to ks --driveorder option, but is it ok? if not mdMemberBootDisk.name in self.drivelist: continue mdRaidDeviceRemap = (firstMdMemberDiskGrubbyName, mdMemberBootDisk.name) stage1TargetGrubbyName = self.grubbyPartitionName(stage1Target) rootPartGrubbyName = self.grubbyPartitionName(mdMemberBootPart) # now replace grub disk name part according to special device # mapping old = self.grubbyDiskName(mdMemberBootDisk).strip('() ') new = firstMdMemberDiskGrubbyName.strip('() ') rootPartGrubbyName = rootPartGrubbyName.replace(old, new) stage1TargetGrubbyName = stage1TargetGrubbyName.replace(old, new) installs.append((mdRaidDeviceRemap, stage1TargetGrubbyName, rootPartGrubbyName)) # This is needed for case when /boot member partitions have # different numbers. Shared stage2 can contain only one reference # to grub.conf file, so let's ensure that it is reference to partition # on disk which we will boot from - that is, install grub to # this disk as last so that its reference is not overwritten. installs.reverse() cmds = [] for mdRaidDeviceRemap, stage1Target, rootPart in installs: if mdRaidDeviceRemap: cmd = "device (%s) /dev/%s\n" % tuple(mdRaidDeviceRemap) else: cmd = '' cmd += "root %s\n" % (rootPart,) cmd += "install %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" % \ (args, grubPath, stage1Target, grubPath, rootPart, grubPath) cmds.append(cmd) return self.runGrubInstall(instRoot, bootDev.name, cmds, cfPath)