[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[PATCH rhel6-branch master f14-branch] Use full EFI path to map drives for grub (#598572)



From: Brian C. Lane <bcl redhat com>

NOTE: This requires grub-0.97-66 to work correctly.

On EFI we map the boot drive so that there is no question as to where
/boot is located. This requires a change in grub to parse the EFI
device path from the map command.

Also make all efibootmgr invocations use PATH instead of hardcoded
locations.

Related: rhbz#598572
---
 booty/bootloaderInfo.py |   42 +++++++++++++++++++++++++++++++++++++++---
 booty/x86.py            |   24 ++++++++++++++++++------
 2 files changed, 57 insertions(+), 9 deletions(-)

diff --git a/booty/bootloaderInfo.py b/booty/bootloaderInfo.py
index 7647fb8..d9ab62e 100644
--- a/booty/bootloaderInfo.py
+++ b/booty/bootloaderInfo.py
@@ -599,7 +599,7 @@ class efiBootloaderInfo(bootloaderInfo):
     # XXX wouldn't it be nice to have a real interface to use efibootmgr from?
     def removeOldEfiEntries(self, instRoot):
         p = os.pipe()
-        rc = iutil.execWithRedirect('/usr/sbin/efibootmgr', [],
+        rc = iutil.execWithRedirect('efibootmgr', [],
                                     root = instRoot, stdout = p[1])
         os.close(p[1])
         if rc:
@@ -618,7 +618,7 @@ class efiBootloaderInfo(bootloaderInfo):
                 continue
             if string.join(fields[1:], " ") == productName:
                 entry = fields[0][4:8]
-                rc = iutil.execWithRedirect('/usr/sbin/efibootmgr',
+                rc = iutil.execWithRedirect('efibootmgr',
                                             ["-b", entry, "-B"],
                                             root = instRoot,
                                             stdout="/dev/tty5", stderr="/dev/tty5")
@@ -650,7 +650,7 @@ class efiBootloaderInfo(bootloaderInfo):
             bootdisk.startswith('rd/') or bootdisk.startswith('sx8/')):
             bootdisk = bootdisk[:-1]
 
-        argv = [ "/usr/sbin/efibootmgr", "-c" , "-w", "-L",
+        argv = [ "efibootmgr", "-c" , "-w", "-L",
                  productName, "-d", "/dev/%s" % bootdisk,
                  "-p", bootpart, "-l", "\\EFI\\redhat\\" + self.bootloader ]
         rc = iutil.execWithRedirect(argv[0], argv[1:], root = instRoot,
@@ -658,6 +658,40 @@ class efiBootloaderInfo(bootloaderInfo):
                                     stderr = "/dev/tty5")
         return rc
 
+    def getEfiProductPath(self, productName, force=False):
+        """ Return the full EFI path of the installed product.
+            eg. HD(4,2c8800,64000,902c1655-2677-4455-b2a5-29d0ce835610)
+
+            pass force=True to skip the cache and rerun efibootmgr
+        """
+        if not force and self._efiProductPath:
+            return self._efiProductPath
+
+        argv = [ "efibootmgr", "-v" ]
+        buf = iutil.execWithCapture(argv[0], argv[1:],
+                                    stderr="/dev/tty5")
+
+        efiProductPath = None
+        for line in buf.splitlines():
+            line = line.strip()
+            if not line:
+                continue
+            if productName in line:
+                efiProductPath = line[line.rfind(productName)+len(productName):].strip()
+                break
+
+        if efiProductPath:
+            # Grab just the drive path
+            import re
+            m = re.match("(.*?\(.*?\)).*", efiProductPath)
+            if m:
+                efiProductPath = m.group(1)
+            else:
+                efiProductPath = None
+
+        self._efiProductPath = efiProductPath
+        return self._efiProductPath
+
     def installGrub(self, instRoot, bootDev, grubTarget, grubPath, cfPath):
         if not iutil.isEfi():
             raise EnvironmentError
@@ -672,6 +706,8 @@ class efiBootloaderInfo(bootloaderInfo):
         else:
             self.storage = instData.storage
 
+        self._efiProductPath = None
+
         if iutil.isEfi():
             self._configdir = "/boot/efi/EFI/redhat"
             self._configname = "grub.conf"
diff --git a/booty/x86.py b/booty/x86.py
index 39c9c88..49b408e 100644
--- a/booty/x86.py
+++ b/booty/x86.py
@@ -219,9 +219,10 @@ class x86BootloaderInfo(efiBootloaderInfo):
             grubPath = "/boot/grub"
             cfPath = "/boot/"
 
-        if not upgrade:
-            self.writeGrubConf(instRoot, bootDev, rootDev, defaultDev, kernelList,
-                               chainList, grubTarget, grubPath, cfPath)
+        if not upgrade and not iutil.isEfi():
+            self.writeGrubConf(instRoot, bootDev, rootDev, defaultDev,
+                               kernelList, chainList, grubTarget, grubPath,
+                               cfPath)
 
         # keep track of which devices are used for the device.map
         usedDevs = set()
@@ -233,7 +234,11 @@ class x86BootloaderInfo(efiBootloaderInfo):
             self.writeDeviceMap(instRoot, usedDevs, upgrade)
             self.writeSysconfig(instRoot, grubTarget, upgrade)
 
-        return self.installGrub(instRoot, bootDev, grubTarget, grubPath, cfPath)
+        ret = self.installGrub(instRoot, bootDev, grubTarget, grubPath, cfPath)
+        if iutil.isEfi():
+            self.writeGrubConf(instRoot, bootDev, rootDev, defaultDev,
+                               kernelList, chainList, grubTarget, grubPath,
+                               cfPath)
 
     def writeGrubConf(self, instRoot, bootDev, rootDev, defaultDev, kernelList,
                       chainList, grubTarget, grubPath, cfPath):
@@ -264,13 +269,20 @@ class x86BootloaderInfo(efiBootloaderInfo):
             f.write("# NOTICE:  You do not have a /boot partition.  "
                     "This means that\n")
             f.write("#          all kernel and initrd paths are relative "
-                    "to /, eg.\n")            
-        
+                    "to /, eg.\n")
+
         f.write('#          root %s\n' % self.grubbyPartitionName(bootDevs[0]))
         f.write("#          kernel %svmlinuz-version ro root=%s\n" % (cfPath, rootDev.path))
         f.write("#          initrd %sinitrd-[generic-]version.img\n" % (cfPath))
         f.write("#boot=/dev/%s\n" % (grubTarget))
 
+        if iutil.isEfi():
+            from product import productName
+            # Map the target device to the full EFI path
+            if self.getEfiProductPath(productName):
+                (n, pn) = getDiskPart(bootDevs[0], self.storage)
+                f.write("device (%s) %s\n" % (self.grubbyDiskName(n), self.getEfiProductPath(productName)))
+
         # get the default image to boot... we have to walk and find it
         # since grub indexes by where it is in the config file
         if defaultDev.name == rootDev.name:
-- 
1.7.2


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]