def matchingBootTargets(self, stage1Devs, bootDevs): matches = [] for stage1Dev in stage1Devs: for mdBootPart in bootDevs: if getDiskPart(stage1Dev, self.storage)[0] == getDiskPart(mdBootPart, self.storage)[0]: matches.append((stage1Dev, mdBootPart)) return matches
def matchingBootTargets(self, stage1Devs, bootDevs): matches = [] for stage1Dev in stage1Devs: for mdBootPart in bootDevs: if getDiskPart(stage1Dev)[0] == getDiskPart(mdBootPart)[0]: matches.append((stage1Dev, mdBootPart)) return matches
def writeDeviceMap(self, instRoot, usedDevs, upgrade=False): if os.access(instRoot + "/boot/grub/device.map", os.R_OK): # For upgrade, we want also e.g. devs that has been added # to file during install for chainloading. if upgrade: f = open(instRoot + "/boot/grub/device.map", "r") for line in f: if line.startswith('(hd'): (grubdisk, dev) = line.split()[:2] dev = dev[5:] if dev in self.drivelist: usedDevs.add(dev) f.close() os.rename(instRoot + "/boot/grub/device.map", instRoot + "/boot/grub/device.map.rpmsave") f = open(instRoot + "/boot/grub/device.map", "w+") f.write("# this device map was generated by anaconda\n") usedDiskDevs = set() for dev in usedDevs: drive = getDiskPart(dev, self.storage)[0] usedDiskDevs.add(drive) devs = list(usedDiskDevs) 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. dev = self.storage.devicetree.getDeviceByName(drive) if not dev.type == "mdarray": f.write("(%s) %s\n" % (self.grubbyDiskName(drive), dev.path)) f.close()
def getRaidDisks(raidDevice, storage, 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, storage)[0] rc.append(disk) else: rc.append(dev) return rc
def writeDeviceMap(self, instRoot, usedDevs, upgrade=False): if os.access(instRoot + "/boot/grub/device.map", os.R_OK): # For upgrade, we want also e.g. devs that has been added # to file during install for chainloading. if upgrade: f = open(instRoot + "/boot/grub/device.map", "r") for line in f: if line.startswith('(hd'): (grubdisk, dev) = line.split()[:2] dev = dev[5:] if dev in self.drivelist: usedDevs.add( self.storage.devicetree.getDeviceByName(dev)) f.close() os.rename(instRoot + "/boot/grub/device.map", instRoot + "/boot/grub/device.map.rpmsave") f = open(instRoot + "/boot/grub/device.map", "w+") f.write("# this device map was generated by anaconda\n") usedDiskDevs = set() for dev in usedDevs: drive = getDiskPart(dev)[0] usedDiskDevs.add(drive) devs = list(usedDiskDevs) devs.sort(key=lambda d: d.name) for dev in devs: f.write("(%s) %s\n" % (self.grubbyDiskName(dev), dev.path)) f.close()
def addMemberMbrs(self, matches, bootDevs): updatedMatches = list(matches) bootDevsHavingStage1Dev = [match[1] for match in matches] for mdBootPart in bootDevs: if mdBootPart not in bootDevsHavingStage1Dev: updatedMatches.append((getDiskPart(mdBootPart, self.storage)[0], mdBootPart)) return updatedMatches
def addMemberMbrs(self, matches, bootDevs): updatedMatches = list(matches) bootDevsHavingStage1Dev = [match[1] for match in matches] for mdBootPart in bootDevs: if mdBootPart not in bootDevsHavingStage1Dev: updatedMatches.append((getDiskPart(mdBootPart)[0], mdBootPart)) return updatedMatches
def getRaidDisks(raidDevice, storage, 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, storage)[0] rc.append(disk) else: rc.append(dev) return rc
def grubbyPartitionName(self, dev): (disk, partNum) = getDiskPart(dev) if partNum != None: return "(%s,%d)" % (self.grubbyDiskName(disk), partNum - 1) else: return "(%s)" % (self.grubbyDiskName(disk))
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 writeSilo(self, instRoot, bl, kernelList, chainList, defaultDev): try: bootDev = self.storage.mountpoints["/boot"] mf = '/silo.message' cf = "/boot/silo.conf" mfdir = '/boot' cfPath = "" if not os.path.isdir(instRoot + "/boot"): os.mkdir(instRoot + "/boot") except KeyError: bootDev = self.storage.rootDevice cf = "/etc/silo.conf" mfdir = '/etc' cfPath = "/boot" f = open(instRoot + mfdir + mf, "w+") f.write("Welcome to %s!\nHit <TAB> for boot options\n\n" % productName) f.close() os.chmod(instRoot + mfdir + mf, 0600) f = open(instRoot + cf, "w+") f.write("# silo.conf generated by anaconda\n\n") f.write("#boot=%s\n" % (bootDev.path,)) f.write("message=%s\n" % (mf,)) f.write("timeout=%s\n" % (self.timeout or 50)) (disk, partNum) = getDiskPart(bootDev) f.write("partition=%s\n" % (partNum,)) if self.password: f.write("password=%s\n" % (self.password,)) f.write("restricted\n") f.write("default=%s\n" % (kernelList[0][0],)) f.write("\n") rootDev = self.storage.rootDevice for (label, longlabel, version) in kernelList: kernelTag = "-" + version kernelFile = "%s/vmlinuz%s" % (cfPath, kernelTag) f.write("image=%s\n" % (kernelFile,)) f.write("\tlabel=%s\n" % (label,)) f.write("\tread-only\n") initrd = self.makeInitrd(kernelTag, instRoot) if initrd: f.write("\tinitrd=%s/%s\n" % (cfPath, initrd)) append = "%s" % (self.args.get(),) realroot = rootDev.fstabSpec if rootIsDevice(realroot): f.write("\troot=%s\n" % (realroot,)) else: if len(append) > 0: append = "%s root=%s" % (append, realroot) else: append = "root=%s" % (realroot,) if len(append) > 0: f.write("\tappend=\"%s\"\n" % (append,)) f.write("\n") f.close() os.chmod(instRoot + cf, 0600) # FIXME: hack to make sure things are written to disk from pyanaconda import isys isys.sync() isys.sync() isys.sync() backup = "%s/backup.b" % (cfPath,) sbinargs = ["/sbin/silo", "-f", "-C", cf, "-S", backup] if (iutil.getSparcMachine() == "sun4u" or iutil.getSparcMachine() == "sun4v"): sbinargs += ["-u"] else: sbinargs += ["-U"] rc = iutil.execWithRedirect(sbinargs[0], sbinargs[1:], stdout = "/dev/tty5", stderr = "/dev/tty5", root = instRoot) if rc: return rc if (not os.access(instRoot + "/etc/silo.conf", os.R_OK) and os.access(instRoot + "/boot/silo.conf", os.R_OK)): os.symlink("../boot/silo.conf", instRoot + "/etc/silo.conf") return 0
def partitionNum (self, path): # getDiskPart returns part numbers 0-based; we need it one based # *sigh* (foo, partitionNumber) = getDiskPart(path, self.storage) return partitionNumber + 1
def grubbyPartitionName(self, dev): (disk, partNum) = getDiskPart(dev) if partNum != None: return "(%s,%d)" % (self.grubbyDiskName(disk), partNum - 1) else: return "(%s)" %(self.grubbyDiskName(disk))
def partitionNum(self, path): # getDiskPart returns part numbers 0-based; we need it one based # *sigh* (foo, partitionNumber) = getDiskPart(path, self.storage) return partitionNumber + 1
def writeGrubConf(self, instRoot, bootDev, rootDev, defaultDev, kernelList, chainList, grubTarget, grubPath, cfPath): bootDevs = self.getPhysicalDevices(bootDev.name) # 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 product import productName # Map the target device to the full EFI path if self.getEfiProductPath(productName): (n, pn) = getDiskPart(bootDevs[0], self.storage) 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)) f.write('timeout=%d\n' % (self.timeout or 0)) if self.serial == 1: # 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: # 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 if self.trusted_boot: f.write('\tkernel %stboot.gz logging=vga,serial,memory\n' % (cfPath)) f.write('\tmodule %s ro%s intel_iommu=on amd_iommu=on' % (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: 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(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(grubTarget) bootDevs = self.getPhysicalDevices(bootDev.name) 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, self.storage)[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, self.storage)[0] # It can happen due to ks --driveorder option, but is it ok? if not mdMemberBootDisk in self.drivelist: continue mdRaidDeviceRemap = (firstMdMemberDiskGrubbyName, mdMemberBootDisk) 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 grubbyPartitionName(self, dev): (name, partNum) = getDiskPart(dev, self.storage) if partNum != None: return "(%s,%d)" % (self.grubbyDiskName(name), partNum) else: return "(%s)" % (self.grubbyDiskName(name))
def getBootloaderTypeAndBoot(instRoot, storage): haveGrubConf = 1 haveLiloConf = 1 haveYabootConf = 1 haveSiloConf = 1 haveZiplConf = 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 not os.access(instRoot + ziplConfigFile, os.R_OK): haveZiplConf = 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, storage) # 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, storage) # 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, storage)[1] != 3: block = getBootBlock(bootDev, instRoot, storage, 1) if block[24:28] == "SILO": return ("SILO", bootDev) if haveZiplConf: bootDev = None f = open(instRoot + ziplConfigFile, "r") lines = f.readlines() for line in lines: if line[0:7] == "target=": bootDev = getBootDevList(line) if bootDev: return ("ZIPL", bootDev) return (None, None)
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 writeAboot(self, instRoot, bl, kernelList, chainList, defaultDev): rootDevice = self.storage.rootDevice try: bootDevice = self.storage.mountpoints["/boot"] except KeyError: bootDevice = rootDevice bootnotroot = bootDevice != rootDevice confFile = instRoot + self.configfile # If /etc/aboot.conf already exists we rename it # /etc/aboot.conf.rpmsave. if os.path.isfile(confFile): os.rename (confFile, confFile + ".rpmsave") # Then we create the necessary files. If the root device isn't # the boot device, we create /boot/etc/ where the aboot.conf # will live, and we create /etc/aboot.conf as a symlink to it. if bootnotroot: # Do we have /boot/etc ? If not, create one if not os.path.isdir (instRoot + '/boot/etc'): os.mkdir(instRoot + '/boot/etc', 0755) # We install the symlink (/etc/aboot.conf has already been # renamed in necessary.) os.symlink("../boot" + self.configfile, confFile) cfPath = instRoot + "/boot" + self.configfile # Kernel path is set to / because a boot partition will # be a root on its own. kernelPath = '/' # Otherwise, we just need to create /etc/aboot.conf. else: cfPath = confFile kernelPath = self.kernelLocation # If we already have an aboot.conf, rename it if os.access (cfPath, os.R_OK): self.perms = os.stat(cfPath)[0] & 0777 os.rename(cfPath, cfPath + '.rpmsave') # Now we're going to create and populate cfPath. f = open (cfPath, 'w+') f.write ("# aboot default configurations\n") if bootnotroot: f.write ("# NOTICE: You have a /boot partition. This means that\n") f.write ("# all kernel paths are relative to /boot/\n") # bpn is the boot partition number. bpn = getDiskPart(bootDevice) lines = 0 # We write entries line using the following format: # <line><bpn><kernel-name> root=<rootdev> [options] # We get all the kernels we need to know about in kernelList. for (kernel, tag, version) in kernelList: kernelTag = "-" + version kernelFile = "%svmlinuz%s" %(kernelPath, kernelTag) f.write("%d:%d%s" %(lines, bpn, kernelFile)) # See if we can come up with an initrd argument that exists initrd = self.makeInitrd(kernelTag, instRoot) if initrd: f.write(" initrd=%s%s" %(kernelPath, initrd)) realroot = rootDevice.fstabSpec f.write(" root=%s" %(realroot,)) args = self.args.get() if args: f.write(" %s" %(args,)) f.write("\n") lines = lines + 1 # We're done writing the file f.close () del f # Now we're ready to write the relevant boot information. wbd # is the whole boot device, bdpn is the boot device partition # number. wbd = getDiskPart(bootDevice)[0] bdpn = getDiskPart(bootDevice)[1] # Calling swriteboot. The first argument is the disk to write # to and the second argument is a path to the bootstrap loader # file. args = [("/dev/%s" % wbd), "/boot/bootlx"] rc = iutil.execWithRedirect ('/sbin/swriteboot', args, root = instRoot, stdout = "/dev/tty5", stderr = "/dev/tty5") if rc: return rc # Calling abootconf to configure the installed aboot. The # first argument is the disk to use, the second argument is # the number of the partition on which aboot.conf resides. # It's always the boot partition whether it's / or /boot (with # the mount point being omitted.) args = [("/dev/%s" % wbd), str (bdpn)] rc = iutil.execWithRedirect ('/sbin/abootconf', args, root = instRoot, stdout = "/dev/tty5", stderr = "/dev/tty5") if rc: return rc return 0
def wholeDevice (self, path): (device, foo) = getDiskPart(path, self.storage) return device
def writeSilo(self, instRoot, bl, kernelList, chainList, defaultDev): try: bootDev = self.storage.mountpoints["/boot"] mf = '/silo.message' cf = "/boot/silo.conf" mfdir = '/boot' cfPath = "" if not os.path.isdir(instRoot + "/boot"): os.mkdir(instRoot + "/boot") except KeyError: bootDev = self.storage.rootDevice cf = "/etc/silo.conf" mfdir = '/etc' cfPath = "/boot" f = open(instRoot + mfdir + mf, "w+") f.write("Welcome to %s!\nHit <TAB> for boot options\n\n" % productName) f.close() os.chmod(instRoot + mfdir + mf, 0600) f = open(instRoot + cf, "w+") f.write("# silo.conf generated by anaconda\n\n") f.write("#boot=%s\n" % (bootDev.path, )) f.write("message=%s\n" % (mf, )) f.write("timeout=%s\n" % (self.timeout or 50)) (disk, partNum) = getDiskPart(bootDev) f.write("partition=%s\n" % (partNum, )) if self.password: f.write("password=%s\n" % (self.password, )) f.write("restricted\n") f.write("default=%s\n" % (kernelList[0][0], )) f.write("\n") rootDev = self.storage.rootDevice for (label, longlabel, version) in kernelList: kernelTag = "-" + version kernelFile = "%s/vmlinuz%s" % (cfPath, kernelTag) f.write("image=%s\n" % (kernelFile, )) f.write("\tlabel=%s\n" % (label, )) f.write("\tread-only\n") initrd = self.makeInitrd(kernelTag, instRoot) if initrd: f.write("\tinitrd=%s/%s\n" % (cfPath, initrd)) append = "%s" % (self.args.get(), ) realroot = rootDev.fstabSpec if rootIsDevice(realroot): f.write("\troot=%s\n" % (realroot, )) else: if len(append) > 0: append = "%s root=%s" % (append, realroot) else: append = "root=%s" % (realroot, ) if len(append) > 0: f.write("\tappend=\"%s\"\n" % (append, )) f.write("\n") f.close() os.chmod(instRoot + cf, 0600) # FIXME: hack to make sure things are written to disk from pyanaconda import isys isys.sync() isys.sync() isys.sync() backup = "%s/backup.b" % (cfPath, ) sbinargs = ["/sbin/silo", "-f", "-C", cf, "-S", backup] if (iutil.getSparcMachine() == "sun4u" or iutil.getSparcMachine() == "sun4v"): sbinargs += ["-u"] else: sbinargs += ["-U"] rc = iutil.execWithRedirect(sbinargs[0], sbinargs[1:], stdout="/dev/tty5", stderr="/dev/tty5", root=instRoot) if rc: return rc if (not os.access(instRoot + "/etc/silo.conf", os.R_OK) and os.access(instRoot + "/boot/silo.conf", os.R_OK)): os.symlink("../boot/silo.conf", instRoot + "/etc/silo.conf") return 0
def wholeDevice(self, path): (device, foo) = getDiskPart(path, self.storage) return device
def grubbyPartitionName(self, dev): (name, partNum) = getDiskPart(dev, self.storage) if partNum != None: return "(%s,%d)" % (self.grubbyDiskName(name), partNum) else: return "(%s)" %(self.grubbyDiskName(name))