/[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.7 - (show annotations) (download) (as text)
Wed Apr 5 05:13:40 2006 UTC (18 years, 8 months ago) by slords
Branch: MAIN
Changes since 1.6: +3 -0 lines
Content type: text/x-python
Make sure all boot devices are included in the map

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 isys
20 import os, sys
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 gtDisk = self.grubbyPartitionName(getDiskPart(bootDev)[0])
893 bPart = self.grubbyPartitionName(bootDev)
894 cmd = "root %s" % (bPart,)
895 cmds.append(cmd)
896
897 stage1Target = gtDisk
898 if target == "partition":
899 stage1Target = self.grubbyPartitionName(bootDev)
900
901 cmd = "install %s/stage1 %s %s1+16 p %s%s/stage2 %s/grub.conf" % \
902 (grubPath, stage1Target, stage1Target, bPart, grubPath, grubPath)
903 cmds.append(cmd)
904
905 if not justConfigFile:
906 log("GRUB commands:")
907 for cmd in cmds:
908 log("\t%s\n", cmd)
909
910 # copy the stage files over into /boot
911 rhpl.executil.execWithRedirect( "/sbin/grub-install",
912 ["/sbin/grub-install", "--just-copy"],
913 stdout = "/dev/tty5", stderr = "/dev/tty5",
914 root = instRoot)
915
916
917
918 # FIXME: hack to try to make sure everything is written to the disk
919 if cfPath == "/":
920 syncDataToDisk(bootDev, "/boot", instRoot)
921 else:
922 syncDataToDisk(bootDev, "/", instRoot)
923
924 # really install the bootloader
925 p = os.pipe()
926 for cmd in cmds:
927 os.write(p[1], cmd + '\n')
928 os.close(p[1])
929 rhpl.executil.execWithRedirect('/sbin/grub' ,
930 [ "grub", "--batch", "--no-floppy",
931 "--device-map=/boot/grub/device.map" ],
932 stdin = p[0],
933 stdout = "/dev/tty5", stderr = "/dev/tty5",
934 root = instRoot)
935 os.close(p[0])
936
937 return ""
938
939 def getMatchingPart(self, bootDev, target):
940 bootName, bootPartNum = getDiskPart(bootDev)
941 devices = self.getPhysicalDevices(target)
942 for device in devices:
943 name, partNum = getDiskPart(device)
944 if name == bootName:
945 return device
946 return devices[0]
947
948 def grubbyDiskName(self, name):
949 return "hd%d" % self.drivelist.index(name)
950
951 def grubbyPartitionName(self, dev):
952 (name, partNum) = getDiskPart(dev)
953 if partNum != None:
954 return "(%s,%d)" % (self.grubbyDiskName(name), partNum)
955 else:
956 return "(%s)" %(self.grubbyDiskName(name))
957
958
959 def getBootloaderConfig(self, instRoot, fsset, bl, langs, kernelList,
960 chainList, defaultDev):
961 config = bootloaderInfo.getBootloaderConfig(self, instRoot, fsset,
962 bl, langs,
963 kernelList, chainList,
964 defaultDev)
965
966 liloTarget = bl.getDevice()
967
968 config.addEntry("boot", '/dev/' + liloTarget, replace = 0)
969 config.addEntry("map", "/boot/map", replace = 0)
970 config.addEntry("install", "/boot/boot.b", replace = 0)
971 message = "/boot/message"
972
973 if self.pure is not None and not self.useGrubVal:
974 config.addEntry("restricted", replace = 0)
975 config.addEntry("password", self.pure, replace = 0)
976
977
978 import language
979 for lang in language.expandLangs(langs.getDefault()):
980 fn = "/boot/message." + lang
981 if os.access(instRoot + fn, os.R_OK):
982 message = fn
983 break
984
985 if self.serial == 1:
986 # grab the 0-based number of the serial console device
987 unit = self.serialDevice[-1]
988 # FIXME: we should probably put some options, but lilo
989 # only supports up to 9600 baud so just use the defaults
990 # it's better than nothing :(
991 config.addEntry("serial=%s" %(unit,))
992 else:
993 # message screws up serial console
994 if os.access(instRoot + message, os.R_OK):
995 config.addEntry("message", message, replace = 0)
996
997 if not config.testEntry('lba32'):
998 if self.forceLBA32 or (bl.above1024 and
999 butil.getArch() != "x86_64" and
1000 edd.detect()):
1001 config.addEntry("lba32", replace = 0)
1002
1003 return config
1004
1005 # this is a hackish function that depends on the way anaconda writes
1006 # out the grub.conf with a #boot= comment
1007 # XXX this falls into the category of self.doUpgradeOnly
1008 def upgradeGrub(self, instRoot, fsset, bl, langs, kernelList, chainList,
1009 defaultDev, justConfigFile):
1010 if justConfigFile:
1011 return ""
1012
1013 theDev = None
1014 for (fn, stanza) in [ ("/etc/sysconfig/grub", "boot="),
1015 ("/boot/grub/grub.conf", "#boot=") ]:
1016 try:
1017 f = open(instRoot + fn, "r")
1018 except:
1019 continue
1020
1021 # the following bits of code are straight from checkbootloader.py
1022 lines = f.readlines()
1023 f.close()
1024 for line in lines:
1025 if line.startswith(stanza):
1026 theDev = checkbootloader.getBootDevString(line)
1027 break
1028 if theDev is not None:
1029 break
1030
1031 if theDev is None:
1032 # we could find the dev before, but can't now... cry about it
1033 return ""
1034
1035 # migrate info to /etc/sysconfig/grub
1036 sysconf = '/etc/sysconfig/grub'
1037 if not os.access(instRoot + sysconf, os.R_OK):
1038 f = open(instRoot + sysconf, "w+")
1039 f.write("boot=%s\n" %(theDev,))
1040 # XXX forcelba never gets read back at all...
1041 if self.forceLBA32:
1042 f.write("forcelba=1\n")
1043 else:
1044 f.write("forcelba=0\n")
1045 f.close()
1046
1047 # more suckage. grub-install can't work without a valid /etc/mtab
1048 # so we have to do shenanigans to get updated grub installed...
1049 # steal some more code above
1050 bootDev = fsset.getEntryByMountPoint("/boot")
1051 grubPath = "/grub"
1052 cfPath = "/"
1053 if not bootDev:
1054 bootDev = fsset.getEntryByMountPoint("/")
1055 grubPath = "/boot/grub"
1056 cfPath = "/boot/"
1057
1058 masterBootDev = bootDev.device.getDevice(asBoot = 0)
1059 if masterBootDev[0:2] == 'md':
1060 rootDevs = checkbootloader.getRaidDisks(masterBootDev, raidLevel=1,
1061 stripPart = 0)
1062 else:
1063 rootDevs = [masterBootDev]
1064
1065 if theDev[5:7] == 'md':
1066 stage1Devs = checkbootloader.getRaidDisks(theDev[5:], raidLevel=1)
1067 else:
1068 stage1Devs = [theDev[5:]]
1069
1070 for stage1Dev in stage1Devs:
1071 # cross fingers; if we can't find a root device on the same
1072 # hardware as this boot device, we just blindly hope the first
1073 # thing in the list works.
1074
1075 grubbyStage1Dev = self.grubbyPartitionName(stage1Dev)
1076
1077 grubbyRootPart = self.grubbyPartitionName(rootDevs[0])
1078
1079 for rootDev in rootDevs:
1080 testGrubbyRootDev = getDiskPart(rootDev)[0]
1081 testGrubbyRootDev = self.grubbyPartitionName(testGrubbyRootDev)
1082
1083 if grubbyStage1Dev == testGrubbyRootDev:
1084 grubbyRootPart = self.grubbyPartitionName(rootDev)
1085 break
1086
1087 cmd = "root %s\ninstall %s/stage1 %s %s1+16 p %s%s/stage2 %s/grub.conf" \
1088 % (grubbyRootPart, grubPath, stage1Dev, stage1Dev,
1089 grubbyRootPart, grubPath, grubPath)
1090
1091 if not justConfigFile:
1092 log("GRUB command %s", cmd)
1093
1094 # copy the stage files over into /boot
1095 rhpl.executil.execWithRedirect( "/sbin/grub-install",
1096 ["/sbin/grub-install", "--just-copy"],
1097 stdout = "/dev/tty5", stderr = "/dev/tty5",
1098 root = instRoot)
1099
1100 # get the stage files synced to disk
1101 import isys
1102 isys.sync()
1103 isys.sync()
1104 isys.sync()
1105
1106 # really install the bootloader
1107 p = os.pipe()
1108 os.write(p[1], cmd + '\n')
1109 os.close(p[1])
1110 rhpl.executil.execWithRedirect('/sbin/grub' ,
1111 [ "grub", "--batch", "--no-floppy",
1112 "--device-map=/boot/grub/device.map" ],
1113 stdin = p[0],
1114 stdout = "/dev/tty5", stderr = "/dev/tty5",
1115 root = instRoot)
1116 os.close(p[0])
1117
1118 return ""
1119
1120
1121 def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
1122 defaultDev, justConfig, intf):
1123 # XXX HACK ALERT - see declaration above
1124 if self.doUpgradeOnly:
1125 if self.useGrubVal:
1126 self.upgradeGrub(instRoot, fsset, bl, langs, kernelList,
1127 chainList, defaultDev, justConfig)
1128
1129 # and the hacks continue. with 2.6, ide-scsi isn't used
1130 # anymore (#116622)
1131 import isys
1132 cdrw = isys.ideCdRwList()
1133 torem = []
1134 for device in cdrw:
1135 torem.append("%s=ide-scsi" %(device,))
1136
1137 for fn in ("/etc/lilo.conf", "/boot/grub/grub.conf",
1138 "/etc/lilo.conf.anaconda"):
1139 if not os.path.exists(instRoot + fn):
1140 continue
1141 f = open(instRoot + fn, "r")
1142 buf = f.read()
1143 f.close()
1144 for dev in torem:
1145 buf = buf.replace(dev, "")
1146 f = open(instRoot + fn, "w")
1147 f.write(buf)
1148 f.close()
1149 return
1150 if len(kernelList) < 1:
1151 self.noKernelsWarn(intf)
1152
1153 str = self.writeGrub(instRoot, fsset, bl, langs, kernelList,
1154 chainList, defaultDev,
1155 justConfig | (not self.useGrubVal))
1156 # XXX move the lilo.conf out of the way if they're using GRUB
1157 # so that /sbin/installkernel does a more correct thing
1158 if self.useGrubVal and os.access(instRoot + '/etc/lilo.conf', os.R_OK):
1159 os.rename(instRoot + "/etc/lilo.conf",
1160 instRoot + "/etc/lilo.conf.anaconda")
1161
1162
1163
1164 def getArgList(self):
1165 args = bootloaderInfo.getArgList(self)
1166
1167 if self.forceLBA32:
1168 args.append("--lba32")
1169 if self.password:
1170 args.append("--md5pass=%s" %(self.password))
1171
1172
1173 # XXX add location of bootloader here too
1174
1175 return args
1176
1177 def __init__(self):
1178 bootloaderInfo.__init__(self)
1179 # XXX use checkbootloader to determine what to default to
1180 self.useGrubVal = 1
1181 self.kernelLocation = "/boot/"
1182 self.configfile = "/etc/lilo.conf"
1183 self.password = None
1184 self.pure = None
1185
1186 class s390BootloaderInfo(bootloaderInfo):
1187 def getBootloaderConfig(self, instRoot, fsset, bl, langs, kernelList,
1188 chainList, defaultDev):
1189 images = bl.images.getImages()
1190
1191 # on upgrade read in the lilo config file
1192 lilo = LiloConfigFile ()
1193 self.perms = 0600
1194 if os.access (instRoot + self.configfile, os.R_OK):
1195 self.perms = os.stat(instRoot + self.configfile)[0] & 0777
1196 lilo.read (instRoot + self.configfile)
1197 os.rename(instRoot + self.configfile,
1198 instRoot + self.configfile + '.rpmsave')
1199
1200 # Remove any invalid entries that are in the file; we probably
1201 # just removed those kernels.
1202 for label in lilo.listImages():
1203 (fsType, sl, path, other) = lilo.getImage(label)
1204 if fsType == "other": continue
1205
1206 if not os.access(instRoot + sl.getPath(), os.R_OK):
1207 lilo.delImage(label)
1208
1209 rootDev = fsset.getEntryByMountPoint("/").device.getDevice()
1210 if not rootDev:
1211 raise RuntimeError, "Installing zipl, but there is no root device"
1212
1213 if rootDev == defaultDev:
1214 lilo.addEntry("default", kernelList[0][0])
1215 else:
1216 lilo.addEntry("default", chainList[0][0])
1217
1218 for (label, longlabel, version) in kernelList:
1219 kernelTag = "-" + version
1220 kernelFile = self.kernelLocation + "vmlinuz" + kernelTag
1221
1222 try:
1223 lilo.delImage(label)
1224 except IndexError, msg:
1225 pass
1226
1227 sl = LiloConfigFile(imageType = "image", path = kernelFile)
1228
1229 initrd = booty.makeInitrd (kernelTag, instRoot)
1230
1231 sl.addEntry("label", label)
1232 if os.access (instRoot + initrd, os.R_OK):
1233 sl.addEntry("initrd",
1234 "%sinitrd%s.img" %(self.kernelLocation, kernelTag))
1235
1236 sl.addEntry("read-only")
1237 sl.addEntry("root", '/dev/' + rootDev)
1238 sl.addEntry("ipldevice", '/dev/' + rootDev[:-1])
1239
1240 if self.args.get():
1241 sl.addEntry('append', '"%s"' % self.args.get())
1242
1243 lilo.addImage (sl)
1244
1245 for (label, longlabel, device) in chainList:
1246 if ((not label) or (label == "")):
1247 continue
1248 try:
1249 (fsType, sl, path, other) = lilo.getImage(label)
1250 lilo.delImage(label)
1251 except IndexError:
1252 sl = LiloConfigFile(imageType = "other",
1253 path = "/dev/%s" %(device))
1254 sl.addEntry("optional")
1255
1256 sl.addEntry("label", label)
1257 lilo.addImage (sl)
1258
1259 # Sanity check #1. There could be aliases in sections which conflict
1260 # with the new images we just created. If so, erase those aliases
1261 imageNames = {}
1262 for label in lilo.listImages():
1263 imageNames[label] = 1
1264
1265 for label in lilo.listImages():
1266 (fsType, sl, path, other) = lilo.getImage(label)
1267 if sl.testEntry('alias'):
1268 alias = sl.getEntry('alias')
1269 if imageNames.has_key(alias):
1270 sl.delEntry('alias')
1271 imageNames[alias] = 1
1272
1273 # Sanity check #2. If single-key is turned on, go through all of
1274 # the image names (including aliases) (we just built the list) and
1275 # see if single-key will still work.
1276 if lilo.testEntry('single-key'):
1277 singleKeys = {}
1278 turnOff = 0
1279 for label in imageNames.keys():
1280 l = label[0]
1281 if singleKeys.has_key(l):
1282 turnOff = 1
1283 singleKeys[l] = 1
1284 if turnOff:
1285 lilo.delEntry('single-key')
1286
1287 return lilo
1288
1289 def writeChandevConf(self, bl, instroot): # S/390 only
1290 cf = "/etc/chandev.conf"
1291 self.perms = 0644
1292 if bl.args.chandevget():
1293 fd = os.open(instroot + "/etc/chandev.conf",
1294 os.O_WRONLY | os.O_CREAT)
1295 os.write(fd, "noauto\n")
1296 for cdev in bl.args.chandevget():
1297 os.write(fd,'%s\n' % cdev)
1298 os.close(fd)
1299 return ""
1300
1301
1302 def writeZipl(self, instRoot, fsset, bl, langs, kernelList, chainList,
1303 defaultDev, justConfigFile):
1304 images = bl.images.getImages()
1305 rootDev = fsset.getEntryByMountPoint("/").device.getDevice()
1306
1307 cf = '/etc/zipl.conf'
1308 self.perms = 0600
1309 if os.access (instRoot + cf, os.R_OK):
1310 self.perms = os.stat(instRoot + cf)[0] & 0777
1311 os.rename(instRoot + cf,
1312 instRoot + cf + '.rpmsave')
1313
1314 f = open(instRoot + cf, "w+")
1315
1316 f.write('[defaultboot]\n')
1317 f.write('default=' + kernelList[0][0] + '\n')
1318 f.write('target=%s\n' % (self.kernelLocation))
1319
1320 cfPath = "/boot/"
1321 for (label, longlabel, version) in kernelList:
1322 kernelTag = "-" + version
1323 kernelFile = "%svmlinuz%s" % (cfPath, kernelTag)
1324
1325 initrd = booty.makeInitrd (kernelTag, instRoot)
1326 f.write('[%s]\n' % (label))
1327 f.write('\timage=%s\n' % (kernelFile))
1328 if os.access (instRoot + initrd, os.R_OK):
1329 f.write('\tramdisk=%sinitrd%s.img\n' %(self.kernelLocation,
1330 kernelTag))
1331 realroot = getRootDevName(initrd, fsset, rootDev, instRoot)
1332 f.write('\tparameters="root=%s' %(realroot,))
1333 if bl.args.get():
1334 f.write(' %s' % (bl.args.get()))
1335 f.write('"\n')
1336
1337 f.close()
1338
1339 if not justConfigFile:
1340 argv = [ "/sbin/zipl" ]
1341 rhpl.executil.execWithRedirect(argv[0], argv, root = instRoot,
1342 stdout = "/dev/stdout",
1343 stderr = "/dev/stderr")
1344
1345 return ""
1346
1347 def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
1348 defaultDev, justConfig, intf):
1349 str = self.writeZipl(instRoot, fsset, bl, langs, kernelList,
1350 chainList, defaultDev,
1351 justConfig | (not self.useZiplVal))
1352 str = self.writeChandevConf(bl, instRoot)
1353
1354 def __init__(self):
1355 bootloaderInfo.__init__(self)
1356 self.useZiplVal = 1 # only used on s390
1357 self.kernelLocation = "/boot/"
1358 self.configfile = "/etc/zipl.conf"
1359
1360
1361 class alphaBootloaderInfo(bootloaderInfo):
1362 def wholeDevice (self, path):
1363 (device, foo) = getDiskPart(path)
1364 return device
1365
1366 def partitionNum (self, path):
1367 # getDiskPart returns part numbers 0-based; we need it one based
1368 # *sigh*
1369 (foo, partitionNumber) = getDiskPart(path)
1370 return partitionNumber + 1
1371
1372 # See if we would have to use MILO. MILO isn't supported by Red Hat.
1373 def useMilo (self):
1374 try:
1375 f = open ('/proc/cpuinfo', 'ro')
1376 except:
1377 return
1378 lines = f.readlines ()
1379 f.close()
1380 serial = ""
1381 for line in lines:
1382 if line.find("system serial number") != -1:
1383 serial = string.strip (string.split (line, ':')[1])
1384 break
1385
1386 if serial and len (serial) >= 4 and serial.startswith("MILO"):
1387 return 1
1388 else:
1389 return 0
1390
1391 def writeAboot(self, instRoot, fsset, bl, langs, kernelList,
1392 chainList, defaultDev, justConfig):
1393 # Get bootDevice and rootDevice
1394 rootDevice = fsset.getEntryByMountPoint("/").device.getDevice()
1395 if fsset.getEntryByMountPoint("/boot"):
1396 bootDevice = fsset.getEntryByMountPoint("/boot").device.getDevice()
1397 else:
1398 bootDevice = rootDevice
1399 bootnotroot = bootDevice != rootDevice
1400
1401 # If /etc/aboot.conf already exists we rename it
1402 # /etc/aboot.conf.rpmsave.
1403 if os.path.isfile(instRoot + self.configfile):
1404 os.rename (instRoot + self.configfile,
1405 instRoot + self.configfile + ".rpmsave")
1406
1407 # Then we create the necessary files. If the root device isn't
1408 # the boot device, we create /boot/etc/ where the aboot.conf
1409 # will live, and we create /etc/aboot.conf as a symlink to it.
1410 if bootnotroot:
1411 # Do we have /boot/etc ? If not, create one
1412 if not os.path.isdir (instRoot + '/boot/etc'):
1413 os.mkdir(instRoot + '/boot/etc', 0755)
1414
1415 # We install the symlink (/etc/aboot.conf has already been
1416 # renamed in necessary.)
1417 os.symlink("../boot" + self.configfile, instRoot + self.configfile)
1418
1419 cfPath = instRoot + "/boot" + self.configfile
1420 # Kernel path is set to / because a boot partition will
1421 # be a root on its own.
1422 kernelPath = '/'
1423 # Otherwise, we just need to create /etc/aboot.conf.
1424 else:
1425 cfPath = instRoot + self.configfile
1426 kernelPath = self.kernelLocation
1427
1428 # If we already have an aboot.conf, rename it
1429 if os.access (cfPath, os.R_OK):
1430 self.perms = os.stat(cfPath)[0] & 0777
1431 os.rename(cfPath, cfPath + '.rpmsave')
1432
1433 # Now we're going to create and populate cfPath.
1434 f = open (cfPath, 'w+')
1435 f.write ("# aboot default configurations\n")
1436
1437 if bootnotroot:
1438 f.write ("# NOTICE: You have a /boot partition. This means that\n")
1439 f.write ("# all kernel paths are relative to /boot/\n")
1440
1441 # bpn is the boot partition number.
1442 bpn = self.partitionNum(bootDevice)
1443 lines = 0
1444
1445 # We write entries line using the following format:
1446 # <line><bpn><kernel-name> root=<rootdev> [options]
1447 # We get all the kernels we need to know about in kernelList.
1448
1449 for (kernel, tag, kernelTag) in kernelList:
1450 kernelFile = "%svmlinuz-%s" %(kernelPath, kernelTag)
1451
1452 f.write("%d:%d%s" %(lines, bpn, kernelFile))
1453
1454 # See if we can come up with an initrd argument that exists
1455 initrd = booty.makeInitrd (kernelTag, instRoot)
1456 if os.access(instRoot + initrd, os.R_OK):
1457 f.write(" initrd=%sinitrd-%s.img" %(kernelPath, kernelTag))
1458
1459 realroot = getRootDevName(initrd, fsset, rootDevice, instRoot)
1460 f.write(" root=%s" %(realroot,))
1461
1462 args = self.args.get()
1463 if args:
1464 f.write(" %s" %(args,))
1465
1466 f.write("\n")
1467 lines = lines + 1
1468
1469 # We're done writing the file
1470 f.close ()
1471 del f
1472
1473 if not justConfig:
1474 # Now we're ready to write the relevant boot information. wbd
1475 # is the whole boot device, bdpn is the boot device partition
1476 # number.
1477 wbd = self.wholeDevice (bootDevice)
1478 bdpn = self.partitionNum (bootDevice)
1479
1480 # Calling swriteboot. The first argument is the disk to write
1481 # to and the second argument is a path to the bootstrap loader
1482 # file.
1483 args = ("swriteboot", ("/dev/%s" % wbd), "/boot/bootlx")
1484 log("swriteboot command: %s" %(args,))
1485 rhpl.executil.execWithRedirect ('/sbin/swriteboot', args,
1486 root = instRoot,
1487 stdout = "/dev/tty5",
1488 stderr = "/dev/tty5")
1489
1490 # Calling abootconf to configure the installed aboot. The
1491 # first argument is the disk to use, the second argument is
1492 # the number of the partition on which aboot.conf resides.
1493 # It's always the boot partition whether it's / or /boot (with
1494 # the mount point being omitted.)
1495 args = ("abootconf", ("/dev/%s" % wbd), str (bdpn))
1496 log("abootconf command: %s" %(args,))
1497 rhpl.executil.execWithRedirect ('/sbin/abootconf', args,
1498 root = instRoot,
1499 stdout = "/dev/tty5",
1500 stderr = "/dev/tty5")
1501
1502
1503 def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
1504 defaultDev, justConfig, intf):
1505 if len(kernelList) < 1:
1506 self.noKernelsWarn(intf)
1507
1508 if self.useMilo():
1509 intf.messageWindow(_("MILO Not Supported"),
1510 "This system requires the support of MILO to " +
1511 "boot linux (MILO is not included in this " +
1512 "distribution.) The installation of the " +
1513 "bootloader can't be completed on this system.")
1514 # elif not justConfig FIXME.
1515 else:
1516 self.writeAboot(instRoot, fsset, bl, langs, kernelList,
1517 chainList, defaultDev, justConfig)
1518
1519 def __init__(self):
1520 bootloaderInfo.__init__(self)
1521 self.useGrubVal = 0
1522 self.configfile = "/etc/aboot.conf"
1523 # self.kernelLocation is already set to what we need.
1524 self.password = None
1525 self.pure = None
1526
1527
1528 class ppcBootloaderInfo(bootloaderInfo):
1529 def writeYaboot(self, instRoot, fsset, bl, langs, kernelList,
1530 chainList, defaultDev, justConfigFile):
1531
1532 from flags import flags
1533
1534 yabootTarget = '/dev/%s' %(bl.getDevice())
1535
1536 bootDev = fsset.getEntryByMountPoint("/boot")
1537 if bootDev:
1538 cf = "/boot/etc/yaboot.conf"
1539 cfPath = ""
1540 if not os.path.isdir(instRoot + "/boot/etc"):
1541 os.mkdir(instRoot + "/boot/etc")
1542 else:
1543 bootDev = fsset.getEntryByMountPoint("/")
1544 cfPath = "/boot"
1545 cf = "/etc/yaboot.conf"
1546 bootDev = bootDev.device.getDevice(asBoot = 1)
1547
1548 f = open(instRoot + cf, "w+")
1549
1550 f.write("# yaboot.conf generated by anaconda\n\n")
1551
1552 f.write("boot=%s\n" %(yabootTarget,))
1553 f.write("init-message=Welcome to %s\\!\nHit <TAB> for boot options\n\n"
1554 %(butil.getProductName(),))
1555
1556 (name, partNum) = getDiskPart(bootDev)
1557 partno = partNum + 1 # 1 based
1558 f.write("partition=%s\n" %(partno,))
1559
1560 f.write("timeout=80\n")
1561 f.write("install=/usr/lib/yaboot/yaboot\n")
1562 f.write("delay=5\n")
1563 f.write("enablecdboot\n")
1564 f.write("enableofboot\n")
1565 f.write("enablenetboot\n")
1566
1567 if butil.getPPCMachine() == "PMac":
1568 # write out the first hfs/hfs+ partition as being macosx
1569 for (label, longlabel, device) in chainList:
1570 if ((not label) or (label == "")):
1571 continue
1572 f.write("macosx=/dev/%s\n" %(device,))
1573 break
1574
1575 f.write("magicboot=/usr/lib/yaboot/ofboot\n")
1576
1577 if butil.getPPCMachine() == "pSeries":
1578 f.write("nonvram\n")
1579
1580 if self.password:
1581 f.write("password=%s\n" %(self.password,))
1582 f.write("restricted\n")
1583
1584 f.write("\n")
1585
1586 rootDev = fsset.getEntryByMountPoint("/").device.getDevice()
1587
1588 for (label, longlabel, version) in kernelList:
1589 kernelTag = "-" + version
1590 kernelFile = "%s/vmlinuz%s" %(cfPath, kernelTag)
1591
1592 f.write("image=%s\n" %(kernelFile,))
1593 f.write("\tlabel=%s\n" %(label,))
1594 f.write("\tread-only\n")
1595
1596 initrd = booty.makeInitrd(kernelTag, instRoot)
1597 if os.access(instRoot + initrd, os.R_OK):
1598 f.write("\tinitrd=%s/initrd%s.img\n" %(cfPath,kernelTag))
1599
1600 append = "%s" %(self.args.get(),)
1601
1602 realroot = getRootDevName(initrd, fsset, rootDev, instRoot)
1603 if not realroot.startswith("LABEL="):
1604 f.write("\troot=%s\n" %(realroot,))
1605 else:
1606 if len(append) > 0:
1607 append = "%s root=%s" %(append,realroot)
1608 else:
1609 append = "root=%s" %(realroot,)
1610
1611 if len(append) > 0:
1612 f.write("\tappend=\"%s\"\n" %(append,))
1613 f.write("\n")
1614
1615 f.close()
1616 os.chmod(instRoot + cf, 0600)
1617
1618 # FIXME: hack to make sure things are written to disk
1619 import isys
1620 isys.sync()
1621 isys.sync()
1622 isys.sync()
1623
1624 ybinargs = [ "/sbin/mkofboot", "-f", "-C", cf ]
1625 if butil.getPPCMachine() == "pSeries":
1626 ybinargs.extend(["--filesystem", "raw"])
1627
1628
1629 log("running: %s" %(ybinargs,))
1630 if not flags.test:
1631 rhpl.executil.execWithRedirect(ybinargs[0],
1632 ybinargs,
1633 stdout = "/dev/tty5",
1634 stderr = "/dev/tty5",
1635 root = instRoot)
1636
1637 if (not os.access(instRoot + "/etc/yaboot.conf", os.R_OK) and
1638 os.access(instRoot + "/boot/etc/yaboot.conf", os.R_OK)):
1639 os.symlink("../boot/etc/yaboot.conf",
1640 instRoot + "/etc/yaboot.conf")
1641
1642 return ""
1643
1644 def setPassword(self, val, isCrypted = 1):
1645 # yaboot just handles the password and doesn't care if its crypted
1646 # or not
1647 self.password = val
1648
1649 def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
1650 defaultDev, justConfig, intf):
1651 if len(kernelList) >= 1:
1652 str = self.writeYaboot(instRoot, fsset, bl, langs, kernelList,
1653 chainList, defaultDev, justConfig)
1654 else:
1655 self.noKernelsWarn(intf)
1656
1657 def __init__(self):
1658 bootloaderInfo.__init__(self)
1659 self.useYabootVal = 1
1660 self.kernelLocation = "/boot"
1661 self.configfile = "/etc/yaboot.conf"
1662
1663
1664 class iseriesBootloaderInfo(bootloaderInfo):
1665 def ddFile(self, inf, of, bs = 4096):
1666 src = os.open(inf, os.O_RDONLY)
1667 dest = os.open(of, os.O_WRONLY | os.O_CREAT)
1668 size = 0
1669
1670 buf = os.read(src, bs)
1671 while len(buf) > 0:
1672 size = size + len(buf)
1673 os.write(dest, buf)
1674 buf = os.read(src, bs)
1675
1676 os.close(src)
1677 os.close(dest)
1678
1679 return size
1680
1681 def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
1682 defaultDev, justConfig, intf):
1683 if len(kernelList) < 1:
1684 self.noKernelsWarn(intf)
1685 return
1686 if len(kernelList) > 1:
1687 # FIXME: how can this happen?
1688 log("more than one kernel on iSeries. bailing and just using "
1689 "the first")
1690
1691 # iseries is Weird (tm) -- here's the basic theory
1692 # a) have /boot/vmlinitrd-$(version)
1693 # b) copy default kernel to PReP partition
1694 # c) dd default kernel to /proc/iSeries/mf/C/vmlinux
1695 # d) set cmdline in /boot/cmdline-$(version)
1696 # e) copy cmdline to /proc/iSeries/mf/C/cmdline
1697 # f) set default side to 'C' i /proc/iSeries/mf/side
1698 # g) put default kernel and cmdline on side B too (#91038)
1699
1700 rootDevice = fsset.getEntryByMountPoint("/").device.getDevice()
1701
1702 # write our command line files
1703 for (kernel, tag, kernelTag) in kernelList:
1704 cmdFile = "%scmdline-%s" %(self.kernelLocation, kernelTag)
1705 initrd = "%sinitrd-%s.img" %(self.kernelLocation, kernelTag)
1706 realroot = getRootDevName(initrd, fsset, rootDevice, instRoot)
1707 f = open(instRoot + cmdFile, "w")
1708 f.write("ro root=%s" %(realroot,))
1709 if bl.args.get():
1710 f.write(" %s" %(bl.args.get(),))
1711 f.write("\n")
1712 f.close()
1713 os.chmod(instRoot + cmdFile, 0644)
1714
1715 kernel, tag, kernelTag = kernelList[0]
1716 kernelFile = "%svmlinitrd-%s" %(self.kernelLocation, kernelTag)
1717
1718 # write the kernel to the PReP partition since that's what
1719 # OS/400 will load as NWSSTG
1720 bootDev = bl.getDevice()
1721 if bootDev:
1722 log("Writing kernel %s to PReP partition %s" %(kernelFile,
1723 bootDev))
1724 try:
1725 self.ddFile(instRoot + kernelFile, "%s/dev/%s" %(instRoot,
1726 bootDev))
1727 except Exception, e:
1728 # FIXME: should this be more fatal
1729 log("Failed to write kernel: %s" %(e,))
1730 else:
1731 log("No PReP boot partition, not writing kernel for NWSSTG")
1732
1733
1734 # now, it's a lot faster to boot if we don't make people go back
1735 # into OS/400, so set up side C (used by default for NWSSTG) with
1736 # our current bits
1737 for side in ("C", "B"):
1738 log("Writing kernel and cmdline to side %s" %(side,))
1739 wrotekernel = 0
1740 try:
1741 self.ddFile(instRoot + kernelFile,
1742 "%s/proc/iSeries/mf/%s/vmlinux" %(instRoot, side))
1743 wrotekernel = 1
1744 except Exception, e:
1745 # FIXME: should this be more fatal?
1746 log("Failed to write kernel to side %s: %s" %(side, e))
1747
1748 if wrotekernel == 1:
1749 try:
1750 # blank it. ugh.
1751 f = open("%s/proc/iSeries/mf/%s/cmdline" %(instRoot, side),
1752 "w+")
1753 f.write(" " * 255)
1754 f.close()
1755
1756 self.ddFile("%s/%scmdline-%s" %(instRoot,
1757 self.kernelLocation,
1758 kernelTag),
1759 "%s/proc/iSeries/mf/%s/cmdline" %(instRoot,
1760 side))
1761 except Exception, e:
1762 log("Failed to write kernel command line to side %s: %s"
1763 %(side, e))
1764
1765 log("Setting default side to C")
1766 f = open(instRoot + "/proc/iSeries/mf/side", "w")
1767 f.write("C")
1768 f.close()
1769
1770 def __init__(self):
1771 bootloaderInfo.__init__(self)
1772 self.kernelLocation = "/boot/"
1773
1774 class sparcBootloaderInfo(bootloaderInfo):
1775 def writeSilo(self, instRoot, fsset, bl, langs, kernelList,
1776 chainList, defaultDev, justConfigFile):
1777
1778 from flags import flags
1779
1780 bootDev = fsset.getEntryByMountPoint("/boot")
1781 if bootDev:
1782 cf = "/boot/silo.conf"
1783 mf = "/boot/silo.message"
1784 cfPath = ""
1785 if not os.path.isdir(instRoot + "/boot"):
1786 os.mkdir(instRoot + "/boot")
1787 else:
1788 bootDev = fsset.getEntryByMountPoint("/")
1789 cf = "/etc/silo.conf"
1790 mf = "/etc/silo.message"
1791 cfPath = "/boot"
1792 bootDev = bootDev.device.getDevice(asBoot = 1)
1793
1794 f = open(instRoot + mf, "w+")
1795 f.write("Welcome to %s!\nHit <TAB> for boot options\n\n" % \
1796 (butil.getProductName(),))
1797 f.close()
1798 os.chmod(instRoot + mf, 0600)
1799
1800 f = open(instRoot + cf, "w+")
1801 f.write("# silo.conf generated by anaconda\n\n")
1802
1803 f.write("#boot=%s\n" % (bootDev,))
1804 f.write("message=%s\n" % (mf,))
1805 f.write("timeout=50\n")
1806
1807 (name, partNum) = getDiskPart(bootDev)
1808 partno = partNum + 1
1809 f.write("partition=%s\n" % (partno,))
1810
1811 if self.password:
1812 f.write("password=%s\n" % (self.password,))
1813 f.write("restricted\n")
1814
1815 f.write("default=%s\n" % (kernelList[0][0],))
1816 f.write("\n")
1817
1818 rootDev = fsset.getEntryByMountPoint("/").device.getDevice()
1819
1820 for (label, longlabel, version) in kernelList:
1821 kernelTag = "-" + version
1822 kernelFile = "%s/vmlinuz%s" % (cfPath, kernelTag)
1823
1824 f.write("image=%s\n" % (kernelFile,))
1825 f.write("\tlabel=%s\n" % (label,))
1826 f.write("\tread-only\n")
1827
1828 initrd = booty.makeInitrd(kernelTag, instRoot)
1829 if os.access(instRoot + initrd, os.R_OK):
1830 f.write("\tinitrd=%s/initrd%s.img\n" % (cfPath, kernelTag))
1831
1832 append = "%s" % (self.args.get(),)
1833
1834 realroot = getRootDevName(initrd, fsset, rootDev, instRoot)
1835 if not realroot.startswith("LABEL="):
1836 f.write("\troot=%s\n" % (realroot,))
1837 else:
1838 if len(append) > 0:
1839 append = "%s root=%s" % (append, realroot)
1840 else:
1841 append = "root=%s" % (realroot,)
1842
1843 if len(append) > 0:
1844 f.write("\tappend=\"%s\"\n" % (append,))
1845 f.write("\n")
1846
1847 f.close()
1848 os.chmod(instRoot + cf, 0600)
1849
1850 # FIXME: hack to make sure things are written to disk
1851 import isys
1852 isys.sync()
1853 isys.sync()
1854 isys.sync()
1855
1856 backup = "%s/backup.b" % (cfPath,)
1857 sbinargs = ["/sbin/silo", "-f", "-C", cf, "-S", backup]
1858 if butil.getSparcMachine() == "sun4u":
1859 sbinargs += ["-u"]
1860 else:
1861 sbinargs += ["-U"]
1862
1863 log("running: %s" % (sbinargs,))
1864 if not flags.test:
1865 rhpl.executil.execWithRedirect(sbinargs[0],
1866 sbinargs,
1867 stdout = "/dev/tty5",
1868 stderr = "/dev/tty5",
1869 root = instRoot)
1870
1871 if (not os.access(instRoot + "/etc/silo.conf", os.R_OK) and
1872 os.access(instRoot + "/boot/etc/silo.conf", os.R_OK)):
1873 os.symlink("../boot/etc/silo.conf",
1874 instRoot + "/etc/silo.conf")
1875
1876 return ""
1877
1878 def setPassword(self, val, isCrypted = 1):
1879 # silo just handles the password unencrypted
1880 self.password = val
1881
1882 def write(self, instRoot, fsset, bl, langs, kernelList, chainList,
1883 defaultDev, justConfig, intf):
1884 if len(kernelList) >= 1:
1885 self.writeSilo(instRoot, fsset, bl, langs, kernelList, chainList,
1886 defaultDev, justConfig)
1887 else:
1888 self.noKernelsWarn(intf)
1889
1890 def __init__(self):
1891 bootloaderInfo.__init__(self)
1892 self.useSiloVal = 1
1893 self.kernelLocation = "/boot"
1894 self.configfile = "/etc/silo.conf"
1895
1896 ###############
1897 # end of boot loader objects... these are just some utility functions used
1898
1899 # return (disk, partition number) eg ('hda', 1)
1900 def getDiskPart(dev):
1901 cut = len(dev)
1902 if (dev.startswith('rd/') or dev.startswith('ida/') or
1903 dev.startswith('cciss/')):
1904 if dev[-2] == 'p':
1905 cut = -1
1906 elif dev[-3] == 'p':
1907 cut = -2
1908 else:
1909 if dev[-2] in string.digits:
1910 cut = -2
1911 elif dev[-1] in string.digits:
1912 cut = -1
1913
1914 name = dev[:cut]
1915
1916 # hack off the trailing 'p' from /dev/cciss/*, for example
1917 if name[-1] == 'p':
1918 for letter in name:
1919 if letter not in string.letters and letter != "/":
1920 name = name[:-1]
1921 break
1922
1923 if cut < 0:
1924 partNum = int(dev[cut:]) - 1
1925 else:
1926 partNum = None
1927
1928 return (name, partNum)
1929
1930 # hackery to determine if we should do root=LABEL=/ or whatnot
1931 # as usual, knows too much about anaconda
1932 def getRootDevName(initrd, fsset, rootDev, instRoot):
1933 if not os.access(instRoot + initrd, os.R_OK):
1934 return "/dev/%s" % (rootDev,)
1935
1936 try:
1937 rootEntry = fsset.getEntryByMountPoint("/")
1938 if rootEntry.getLabel() is not None:
1939 return "LABEL=%s" %(rootEntry.getLabel(),)
1940 return "/dev/%s" %(rootDev,)
1941 except:
1942 return "/dev/%s" %(rootDev,)
1943

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