Linux Archive

Linux Archive (http://www.linux-archive.org/)
-   Debian Kernel (http://www.linux-archive.org/debian-kernel/)
-   -   Generate more complete device.map grub file when upgrading grub (#533621). (http://www.linux-archive.org/debian-kernel/279851-generate-more-complete-device-map-grub-file-when-upgrading-grub-533621-a.html)

Hans de Goede 11-13-2009 09:41 AM

Generate more complete device.map grub file when upgrading grub (#533621).
 
Hi,

Looks ok, so ack.

Regards,

Hans


On 11/13/2009 11:01 AM, Radek Vykydal wrote:

When updating device.map during upgrade of grub, I missed case when driveorder
changes between install and upgrade (e.g. when driveorder different from that
detected during upgrade had been specified when isntalling) in my previous
patch. To fix it, I generate device.map in similar way as when installing (only
updating it with some devices that we can know about only from updated
device.map - e.g. chainloaded devices). This brought me to another
consolidation of the code (started in previous grub installation patches):

* remove updateGrub, use writeGrub with upgrade flag instead
* move code from writeGrub into separate methods
writeGrubConf (called only for grub (re)install)
writeSysconfig (called both for grub (re)install and upgrade)
writeDeviceMap (called both for grub (re)install and upgrade)
* remove old writeSysconfig and updateDeviceMap that were called
only from upgradeGrub, use new writeSysconfig and writeDeviceMap
with upgrade flag instead.
---
booty/x86.py | 164 ++++++++++++++++++++++-----------------------------------
1 files changed, 63 insertions(+), 101 deletions(-)

diff --git a/booty/x86.py b/booty/x86.py
index 9106bb0..40ec7f2 100644
--- a/booty/x86.py
+++ b/booty/x86.py
@@ -200,9 +200,44 @@ class x86BootloaderInfo(efiBootloaderInfo):
return self.runGrubInstall(instRoot, bootDev.name, cmds, cfPath)

def writeGrub(self, instRoot, bl, kernelList, chainList,
- defaultDev, justConfigFile):
+ defaultDev, justConfigFile, upgrade=False):

rootDev = self.storage.rootDevice
+ grubTarget = bl.getDevice()
+
+ try:
+ bootDev = self.storage.mountpoints["/boot"]
+ grubPath = "/grub"
+ cfPath = "/"
+ except KeyError:
+ bootDev = rootDev
+ grubPath = "/boot/grub"
+ cfPath = "/boot/"
+
+ if not upgrade:
+ self.writeGrubConf(instRoot, bootDev, rootDev, defaultDev, kernelList,
+ chainList, grubTarget, grubPath, cfPath)
+
+ # keep track of which devices are used for the device.map
+ usedDevs = set()
+ usedDevs.update(self.getPhysicalDevices(grubTarget ))
+ usedDevs.update(self.getPhysicalDevices(rootDev.na me))
+ usedDevs.update(self.getPhysicalDevices(bootDev.na me))
+ usedDevs.update([dev for (label, longlabel, dev) in chainList if longlabel])
+
+ if not justConfigFile or not upgrade:
+ self.writeDeviceMap(instRoot, usedDevs, upgrade)
+ self.writeSysconfig(instRoot, grubTarget, upgrade)
+
+ if not justConfigFile:
+ return self.installGrub(instRoot, bootDev, grubTarget, grubPath, cfPath)
+
+ return 0
+
+ def writeGrubConf(self, instRoot, bootDev, rootDev, defaultDev, kernelList,
+ chainList, grubTarget, grubPath, cfPath):
+
+ bootDevs = self.getPhysicalDevices(bootDev.name)

# XXX old config file should be read here for upgrade

@@ -212,8 +247,6 @@ class x86BootloaderInfo(efiBootloaderInfo):
self.perms = os.stat(cf)[0]& 0777
os.rename(cf, cf + '.rpmsave')

- grubTarget = bl.getDevice()
-
f = open(cf, "w+")

f.write("# grub.conf generated by anaconda
")
@@ -221,24 +254,16 @@ class x86BootloaderInfo(efiBootloaderInfo):
f.write("# Note that you do not have to rerun grub "
"after making changes to this file
")

- try:
- bootDev = self.storage.mountpoints["/boot"]
- grubPath = "/grub"
- cfPath = "/"
+ if grubPath == "/grub":
f.write("# NOTICE: You have a /boot partition. This means "
"that
")
f.write("# all kernel and initrd paths are relative "
"to /boot/, eg.
")
- except KeyError:
- bootDev = rootDev
- grubPath = "/boot/grub"
- cfPath = "/boot/"
+ else:
f.write("# NOTICE: You do not have a /boot partition. "
"This means that
")
f.write("# all kernel and initrd paths are relative "
"to /, eg.
")
-
- bootDevs = self.getPhysicalDevices(bootDev.name)

f.write('# root %s
' % self.grubbyPartitionName(bootDevs[0]))
f.write("# kernel %svmlinuz-version ro root=%s
" % (cfPath, rootDev.path))
@@ -254,8 +279,6 @@ class x86BootloaderInfo(efiBootloaderInfo):
# chain list
default = len(kernelList)

- # keep track of which devices are used for the device.map
- usedDevs = {}

f.write('default=%s
' % (default))
f.write('timeout=%d
' % (self.timeout or 0))
@@ -285,8 +308,6 @@ class x86BootloaderInfo(efiBootloaderInfo):
% (self.grubbyPartitionName(bootDevs[0]), cfPath))
f.write("hiddenmenu
")

- for dev in self.getPhysicalDevices(grubTarget):
- usedDevs[dev] = 1

if self.password:
f.write('password --md5 %s
' %(self.password))
@@ -345,7 +366,6 @@ class x86BootloaderInfo(efiBootloaderInfo):
# f.write(' makeactive
')
f.write(' chainloader +1')
f.write('
')
- usedDevs[device] = 1

f.close()

@@ -369,24 +389,31 @@ class x86BootloaderInfo(efiBootloaderInfo):
os.symlink(".." + self.configfile, etcgrub)
except:
pass
-
- for dev in self.getPhysicalDevices(rootDev.name) + bootDevs:
- usedDevs[dev] = 1
+
+ def writeDeviceMap(self, instRoot, usedDevs, upgrade=False):

if os.access(instRoot + "/boot/grub/device.map", os.R_OK):
+ # For upgrade, we want also e.g. devs that has been added
+ # to file during install for chainloading.
+ if upgrade:
+ f = open(instRoot + "/boot/grub/device.map", "r")
+ for line in f:
+ if line.startswith('(hd'):
+ (grubdisk, dev) = line.split()[:2]
+ dev = dev[5:]
+ if dev in self.drivelist:
+ usedDevs.add(dev)
+ f.close()
os.rename(instRoot + "/boot/grub/device.map",
instRoot + "/boot/grub/device.map.rpmsave")

f = open(instRoot + "/boot/grub/device.map", "w+")
f.write("# this device map was generated by anaconda
")
- devs = usedDevs.keys()
- usedDevs = {}
- for dev in devs:
+ usedDiskDevs = set()
+ for dev in usedDevs:
drive = getDiskPart(dev, self.storage)[0]
- if usedDevs.has_key(drive):
- continue
- usedDevs[drive] = 1
- devs = usedDevs.keys()
+ usedDiskDevs.add(drive)
+ devs = list(usedDiskDevs)
devs.sort()
for drive in devs:
# XXX hack city. If they're not the sort of thing that'll
@@ -396,25 +423,25 @@ class x86BootloaderInfo(efiBootloaderInfo):
f.write("(%s) %s
" % (self.grubbyDiskName(drive), dev.path))
f.close()

+ def writeSysconfig(self, instRoot, grubTarget, upgrade):
sysconf = '/etc/sysconfig/grub'
if os.access (instRoot + sysconf, os.R_OK):
+ if upgrade:
+ return
self.perms = os.stat(instRoot + sysconf)[0]& 0777
os.rename(instRoot + sysconf,
instRoot + sysconf + '.rpmsave')
# if it's an absolute symlink, just get it out of our way
elif (os.path.islink(instRoot + sysconf) and
os.readlink(instRoot + sysconf)[0] == '/'):
+ if upgrade:
+ return
os.rename(instRoot + sysconf,
instRoot + sysconf + '.rpmsave')
f = open(instRoot + sysconf, 'w+')
f.write("boot=/dev/%s
" %(grubTarget,))
f.write("forcelba=0
")
f.close()
-
- if not justConfigFile:
- return self.installGrub(instRoot, bootDev, grubTarget, grubPath, cfPath)
-
- return 0

def grubbyDiskName(self, name):
return "hd%d" % self.drivelist.index(name)
@@ -462,72 +489,6 @@ class x86BootloaderInfo(efiBootloaderInfo):

return config

- def updateDeviceMap(self, instRoot):
- if os.access(instRoot + "/boot/grub/device.map", os.R_OK):
- f = open(instRoot + "/boot/grub/device.map", "r")
- updatedlines = []
- update = False
- for line in f:
- line = line.strip()
- if line.startswith('(hd'):
- (grubdisk, path) = line.split()[:2]
- i = int(grubdisk.lstrip('(hd ').rstrip(') '))
- actual_path = self.storage.devicetree.getDeviceByName(self.drive list[i]).path
- if path != actual_path:
- line = "%s %s" % (grubdisk, actual_path)
- update = True
- updatedlines.append(line)
- f.close()
-
- if update:
- os.rename(instRoot + "/boot/grub/device.map",
- instRoot + "/boot/grub/device.map.rpmsave")
- f = open(instRoot + "/boot/grub/device.map", "w+")
- upd_comment = "# file updated by anaconda
"
- f.write(upd_comment + '
'.join(updatedlines) + '
')
- f.close()
-
- # this is a hackish function that depends on the way anaconda writes
- # out the grub.conf with a #boot= comment
- # XXX this falls into the category of self.doUpgradeOnly
- def upgradeGrub(self, instRoot, bl, kernelList, chainList,
- defaultDev, justConfigFile):
- if justConfigFile:
- return ""
-
- grubTarget = bl.getDevice()
-
- if grubTarget is None:
- return ""
-
- # migrate info to /etc/sysconfig/grub
- self.writeSysconfig(instRoot, grubTarget)
-
- # update device.map
- self.updateDeviceMap(instRoot)
-
- # more suckage. grub-install can't work without a valid /etc/mtab
- # so we have to do shenanigans to get updated grub installed...
- # steal some more code above
- try:
- bootDev = self.storage.mountpoints["/boot"]
- grubPath = "/grub"
- cfPath = "/"
- except KeyError:
- bootDev = self.storage.rootDevice
- grubPath = "/boot/grub"
- cfPath = "/boot/"
-
- return self.installGrub(instRoot, bootDev, grubTarget, grubPath, cfPath)
-
- def writeSysconfig(self, instRoot, installDev):
- sysconf = '/etc/sysconfig/grub'
- if not os.access(instRoot + sysconf, os.R_OK):
- f = open(instRoot + sysconf, "w+")
- f.write("boot=%s
" %(installDev,))
- f.write("forcelba=0
")
- f.close()
-
def write(self, instRoot, bl, kernelList, chainList,
defaultDev, justConfig):
if self.timeout is None and chainList:
@@ -536,8 +497,9 @@ class x86BootloaderInfo(efiBootloaderInfo):
# XXX HACK ALERT - see declaration above
if self.doUpgradeOnly:
if self.useGrubVal:
- return self.upgradeGrub(instRoot, bl, kernelList,
- chainList, defaultDev, justConfig)
+ return self.writeGrub(instRoot, bl, kernelList,
+ chainList, defaultDev, justConfig,
+ upgrade = True)
return 0

if len(kernelList)< 1:


_______________________________________________
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 11:56 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.