[PATCH rhel6-branch] PPC: strengthen PReP-picking algorithm (#877852)

David Lehman dlehman at redhat.com
Tue Sep 10 18:29:58 UTC 2013


On Tue, 2013-09-10 at 13:58 -0400, Will Woods wrote:
> pSeries-style systems can have multiple PReP partitions, as long as
> there's only one per disk. It's kind of like the x86 MBR that way.
> 
> The current code in booty and platform.py *always* picks the first PReP
> partition, which will fail if if you have (e.g.) an OS already installed
> on /dev/sda and you're doing a new install onto /dev/sdb.
> 
> This patch adds ppcBootloaderInfo.pickPReP(), which tries to find the
> best PReP partition to use according to the following rules:
> 
> 1) If we're creating a new PReP partition, use that.
> 2) Otherwise, if there's a PReP partition already on the disk that
>    contains /boot (or "any disk that contains /boot" if mdraid), use that.
> 3) Failing that, use the first available PReP partition (as before).
> 
> This should make mkofboot actually install yaboot into the correct PReP
> partition.
> 
> IPSeriesPPC.bootDevice() has been changed to use this same algorithm, so
> the two of them will agree about what the boot device is.
> 
> ยน If /boot is an mdraid device, check each of its member disks for a
> PReP partition, and return the first one found.

Looks good to me. I do think this all happens after processing storage
actions, but if I'm wrong about that you might want to add a check that
any device you got from findActions is still in storage.devices (it will
not be there if it has since been removed/canceled). I suspect it isn't
necessary.

> ---
>  booty/ppc.py | 38 +++++++++++++++++++++++++++++++++-----
>  platform.py  | 11 ++---------
>  2 files changed, 35 insertions(+), 14 deletions(-)
> 
> diff --git a/booty/ppc.py b/booty/ppc.py
> index 6f62071..3fc5582 100644
> --- a/booty/ppc.py
> +++ b/booty/ppc.py
> @@ -7,6 +7,36 @@ from bootloaderInfo import *
>  import iutil
>  
>  class ppcBootloaderInfo(bootloaderInfo):
> +    def pickPReP(self):
> +        # if we created a new PReP partition, pick that
> +        for a in self.storage.findActions(type="create", obj="format"):
> +            if a.format.type == "prepboot":
> +                return a.device
> +
> +        # otherwise, look at the existing PReP partitions.
> +        prepdevs = []
> +        for dev in self.storage.fsset.devices:
> +            if (dev.format.type == "prepboot" and
> +                    dev.partedPartition.getFlag(parted.PARTITION_BOOT)):
> +                prepdevs.append(dev)
> +
> +        # (no PReP found? bail out.)
> +        if len(prepdevs) == 0:
> +            return None
> +
> +        # we'd prefer a PReP partition that's on the same disk as /boot.
> +        bootdev = self.storage.mountpoints.get("/boot",self.storage.rootDevice)
> +        if bootdev.type == "mdarray":
> +            bootdisks = set(p.disk for p in bootdev.parents)
> +        else:
> +            bootdisks = set([bootdev.disk])
> +        for dev in prepdevs:
> +            if dev.disk in bootdisks:
> +                return dev
> +
> +        # failing that, return the first PReP partition we found
> +        return prepdevs[0]
> +
>      def getBootDevs(self, bl):
>          import parted
>  
> @@ -14,10 +44,9 @@ class ppcBootloaderInfo(bootloaderInfo):
>          machine = iutil.getPPCMachine()
>  
>          if machine == 'pSeries':
> -            for dev in self.storage.fsset.devices:
> -                if (dev.format.type == "prepboot" and
> -                        dev.partedPartition.getFlag(parted.PARTITION_BOOT)):
> -                    retval.append(dev.path)
> +            prep = self.pickPReP()
> +            if prep:
> +                retval.append(prep.path)
>          elif machine == 'PMac':
>              for dev in self.storage.fsset.devices:
>                  if dev.format.type == "hfs" and dev.format.bootable:
> @@ -31,7 +60,6 @@ class ppcBootloaderInfo(bootloaderInfo):
>                  except KeyError:
>                      # Try / if we don't have this we're not going to work
>                      device = self.storage.rootDevice
> -
>                  retval.append(device.path)
>              else:
>                  if bl.getDevice():
> diff --git a/platform.py b/platform.py
> index 7bc75ec..e866133 100644
> --- a/platform.py
> +++ b/platform.py
> @@ -392,15 +392,8 @@ class IPSeriesPPC(PPC):
>      _maxBootPartSize = 10
>  
>      def bootDevice(self):
> -        bootDev = None
> -
> -        # We want the first PReP partition.
> -        for device in self.anaconda.id.storage.partitions:
> -            if device.format.type == "prepboot":
> -                bootDev = device
> -                break
> -
> -        return bootDev
> +        # use booty's PReP-picking algorithm
> +        return self.anaconda.id.bootloader.pickPReP()
>  
>      def bootloaderChoices(self, bl):
>          ret = {}




More information about the anaconda-patches mailing list