/[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.11 - (show annotations) (download) (as text)
Fri Jun 9 05:02:59 2006 UTC (17 years, 11 months ago) by gordonr
Branch: MAIN
CVS Tags: HEAD
Changes since 1.10: +0 -0 lines
Content type: text/x-python
FILE REMOVED
See bug 1510 - all changes should be in the anaconda CVS repository

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

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