/[smeserver]/cdrom.image/updates/raid.py
ViewVC logotype

Contents of /cdrom.image/updates/raid.py

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download) (as text)
Wed Apr 5 21:11:51 2006 UTC (18 years, 8 months ago) by slords
Branch: MAIN
Changes since 1.2: +15 -4 lines
Content type: text/x-python
Cleanup

1 #!/usr/bin/python
2 #
3 # raid.py - raid probing control
4 #
5 # Erik Troan <ewt@redhat.com>
6 #
7 # Copyright 1999-2002 Red Hat, Inc.
8 #
9 # This software may be freely redistributed under the terms of the GNU
10 # library public license.
11 #
12 # You should have received a copy of the GNU Library Public License
13 # along with this program; if not, write to the Free Software
14 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 #
16 """Raid probing control."""
17
18 import parted
19 import isys
20 import os
21 import partitioning
22 import partedUtils
23
24 from rhpl.log import log
25
26 # these arches can have their /boot on RAID and not have their
27 # boot loader blow up
28 raidBootArches = [ "i386", "x86_64", "ppc" ]
29
30 def scanForRaid(drives):
31 """Scans for raid devices on drives.
32
33 drives is a list of device names.
34 Returns a list of (mdMinor, devices, level, totalDisks) tuples.
35 """
36
37 raidSets = {}
38 raidDevices = {}
39
40 for d in drives:
41 parts = []
42 isys.makeDevInode(d, "/tmp/" + d)
43 try:
44 dev = parted.PedDevice.get("/tmp/" + d)
45 disk = parted.PedDisk.new(dev)
46
47 raidParts = partedUtils.get_raid_partitions(disk)
48 for part in raidParts:
49 parts.append(partedUtils.get_partition_name(part))
50 except:
51 pass
52
53 os.remove("/tmp/" + d)
54 for dev in parts:
55 try:
56 (major, minor, raidSet, level, nrDisks, totalDisks, mdMinor) =\
57 isys.raidsb(dev)
58 except ValueError:
59 # bad magic, this can't be part of our raid set
60 log("reading raid sb failed for %s",dev)
61 continue
62
63 if raidSets.has_key(raidSet):
64 (knownLevel, knownDisks, knownMinor, knownDevices) = \
65 raidSets[raidSet]
66 if knownLevel != level or knownDisks != totalDisks or \
67 knownMinor != mdMinor:
68 # Raise hell
69 log("raid set inconsistency for md%d: "
70 "all drives in this raid set do not "
71 "agree on raid parameters. Skipping raid device",
72 mdMinor)
73 continue
74 knownDevices.append(dev)
75 raidSets[raidSet] = (knownLevel, knownDisks, knownMinor,
76 knownDevices)
77 else:
78 raidSets[raidSet] = (level, totalDisks, mdMinor, [dev,])
79
80 if raidDevices.has_key(mdMinor):
81 if (raidDevices[mdMinor] != raidSet):
82 log("raid set inconsistency for md%d: "
83 "found members of multiple raid sets "
84 "that claim to be md%d. Using only the first "
85 "array found.", mdMinor, mdMinor)
86 continue
87 else:
88 raidDevices[mdMinor] = raidSet
89
90 raidList = []
91 for key in raidSets.keys():
92 (level, totalDisks, mdMinor, devices) = raidSets[key]
93 if len(devices) == totalDisks - 1 and level in (1, 5, 6):
94 log("missing components of raid device md%d. The "
95 "raid device needs %d drive(s) and only %d (was/were) found. "
96 "This raid device will be started in degraded mode.", mdMinor,
97 totalDisks, len(devices))
98 elif len(devices) == totalDisks - 2 and level == 6:
99 log("missing components of raid device md%d. The "
100 "raid device needs %d drive(s) and only %d (was/were) found. "
101 "This raid device will be started in degraded mode.", mdMinor,
102 totalDisks, len(devices))
103 elif len(devices) < totalDisks:
104 log("missing components of raid device md%d. The "
105 "raid device needs %d drive(s) and only %d (was/were) found. "
106 "This raid device will not be started.", mdMinor,
107 totalDisks, len(devices))
108 continue
109 raidList.append((mdMinor, devices, level, totalDisks))
110
111 return raidList
112
113 def startAllRaid(driveList):
114 """Do a raid start on raid devices and return a list like scanForRaid."""
115 rc = []
116 mdList = scanForRaid(driveList)
117 for mdDevice, deviceList, level, numActive in mdList:
118 devName = "md%d" % (mdDevice,)
119 isys.raidstart(devName, deviceList[0])
120 rc.append((devName, deviceList, level, numActive))
121 return rc
122
123 def stopAllRaid(mdList):
124 """Do a raid stop on each of the raid device tuples given."""
125 for dev, devices, level, numActive in mdList:
126 isys.raidstop(dev)
127
128 def isRaid6(raidlevel):
129 """Return whether raidlevel is a valid descriptor of RAID6."""
130 if raidlevel == "RAID6":
131 return 1
132 elif raidlevel == 6:
133 return 1
134 elif raidlevel == "6":
135 return 1
136 return 0
137
138 def isRaid5(raidlevel):
139 """Return whether raidlevel is a valid descriptor of RAID5."""
140 if raidlevel == "RAID5":
141 return 1
142 elif raidlevel == 5:
143 return 1
144 elif raidlevel == "5":
145 return 1
146 return 0
147
148 def isRaid1(raidlevel):
149 """Return whether raidlevel is a valid descriptor of RAID1."""
150 if raidlevel == "RAID1":
151 return 1
152 elif raidlevel == 1:
153 return 1
154 elif raidlevel == "1":
155 return 1
156 return 0
157
158 def isRaid0(raidlevel):
159 """Return whether raidlevel is a valid descriptor of RAID0."""
160 if raidlevel == "RAID0":
161 return 1
162 elif raidlevel == 0:
163 return 1
164 elif raidlevel == "0":
165 return 1
166 return 0
167
168 def get_raid_min_members(raidlevel):
169 """Return the minimum number of raid members required for raid level"""
170 if isRaid0(raidlevel):
171 return 2
172 elif isRaid1(raidlevel):
173 return 1
174 elif isRaid5(raidlevel):
175 return 2
176 elif isRaid6(raidlevel):
177 return 2
178 else:
179 raise ValueError, "invalid raidlevel in get_raid_min_members"
180
181 def get_raid_max_spares(raidlevel, nummembers):
182 """Return the maximum number of raid spares for raidlevel."""
183 if isRaid0(raidlevel):
184 return 0
185 elif isRaid1(raidlevel) or isRaid5(raidlevel) or isRaid6(raidlevel):
186 return max(0, nummembers - get_raid_min_members(raidlevel))
187 else:
188 raise ValueError, "invalid raidlevel in get_raid_max_spares"
189
190 def register_raid_device(mdname, newdevices, newlevel, newnumActive):
191 """Register a new RAID device in the mdlist."""
192 for dev, devices, level, numActive in partedUtils.DiskSet.mdList:
193 if mdname == dev:
194 if (devices != newdevices or level != newlevel or
195 numActive != newnumActive):
196 raise ValueError, "%s is already in the mdList!" % (mdname,)
197 else:
198 return
199 partedUtils.DiskSet.mdList.append((mdname, newdevices[:], newlevel,
200 newnumActive))
201
202 def lookup_raid_device(mdname):
203 """Return the requested RAID device information."""
204 for dev, devices, level, numActive in partedUtils.DiskSet.mdList:
205 if mdname == dev:
206 return (dev, devices, level, numActive)
207 raise KeyError, "md device not found"
208
209 def getRaidLevels():
210 avail = []
211 try:
212 f = open("/proc/mdstat", "r")
213 except:
214 pass
215 else:
216 for l in f.readlines():
217 if not l.startswith("Personalities"):
218 continue
219 for tok in l.split():
220 for lev in ("RAID0", "RAID1", "RAID5", "RAID6"):
221 if tok.upper().find(lev) != -1:
222 avail.append(lev)
223
224 f.close()
225
226 return avail
227
228
229

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed