/[smeserver]/cdrom.image/updates/bootloaderInfo.py
ViewVC logotype

Annotation of /cdrom.image/updates/bootloaderInfo.py

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (hide annotations) (download) (as text)
Wed Jul 13 21:59:02 2005 UTC (19 years, 5 months ago) by slords
Branch: MAIN
Changes since 1.1: +5 -1 lines
Content type: text/x-python
Pick correct kernel based on hyperthreading and smp capabilities

1 slords 1.1 #
2     # bootloaderInfo.py - bootloader config object used in creation of new
3     # bootloader configs. Originally from anaconda
4     #
5     # Jeremy Katz <katzj@redhat.com>
6     # Erik Troan <ewt@redhat.com>
7     #
8     # Copyright 2002 Red Hat, Inc.
9     #
10     # This software may be freely redistributed under the terms of the GNU
11     # library public license.
12     #
13     # You should have received a copy of the GNU Library Public License
14     # along with this program; if not, write to the Free Software
15     # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16     #
17    
18 slords 1.2 import isys
19 slords 1.1 import os, sys
20     import crypt
21     import whrandom
22     import butil
23     import string
24    
25     from lilo import LiloConfigFile
26     from rhpl.log import log
27     from rhpl.translate import _, N_
28     import rhpl.executil
29    
30     import booty
31     import checkbootloader
32    
33     dosFilesystems = ('FAT', 'fat16', 'fat32', 'ntfs', 'hpfs')
34    
35     if os.path.exists('edd'):
36     sys.path.append('edd/')
37     else:
38     sys.path.append('/usr/lib/bootloader')
39    
40     if butil.getArch() == "i386":
41     import edd
42    
43     def doesDualBoot():
44     if butil.getArch() == "i386" or butil.getArch() == "x86_64":
45     return 1
46     return 0
47    
48     # hack and a half
49     # there's no guarantee that data is written to the disk and grub
50     # reads both the filesystem and the disk. suck.
51     def syncDataToDisk(dev, mntpt, instRoot = "/"):
52     import isys, fsset
53     isys.sync()
54     isys.sync()
55     isys.sync()
56    
57     # and xfs is even more "special" (#117968)
58     if fsset.isValidXFS(dev):
59     rhpl.executil.execWithRedirect( "/usr/sbin/xfs_freeze",
60     ["/usr/sbin/xfs_freeze", "-f", mntpt],
61     stdout = "/dev/tty5",
62     stderr = "/dev/tty5",
63     root = instRoot)
64     rhpl.executil.execWithRedirect( "/usr/sbin/xfs_freeze",
65     ["/usr/sbin/xfs_freeze", "-u", mntpt],
66     stdout = "/dev/tty5",
67     stderr = "/dev/tty5",
68     root = instRoot)
69    
70     class BootyNoKernelWarning:
71     def __init__ (self, value=""):
72     self.value = value
73    
74     def __str__ (self):
75     return self.value
76    
77     class KernelArguments:
78    
79     def get(self):
80     return self.args
81    
82     def set(self, args):
83     self.args = args
84    
85     def chandevget(self):
86     return self.cargs
87    
88     def chandevset(self, args):
89     self.cargs = args
90    
91     def append(self, args):
92     if self.args:
93     # don't duplicate the addition of an argument (#128492)
94     if self.args.find(args) != -1:
95     return
96     self.args = self.args + " "
97     self.args = self.args + "%s" % (args,)
98    
99    
100     def __init__(self):
101     str = ""
102    
103     if butil.getArch() == "s390":
104     self.cargs = []
105     f = open("/tmp/install.cfg")
106     lines = f.readlines()
107     for line in lines:
108     try:
109     (vname,vparm) = line.split('=', 1)
110     vname = vname.strip()
111     vparm = vparm.replace('"','')
112     vparm = vparm.strip()
113     if vname == "DASD":
114     str = str + "dasd=" + vparm
115     if vname == "CHANDEV":
116     self.cargs.append(vparm)
117     if vname == "QETHPARM":
118     self.cargs.append(vparm)
119     except Exception, e:
120     pass
121    
122     # look for kernel arguments we know should be preserved and add them
123     ourargs = ["speakup_synth=", "apic", "noapic", "apm=", "ide=nodma", "noht", "acpi=", "video="]
124     f = open("/proc/cmdline")
125     cmdline = f.read()[:-1]
126     f.close()
127     cmdlineargs = cmdline.split(" ")
128     for arg in cmdlineargs:
129     for check in ourargs:
130     if arg.startswith(check):
131     if str: str = str + " "
132     str = str + arg
133    
134     self.args = str
135    
136     class BootImages:
137     # returns dictionary of (label, longlabel, devtype) pairs indexed by device
138     def getImages(self):
139     # return a copy so users can modify it w/o affecting us
140    
141     dict = {}
142     for key in self.images.keys():
143     dict[key] = self.images[key]
144    
145     return dict
146    
147     def setImageLabel(self, dev, label, setLong = 0):
148     if setLong:
149     self.images[dev] = (self.images[dev][0], label,
150     self.images[dev][2])
151     else:
152     self.images[dev] = (label, self.images[dev][1],
153     self.images[dev][2])
154    
155    
156     # default is a device
157     def setDefault(self, default):
158     self.default = default
159    
160     def getDefault(self):
161     return self.default
162    
163     # XXX this has internal anaconda-ish knowledge. ick
164     def setup(self, diskSet, fsset):
165     devices = {}
166     devs = self.availableBootDevices(diskSet, fsset)
167     for (dev, type) in devs:
168     devices[dev] = 1
169    
170     # These partitions have disappeared
171     for dev in self.images.keys():
172     if not devices.has_key(dev): del self.images[dev]
173    
174     # These have appeared
175     for (dev, type) in devs:
176     if not self.images.has_key(dev):
177     if type in dosFilesystems:
178     self.images[dev] = ("Other", "Other", type)
179     else:
180     self.images[dev] = (None, None, type)
181    
182    
183     if not self.images.has_key(self.default):
184     entry = fsset.getEntryByMountPoint('/')
185     self.default = entry.device.getDevice()
186     (label, longlabel, type) = self.images[self.default]
187     if not label:
188     self.images[self.default] = ("linux",
189     butil.getProductName(), type)
190    
191     # XXX more internal anaconda knowledge
192     def availableBootDevices(self, diskSet, fsset):
193     devs = []
194     foundDos = 0
195     for (dev, type) in diskSet.partitionTypes():
196     if type in dosFilesystems and not foundDos and doesDualBoot():
197     import isys
198     import partedUtils
199    
200     isys.makeDevInode(dev, '/tmp/' + dev)
201     part = partedUtils.get_partition_by_name(diskSet.disks, dev)
202     if part.native_type not in partedUtils.dosPartitionTypes:
203     continue
204    
205     try:
206     bootable = isys.checkBoot('/tmp/' + dev)
207     devs.append((dev, type))
208     foundDos = 1
209     except Exception, e:
210     log("exception checking %s: %s" %(dev, e))
211     pass
212     elif ((type == 'ntfs' or type =='hpfs') and not foundDos
213     and doesDualBoot()):
214     devs.append((dev, type))
215     # maybe questionable, but the first ntfs or fat is likely to
216     # be the correct one to boot with XP using ntfs
217     foundDos = 1
218     elif (type == 'hfs') and butil.getPPCMachine() == "PMac":
219     import isys
220     import partedUtils
221    
222     isys.makeDevInode(dev, '/tmp/' + dev)
223     part = partedUtils.get_partition_by_name(diskSet.disks, dev)
224     if partedUtils.get_flags(part) != "boot":
225     devs.append((dev, type))
226    
227     slash = fsset.getEntryByMountPoint('/')
228     if not slash or not slash.device or not slash.fsystem:
229     raise ValueError, ("Trying to pick boot devices but do not have a "
230     "sane root partition. Aborting install.")
231     devs.append((slash.device.getDevice(), slash.fsystem.getName()))
232    
233     devs.sort()
234    
235     return devs
236    
237    
238    
239     def __init__(self):
240     self.default = None
241     self.images = {}
242    
243    
244     class bootloaderInfo:
245     def setUseGrub(self, val):
246     pass
247    
248     def useGrub(self):
249     return self.useGrubVal
250    
251     def setForceLBA(self, val):
252     pass
253    
254     def setPassword(self, val, isCrypted = 1):
255     pass
256    
257     def getPassword(self):
258     pass
259    
260     def getDevice(self):
261     return self.device
262    
263     def setDevice(self, device):
264     self.device = device
265    
266     (dev, part) = getDiskPart(device)
267     if part is None:
268     self.defaultDevice = "mbr"
269     else:
270     self.defaultDevice = "partition"
271    
272     # XXX need to abstract out the requirement for a fsset to be able
273     # to get it "on the fly" on a running system as well as being able
274     # to get it how we do now from anaconda. probably by having the
275     # first thing in the chain create a "fsset" object that has the
276     # dictionary of mounted filesystems since that's what we care about
277     def getBootloaderConfig(self, instRoot, fsset, bl, langs, kernelList,
278     chainList, defaultDev):
279     images = bl.images.getImages()
280    
281     # on upgrade read in the lilo config file
282     lilo = LiloConfigFile ()
283     self.perms = 0600
284     if os.access (instRoot + self.configfile, os.R_OK):
285     self.perms = os.stat(instRoot + self.configfile)[0] & 0777
286     lilo.read (instRoot + self.configfile)
287     os.rename(instRoot + self.configfile,
288     instRoot + self.configfile + '.rpmsave')
289     # if it's an absolute symlink, just get it out of our way
290     elif (os.path.islink(instRoot + self.configfile) and
291     os.readlink(instRoot + self.configfile)[0] == '/'):
292     os.rename(instRoot + self.configfile,
293     instRoot + self.configfile + '.rpmsave')
294    
295     # Remove any invalid entries that are in the file; we probably
296     # just removed those kernels.
297     for label in lilo.listImages():
298     (fsType, sl, path, other) = lilo.getImage(label)
299     if fsType == "other": continue
300    
301     if not os.access(instRoot + sl.getPath(), os.R_OK):
302     lilo.delImage(label)
303    
304     lilo.addEntry("prompt", replace = 0)
305     lilo.addEntry("timeout", "20", replace = 0)
306    
307     rootDev = fsset.getEntryByMountPoint("/").device.getDevice()
308     if not rootDev:
309     raise RuntimeError, "Installing lilo, but there is no root device"
310    
311     if rootDev == defaultDev:
312     lilo.addEntry("default", kernelList[0][0])
313     else:
314     lilo.addEntry("default", chainList[0][0])
315    
316     for (label, longlabel, version) in kernelList:
317     kernelTag = "-" + version
318     kernelFile = self.kernelLocation + "vmlinuz" + kernelTag
319    
320     try:
321     lilo.delImage(label)
322     except IndexError, msg:
323     pass
324    
325     sl = LiloConfigFile(imageType = "image", path = kernelFile)
326    
327     initrd = booty.makeInitrd (kernelTag, instRoot)
328    
329     sl.addEntry("label", label)
330     if os.access (instRoot + initrd, os.R_OK):
331     sl.addEntry("initrd", "%sinitrd%s.img" %(self.kernelLocation,
332     kernelTag))
333    
334     sl.addEntry("read-only")
335    
336     append = "%s" %(self.args.get(),)
337     realroot = getRootDevName(initrd, fsset, rootDev, instRoot)
338     if not realroot.startswith("LABEL="):
339     sl.addEntry("root", '/dev/' + rootDev)
340     else:
341     if len(append) > 0:
342     append = "%s root=%s" %(append,realroot)
343     else:
344     append = "root=%s" %(realroot,)
345    
346     if len(append) > 0:
347     sl.addEntry('append', '"%s"' % (append,))
348    
349     lilo.addImage (sl)
350    
351     for (label, longlabel, device) in chainList:
352     if ((not label) or (label == "")):
353     continue
354     try:
355     (fsType, sl, path, other) = lilo.getImage(label)
356     lilo.delImage(label)
357     except IndexError:
358     sl = LiloConfigFile(imageType = "other",
359     path = "/dev/%s" %(device))
360     sl.addEntry("optional")
361    
362     sl.addEntry("label", label)
363     lilo.addImage (sl)
364    
365     # Sanity check #1. There could be aliases in sections which conflict
366     # with the new images we just created. If so, erase those aliases
367     imageNames = {}
368     for label in lilo.listImages():
369     imageNames[label] = 1
370    
371     for label in lilo.listImages():
372     (fsType, sl, path, other) = lilo.getImage(label)
373     if sl.testEntry('alias'):
374     alias = sl.getEntry('alias')
375     if imageNames.has_key(alias):
376     sl.delEntry('alias')
377     imageNames[alias] = 1
378    
379     # Sanity check #2. If single-key is turned on, go through all of
380     # the image names (including aliases) (we just built the list) and
381     # see if single-key will still work.
382     if lilo.testEntry('single-key'):
383     singleKeys = {}
384     turnOff = 0
385     for label in imageNames.keys():
386     l = label[0]
387     if singleKeys.has_key(l):
388     turnOff = 1
389     singleKeys[l] = 1
390     if turnOff:
391     lilo.delEntry('single-key')
392    
393     return lilo
394    
395     def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
396     defaultDev, justConfig, intf = None):
397     if len(kernelList) >= 1:
398     config = self.getBootloaderConfig(instRoot, fsset, bl, langs,
399     kernelList, chainList,
400     defaultDev)
401     config.write(instRoot + self.configfile, perms = self.perms)
402     else:
403     self.noKernelsWarn(intf)
404    
405     return ""
406    
407     # XXX in the future we also should do some validation on the config
408     # file that's already there
409     # XXX concept of the intf isn't very well defined outside of anaconda...
410     # probably should just pass back up an error
411     def noKernelsWarn(self, intf):
412     raise BootyNoKernelWarning
413    
414     def getArgList(self):
415     args = []
416    
417     if self.defaultDevice is None:
418     args.append("--location=none")
419     return args
420    
421     args.append("--location=%s" % (self.defaultDevice,))
422    
423     if self.args.get():
424     args.append("--append=\"%s\"" %(self.args.get()))
425    
426     return args
427    
428     def writeKS(self, f):
429     f.write("bootloader")
430     for arg in self.getArgList():
431     f.write(" " + arg)
432     f.write("\n")
433    
434     def createDriveList(self):
435     # create a drive list that we can use for drive mappings
436     # XXX has anaconda internals knowledge
437     import isys
438     import flags
439     drives = isys.hardDriveDict().keys()
440     drives.sort (isys.compareDrives)
441    
442     # now filter out all of the removable media unless expert mode
443     rc = []
444     for drive in drives:
445     if not isys.driveIsRemovable(drive) or flags.flags.expert:
446     rc.append(drive)
447     return rc
448    
449     def __init__(self):
450     self.args = KernelArguments()
451     self.images = BootImages()
452     self.device = None
453     self.useLinear = 1 # only used for kickstart compatibility
454     self.defaultDevice = None # XXX hack, used by kickstart
455     self.useGrubVal = 0 # only used on x86
456     self.configfile = None
457     self.kernelLocation = "/boot/"
458     self.forceLBA32 = 0
459     self.password = None
460     self.pure = None
461     self.above1024 = 0
462    
463     # this has somewhat strange semantics. if 0, act like a normal
464     # "install" case. if 1, update lilo.conf (since grubby won't do that)
465     # and then run lilo or grub only.
466     # XXX THIS IS A HACK. implementation details are only there for x86
467     self.doUpgradeOnly = 0
468     self.kickstart = 0
469    
470     self.drivelist = self.createDriveList()
471    
472     from flags import flags
473     if flags.serial != 0:
474     # now look at /proc/cmdline to pull any serial console
475     # args
476     f = open("/proc/cmdline", "r")
477     cmdline = f.read()[:-1]
478     f.close()
479    
480     options = ""
481     device = None
482     cmdlineargs = cmdline.split(" ")
483     for arg in cmdlineargs:
484     # found a console argument
485     if arg.startswith("console="):
486     (foo, console) = arg.split("=")
487     # the options are everything after the comma
488     comma = console.find(",")
489     if comma != -1:
490     options = console[comma:]
491     device = console[:comma]
492     else:
493     options = ""
494     device = console
495    
496     if device is None:
497     self.serialDevice = "ttyS0"
498     self.serialOptions = ""
499     else:
500     self.serialDevice = device
501     # don't keep the comma in the options
502     self.serialOptions = options[1:]
503    
504     self.args.append("console=%s%s" %(self.serialDevice, options))
505    
506     self.serial = 1
507     else:
508     self.serial = 0
509     self.serialDevice = None
510     self.serialOptions = None
511    
512     if flags.virtpconsole is not None:
513     if flags.virtpconsole.startswith("/dev/"):
514     con = flags.virtpconsole[5:]
515     else:
516     con = flags.virtpconsole
517     self.args.append("console=%s" %(con,))
518    
519    
520     class ia64BootloaderInfo(bootloaderInfo):
521     # XXX wouldn't it be nice to have a real interface to use efibootmgr from?
522     def removeOldEfiEntries(self, instRoot):
523     p = os.pipe()
524     rhpl.executil.execWithRedirect('/usr/sbin/efibootmgr', ["efibootmgr"],
525     root = instRoot, stdout = p[1])
526     os.close(p[1])
527    
528     c = os.read(p[0], 1)
529     buf = c
530     while (c):
531     c = os.read(p[0], 1)
532     buf = buf + c
533     os.close(p[0])
534     lines = string.split(buf, '\n')
535     for line in lines:
536     fields = string.split(line)
537     if len(fields) < 2:
538     continue
539     if string.join(fields[1:], " ") == butil.getProductName():
540     entry = fields[0][4:8]
541     rhpl.executil.execWithRedirect('/usr/sbin/efibootmgr',
542     ["efibootmgr", "-b", entry, "-B"],
543     root = instRoot,
544     stdout="/dev/tty5", stderr="/dev/tty5")
545    
546     def getBootloaderConfig(self, instRoot, fsset, bl, langs, kernelList,
547     chainList, defaultDev):
548     config = bootloaderInfo.getBootloaderConfig(self, instRoot, fsset,
549     bl, langs,
550     kernelList, chainList,
551     defaultDev)
552     # altix boxes need relocatable (#120851)
553     config.addEntry("relocatable")
554    
555     return config
556    
557     def writeLilo(self, instRoot, fsset, bl, langs, kernelList,
558     chainList, defaultDev, justConfig):
559     config = self.getBootloaderConfig(instRoot, fsset, bl, langs,
560     kernelList, chainList, defaultDev)
561     config.write(instRoot + self.configfile, perms = self.perms)
562    
563     return ""
564    
565     def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
566     defaultDev, justConfig, intf):
567     if len(kernelList) >= 1:
568     str = self.writeLilo(instRoot, fsset, bl, langs, kernelList,
569     chainList, defaultDev, justConfig)
570     else:
571     self.noKernelsWarn(intf)
572    
573     bootdev = fsset.getEntryByMountPoint("/boot/efi").device.getDevice()
574     if not bootdev:
575     bootdev = fsset.getEntryByDeviceName("sda1").device.getDevice()
576    
577     if not os.access(instRoot + "/etc/elilo.conf", os.R_OK):
578     os.symlink("../" + self.configfile, instRoot + "/etc/elilo.conf")
579    
580     ind = len(bootdev)
581     try:
582     while (bootdev[ind-1] in string.digits):
583     ind = ind - 1
584     except IndexError:
585     ind = len(bootdev) - 1
586    
587     bootdisk = bootdev[:ind]
588     bootpart = bootdev[ind:]
589     if (bootdisk.startswith('ida/') or bootdisk.startswith('cciss/') or
590     bootdisk.startswith('rd/')):
591     bootdisk = bootdisk[:-1]
592    
593     self.removeOldEfiEntries(instRoot)
594    
595     argv = [ "/usr/sbin/efibootmgr", "-c" , "-w", "-L",
596     butil.getProductName(), "-d", "/dev/%s" % bootdisk,
597     "-p", bootpart, "-l", "EFI\\redhat\\elilo.efi" ]
598     rhpl.executil.execWithRedirect(argv[0], argv, root = instRoot,
599     stdout = "/dev/tty5",
600     stderr = "/dev/tty5")
601    
602    
603     def __init__(self):
604     bootloaderInfo.__init__(self)
605     self.useGrubVal = 1
606     self.kernelLocation = ""
607     self.configfile = "/boot/efi/EFI/redhat/elilo.conf"
608    
609    
610     class x86BootloaderInfo(bootloaderInfo):
611     def setPassword(self, val, isCrypted = 1):
612     if not val:
613     self.password = val
614     self.pure = val
615     return
616    
617     if isCrypted and self.useGrubVal == 0:
618     log("requested crypted password with lilo; ignoring")
619     self.pure = None
620     return
621     elif isCrypted:
622     self.password = val
623     self.pure = None
624     else:
625     salt = "$1$"
626     saltLen = 8
627    
628     for i in range(saltLen):
629     salt = salt + whrandom.choice (string.letters +
630     string.digits + './')
631    
632     self.password = crypt.crypt (val, salt)
633     self.pure = val
634    
635     def getPassword (self):
636     return self.pure
637    
638     def setForceLBA(self, val):
639     self.forceLBA32 = val
640    
641     def setUseGrub(self, val):
642     self.useGrubVal = val
643    
644     def getPhysicalDevices(self, device):
645     # This finds a list of devices on which the given device name resides.
646     # Accepted values for "device" are raid1 md devices (i.e. "md0"),
647     # physical disks ("hda"), and real partitions on physical disks
648     # ("hda1"). Volume groups/logical volumes are not accepted.
649     #
650     # XXX this has internal anaconda-ish knowledge. ick.
651     import isys
652     import lvm
653    
654     if string.split(device, '/', 1)[0] in map (lambda vg: vg[0],
655     lvm.vglist()):
656     return []
657    
658     if device.startswith('md'):
659     bootable = 0
660     parts = checkbootloader.getRaidDisks(device, 1, stripPart=0)
661     parts.sort()
662     return parts
663    
664     return [device]
665    
666     def writeGrub(self, instRoot, fsset, bl, langs, kernelList, chainList,
667     defaultDev, justConfigFile):
668     if len(kernelList) < 1:
669     return ""
670    
671     images = bl.images.getImages()
672     rootDev = fsset.getEntryByMountPoint("/").device.getDevice()
673    
674     if not os.path.isdir(instRoot + '/boot/grub/'):
675     os.mkdir(instRoot + '/boot/grub', 0755)
676    
677     # XXX old config file should be read here for upgrade
678    
679     cf = '/boot/grub/grub.conf'
680     self.perms = 0600
681     if os.access (instRoot + cf, os.R_OK):
682     self.perms = os.stat(instRoot + cf)[0] & 0777
683     os.rename(instRoot + cf,
684     instRoot + cf + '.rpmsave')
685    
686     grubTarget = bl.getDevice()
687     target = "mbr"
688     if grubTarget[-1].isdigit() and not grubTarget.startswith('md'):
689     target = "partition"
690    
691     f = open(instRoot + cf, "w+")
692    
693     f.write("# grub.conf generated by anaconda\n")
694     f.write("#\n")
695     f.write("# Note that you do not have to rerun grub "
696     "after making changes to this file\n")
697    
698     bootDev = fsset.getEntryByMountPoint("/boot")
699     grubPath = "/grub"
700     cfPath = "/"
701     if not bootDev:
702     bootDev = fsset.getEntryByMountPoint("/")
703     grubPath = "/boot/grub"
704     cfPath = "/boot/"
705     f.write("# NOTICE: You do not have a /boot partition. "
706     "This means that\n")
707     f.write("# all kernel and initrd paths are relative "
708     "to /, eg.\n")
709     else:
710     f.write("# NOTICE: You have a /boot partition. This means "
711     "that\n")
712     f.write("# all kernel and initrd paths are relative "
713     "to /boot/, eg.\n")
714    
715     bootDevs = self.getPhysicalDevices(bootDev.device.getDevice())
716     bootDev = bootDev.device.getDevice()
717    
718     f.write('# root %s\n' % self.grubbyPartitionName(bootDevs[0]))
719     f.write("# kernel %svmlinuz-version ro "
720     "root=/dev/%s\n" % (cfPath, rootDev))
721     f.write("# initrd %sinitrd-version.img\n" % (cfPath))
722     f.write("#boot=/dev/%s\n" % (grubTarget))
723    
724     # get the default image to boot... we have to walk and find it
725     # since grub indexes by where it is in the config file
726     if defaultDev == rootDev:
727 slords 1.2 for kernel in range(0, len(kernelList)):
728     default=kernel
729     if kernelList[kernel][2].find('smp')<0 or isys.smpAvailable() or isys.htavailable():
730     break
731 slords 1.1 else:
732     # if the default isn't linux, it's the first thing in the
733     # chain list
734     default = len(kernelList)
735    
736     # keep track of which devices are used for the device.map
737     usedDevs = {}
738    
739     f.write('default=%s\n' % (default))
740     if len(chainList) > 0:
741     timeout = 5
742     else:
743     timeout = 5
744     f.write('timeout=%d\n' %(timeout,))
745    
746     if self.serial == 1:
747     # grub the 0-based number of the serial console device
748     unit = self.serialDevice[-1]
749    
750     # and we want to set the speed too
751     speedend = 0
752     for char in self.serialOptions:
753     if char not in string.digits:
754     break
755     speedend = speedend + 1
756     if speedend != 0:
757     speed = self.serialOptions[:speedend]
758     else:
759     # reasonable default
760     speed = "9600"
761    
762     f.write("serial --unit=%s --speed=%s\n" %(unit, speed))
763     f.write("terminal --timeout=5 serial console\n")
764     else:
765     # we only want splashimage if they're not using a serial console
766     if os.access("%s/boot/grub/splash.xpm.gz" %(instRoot,), os.R_OK):
767     f.write('splashimage=%s%sgrub/splash.xpm.gz\n'
768     % (self.grubbyPartitionName(bootDevs[0]), cfPath))
769     f.write("hiddenmenu\n")
770    
771     for dev in self.getPhysicalDevices(grubTarget):
772     usedDevs[dev] = 1
773    
774     if self.password:
775     f.write('password --md5 %s\n' %(self.password))
776    
777     for (label, longlabel, version) in kernelList:
778     kernelTag = "-" + version
779     kernelFile = "%svmlinuz%s" % (cfPath, kernelTag)
780    
781     initrd = booty.makeInitrd (kernelTag, instRoot)
782    
783     f.write('title %s (%s)\n' % (longlabel, version))
784     f.write('\troot %s\n' % self.grubbyPartitionName(bootDevs[0]))
785    
786     realroot = getRootDevName(initrd, fsset, rootDev, instRoot)
787     realroot = " root=%s" %(realroot,)
788    
789     f.write('\tkernel %s ro%s' % (kernelFile, realroot))
790     if self.args.get():
791     f.write(' %s' % self.args.get())
792     f.write('\n')
793    
794     if os.access (instRoot + initrd, os.R_OK):
795     f.write('\tinitrd %sinitrd%s.img\n' % (cfPath, kernelTag))
796    
797     for (label, longlabel, device) in chainList:
798     if ((not longlabel) or (longlabel == "")):
799     continue
800     f.write('title %s\n' % (longlabel))
801     f.write('\trootnoverify %s\n' % self.grubbyPartitionName(device))
802     # f.write('\tmakeactive\n')
803     f.write('\tchainloader +1')
804     f.write('\n')
805     usedDevs[device] = 1
806    
807     f.close()
808     os.chmod(instRoot + "/boot/grub/grub.conf", self.perms)
809    
810     try:
811     # make symlink for menu.lst (default config file name)
812     if os.access (instRoot + "/boot/grub/menu.lst", os.R_OK):
813     os.rename(instRoot + "/boot/grub/menu.lst",
814     instRoot + "/boot/grub/menu.lst.rpmsave")
815     os.symlink("./grub.conf", instRoot + "/boot/grub/menu.lst")
816     except:
817     pass
818    
819     try:
820     # make symlink for /etc/grub.conf (config files belong in /etc)
821     if os.access (instRoot + "/etc/grub.conf", os.R_OK):
822     os.rename(instRoot + "/etc/grub.conf",
823     instRoot + "/etc/grub.conf.rpmsave")
824     os.symlink("../boot/grub/grub.conf", instRoot + "/etc/grub.conf")
825     except:
826     pass
827    
828     for dev in self.getPhysicalDevices(rootDev):
829     usedDevs[dev] = 1
830    
831     if not os.access(instRoot + "/boot/grub/device.map", os.R_OK):
832     f = open(instRoot + "/boot/grub/device.map", "w+")
833     f.write("# this device map was generated by anaconda\n")
834     f.write("(fd0) /dev/fd0\n")
835     devs = usedDevs.keys()
836     usedDevs = {}
837     for dev in devs:
838     drive = getDiskPart(dev)[0]
839     if usedDevs.has_key(drive):
840     continue
841     usedDevs[drive] = 1
842     devs = usedDevs.keys()
843     devs.sort()
844     for drive in devs:
845     # XXX hack city. If they're not the sort of thing that'll
846     # be in the device map, they shouldn't still be in the list.
847     if not drive.startswith('md'):
848     f.write("(%s) /dev/%s\n" % (self.grubbyDiskName(drive),
849     drive))
850     f.close()
851    
852     if self.forceLBA32:
853     forcelba = "--force-lba "
854     else:
855     forcelba = ""
856    
857     sysconf = '/etc/sysconfig/grub'
858     if os.access (instRoot + sysconf, os.R_OK):
859     self.perms = os.stat(instRoot + sysconf)[0] & 0777
860     os.rename(instRoot + sysconf,
861     instRoot + sysconf + '.rpmsave')
862     # if it's an absolute symlink, just get it out of our way
863     elif (os.path.islink(instRoot + sysconf) and
864     os.readlink(instRoot + sysconf)[0] == '/'):
865     os.rename(instRoot + sysconf,
866     instRoot + sysconf + '.rpmsave')
867     f = open(instRoot + sysconf, 'w+')
868     f.write("boot=/dev/%s\n" %(grubTarget,))
869     if self.forceLBA32:
870     f.write("forcelba=1\n")
871     else:
872     f.write("forcelba=0\n")
873     f.close()
874    
875     cmds = []
876     for bootDev in bootDevs:
877     gtPart = self.getMatchingPart(bootDev, grubTarget)
878     gtDisk = self.grubbyPartitionName(getDiskPart(gtPart)[0])
879     bPart = self.grubbyPartitionName(bootDev)
880     cmd = "root %s" % (bPart,)
881     cmds.append(cmd)
882    
883     stage1Target = gtDisk
884     if target == "partition":
885     stage1Target = self.grubbyPartitionName(gtPart)
886    
887     cmd = "install %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" % \
888     (forcelba, grubPath, stage1Target, grubPath, bPart, grubPath)
889     cmds.append(cmd)
890    
891     if not justConfigFile:
892     log("GRUB commands:")
893     for cmd in cmds:
894     log("\t%s\n", cmd)
895    
896     # copy the stage files over into /boot
897     rhpl.executil.execWithRedirect( "/sbin/grub-install",
898     ["/sbin/grub-install", "--just-copy"],
899     stdout = "/dev/tty5", stderr = "/dev/tty5",
900     root = instRoot)
901    
902    
903    
904     # FIXME: hack to try to make sure everything is written to the disk
905     if cfPath == "/":
906     syncDataToDisk(bootDev, "/boot", instRoot)
907     else:
908     syncDataToDisk(bootDev, "/", instRoot)
909    
910     # really install the bootloader
911     p = os.pipe()
912     for cmd in cmds:
913     os.write(p[1], cmd + '\n')
914     os.close(p[1])
915     rhpl.executil.execWithRedirect('/sbin/grub' ,
916     [ "grub", "--batch", "--no-floppy",
917     "--device-map=/boot/grub/device.map" ],
918     stdin = p[0],
919     stdout = "/dev/tty5", stderr = "/dev/tty5",
920     root = instRoot)
921     os.close(p[0])
922    
923     return ""
924    
925     def getMatchingPart(self, bootDev, target):
926     bootName, bootPartNum = getDiskPart(bootDev)
927     devices = self.getPhysicalDevices(target)
928     for device in devices:
929     name, partNum = getDiskPart(device)
930     if name == bootName:
931     return device
932     return devices[0]
933    
934    
935     def grubbyDiskName(self, name):
936     return "hd%d" % self.drivelist.index(name)
937    
938     def grubbyPartitionName(self, dev):
939     (name, partNum) = getDiskPart(dev)
940     if partNum != None:
941     return "(%s,%d)" % (self.grubbyDiskName(name), partNum)
942     else:
943     return "(%s)" %(self.grubbyDiskName(name))
944    
945    
946     def getBootloaderConfig(self, instRoot, fsset, bl, langs, kernelList,
947     chainList, defaultDev):
948     config = bootloaderInfo.getBootloaderConfig(self, instRoot, fsset,
949     bl, langs,
950     kernelList, chainList,
951     defaultDev)
952    
953     liloTarget = bl.getDevice()
954    
955     config.addEntry("boot", '/dev/' + liloTarget, replace = 0)
956     config.addEntry("map", "/boot/map", replace = 0)
957     config.addEntry("install", "/boot/boot.b", replace = 0)
958     message = "/boot/message"
959    
960     if self.pure is not None and not self.useGrubVal:
961     config.addEntry("restricted", replace = 0)
962     config.addEntry("password", self.pure, replace = 0)
963    
964    
965     import language
966     for lang in language.expandLangs(langs.getDefault()):
967     fn = "/boot/message." + lang
968     if os.access(instRoot + fn, os.R_OK):
969     message = fn
970     break
971    
972     if self.serial == 1:
973     # grab the 0-based number of the serial console device
974     unit = self.serialDevice[-1]
975     # FIXME: we should probably put some options, but lilo
976     # only supports up to 9600 baud so just use the defaults
977     # it's better than nothing :(
978     config.addEntry("serial=%s" %(unit,))
979     else:
980     # message screws up serial console
981     if os.access(instRoot + message, os.R_OK):
982     config.addEntry("message", message, replace = 0)
983    
984     if not config.testEntry('lba32') and not config.testEntry('linear'):
985     if self.forceLBA32 or (bl.above1024 and
986     butil.getArch() != "x86_64" and
987     edd.detect()):
988     config.addEntry("lba32", replace = 0)
989     elif self.useLinear:
990     config.addEntry("linear", replace = 0)
991     else:
992     config.addEntry("nolinear", replace = 0)
993    
994     return config
995    
996     def writeLilo(self, instRoot, fsset, bl, langs, kernelList,
997     chainList, defaultDev, justConfig):
998     if not self.doUpgradeOnly and len(kernelList) >= 1:
999     config = self.getBootloaderConfig(instRoot, fsset, bl, langs,
1000     kernelList, chainList, defaultDev)
1001     config.write(instRoot + self.configfile, perms = self.perms)
1002     elif self.doUpgradeOnly:
1003     # this is to work around the fact that older kernels don't
1004     # remove themselves from lilo.conf on upgrade
1005     # it's a really bad hack, probably also needs to happen on
1006     # other arches once they support upgradeonly
1007     config = LiloConfigFile ()
1008     if os.access (instRoot + self.configfile, os.R_OK):
1009     self.perms = os.stat(instRoot + self.configfile)[0] & 0777
1010     config.read (instRoot + self.configfile)
1011     # Remove any invalid entries that are in the file; we probably
1012     # just removed those kernels.
1013     for label in config.listImages():
1014     (fsType, sl, path, other) = config.getImage(label)
1015     if fsType == "other": continue
1016    
1017     if not os.access(instRoot + sl.getPath(), os.R_OK):
1018     config.delImage(label)
1019    
1020     # make sure that the default entry really exists. since
1021     # getDefault actually gets the entry for us, we'll get an
1022     # exception if it doesn't really exist.
1023     try:
1024     default = config.getDefault()
1025     except:
1026     try:
1027     config.delEntry("default")
1028     except:
1029     pass
1030    
1031     config.write(instRoot + self.configfile, perms = self.perms)
1032    
1033     # FIXME: do some syncs, just to make sure the config is written out
1034     import isys
1035     isys.sync()
1036     isys.sync()
1037     isys.sync()
1038    
1039     if not justConfig:
1040     str = rhpl.executil.execWithRedirect('/sbin/lilo' ,
1041     ["/sbin/lilo", "-v"],
1042     stdout = "/dev/tty5",
1043     stderr = "/dev/tty5",
1044     root = instRoot)
1045     else:
1046     str = ""
1047    
1048     return str
1049    
1050     # this is a hackish function that depends on the way anaconda writes
1051     # out the grub.conf with a #boot= comment
1052     # XXX this falls into the category of self.doUpgradeOnly
1053     def upgradeGrub(self, instRoot, fsset, bl, langs, kernelList, chainList,
1054     defaultDev, justConfigFile):
1055     if justConfigFile:
1056     return ""
1057    
1058     theDev = None
1059     for (fn, stanza) in [ ("/etc/sysconfig/grub", "boot="),
1060     ("/boot/grub/grub.conf", "#boot=") ]:
1061     try:
1062     f = open(instRoot + fn, "r")
1063     except:
1064     continue
1065    
1066     # the following bits of code are straight from checkbootloader.py
1067     lines = f.readlines()
1068     f.close()
1069     for line in lines:
1070     if line.startswith(stanza):
1071     import checkbootloader
1072     theDev = checkbootloader.getBootDevString(line)
1073     break
1074     if theDev is not None:
1075     break
1076    
1077     if theDev is None:
1078     # we could find the dev before, but can't now... cry about it
1079     return ""
1080    
1081     # migrate info to /etc/sysconfig/grub
1082     sysconf = '/etc/sysconfig/grub'
1083     if not os.access(instRoot + sysconf, os.R_OK):
1084     f = open(instRoot + sysconf, "w+")
1085     f.write("boot=%s\n" %(theDev,))
1086     if self.forceLBA32:
1087     f.write("forcelba=1\n")
1088     else:
1089     f.write("forcelba=0\n")
1090     f.close()
1091    
1092     # more suckage. grub-install can't work without a valid /etc/mtab
1093     # so we have to do shenanigans to get updated grub installed...
1094     # steal some more code above
1095     bootDev = fsset.getEntryByMountPoint("/boot")
1096     grubPath = "/grub"
1097     cfPath = "/"
1098     if not bootDev:
1099     bootDev = fsset.getEntryByMountPoint("/")
1100     grubPath = "/boot/grub"
1101     cfPath = "/boot/"
1102    
1103     masterBootDev = bootDev.device.getDevice(asBoot = 0)
1104     if masterBootDev[0:2] == 'md':
1105     rootDevs = checkbootloader.getRaidDisks(masterBootDev, raidLevel=1,
1106     stripPart = 0)
1107     else:
1108     rootDevs = [masterBootDev]
1109    
1110     if theDev[5:7] == 'md':
1111     stage1Devs = checkbootloader.getRaidDisks(theDev[5:], raidLevel=1)
1112     else:
1113     stage1Devs = [theDev[5:]]
1114    
1115     for stage1Dev in stage1Devs:
1116     # cross fingers; if we can't find a root device on the same
1117     # hardware as this boot device, we just blindly hope the first
1118     # thing in the list works.
1119    
1120     grubbyStage1Dev = self.grubbyPartitionName(stage1Dev)
1121    
1122     grubbyRootPart = self.grubbyPartitionName(rootDevs[0])
1123    
1124     for rootDev in rootDevs:
1125     testGrubbyRootDev = getDiskPart(rootDev)[0]
1126     testGrubbyRootDev = self.grubbyPartitionName(testGrubbyRootDev)
1127    
1128     if grubbyStage1Dev == testGrubbyRootDev:
1129     grubbyRootPart = self.grubbyPartitionName(rootDev)
1130     break
1131    
1132     cmd = "root %s\ninstall %s/stage1 d %s %s/stage2 p %s%s/grub.conf" \
1133     % (grubbyRootPart, grubPath, grubbyStage1Dev,
1134     grubPath, grubbyRootPart, grubPath)
1135    
1136     if not justConfigFile:
1137     log("GRUB command %s", cmd)
1138    
1139     # copy the stage files over into /boot
1140     rhpl.executil.execWithRedirect( "/sbin/grub-install",
1141     ["/sbin/grub-install", "--just-copy"],
1142     stdout = "/dev/tty5", stderr = "/dev/tty5",
1143     root = instRoot)
1144    
1145     # get the stage files synced to disk
1146     import isys
1147     isys.sync()
1148     isys.sync()
1149     isys.sync()
1150    
1151     # really install the bootloader
1152     p = os.pipe()
1153     os.write(p[1], cmd + '\n')
1154     os.close(p[1])
1155     rhpl.executil.execWithRedirect('/sbin/grub' ,
1156     [ "grub", "--batch", "--no-floppy",
1157     "--device-map=/boot/grub/device.map" ],
1158     stdin = p[0],
1159     stdout = "/dev/tty5", stderr = "/dev/tty5",
1160     root = instRoot)
1161     os.close(p[0])
1162    
1163     return ""
1164    
1165    
1166     def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
1167     defaultDev, justConfig, intf):
1168     # XXX HACK ALERT - see declaration above
1169     if self.doUpgradeOnly:
1170     if not self.useGrubVal:
1171     # we do upgrades sort of right for lilo...
1172     str = self.writeLilo(instRoot, fsset, bl, langs, kernelList,
1173     chainList, defaultDev,
1174     justConfig | (self.useGrubVal))
1175     else:
1176     self.upgradeGrub(instRoot, fsset, bl, langs, kernelList,
1177     chainList, defaultDev, justConfig)
1178    
1179     # and the hacks continue. with 2.6, ide-scsi isn't used
1180     # anymore (#116622)
1181     import isys
1182     cdrw = isys.ideCdRwList()
1183     torem = []
1184     for device in cdrw:
1185     torem.append("%s=ide-scsi" %(device,))
1186    
1187     for fn in ("/etc/lilo.conf", "/boot/grub/grub.conf",
1188     "/etc/lilo.conf.anaconda"):
1189     if not os.path.exists(instRoot + fn):
1190     continue
1191     f = open(instRoot + fn, "r")
1192     buf = f.read()
1193     f.close()
1194     for dev in torem:
1195     buf = buf.replace(dev, "")
1196     f = open(instRoot + fn, "w")
1197     f.write(buf)
1198     f.close()
1199     return
1200     if len(kernelList) < 1:
1201     self.noKernelsWarn(intf)
1202    
1203     str = self.writeLilo(instRoot, fsset, bl, langs, kernelList,
1204     chainList, defaultDev,
1205     justConfig | (self.useGrubVal))
1206     str = self.writeGrub(instRoot, fsset, bl, langs, kernelList,
1207     chainList, defaultDev,
1208     justConfig | (not self.useGrubVal))
1209     # XXX move the lilo.conf out of the way if they're using GRUB
1210     # so that /sbin/installkernel does a more correct thing
1211     if self.useGrubVal and os.access(instRoot + '/etc/lilo.conf', os.R_OK):
1212     os.rename(instRoot + "/etc/lilo.conf",
1213     instRoot + "/etc/lilo.conf.anaconda")
1214    
1215    
1216    
1217     def getArgList(self):
1218     args = bootloaderInfo.getArgList(self)
1219    
1220     if not self.useGrubVal:
1221     args.append("--useLilo")
1222     if self.forceLBA32:
1223     args.append("--lba32")
1224     if not self.useLinear:
1225     args.append("--nolinear")
1226     if self.password:
1227     args.append("--md5pass=%s" %(self.password))
1228    
1229    
1230     # XXX add location of bootloader here too
1231    
1232     return args
1233    
1234     def __init__(self):
1235     bootloaderInfo.__init__(self)
1236     # XXX use checkbootloader to determine what to default to
1237     self.useGrubVal = 1
1238     self.kernelLocation = "/boot/"
1239     self.configfile = "/etc/lilo.conf"
1240     self.password = None
1241     self.pure = None
1242    
1243     class s390BootloaderInfo(bootloaderInfo):
1244     def getBootloaderConfig(self, instRoot, fsset, bl, langs, kernelList,
1245     chainList, defaultDev):
1246     images = bl.images.getImages()
1247    
1248     # on upgrade read in the lilo config file
1249     lilo = LiloConfigFile ()
1250     self.perms = 0600
1251     if os.access (instRoot + self.configfile, os.R_OK):
1252     self.perms = os.stat(instRoot + self.configfile)[0] & 0777
1253     lilo.read (instRoot + self.configfile)
1254     os.rename(instRoot + self.configfile,
1255     instRoot + self.configfile + '.rpmsave')
1256    
1257     # Remove any invalid entries that are in the file; we probably
1258     # just removed those kernels.
1259     for label in lilo.listImages():
1260     (fsType, sl, path, other) = lilo.getImage(label)
1261     if fsType == "other": continue
1262    
1263     if not os.access(instRoot + sl.getPath(), os.R_OK):
1264     lilo.delImage(label)
1265    
1266     rootDev = fsset.getEntryByMountPoint("/").device.getDevice()
1267     if not rootDev:
1268     raise RuntimeError, "Installing zipl, but there is no root device"
1269    
1270     if rootDev == defaultDev:
1271     lilo.addEntry("default", kernelList[0][0])
1272     else:
1273     lilo.addEntry("default", chainList[0][0])
1274    
1275     for (label, longlabel, version) in kernelList:
1276     kernelTag = "-" + version
1277     kernelFile = self.kernelLocation + "vmlinuz" + kernelTag
1278    
1279     try:
1280     lilo.delImage(label)
1281     except IndexError, msg:
1282     pass
1283    
1284     sl = LiloConfigFile(imageType = "image", path = kernelFile)
1285    
1286     initrd = booty.makeInitrd (kernelTag, instRoot)
1287    
1288     sl.addEntry("label", label)
1289     if os.access (instRoot + initrd, os.R_OK):
1290     sl.addEntry("initrd",
1291     "%sinitrd%s.img" %(self.kernelLocation, kernelTag))
1292    
1293     sl.addEntry("read-only")
1294     sl.addEntry("root", '/dev/' + rootDev)
1295     sl.addEntry("ipldevice", '/dev/' + rootDev[:-1])
1296    
1297     if self.args.get():
1298     sl.addEntry('append', '"%s"' % self.args.get())
1299    
1300     lilo.addImage (sl)
1301    
1302     for (label, longlabel, device) in chainList:
1303     if ((not label) or (label == "")):
1304     continue
1305     try:
1306     (fsType, sl, path, other) = lilo.getImage(label)
1307     lilo.delImage(label)
1308     except IndexError:
1309     sl = LiloConfigFile(imageType = "other",
1310     path = "/dev/%s" %(device))
1311     sl.addEntry("optional")
1312    
1313     sl.addEntry("label", label)
1314     lilo.addImage (sl)
1315    
1316     # Sanity check #1. There could be aliases in sections which conflict
1317     # with the new images we just created. If so, erase those aliases
1318     imageNames = {}
1319     for label in lilo.listImages():
1320     imageNames[label] = 1
1321    
1322     for label in lilo.listImages():
1323     (fsType, sl, path, other) = lilo.getImage(label)
1324     if sl.testEntry('alias'):
1325     alias = sl.getEntry('alias')
1326     if imageNames.has_key(alias):
1327     sl.delEntry('alias')
1328     imageNames[alias] = 1
1329    
1330     # Sanity check #2. If single-key is turned on, go through all of
1331     # the image names (including aliases) (we just built the list) and
1332     # see if single-key will still work.
1333     if lilo.testEntry('single-key'):
1334     singleKeys = {}
1335     turnOff = 0
1336     for label in imageNames.keys():
1337     l = label[0]
1338     if singleKeys.has_key(l):
1339     turnOff = 1
1340     singleKeys[l] = 1
1341     if turnOff:
1342     lilo.delEntry('single-key')
1343    
1344     return lilo
1345    
1346     def writeChandevConf(self, bl, instroot): # S/390 only
1347     cf = "/etc/chandev.conf"
1348     self.perms = 0644
1349     if bl.args.chandevget():
1350     fd = os.open(instroot + "/etc/chandev.conf",
1351     os.O_WRONLY | os.O_CREAT)
1352     os.write(fd, "noauto\n")
1353     for cdev in bl.args.chandevget():
1354     os.write(fd,'%s\n' % cdev)
1355     os.close(fd)
1356     return ""
1357    
1358    
1359     def writeZipl(self, instRoot, fsset, bl, langs, kernelList, chainList,
1360     defaultDev, justConfigFile):
1361     images = bl.images.getImages()
1362     rootDev = fsset.getEntryByMountPoint("/").device.getDevice()
1363    
1364     cf = '/etc/zipl.conf'
1365     self.perms = 0600
1366     if os.access (instRoot + cf, os.R_OK):
1367     self.perms = os.stat(instRoot + cf)[0] & 0777
1368     os.rename(instRoot + cf,
1369     instRoot + cf + '.rpmsave')
1370    
1371     f = open(instRoot + cf, "w+")
1372    
1373     f.write('[defaultboot]\n')
1374     f.write('default=' + kernelList[0][0] + '\n')
1375     f.write('target=%s\n' % (self.kernelLocation))
1376    
1377     cfPath = "/boot/"
1378     for (label, longlabel, version) in kernelList:
1379     kernelTag = "-" + version
1380     kernelFile = "%svmlinuz%s" % (cfPath, kernelTag)
1381    
1382     initrd = booty.makeInitrd (kernelTag, instRoot)
1383     f.write('[%s]\n' % (label))
1384     f.write('\timage=%s\n' % (kernelFile))
1385     if os.access (instRoot + initrd, os.R_OK):
1386     f.write('\tramdisk=%sinitrd%s.img\n' %(self.kernelLocation,
1387     kernelTag))
1388     realroot = getRootDevName(initrd, fsset, rootDev, instRoot)
1389     f.write('\tparameters="root=%s' %(realroot,))
1390     if bl.args.get():
1391     f.write(' %s' % (bl.args.get()))
1392     f.write('"\n')
1393    
1394     f.close()
1395    
1396     if not justConfigFile:
1397     argv = [ "/sbin/zipl" ]
1398     rhpl.executil.execWithRedirect(argv[0], argv, root = instRoot,
1399     stdout = "/dev/stdout",
1400     stderr = "/dev/stderr")
1401    
1402     return ""
1403    
1404     def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
1405     defaultDev, justConfig, intf):
1406     str = self.writeZipl(instRoot, fsset, bl, langs, kernelList,
1407     chainList, defaultDev,
1408     justConfig | (not self.useZiplVal))
1409     str = self.writeChandevConf(bl, instRoot)
1410    
1411     def __init__(self):
1412     bootloaderInfo.__init__(self)
1413     self.useZiplVal = 1 # only used on s390
1414     self.kernelLocation = "/boot/"
1415     self.configfile = "/etc/zipl.conf"
1416    
1417    
1418     class alphaBootloaderInfo(bootloaderInfo):
1419     def wholeDevice (self, path):
1420     (device, foo) = getDiskPart(path)
1421     return device
1422    
1423     def partitionNum (self, path):
1424     # getDiskPart returns part numbers 0-based; we need it one based
1425     # *sigh*
1426     (foo, partitionNumber) = getDiskPart(path)
1427     return partitionNumber + 1
1428    
1429     # See if we would have to use MILO. MILO isn't supported by Red Hat.
1430     def useMilo (self):
1431     try:
1432     f = open ('/proc/cpuinfo', 'ro')
1433     except:
1434     return
1435     lines = f.readlines ()
1436     f.close()
1437     serial = ""
1438     for line in lines:
1439     if line.find("system serial number") != -1:
1440     serial = string.strip (string.split (line, ':')[1])
1441     break
1442    
1443     if serial and len (serial) >= 4 and serial.startswith("MILO"):
1444     return 1
1445     else:
1446     return 0
1447    
1448     def writeAboot(self, instRoot, fsset, bl, langs, kernelList,
1449     chainList, defaultDev, justConfig):
1450     # Get bootDevice and rootDevice
1451     rootDevice = fsset.getEntryByMountPoint("/").device.getDevice()
1452     if fsset.getEntryByMountPoint("/boot"):
1453     bootDevice = fsset.getEntryByMountPoint("/boot").device.getDevice()
1454     else:
1455     bootDevice = rootDevice
1456     bootnotroot = bootDevice != rootDevice
1457    
1458     # If /etc/aboot.conf already exists we rename it
1459     # /etc/aboot.conf.rpmsave.
1460     if os.path.isfile(instRoot + self.configfile):
1461     os.rename (instRoot + self.configfile,
1462     instRoot + self.configfile + ".rpmsave")
1463    
1464     # Then we create the necessary files. If the root device isn't
1465     # the boot device, we create /boot/etc/ where the aboot.conf
1466     # will live, and we create /etc/aboot.conf as a symlink to it.
1467     if bootnotroot:
1468     # Do we have /boot/etc ? If not, create one
1469     if not os.path.isdir (instRoot + '/boot/etc'):
1470     os.mkdir(instRoot + '/boot/etc', 0755)
1471    
1472     # We install the symlink (/etc/aboot.conf has already been
1473     # renamed in necessary.)
1474     os.symlink("../boot" + self.configfile, instRoot + self.configfile)
1475    
1476     cfPath = instRoot + "/boot" + self.configfile
1477     # Kernel path is set to / because a boot partition will
1478     # be a root on its own.
1479     kernelPath = '/'
1480     # Otherwise, we just need to create /etc/aboot.conf.
1481     else:
1482     cfPath = instRoot + self.configfile
1483     kernelPath = self.kernelLocation
1484    
1485     # If we already have an aboot.conf, rename it
1486     if os.access (cfPath, os.R_OK):
1487     self.perms = os.stat(cfPath)[0] & 0777
1488     os.rename(cfPath, cfPath + '.rpmsave')
1489    
1490     # Now we're going to create and populate cfPath.
1491     f = open (cfPath, 'w+')
1492     f.write ("# aboot default configurations\n")
1493    
1494     if bootnotroot:
1495     f.write ("# NOTICE: You have a /boot partition. This means that\n")
1496     f.write ("# all kernel paths are relative to /boot/\n")
1497    
1498     # bpn is the boot partition number.
1499     bpn = self.partitionNum(bootDevice)
1500     lines = 0
1501    
1502     # We write entries line using the following format:
1503     # <line><bpn><kernel-name> root=<rootdev> [options]
1504     # We get all the kernels we need to know about in kernelList.
1505    
1506     for (kernel, tag, kernelTag) in kernelList:
1507     kernelFile = "%svmlinuz-%s" %(kernelPath, kernelTag)
1508    
1509     f.write("%d:%d%s" %(lines, bpn, kernelFile))
1510    
1511     # See if we can come up with an initrd argument that exists
1512     initrd = booty.makeInitrd (kernelTag, instRoot)
1513     if os.access(instRoot + initrd, os.R_OK):
1514     f.write(" initrd=%sinitrd-%s.img" %(kernelPath, kernelTag))
1515    
1516     realroot = getRootDevName(initrd, fsset, rootDevice, instRoot)
1517     f.write(" root=%s" %(realroot,))
1518    
1519     args = self.args.get()
1520     if args:
1521     f.write(" %s" %(args,))
1522    
1523     f.write("\n")
1524     lines = lines + 1
1525    
1526     # We're done writing the file
1527     f.close ()
1528     del f
1529    
1530     if not justConfig:
1531     # Now we're ready to write the relevant boot information. wbd
1532     # is the whole boot device, bdpn is the boot device partition
1533     # number.
1534     wbd = self.wholeDevice (bootDevice)
1535     bdpn = self.partitionNum (bootDevice)
1536    
1537     # Calling swriteboot. The first argument is the disk to write
1538     # to and the second argument is a path to the bootstrap loader
1539     # file.
1540     args = ("swriteboot", ("/dev/%s" % wbd), "/boot/bootlx")
1541     log("swriteboot command: %s" %(args,))
1542     rhpl.executil.execWithRedirect ('/sbin/swriteboot', args,
1543     root = instRoot,
1544     stdout = "/dev/tty5",
1545     stderr = "/dev/tty5")
1546    
1547     # Calling abootconf to configure the installed aboot. The
1548     # first argument is the disk to use, the second argument is
1549     # the number of the partition on which aboot.conf resides.
1550     # It's always the boot partition whether it's / or /boot (with
1551     # the mount point being omitted.)
1552     args = ("abootconf", ("/dev/%s" % wbd), str (bdpn))
1553     log("abootconf command: %s" %(args,))
1554     rhpl.executil.execWithRedirect ('/sbin/abootconf', args,
1555     root = instRoot,
1556     stdout = "/dev/tty5",
1557     stderr = "/dev/tty5")
1558    
1559    
1560     def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
1561     defaultDev, justConfig, intf):
1562     if len(kernelList) < 1:
1563     self.noKernelsWarn(intf)
1564    
1565     if self.useMilo():
1566     intf.messageWindow(_("MILO Not Supported"),
1567     "This system requires the support of MILO to " +
1568     "boot linux (MILO is not included in this " +
1569     "distribution.) The installation of the " +
1570     "bootloader can't be completed on this system.")
1571     # elif not justConfig FIXME.
1572     else:
1573     self.writeAboot(instRoot, fsset, bl, langs, kernelList,
1574     chainList, defaultDev, justConfig)
1575    
1576     def __init__(self):
1577     bootloaderInfo.__init__(self)
1578     self.useGrubVal = 0
1579     self.configfile = "/etc/aboot.conf"
1580     # self.kernelLocation is already set to what we need.
1581     self.password = None
1582     self.pure = None
1583    
1584    
1585     class ppcBootloaderInfo(bootloaderInfo):
1586     def writeYaboot(self, instRoot, fsset, bl, langs, kernelList,
1587     chainList, defaultDev, justConfigFile):
1588    
1589     from flags import flags
1590    
1591     yabootTarget = '/dev/%s' %(bl.getDevice())
1592    
1593     bootDev = fsset.getEntryByMountPoint("/boot")
1594     if bootDev:
1595     cf = "/boot/etc/yaboot.conf"
1596     cfPath = ""
1597     if not os.path.isdir(instRoot + "/boot/etc"):
1598     os.mkdir(instRoot + "/boot/etc")
1599     else:
1600     bootDev = fsset.getEntryByMountPoint("/")
1601     cfPath = "/boot"
1602     cf = "/etc/yaboot.conf"
1603     bootDev = bootDev.device.getDevice(asBoot = 1)
1604    
1605     f = open(instRoot + cf, "w+")
1606     f.write("# yaboot.conf generated by anaconda\n\n")
1607    
1608     f.write("boot=%s\n" %(yabootTarget,))
1609     f.write("init-message=Welcome to %s\\!\nHit <TAB> for boot options\n\n"
1610     %(butil.getProductName(),))
1611    
1612     (name, partNum) = getDiskPart(bootDev)
1613     partno = partNum + 1 # 1 based
1614     f.write("partition=%s\n" %(partno,))
1615    
1616     f.write("timeout=20\n")
1617     f.write("install=/usr/lib/yaboot/yaboot\n")
1618     f.write("delay=5\n")
1619    
1620     if butil.getPPCMachine() == "PMac":
1621     f.write("magicboot=/usr/lib/yaboot/ofboot\n")
1622    
1623     if butil.getPPCMachine() == "pSeries":
1624     f.write("nonvram\n")
1625    
1626     if self.password:
1627     f.write("password=%s\n" %(self.password,))
1628     f.write("restricted\n")
1629    
1630    
1631     f.write("\n")
1632    
1633     rootDev = fsset.getEntryByMountPoint("/").device.getDevice()
1634    
1635     for (label, longlabel, version) in kernelList:
1636     kernelTag = "-" + version
1637     kernelFile = "%s/vmlinuz%s" %(cfPath, kernelTag)
1638    
1639     f.write("image=%s\n" %(kernelFile,))
1640     f.write("\tlabel=%s\n" %(label,))
1641     f.write("\tread-only\n")
1642    
1643     initrd = booty.makeInitrd(kernelTag, instRoot)
1644     if os.access(instRoot + initrd, os.R_OK):
1645     f.write("\tinitrd=%s/initrd%s.img\n" %(cfPath,kernelTag))
1646    
1647     append = "%s" %(self.args.get(),)
1648    
1649     realroot = getRootDevName(initrd, fsset, rootDev, instRoot)
1650     if not realroot.startswith("LABEL="):
1651     f.write("\troot=%s\n" %(realroot,))
1652     else:
1653     if len(append) > 0:
1654     append = "%s root=%s" %(append,realroot)
1655     else:
1656     append = "root=%s" %(realroot,)
1657    
1658     if len(append) > 0:
1659     f.write("\tappend=\"%s\"\n" %(append,))
1660     f.write("\n")
1661    
1662     f.close()
1663     os.chmod(instRoot + cf, 0600)
1664    
1665     # FIXME: hack to make sure things are written to disk
1666     import isys
1667     isys.sync()
1668     isys.sync()
1669     isys.sync()
1670    
1671     ybinargs = [ "/sbin/mkofboot", "-f", "-C", cf ]
1672     if butil.getPPCMachine() == "pSeries":
1673     ybinargs.extend(["--filesystem", "raw"])
1674    
1675    
1676     log("running: %s" %(ybinargs,))
1677     if not flags.test:
1678     rhpl.executil.execWithRedirect(ybinargs[0],
1679     ybinargs,
1680     stdout = "/dev/tty5",
1681     stderr = "/dev/tty5",
1682     root = instRoot)
1683    
1684     if (not os.access(instRoot + "/etc/yaboot.conf", os.R_OK) and
1685     os.access(instRoot + "/boot/etc/yaboot.conf", os.R_OK)):
1686     os.symlink("../boot/etc/yaboot.conf",
1687     instRoot + "/etc/yaboot.conf")
1688    
1689     return ""
1690    
1691     def setPassword(self, val, isCrypted = 1):
1692     # yaboot just handles the password and doesn't care if its crypted
1693     # or not
1694     self.password = val
1695    
1696     def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
1697     defaultDev, justConfig, intf):
1698     if len(kernelList) >= 1:
1699     str = self.writeYaboot(instRoot, fsset, bl, langs, kernelList,
1700     chainList, defaultDev, justConfig)
1701     else:
1702     self.noKernelsWarn(intf)
1703    
1704     def __init__(self):
1705     bootloaderInfo.__init__(self)
1706     self.useYabootVal = 1
1707     self.kernelLocation = "/boot"
1708     self.configfile = "/etc/yaboot.conf"
1709    
1710    
1711     class iseriesBootloaderInfo(bootloaderInfo):
1712     def ddFile(self, inf, of, bs = 4096):
1713     src = os.open(inf, os.O_RDONLY)
1714     dest = os.open(of, os.O_WRONLY | os.O_CREAT)
1715     size = 0
1716    
1717     buf = os.read(src, bs)
1718     while len(buf) > 0:
1719     size = size + len(buf)
1720     os.write(dest, buf)
1721     buf = os.read(src, bs)
1722    
1723     os.close(src)
1724     os.close(dest)
1725    
1726     return size
1727    
1728     def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
1729     defaultDev, justConfig, intf):
1730     if len(kernelList) < 1:
1731     self.noKernelsWarn(intf)
1732     return
1733     if len(kernelList) > 1:
1734     # FIXME: how can this happen?
1735     log("more than one kernel on iSeries. bailing and just using "
1736     "the first")
1737    
1738     # iseries is Weird (tm) -- here's the basic theory
1739     # a) have /boot/vmlinitrd-$(version)
1740     # b) copy default kernel to PReP partition
1741     # c) dd default kernel to /proc/iSeries/mf/C/vmlinux
1742     # d) set cmdline in /boot/cmdline-$(version)
1743     # e) copy cmdline to /proc/iSeries/mf/C/cmdline
1744     # f) set default side to 'C' i /proc/iSeries/mf/side
1745     # g) put default kernel and cmdline on side B too (#91038)
1746    
1747     rootDevice = fsset.getEntryByMountPoint("/").device.getDevice()
1748    
1749     # write our command line files
1750     for (kernel, tag, kernelTag) in kernelList:
1751     cmdFile = "%scmdline-%s" %(self.kernelLocation, kernelTag)
1752     initrd = "%sinitrd-%s.img" %(self.kernelLocation, kernelTag)
1753     realroot = getRootDevName(initrd, fsset, rootDevice, instRoot)
1754     f = open(instRoot + cmdFile, "w")
1755     f.write("ro root=%s" %(realroot,))
1756     if bl.args.get():
1757     f.write(" %s" %(bl.args.get(),))
1758     f.write("\n")
1759     f.close()
1760     os.chmod(instRoot + cmdFile, 0644)
1761    
1762     kernel, tag, kernelTag = kernelList[0]
1763     kernelFile = "%svmlinitrd-%s" %(self.kernelLocation, kernelTag)
1764    
1765     # write the kernel to the PReP partition since that's what
1766     # OS/400 will load as NWSSTG
1767     bootDev = bl.getDevice()
1768     if bootDev:
1769     log("Writing kernel %s to PReP partition %s" %(kernelFile,
1770     bootDev))
1771     try:
1772     self.ddFile(instRoot + kernelFile, "%s/dev/%s" %(instRoot,
1773     bootDev))
1774     except Exception, e:
1775     # FIXME: should this be more fatal
1776     log("Failed to write kernel: %s" %(e,))
1777     else:
1778     log("No PReP boot partition, not writing kernel for NWSSTG")
1779    
1780    
1781     # now, it's a lot faster to boot if we don't make people go back
1782     # into OS/400, so set up side C (used by default for NWSSTG) with
1783     # our current bits
1784     for side in ("C", "B"):
1785     log("Writing kernel and cmdline to side %s" %(side,))
1786     wrotekernel = 0
1787     try:
1788     self.ddFile(instRoot + kernelFile,
1789     "%s/proc/iSeries/mf/%s/vmlinux" %(instRoot, side))
1790     wrotekernel = 1
1791     except Exception, e:
1792     # FIXME: should this be more fatal?
1793     log("Failed to write kernel to side %s: %s" %(side, e))
1794    
1795     if wrotekernel == 1:
1796     try:
1797     # blank it. ugh.
1798     f = open("%s/proc/iSeries/mf/%s/cmdline" %(instRoot, side),
1799     "w+")
1800     f.write(" " * 255)
1801     f.close()
1802    
1803     self.ddFile("%s/%scmdline-%s" %(instRoot,
1804     self.kernelLocation,
1805     kernelTag),
1806     "%s/proc/iSeries/mf/%s/cmdline" %(instRoot,
1807     side))
1808     except Exception, e:
1809     log("Failed to write kernel command line to side %s: %s"
1810     %(side, e))
1811    
1812     log("Setting default side to C")
1813     f = open(instRoot + "/proc/iSeries/mf/side", "w")
1814     f.write("C")
1815     f.close()
1816    
1817     def __init__(self):
1818     bootloaderInfo.__init__(self)
1819     self.kernelLocation = "/boot/"
1820    
1821    
1822    
1823     ###############
1824     # end of boot loader objects... these are just some utility functions used
1825    
1826     # return (disk, partition number) eg ('hda', 1)
1827     def getDiskPart(dev):
1828     cut = len(dev)
1829     if (dev.startswith('rd/') or dev.startswith('ida/') or
1830     dev.startswith('cciss/')):
1831     if dev[-2] == 'p':
1832     cut = -1
1833     elif dev[-3] == 'p':
1834     cut = -2
1835     else:
1836     if dev[-2] in string.digits:
1837     cut = -2
1838     elif dev[-1] in string.digits:
1839     cut = -1
1840    
1841     name = dev[:cut]
1842    
1843     # hack off the trailing 'p' from /dev/cciss/*, for example
1844     if name[-1] == 'p':
1845     for letter in name:
1846     if letter not in string.letters and letter != "/":
1847     name = name[:-1]
1848     break
1849    
1850     if cut < 0:
1851     partNum = int(dev[cut:]) - 1
1852     else:
1853     partNum = None
1854    
1855     return (name, partNum)
1856    
1857     # hackery to determine if we should do root=LABEL=/ or whatnot
1858     # as usual, knows too much about anaconda
1859     def getRootDevName(initrd, fsset, rootDev, instRoot):
1860     if not os.access(instRoot + initrd, os.R_OK):
1861     return "/dev/%s" % (rootDev,)
1862    
1863     try:
1864     rootEntry = fsset.getEntryByMountPoint("/")
1865     if rootEntry.getLabel() is not None:
1866     return "LABEL=%s" %(rootEntry.getLabel(),)
1867     return "/dev/%s" %(rootDev,)
1868     except:
1869     return "/dev/%s" %(rootDev,)
1870    

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed