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. --- 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 = {}
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:
- If we're creating a new PReP partition, use that.
- Otherwise, if there's a PReP partition already on the disk that contains /boot (or "any disk that contains /boot" if mdraid), use that.
- 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 thatfor 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" anddev.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 foundreturn 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" anddev.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 = devicebreakreturn bootDev
# use booty's PReP-picking algorithmreturn self.anaconda.id.bootloader.pickPReP()def bootloaderChoices(self, bl): ret = {}
anaconda-patches@lists.fedorahosted.org