/[smeserver]/cdrom.image/sme9/updates/storage/devicelibs/mdraid.py
ViewVC logotype

Annotation of /cdrom.image/sme9/updates/storage/devicelibs/mdraid.py

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


Revision 1.1 - (hide annotations) (download) (as text)
Sun Oct 20 23:12:54 2013 UTC (11 years ago) by charliebrady
Branch: MAIN
Content type: text/x-python
Add devicelibs and formats subdirectories of storage, and contained .py
files, in preparation to modifying to allow degraded RAID install.

1 charliebrady 1.1 #
2     # mdraid.py
3     # mdraid functions
4     #
5     # Copyright (C) 2009 Red Hat, Inc. All rights reserved.
6     #
7     # This program is free software; you can redistribute it and/or modify
8     # it under the terms of the GNU General Public License as published by
9     # the Free Software Foundation; either version 2 of the License, or
10     # (at your option) any later version.
11     #
12     # This program is distributed in the hope that it will be useful,
13     # but WITHOUT ANY WARRANTY; without even the implied warranty of
14     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     # GNU General Public License for more details.
16     #
17     # You should have received a copy of the GNU General Public License
18     # along with this program. If not, see <http://www.gnu.org/licenses/>.
19     #
20     # Author(s): Dave Lehman <dlehman@redhat.com>
21     #
22    
23     import os
24    
25     import iutil
26     from ..errors import *
27    
28     import gettext
29     _ = lambda x: gettext.ldgettext("anaconda", x)
30    
31     import logging
32     log = logging.getLogger("storage")
33    
34     # raidlevels constants
35     RAID10 = 10
36     RAID6 = 6
37     RAID5 = 5
38     RAID4 = 4
39     RAID1 = 1
40     RAID0 = 0
41    
42     def getRaidLevels():
43     mdstat_descriptors = {
44     RAID10: ("[RAID10]", "[raid10]"),
45     RAID6: ("[RAID6]", "[raid6]"),
46     RAID5: ("[RAID5]", "[raid5]"),
47     RAID4: ("[RAID4]", "[raid4]"),
48     RAID1: ("[RAID1]", "[raid1]"),
49     RAID0: ("[RAID0]", "[raid0]"),
50     }
51     avail = []
52     try:
53     f = open("/proc/mdstat", "r")
54     except IOError:
55     pass
56     else:
57     for l in f.readlines():
58     if not l.startswith("Personalities"):
59     continue
60    
61     lst = l.split()
62    
63     for level in mdstat_descriptors:
64     for d in mdstat_descriptors[level]:
65     if d in lst:
66     avail.append(level)
67     break
68    
69     f.close()
70    
71     avail.sort()
72     return avail
73    
74     raid_levels = getRaidLevels()
75    
76     def raidLevel(descriptor):
77     for level in raid_levels:
78     if isRaid(level, descriptor):
79     return level
80     else:
81     raise ValueError, "invalid raid level descriptor %s" % descriptor
82    
83     def isRaid(raid, raidlevel):
84     """Return whether raidlevel is a valid descriptor of raid"""
85     raid_descriptors = {RAID10: ("RAID10", "raid10", "10", 10),
86     RAID6: ("RAID6", "raid6", "6", 6),
87     RAID5: ("RAID5", "raid5", "5", 5),
88     RAID4: ("RAID4", "raid4", "4", 4),
89     RAID1: ("mirror", "RAID1", "raid1", "1", 1),
90     RAID0: ("stripe", "RAID0", "raid0", "0", 0)}
91    
92     if raid in raid_descriptors:
93     return raidlevel in raid_descriptors[raid]
94     else:
95     raise ValueError, "invalid raid level %d" % raid
96    
97     def get_raid_min_members(raidlevel):
98     """Return the minimum number of raid members required for raid level"""
99     raid_min_members = {RAID10: 2,
100     RAID6: 4,
101     RAID5: 3,
102     RAID4: 3,
103     RAID1: 2,
104     RAID0: 2}
105    
106     for raid, min_members in raid_min_members.items():
107     if isRaid(raid, raidlevel):
108     return min_members
109    
110     raise ValueError, "invalid raid level %d" % raidlevel
111    
112     def get_raid_max_spares(raidlevel, nummembers):
113     """Return the maximum number of raid spares for raidlevel."""
114     raid_max_spares = {RAID10: lambda: max(0, nummembers - get_raid_min_members(RAID10)),
115     RAID6: lambda: max(0, nummembers - get_raid_min_members(RAID6)),
116     RAID5: lambda: max(0, nummembers - get_raid_min_members(RAID5)),
117     RAID4: lambda: max(0, nummembers - get_raid_min_members(RAID4)),
118     RAID1: lambda: max(0, nummembers - get_raid_min_members(RAID1)),
119     RAID0: lambda: 0}
120    
121     for raid, max_spares_func in raid_max_spares.items():
122     if isRaid(raid, raidlevel):
123     return max_spares_func()
124    
125     raise ValueError, "invalid raid level %d" % raidlevel
126    
127     def mdadm(args, progress=None):
128     rc = iutil.execWithPulseProgress("mdadm", args,
129     stdout = "/dev/tty5",
130     stderr = "/dev/tty5",
131     progress=progress)
132     if not rc:
133     return
134    
135     try:
136     msg = open("/tmp/program.log").readlines()[-1].strip()
137     except Exception:
138     msg = ""
139    
140     raise MDRaidError(msg)
141    
142     def mdcreate(device, level, disks, spares=0, metadataVer=None, bitmap=False,
143     progress=None):
144     argv = ["--create", device, "--run", "--level=%s" % level]
145     raid_devs = len(disks) - spares
146     argv.append("--raid-devices=%d" % raid_devs)
147     if spares:
148     argv.append("--spare-devices=%d" % spares)
149     if metadataVer:
150     argv.append("--metadata=%s" % metadataVer)
151     if bitmap:
152     argv.append("--bitmap=internal")
153     argv.extend(disks)
154    
155     try:
156     mdadm(argv, progress=progress)
157     except MDRaidError as msg:
158     raise MDRaidError("mdcreate failed for %s: %s" % (device, msg))
159    
160     def mddestroy(device):
161     args = ["--zero-superblock", device]
162    
163     try:
164     mdadm(args)
165     except MDRaidError as msg:
166     raise MDRaidError("mddestroy failed for %s: %s" % (device, msg))
167    
168     def mdadd(device):
169     args = ["--incremental", "--quiet"]
170     args.append(device)
171    
172     try:
173     mdadm(args)
174     except MDRaidError as msg:
175     raise MDRaidError("mdadd failed for %s: %s" % (device, msg))
176    
177     def mdactivate(device, members=[], super_minor=None, update_super_minor=False,
178     uuid=None):
179     if super_minor is None and not uuid:
180     raise ValueError("mdactivate requires either a uuid or a super-minor")
181    
182     if uuid:
183     identifier = "--uuid=%s" % uuid
184     elif super_minor is not None:
185     identifier = "--super-minor=%d" % super_minor
186     else:
187     identifier = ""
188    
189     if update_super_minor:
190     extra_args = ["--update=super-minor"]
191     else:
192     extra_args = [ ]
193    
194     args = ["--assemble", device, identifier, "--run", "--auto=md"]
195     args += extra_args
196     args += members
197    
198     try:
199     mdadm(args)
200     except MDRaidError as msg:
201     raise MDRaidError("mdactivate failed for %s: %s" % (device, msg))
202    
203     def mddeactivate(device):
204     args = ["--stop", device]
205    
206     try:
207     mdadm(args)
208     except MDRaidError as msg:
209     raise MDRaidError("mddeactivate failed for %s: %s" % (device, msg))
210    
211     def mdexamine(device):
212     vars = iutil.execWithCapture("mdadm",
213     ["--examine", "--brief", device],
214     stderr="/dev/tty5").split()
215    
216     info = {}
217     if vars:
218     try:
219     info["device"] = vars[1]
220     vars = vars[2:]
221     except IndexError:
222     return {}
223    
224     for var in vars:
225     (name, equals, value) = var.partition("=")
226     if not equals:
227     continue
228    
229     info[name.lower()] = value.strip()
230    
231     return info
232    

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