home *** CD-ROM | disk | FTP | other *** search
/ Australian Personal Computer 2000 July / CD 3 / redhat-6.2.iso / RedHat / instimage / usr / lib / anaconda / silo.py < prev    next >
Encoding:
Python Source  |  2000-03-08  |  11.8 KB  |  452 lines

  1. import string
  2. import os
  3. from lilo import LiloConfigFile
  4. import _silo
  5. import iutil
  6. import isys
  7.  
  8. class SiloInstall:
  9.     def allowSiloLocationConfig(self, fstab):
  10.     bootDevice = fstab.getBootDevice()
  11.     if bootDevice[0:2] == "md":
  12.         self.setDevice(("raid", bootDevice))
  13.         return None
  14.     return 1
  15.  
  16.     def checkUFS(self, dev):
  17.     f = open("/proc/mounts","r")
  18.     lines = f.readlines ()
  19.     f.close ()
  20.     mounted = None
  21.     ufstype = None
  22.     for line in lines:
  23.         fields = string.split (line)
  24.         if fields[0] == '/dev/' + dev and fields[2] == 'ufs':
  25.         mounted = fields[1]
  26.     if not mounted:
  27.         try:
  28.         os.mkdir ("/tmp/ufsmntpoint")
  29.         isys.makeDevInode (dev, "/tmp/" + dev)
  30.         isys.mount ("/tmp/" + dev, "/tmp/ufsmntpoint", "ufs")
  31.         except:
  32.         try:
  33.             os.remove ("/tmp/" + dev)
  34.         except:
  35.             pass
  36.         try:
  37.             os.rmdir ("/tmp/ufsmntpoint")
  38.         except:
  39.             pass
  40.         return None
  41.         root = "/tmp/ufsmntpoint"
  42.     else:
  43.         root = mounted
  44.     if os.access (root + "/etc/system", os.X_OK):
  45.         if os.access (root + "/kernel/unix", os.X_OK):
  46.         ufstype = "Solaris"
  47.         elif os.access (root + "/kernel/genunix", os.X_OK):
  48.         ufstype = "Solaris"
  49.     if os.access (root + "/vmunix", os.X_OK) or os.access (root + "/stand", os.X_OK):
  50.         if os.access (root + "/bin/sh", os.X_OK):
  51.         # Check if /bin/sh is a.out SPARC binary
  52.         aout = None
  53.         try:
  54.             f = open (root + "/bin/sh", "r")
  55.             aout = f.read(4)
  56.             f.close()
  57.         except:
  58.             pass
  59.         if aout and len(aout) == 4 and aout[1] == "\x03" and aout[2] == "\x01":
  60.             if aout[3] == "\x07" or aout[3] == "\x08" or aout[3] == "\x0b":
  61.             ufstype = "SunOS"
  62.     if not mounted:
  63.         try:
  64.         isys.umount ("/tmp/ufsmntpoint")
  65.         except:
  66.         pass
  67.         try:
  68.         os.rmdir ("/tmp/ufsmntpoint")
  69.         except:
  70.         pass
  71.         try:
  72.         os.remove ("/tmp/" + dev)
  73.         except:
  74.         pass
  75.     return ufstype
  76.  
  77.     def setSiloImages(self, images):
  78.     self.siloImages = images
  79.  
  80.     def getSiloImages(self, fstab):
  81.     (drives, raid) = fstab.raidList()
  82.  
  83.     # rearrange the fstab so it's indexed by device
  84.     mountsByDev = {}
  85.     for (mntpoint, device, fsystem, doFormat, size) in \
  86.         fstab.mountList():
  87.         mountsByDev[device] = mntpoint
  88.  
  89.     for (mntpoint, device, fstype, raidType, start, size, makeup) in raid:
  90.         mountsByDev[device] = mntpoint
  91.         drives.append(device, "", 2, 0, 0)
  92.  
  93.     for (device, mntpoint, fsystem, makeup) in fstab.existingRaidList():
  94.         mountsByDev[device] = mntpoint
  95.         drives.append(device, "", 2, 0, 0)
  96.  
  97.     oldImages = {}
  98.     for dev in self.siloImages.keys():
  99.         oldImages[dev] = self.siloImages[dev]
  100.  
  101.     self.siloImages = {}
  102.     nSolaris = 0
  103.     nSunOS = 0
  104.     for (dev, devName, type, start, size) in drives:
  105.         # ext2 and raid partitions get listed if 
  106.         #        1) they're /
  107.         #        2) they're not mounted
  108.         #           and contain /boot of
  109.         #           some Linux installation
  110.         # FIXME: For now only list / and UFS partitions,
  111.         # for 7.0 write code which will read and parse silo.conf from other
  112.         # Linux partitions and merge it in (after required device
  113.         # substitions etc.
  114.  
  115.         # only list ext2 and ufs partitions
  116.         if type != 2 and type != 6:
  117.         continue
  118.  
  119.         if (mountsByDev.has_key(dev)):
  120.         if mountsByDev[dev] == '/':
  121.             self.siloImages[dev] = ("linux", 2)
  122.         elif type == 6:
  123.         if not oldImages.has_key(dev):
  124.             self.siloImages[dev] = ("", type)
  125.         else:
  126.             self.siloImages[dev] = oldImages[dev]
  127.         ostype = self.checkUFS(dev)
  128.         if ostype == "Solaris":
  129.             if nSolaris == 0:
  130.             self.siloImages[dev] = ("solaris", type)
  131.             else:
  132.             self.siloImages[dev] = ("solaris%d" % nSolaris, type)
  133.             nSolaris = nSolaris + 1
  134.         elif ostype == "SunOS":
  135.             if nSunOS == 0:
  136.             self.siloImages[dev] = ("sunos", type)
  137.             else:
  138.             self.siloImages[dev] = ("sunos%d" % nSunOS, type)
  139.             nSunOS = nSunOS + 1
  140.  
  141.     return (self.siloImages, self.default)
  142.  
  143.     def getSiloMbrDefault(self, fstab):
  144.     # Check partition at cylinder 0 on the boot disk
  145.     # is /, /boot or Linux swap
  146.     bootpart = fstab.getBootDevice()
  147.     if bootpart[:2] == "md":
  148.         return "mbr"
  149.     i = len (bootpart) - 1
  150.     while i > 0 and bootpart[i] in string.digits:
  151.         i = i - 1
  152.     boothd = bootpart[:i+1]
  153.     (drives, raid) = fstab.partitionList()
  154.     for (dev, devName, type, start, size) in drives:
  155.         i = len (dev) - 1
  156.         while i > 0 and dev[i] in string.digits:
  157.         i = i - 1
  158.         devhd = dev[:i+1]
  159.         if devhd == boothd and start == 0:
  160.         if type == 5:
  161.             return "mbr"
  162.         elif type == 2:
  163.             if dev == bootpart:
  164.             return "mbr"
  165.             elif dev == fstab.getRootDevice()[0]:
  166.             return "mbr"
  167.         return "partition"
  168.     return "partition"
  169.  
  170.     def hasUsableFloppy(self):
  171.     try:
  172.         f = open("/proc/devices", "r")
  173.     except:
  174.         return 0
  175.     lines = f.readlines ()
  176.     f.close ()
  177.     for line in lines:
  178.         if string.strip (line) == "2 fd":
  179.         name = _silo.promRootName()
  180.         if name and name[0:10] == 'SUNW,Ultra' and string.find(name, "Engine") == -1:
  181.             # Seems like SMCC Ultra box. It is highly probable
  182.             # the floppies will be unbootable
  183.             return 1
  184.         return 2
  185.     return 0
  186.  
  187.     def setPROM(self, linuxAlias, bootDevice):
  188.     self.linuxAlias = linuxAlias
  189.     self.bootDevice = bootDevice
  190.  
  191.     def hasAliases(self):
  192.     return _silo.hasAliases()
  193.  
  194.     def disk2PromPath(self,dev):
  195.     return _silo.disk2PromPath(dev)
  196.  
  197.     def makeInitrd (self, kernelTag, instRoot):
  198.     initrd = "/boot/initrd%s.img" % (kernelTag, )
  199.     if not self.initrdsMade.has_key(initrd):
  200.         iutil.execWithRedirect("/sbin/mkinitrd",
  201.                   [ "/sbin/mkinitrd",
  202.                     "--ifneeded",
  203.                     initrd,
  204.                     kernelTag[1:] ],
  205.                   stdout = None, stderr = None, searchPath = 1,
  206.                   root = instRoot)
  207.         self.initrdsMade[kernelTag] = 1
  208.     return initrd
  209.  
  210.     def getMbrDevices(self, fstab):
  211.     bootpart = fstab.getBootDevice()
  212.     mbrdevs = []
  213.     if bootpart[:2] == "md":
  214.         (devices, raid) = fstab.raidList()
  215.         for (raidMntPoint, raidDevice, fsType, raidType, raidStart, raidSize, raidDevs) in raid:
  216.         if raidDevice != bootpart: continue
  217.         for raidDev in raidDevs:
  218.             for (device, name, type, start, size) in devices:
  219.             if name == raidDev:
  220.                 i = len(device) - 1
  221.                 while i > 0 and device[i] in string.digits:
  222.                 i = i - 1
  223.                 mbrdevs.append(device[:i+1])
  224.     else:
  225.         # Do not use fstab.getMbrDevice() here
  226.         i = len (bootpart) - 1
  227.         while i > 0 and bootpart[i] in string.digits:
  228.         i = i - 1
  229.         mbrdevs.append(bootpart[:i+1])
  230.     return mbrdevs
  231.  
  232.     def getMbrDevice(self, fstab):
  233.     return self.getMbrDevices(fstab)[0]
  234.  
  235.     def install(self, fstab, instRoot, hdList, upgrade):
  236.     if not self.siloDevice: return
  237.  
  238.     silo = LiloConfigFile ()
  239.  
  240.     if not self.siloImages:
  241.         (images, default) = self.getSiloImages(fstab)
  242.         self.setSiloImages(images)
  243.  
  244.     bootpart = fstab.getBootDevice()
  245.     boothd = self.getMbrDevice(fstab)
  246.     smpInstalled = (hdList.has_key('kernel-smp') and 
  247.             hdList['kernel-smp'].selected)
  248.  
  249.     rootDev = fstab.getRootDevice ()
  250.     if rootDev:
  251.         # strip off the filesystem; we don't need it
  252.         rootDev = rootDev[0]
  253.     else:
  254.         raise RuntimeError, "Installing silo, but there is no root device"
  255.  
  256.     args = [ "silo" ]
  257.  
  258.     if bootpart[:2] == "md":
  259.         self.siloDevice = "mbr"
  260.     else:
  261.         if self.siloDevice != "mbr":
  262.         args.append("-t")
  263.  
  264.         i = len (bootpart) - 1
  265.         while i > 0 and bootpart[i] in string.digits:
  266.         i = i - 1
  267.         silo.addEntry("partition", bootpart[i+1:])
  268.  
  269.     silo.addEntry("timeout", "50")
  270.     silo.addEntry("root", '/dev/' + rootDev)
  271.     silo.addEntry("read-only")
  272.  
  273.     kernelList = []
  274.     otherList = []
  275.  
  276.     main = "linux"
  277.  
  278.     for (drive, (label, siloType)) in self.siloImages.items ():
  279.         if (drive == rootDev) and label:
  280.         main = label
  281.         elif label:
  282.         i = len(drive) - 1
  283.         while i > 0 and drive[i] in string.digits:
  284.             i = i - 1
  285.         prompath = drive[:i+1]
  286.         if bootpart[:2] != "md" and prompath == boothd:
  287.             prompath = drive[i+1:]
  288.         else:
  289.             prompath = self.disk2PromPath(prompath)
  290.             if prompath:
  291.             if prompath[:3] == 'sd(':
  292.                 prompath = prompath + drive[i+1:]
  293.             else:
  294.                 prompath = prompath + ";" + drive[i+1:]
  295.         if prompath:
  296.             otherList.append (label, prompath)
  297.  
  298.     silo.addEntry("default", main)
  299.  
  300.     label = main
  301.     if (smpInstalled):
  302.         kernelList.append((main, hdList['kernel-smp'], "smp"))
  303.         label = main + "-up"
  304.  
  305.     kernelList.append((label, hdList['kernel'], ""))
  306.  
  307.     for (label, kernel, tag) in kernelList:
  308.         kernelTag = "-%s-%s%s" % (kernel['version'], kernel['release'], tag)
  309.         initrd = self.makeInitrd (kernelTag, instRoot)
  310.         if rootDev == bootpart:
  311.         kernelFile = "/boot/vmlinuz" + kernelTag
  312.         initrdFile = initrd
  313.         else:
  314.         kernelFile = "/vmlinuz" + kernelTag
  315.         initrdFile = initrd[5:]
  316.  
  317.         sl = LiloConfigFile()
  318.  
  319.         sl.addEntry("label", label)
  320.         if os.access (instRoot + initrd, os.R_OK):
  321.         sl.addEntry("initrd", initrdFile)
  322.  
  323.         if self.siloAppend:
  324.         sl.addEntry('append', '"%s"' % self.siloAppend)
  325.  
  326.         silo.addImage ("image", kernelFile, sl)
  327.  
  328.     for (label, device) in otherList:
  329.         sl = LiloConfigFile()
  330.         sl.addEntry("label", label)
  331.         silo.addImage ("other", device, sl)
  332.  
  333.     # for (siloType, name, config) in silo.images:
  334.     #    # remove entries for missing kernels (upgrade)
  335.     #    if siloType == "image":
  336.     #    if not os.access (todo.instPath + name, os.R_OK):
  337.     #        silo.delImage (name)
  338.     #    # remove entries for unbootable partitions
  339.     #    elif siloType == "other":
  340.     #    device = name[5:]
  341.     #    isys.makeDevInode(device, '/tmp/' + device)
  342.     #    if not isys.checkBoot ('/tmp/' + device):
  343.     #        lilo.delImage (name)
  344.     #    os.remove ('/tmp/' + device)
  345.  
  346.     # pass 2, remove duplicate entries
  347.     labels = []
  348.  
  349.     for (siloType, name, config) in silo.images:
  350.         if not name in labels:
  351.         labels.append (name)
  352.         else: # duplicate entry, first entry wins
  353.         silo.delImage (name)
  354.  
  355.     if fstab.getBootDevice() != fstab.getRootDevice()[0]:
  356.         silo.write(instRoot + "/boot/silo.conf")
  357.         try:
  358.         os.remove(instRoot + "/etc/silo.conf")
  359.         except:
  360.         pass
  361.         os.symlink("../boot/silo.conf", instRoot + "/etc/silo.conf")
  362.     else:
  363.         silo.write(instRoot + "/etc/silo.conf")
  364.  
  365.     if self.serial:
  366.         messages = "/tmp/silo.log"
  367.     else:
  368.         messages = "/dev/tty3"
  369.     iutil.execWithRedirect('/sbin/silo',
  370.                    args,
  371.                    stdout = None,
  372.                    root = instRoot)
  373.  
  374.     if bootpart[:2] == "md":
  375.         mbrdevs = self.getMbrDevices(fstab)
  376.         linuxAliases = []
  377.         for mbrdev in mbrdevs:
  378.         device = mbrdev
  379.         try:
  380.             num = _silo.zeroBasedPart(instRoot + "/dev/" + mbrdev)
  381.             if num:
  382.             device = mbrdev + "%d" % num
  383.         except:
  384.             pass
  385.         linuxAliases.append(self.disk2PromPath(device))
  386.         bootDevice = linuxAliases[0]
  387.         linuxAlias = ""
  388.         for alias in linuxAliases:
  389.         if alias and alias != "":
  390.             if linuxAlias != "":
  391.             linuxAlias = linuxAlias + ";"
  392.             linuxAlias = linuxAlias + alias
  393.     elif self.siloDevice == "mbr":
  394.         device = boothd
  395.         try:
  396.         num = _silo.zeroBasedPart(instRoot + "/dev/" + boothd)
  397.         if num:
  398.             device = boothd + "%d" % num
  399.         except:
  400.         pass
  401.         linuxAlias = self.disk2PromPath(device)
  402.         bootDevice = linuxAlias
  403.     else:
  404.         device = bootpart
  405.         linuxAlias = self.disk2PromPath(device)
  406.         bootDevice = linuxAlias
  407.  
  408.     if not (self.linuxAlias and self.hasAliases()):
  409.         linuxAlias = ""
  410.     if not self.bootDevice:
  411.         bootDevice = ""
  412.     if not linuxAlias:
  413.         linuxAlias = ""
  414.     _silo.setPromVars(linuxAlias,bootDevice)
  415.  
  416.     def setDevice(self, device):
  417.     if (type(device) == type((1,))):
  418.         self.siloDevice = device
  419.     elif device != "mbr" and device != "partition" and device:
  420.         raise ValueError, "device must be raid, mbr, partition, or None"
  421.     self.siloDevice = device
  422.  
  423.     def setAppend(self, append):
  424.     self.siloAppend = append
  425.  
  426.     def setDefault(self, default):
  427.     for (label, fsType) in self.siloImages.values():
  428.         if label == default:
  429.         self.default = default
  430.         return
  431.     raise IndexError, "unknown silo label %s" % (default,)
  432.  
  433.     def getLinear(self):
  434.     return self.siloLinear
  435.  
  436.     def getDevice(self):
  437.     return self.siloDevice
  438.  
  439.     def getAppend(self):
  440.     return self.siloAppend
  441.  
  442.     def __init__(self, serial = 0):
  443.     self.siloImages = {}
  444.     self.siloDevice = 'mbr'
  445.     self.siloLinear = 1
  446.     self.siloAppend = None
  447.     self.default = None
  448.     self.initrdsMade = {}
  449.     self.serial = serial
  450.     self.linuxAlias = 1
  451.     self.bootDevice = 1
  452.