This version of the patch fixes a potential misfire if bootDevice() is called before partitioning is committed - we could have a "create" action with a later "destroy" action, which would render the earlier "create" moot.
The differences from the previous patch are:
- if a.format.type == "prepboot": + if a.format.type == "prepboot" and a.device in self.storage.devices:
...which works because (if I understand dlehman correctly) devices that are *actually* going to be created by the requested actions will be in the self.storage.devices list.. and I removed a stray footnote from the commit message.
-w
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. --- 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..096de39 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" and a.device in self.storage.devices: + 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 = {}
ACK
On Tue, 2013-09-10 at 16:34 -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.
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..096de39 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" and a.device in self.storage.devices: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