1 |
diff -Nur -x '*.orig' -x '*.rej' booty-0.44.4/bootloaderInfo.py mezzanine_patched_booty-0.44.4/bootloaderInfo.py |
2 |
--- booty-0.44.4/bootloaderInfo.py 2006-04-19 14:37:24.000000000 -0600 |
3 |
+++ mezzanine_patched_booty-0.44.4/bootloaderInfo.py 2007-05-17 22:24:05.000000000 -0600 |
4 |
@@ -16,6 +16,7 @@ |
5 |
# |
6 |
|
7 |
import os, sys |
8 |
+import isys |
9 |
import crypt |
10 |
import whrandom |
11 |
import butil |
12 |
@@ -419,6 +420,7 @@ |
13 |
return args |
14 |
|
15 |
args.append("--location=%s" % (self.defaultDevice,)) |
16 |
+ args.append("--driveorder=%s" % (",".join(self.drivelist))) |
17 |
|
18 |
if self.args.get(): |
19 |
args.append("--append=\"%s\"" %(self.args.get())) |
20 |
@@ -642,6 +644,28 @@ |
21 |
def setUseGrub(self, val): |
22 |
self.useGrubVal = val |
23 |
|
24 |
+ def getPhysicalDevices(self, device): |
25 |
+ # This finds a list of devices on which the given device name resides. |
26 |
+ # Accepted values for "device" are raid1 md devices (i.e. "md0"), |
27 |
+ # physical disks ("hda"), and real partitions on physical disks |
28 |
+ # ("hda1"). Volume groups/logical volumes are not accepted. |
29 |
+ # |
30 |
+ # XXX this has internal anaconda-ish knowledge. ick. |
31 |
+ import isys |
32 |
+ import lvm |
33 |
+ |
34 |
+ if string.split(device, '/', 1)[0] in map (lambda vg: vg[0], |
35 |
+ lvm.vglist()): |
36 |
+ return [] |
37 |
+ |
38 |
+ if device.startswith('md'): |
39 |
+ bootable = 0 |
40 |
+ parts = checkbootloader.getRaidDisks(device, 1, stripPart=0) |
41 |
+ parts.sort() |
42 |
+ return parts |
43 |
+ |
44 |
+ return [device] |
45 |
+ |
46 |
def writeGrub(self, instRoot, fsset, bl, langs, kernelList, chainList, |
47 |
defaultDev, justConfigFile): |
48 |
if len(kernelList) < 1: |
49 |
@@ -663,10 +687,12 @@ |
50 |
instRoot + cf + '.rpmsave') |
51 |
|
52 |
grubTarget = bl.getDevice() |
53 |
- # XXX wouldn't it be nice if grub really understood raid? :) |
54 |
- if grubTarget.startswith('md'): |
55 |
- ent = fsset.getEntryByDeviceName(grubTarget) |
56 |
- grubTarget = ent.device.members[0] |
57 |
+ target = "mbr" |
58 |
+ if (grubTarget.startswith('rd/') or grubTarget.startswith('ida/') or grubTarget.startswith('cciss/')): |
59 |
+ if grubTarget[-2] == 'p' or grubTarget[-3] == 'p': |
60 |
+ target = "partition" |
61 |
+ elif grubTarget[-1].isdigit() and not grubTarget.startswith('md'): |
62 |
+ target = "partition" |
63 |
|
64 |
f = open(instRoot + cf, "w+") |
65 |
|
66 |
@@ -692,9 +718,10 @@ |
67 |
f.write("# all kernel and initrd paths are relative " |
68 |
"to /boot/, eg.\n") |
69 |
|
70 |
- bootDev = bootDev.device.getDevice(asBoot = 1) |
71 |
+ bootDevs = self.getPhysicalDevices(bootDev.device.getDevice()) |
72 |
+ bootDev = bootDev.device.getDevice() |
73 |
|
74 |
- f.write('# root %s\n' % self.grubbyPartitionName(bootDev)) |
75 |
+ f.write('# root %s\n' % self.grubbyPartitionName(bootDevs[0])) |
76 |
f.write("# kernel %svmlinuz-version ro " |
77 |
"root=/dev/%s\n" % (cfPath, rootDev)) |
78 |
f.write("# initrd %sinitrd-version.img\n" % (cfPath)) |
79 |
@@ -741,11 +768,11 @@ |
80 |
# we only want splashimage if they're not using a serial console |
81 |
if os.access("%s/boot/grub/splash.xpm.gz" %(instRoot,), os.R_OK): |
82 |
f.write('splashimage=%s%sgrub/splash.xpm.gz\n' |
83 |
- % (self.grubbyPartitionName(bootDev), cfPath)) |
84 |
+ % (self.grubbyPartitionName(bootDevs[0]), cfPath)) |
85 |
f.write("hiddenmenu\n") |
86 |
|
87 |
- usedDevs[bootDev] = 1 |
88 |
- usedDevs[grubTarget] = 1 |
89 |
+ for dev in self.getPhysicalDevices(grubTarget): |
90 |
+ usedDevs[dev] = 1 |
91 |
|
92 |
if self.password: |
93 |
f.write('password --md5 %s\n' %(self.password)) |
94 |
@@ -757,7 +784,7 @@ |
95 |
initrd = booty.makeInitrd (kernelTag, instRoot) |
96 |
|
97 |
f.write('title %s (%s)\n' % (longlabel, version)) |
98 |
- f.write('\troot %s\n' % self.grubbyPartitionName(bootDev)) |
99 |
+ f.write('\troot %s\n' % self.grubbyPartitionName(bootDevs[0])) |
100 |
|
101 |
realroot = getRootDevName(initrd, fsset, rootDev, instRoot) |
102 |
realroot = " root=%s" %(realroot,) |
103 |
@@ -801,21 +828,31 @@ |
104 |
except: |
105 |
pass |
106 |
|
107 |
+ for dev in self.getPhysicalDevices(rootDev): |
108 |
+ usedDevs[dev] = 1 |
109 |
+ |
110 |
+ for dev in bootDevs: |
111 |
+ usedDevs[dev] = 1 |
112 |
|
113 |
if not os.access(instRoot + "/boot/grub/device.map", os.R_OK): |
114 |
f = open(instRoot + "/boot/grub/device.map", "w+") |
115 |
f.write("# this device map was generated by anaconda\n") |
116 |
f.write("(fd0) /dev/fd0\n") |
117 |
devs = usedDevs.keys() |
118 |
- devs.sort() |
119 |
usedDevs = {} |
120 |
for dev in devs: |
121 |
drive = getDiskPart(dev)[0] |
122 |
if usedDevs.has_key(drive): |
123 |
continue |
124 |
- f.write("(%s) /dev/%s\n" % (self.grubbyDiskName(drive), |
125 |
- drive)) |
126 |
usedDevs[drive] = 1 |
127 |
+ devs = usedDevs.keys() |
128 |
+ devs.sort() |
129 |
+ for drive in devs: |
130 |
+ # XXX hack city. If they're not the sort of thing that'll |
131 |
+ # be in the device map, they shouldn't still be in the list. |
132 |
+ if not drive.startswith('md'): |
133 |
+ f.write("(%s) /dev/%s\n" % (self.grubbyDiskName(drive), |
134 |
+ drive)) |
135 |
f.close() |
136 |
|
137 |
args = "--stage2=/boot/grub/stage2 " |
138 |
@@ -840,14 +877,22 @@ |
139 |
f.write("forcelba=0\n") |
140 |
f.close() |
141 |
|
142 |
- part = self.grubbyPartitionName(bootDev) |
143 |
- prefix = "%s/%s" % (self.grubbyPartitionName(bootDev), grubPath) |
144 |
- cmd = "root %s\ninstall %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" % \ |
145 |
- (part, args, grubPath, self.grubbyPartitionName(grubTarget), |
146 |
- grubPath, part, grubPath) |
147 |
+ cmds = [] |
148 |
+ for bootDev in bootDevs: |
149 |
+ gtDisk = self.grubbyPartitionName(getDiskPart(bootDev)[0]) |
150 |
+ bPart = self.grubbyPartitionName(bootDev) |
151 |
+ |
152 |
+ stage1Target = gtDisk |
153 |
+ if target == "partition": |
154 |
+ stage1Target = self.grubbyPartitionName(bootDev) |
155 |
+ |
156 |
+ cmd = "root %s\nsetup %s" % (bPart, stage1Target) |
157 |
+ cmds.append(cmd) |
158 |
|
159 |
if not justConfigFile: |
160 |
- log("GRUB command %s", cmd) |
161 |
+ log("GRUB commands:") |
162 |
+ for cmd in cmds: |
163 |
+ log("\t%s\n", cmd) |
164 |
|
165 |
# copy the stage files over into /boot |
166 |
rhpl.executil.execWithRedirect( "/sbin/grub-install", |
167 |
@@ -865,7 +910,8 @@ |
168 |
|
169 |
# really install the bootloader |
170 |
p = os.pipe() |
171 |
- os.write(p[1], cmd + '\n') |
172 |
+ for cmd in cmds: |
173 |
+ os.write(p[1], cmd + '\n') |
174 |
os.close(p[1]) |
175 |
rhpl.executil.execWithRedirect('/sbin/grub' , |
176 |
[ "grub", "--batch", "--no-floppy", |
177 |
@@ -1044,41 +1090,64 @@ |
178 |
bootDev = fsset.getEntryByMountPoint("/") |
179 |
grubPath = "/boot/grub" |
180 |
cfPath = "/boot/" |
181 |
- bootDev = bootDev.device.getDevice(asBoot = 1) |
182 |
|
183 |
- part = self.grubbyPartitionName(bootDev) |
184 |
- prefix = "%s/%s" % (self.grubbyPartitionName(bootDev), grubPath) |
185 |
- args = "--stage2=/boot/grub/stage2 " |
186 |
- cmd = "root %s\ninstall %s%s/stage1 d %s %s/stage2 p %s%s/grub.conf" % \ |
187 |
- (part, args, grubPath, self.grubbyPartitionName(theDev[5:]), |
188 |
- grubPath, part, grubPath) |
189 |
- |
190 |
- if not justConfigFile: |
191 |
- log("GRUB command %s", cmd) |
192 |
+ masterBootDev = bootDev.device.getDevice(asBoot = 0) |
193 |
+ if masterBootDev[0:2] == 'md': |
194 |
+ rootDevs = checkbootloader.getRaidDisks(masterBootDev, raidLevel=1, |
195 |
+ stripPart = 0) |
196 |
+ else: |
197 |
+ rootDevs = [masterBootDev] |
198 |
|
199 |
- # copy the stage files over into /boot |
200 |
- rhpl.executil.execWithRedirect( "/sbin/grub-install", |
201 |
+ if theDev[5:7] == 'md': |
202 |
+ stage1Devs = checkbootloader.getRaidDisks(theDev[5:], raidLevel=1) |
203 |
+ else: |
204 |
+ stage1Devs = [theDev[5:]] |
205 |
+ |
206 |
+ for stage1Dev in stage1Devs: |
207 |
+ # cross fingers; if we can't find a root device on the same |
208 |
+ # hardware as this boot device, we just blindly hope the first |
209 |
+ # thing in the list works. |
210 |
+ |
211 |
+ grubbyStage1Dev = self.grubbyPartitionName(stage1Dev) |
212 |
+ |
213 |
+ grubbyRootPart = self.grubbyPartitionName(rootDevs[0]) |
214 |
+ |
215 |
+ for rootDev in rootDevs: |
216 |
+ testGrubbyRootDev = getDiskPart(rootDev)[0] |
217 |
+ testGrubbyRootDev = self.grubbyPartitionName(testGrubbyRootDev) |
218 |
+ |
219 |
+ if grubbyStage1Dev == testGrubbyRootDev: |
220 |
+ grubbyRootPart = self.grubbyPartitionName(rootDev) |
221 |
+ break |
222 |
+ |
223 |
+ cmd = "root %s\nsetup %s" % (grubbyRootPart, grubbyStage1Dev) |
224 |
+ |
225 |
+ if not justConfigFile: |
226 |
+ log("GRUB command %s", cmd) |
227 |
+ |
228 |
+ # copy the stage files over into /boot |
229 |
+ rhpl.executil.execWithRedirect( "/sbin/grub-install", |
230 |
["/sbin/grub-install", "--just-copy"], |
231 |
stdout = "/dev/tty5", stderr = "/dev/tty5", |
232 |
root = instRoot) |
233 |
|
234 |
- # get the stage files synced to disk |
235 |
- import isys |
236 |
- isys.sync() |
237 |
- isys.sync() |
238 |
- isys.sync() |
239 |
+ # get the stage files synced to disk |
240 |
+ import isys |
241 |
+ isys.sync() |
242 |
+ isys.sync() |
243 |
+ isys.sync() |
244 |
|
245 |
- # really install the bootloader |
246 |
- p = os.pipe() |
247 |
- os.write(p[1], cmd + '\n') |
248 |
- os.close(p[1]) |
249 |
- rhpl.executil.execWithRedirect('/sbin/grub' , |
250 |
+ # really install the bootloader |
251 |
+ p = os.pipe() |
252 |
+ os.write(p[1], cmd + '\n') |
253 |
+ os.close(p[1]) |
254 |
+ rhpl.executil.execWithRedirect('/sbin/grub' , |
255 |
[ "grub", "--batch", "--no-floppy", |
256 |
"--device-map=/boot/grub/device.map" ], |
257 |
stdin = p[0], |
258 |
stdout = "/dev/tty5", stderr = "/dev/tty5", |
259 |
root = instRoot) |
260 |
- os.close(p[0]) |
261 |
+ os.close(p[0]) |
262 |
|
263 |
return "" |
264 |
|
265 |
diff -Nur -x '*.orig' -x '*.rej' booty-0.44.4/checkbootloader.py mezzanine_patched_booty-0.44.4/checkbootloader.py |
266 |
--- booty-0.44.4/checkbootloader.py 2003-03-04 17:11:48.000000000 -0700 |
267 |
+++ mezzanine_patched_booty-0.44.4/checkbootloader.py 2007-05-17 22:23:10.000000000 -0600 |
268 |
@@ -56,8 +56,13 @@ |
269 |
return (name, partNum) |
270 |
|
271 |
|
272 |
-def getRaidDisks(raidDevice): |
273 |
+def getRaidDisks(raidDevice, raidLevel=None, stripPart=1): |
274 |
rc = [] |
275 |
+ if raidLevel is not None: |
276 |
+ try: |
277 |
+ raidLevel = "raid%d" % (int(raidLevel),) |
278 |
+ except ValueError: |
279 |
+ pass |
280 |
|
281 |
try: |
282 |
f = open("/proc/mdstat", "r") |
283 |
@@ -69,14 +74,19 @@ |
284 |
for line in lines: |
285 |
fields = string.split(line, ' ') |
286 |
if fields[0] == raidDevice: |
287 |
+ if raidLevel is not None and fields[3] != raidLevel: |
288 |
+ continue |
289 |
for field in fields[4:]: |
290 |
if string.find(field, "[") == -1: |
291 |
continue |
292 |
dev = string.split(field, '[')[0] |
293 |
if len(dev) == 0: |
294 |
continue |
295 |
- disk = getDiskPart(dev)[0] |
296 |
- rc.append(disk) |
297 |
+ if stripPart: |
298 |
+ disk = getDiskPart(dev)[0] |
299 |
+ rc.append(disk) |
300 |
+ else: |
301 |
+ rc.append(dev) |
302 |
|
303 |
return rc |
304 |
|