Use full EFI path to map drives for grub (#598572)
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. Related: rhbz#598572 --- booty/bootloaderInfo.py | 36 ++++++++++++++++++++++++++++++++++++ booty/x86.py | 10 ++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/booty/bootloaderInfo.py b/booty/bootloaderInfo.py index 7647fb8..9022063 100644 --- a/booty/bootloaderInfo.py +++ b/booty/bootloaderInfo.py @@ -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 = [ "/usr/sbin/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..1ef67dd 100644 --- a/booty/x86.py +++ b/booty/x86.py @@ -264,13 +264,19 @@ class x86BootloaderInfo(efiBootloaderInfo): f.write("# NOTICE: You do not have a /boot partition. " "This means that ") f.write("# all kernel and initrd paths are relative " - "to /, eg. ") - + "to /, eg. ") + f.write('# root %s ' % self.grubbyPartitionName(bootDevs[0])) f.write("# kernel %svmlinuz-version ro root=%s " % (cfPath, rootDev.path)) f.write("# initrd %sinitrd-[generic-]version.img " % (cfPath)) f.write("#boot=/dev/%s " % (grubTarget)) + if iutil.isEfi(): + from product import productName + # Map the target device to the full EFI path + if self.getEfiProductPath(productName): + f.write("map %s %s " % (self.getEfiProductPath(productName), grubTarget)) + # 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 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@redhat.com https://www.redhat.com/mailman/listinfo/anaconda-devel-list |
Use full EFI path to map drives for grub (#598572)
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 On 08/04/2010 06:05 PM, Brian C. Lane wrote: > 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. > > Related: rhbz#598572 Here is an update image, created against current rhel6-branch (65069be291e3c9792424e7fb301829e86ee2d97a) http://bcl.fedorapeople.org/updates/598572.img I've tested it somewhat with my EFI machine -- which has been giving me fits. It seems to have lost the ability to use any USB devices other than the USB keyboard. The mouse drops off the bus as does the USB flash drive I was using to test with. Brian - -- Brian C. Lane <bcl@redhat.com> Red Hat / Port Orchard, WA -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) Comment: Remember Lexington Green! iQEVAwUBTFoQSRF+jBaO/jp/AQLYgwf9HaYeoRYelFHmHUe33vrh55ij+NHfgTDN BUvzMyfrW4KSG2gaEr6zDWkwefCqeWyJNV9a+8g4LET/RcP162MIRSH/qaRloPdZ mw4TH54Ht1owStQ8i+Gnop/WgVBBRipbodax3jc/q3fXC7zx8PJgRBJ0L/2krLT9 hi+Ln0kbtwBjD+d2bvO6luokqkrHVSk/DQ3ezcE5jxuwaRbUzSNbtzpUnidg8SU2 Gn2W5zUrEwUpdWXxPkNGb/eq2kKgH2mBW1kszL+tMYWX5TvZTopz1XT0IO1OnG8J UXwTwAsY4XDuIwzKoVW7KQC8hXaI358w/VucWUTfeW9rcWvW1VgP7Q== =MVwr -----END PGP SIGNATURE----- _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@redhat.com https://www.redhat.com/mailman/listinfo/anaconda-devel-list |
Use full EFI path to map drives for grub (#598572)
Ack with one comment.
Without being an EFI expert, the code itself looks fine. The only comment I have is below. On Wed, 4 Aug 2010, Brian C. Lane wrote: 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. Related: rhbz#598572 --- booty/bootloaderInfo.py | 36 ++++++++++++++++++++++++++++++++++++ booty/x86.py | 10 ++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/booty/bootloaderInfo.py b/booty/bootloaderInfo.py index 7647fb8..9022063 100644 --- a/booty/bootloaderInfo.py +++ b/booty/bootloaderInfo.py @@ -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 = [ "/usr/sbin/efibootmgr", "-v" ] Would rather this just be 'efibootmgr' since explicit paths in execWithCapture() calls have bitten us before. + 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..1ef67dd 100644 --- a/booty/x86.py +++ b/booty/x86.py @@ -264,13 +264,19 @@ class x86BootloaderInfo(efiBootloaderInfo): f.write("# NOTICE: You do not have a /boot partition. " "This means that ") f.write("# all kernel and initrd paths are relative " - "to /, eg. ") - + "to /, eg. ") + f.write('# root %s ' % self.grubbyPartitionName(bootDevs[0])) f.write("# kernel %svmlinuz-version ro root=%s " % (cfPath, rootDev.path)) f.write("# initrd %sinitrd-[generic-]version.img " % (cfPath)) f.write("#boot=/dev/%s " % (grubTarget)) + if iutil.isEfi(): + from product import productName + # Map the target device to the full EFI path + if self.getEfiProductPath(productName): + f.write("map %s %s " % (self.getEfiProductPath(productName), grubTarget)) + # 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: -- David Cantrell <dcantrell@redhat.com> Red Hat / Honolulu, HI _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@redhat.com https://www.redhat.com/mailman/listinfo/anaconda-devel-list |
Use full EFI path to map drives for grub (#598572)
On 08/05/2010 12:50 PM, David Cantrell wrote:
> Ack with one comment. > > Without being an EFI expert, the code itself looks fine. The only comment I > have is below. > > On Wed, 4 Aug 2010, Brian C. Lane wrote: > >> 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. >> >> Related: rhbz#598572 >> --- >> booty/bootloaderInfo.py | 36 ++++++++++++++++++++++++++++++++++++ >> booty/x86.py | 10 ++++++++-- >> 2 files changed, 44 insertions(+), 2 deletions(-) >> >> diff --git a/booty/bootloaderInfo.py b/booty/bootloaderInfo.py >> index 7647fb8..9022063 100644 >> --- a/booty/bootloaderInfo.py >> +++ b/booty/bootloaderInfo.py >> @@ -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 = [ "/usr/sbin/efibootmgr", "-v" ] > > Would rather this just be 'efibootmgr' since explicit paths in > execWithCapture() calls have bitten us before. Yeah, it should be. > >> + 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..1ef67dd 100644 >> --- a/booty/x86.py >> +++ b/booty/x86.py >> @@ -264,13 +264,19 @@ class x86BootloaderInfo(efiBootloaderInfo): >> f.write("# NOTICE: You do not have a /boot partition. " >> "This means that ") >> f.write("# all kernel and initrd paths are relative " >> - "to /, eg. ") >> - >> + "to /, eg. ") >> + Not sure what's up here, but it shouldn't matter. >> f.write('# root %s ' % self.grubbyPartitionName(bootDevs[0])) >> f.write("# kernel %svmlinuz-version ro root=%s " % (cfPath, rootDev.path)) >> f.write("# initrd %sinitrd-[generic-]version.img " % (cfPath)) >> f.write("#boot=/dev/%s " % (grubTarget)) >> >> + if iutil.isEfi(): >> + from product import productName >> + # Map the target device to the full EFI path >> + if self.getEfiProductPath(productName): >> + f.write("map %s %s " % (self.getEfiProductPath(productName), grubTarget)) >> + This should either be "device" or "efimap", not just "map". >> # 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: >> > -- Peter I hope you know that this will go down on your permanent record. 01234567890123456789012345678901234567890123456789 012345678901234567890123456789 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@redhat.com https://www.redhat.com/mailman/listinfo/anaconda-devel-list |
Use full EFI path to map drives for grub (#598572)
On 08/04/2010 09:05 PM, Brian C. Lane wrote:
> 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. Okay, so the problem we were seeing yesterday is that installGrub() is getting called after writeGrubConf(), but writeGrubConf() needs the result of installGrub() in order to work right here. I've updated your patch to swap the order of those on UEFI machines, which is kindof ugly in that it's not really generic, but it should actually work. The way to avoid that problem is either a) do our own building of the disk's efi device path or b) teach efibootmgr how to show us the device path without changing or reading the boot order table. Neither of those seems practical right now. I'll send an updated patch in response to this message. -- Peter The Shuttle is now going five times the sound of speed. -- Dan Rather, first landing of Columbia 01234567890123456789012345678901234567890123456789 012345678901234567890123456789 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@redhat.com https://www.redhat.com/mailman/listinfo/anaconda-devel-list |
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 I don't have the equipment to test this, but it looks alright to me. - Chris _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@redhat.com https://www.redhat.com/mailman/listinfo/anaconda-devel-list |
| All times are GMT. The time now is 07:55 AM. |
VBulletin, Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.