/[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.6 - (show annotations) (download) (as text)
Wed Apr 5 04:20:56 2006 UTC (18 years, 8 months ago) by slords
Branch: MAIN
Changes since 1.5: +7 -8 lines
Content type: text/x-python
Create /boot partition first to get it in sync faster.
Install grub so hard drives can fail nicely.

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

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