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

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

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


Revision 1.9 - (show annotations) (download) (as text)
Tue Jun 6 18:23:19 2006 UTC (18 years, 6 months ago) by segfault-
Branch: MAIN
Changes since 1.8: +11 -5 lines
Content type: text/x-python
Revert grub install behaviour to fix BZ 1510

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

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