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

Contents of /cdrom.image/sme9/updates/storage/devicelibs/lvm.py

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


Revision 1.2 - (show annotations) (download) (as text)
Sun Dec 22 04:27:52 2013 UTC (10 years, 9 months ago) by wellsi
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-python
FILE REMOVED
anaconda updates now handled via patches

1 #
2 # lvm.py
3 # lvm 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 import math
25 import re
26
27 import iutil
28 import logging
29 log = logging.getLogger("storage")
30
31 from ..errors import *
32 from constants import *
33
34 import gettext
35 _ = lambda x: gettext.ldgettext("anaconda", x)
36
37 MAX_LV_SLOTS = 256
38
39 def has_lvm():
40 has_lvm = False
41 for path in os.environ["PATH"].split(":"):
42 if os.access("%s/lvm" % path, os.X_OK):
43 has_lvm = True
44 break
45
46 if has_lvm:
47 has_lvm = False
48 for line in open("/proc/devices").readlines():
49 if "device-mapper" in line.split():
50 has_lvm = True
51 break
52
53 return has_lvm
54
55 # Start config_args handling code
56 #
57 # Theoretically we can handle all that can be handled with the LVM --config
58 # argument. For every time we call an lvm_cc (lvm compose config) funciton
59 # we regenerate the config_args with all global info.
60 config_args = [] # Holds the final argument list
61 config_args_data = { "filterRejects": [], # regular expressions to reject.
62 "filterAccepts": [] } # regexp to accept
63
64 def _composeConfig():
65 """lvm command accepts lvm.conf type arguments preceded by --config. """
66 global config_args, config_args_data
67 config_args = []
68
69 filter_string = ""
70 # we don't need the accept for now.
71 # accepts = config_args_data["filterAccepts"]
72 # if len(accepts) > 0:
73 # for i in range(len(rejects)):
74 # filter_string = filter_string + ("\"a|/%s$|\", " % accepts[i])
75
76 rejects = config_args_data["filterRejects"]
77 for reject in rejects:
78 filter_string += ("\"r|/%s$|\"," % reject)
79
80 filter_string = " filter=[%s] " % filter_string.strip(",")
81
82 # As we add config strings we should check them all.
83 if filter_string == "":
84 # Nothing was really done.
85 return
86
87 # devices_string can have (inside the brackets) "dir", "scan",
88 # "preferred_names", "filter", "cache_dir", "write_cache_state",
89 # "types", "sysfs_scan", "md_component_detection". see man lvm.conf.
90 devices_string = " devices {%s} " % (filter_string) # strings can be added
91 config_string = devices_string # more strings can be added.
92 config_args = ["--config", config_string]
93
94 def lvm_cc_addFilterRejectRegexp(regexp):
95 """ Add a regular expression to the --config string."""
96 global config_args_data
97 log.debug("lvm filter: adding %s to the reject list" % regexp)
98 config_args_data["filterRejects"].append(regexp)
99
100 # compoes config once more.
101 _composeConfig()
102
103 def lvm_cc_resetFilter():
104 global config_args, config_args_data
105 config_args_data["filterRejects"] = []
106 config_args_data["filterAccepts"] = []
107 config_args = []
108 # End config_args handling code.
109
110 # Names that should not be used int the creation of VGs
111 lvm_vg_blacklist = []
112 def blacklistVG(name):
113 global lvm_vg_blacklist
114 lvm_vg_blacklist.append(name)
115
116 def getPossiblePhysicalExtents(floor=0):
117 """Returns a list of integers representing the possible values for
118 the physical extent of a volume group. Value is in KB.
119
120 floor - size (in KB) of smallest PE we care about.
121 """
122
123 possiblePE = []
124 curpe = 8
125 while curpe <= 16384*1024:
126 if curpe >= floor:
127 possiblePE.append(curpe)
128 curpe = curpe * 2
129
130 return possiblePE
131
132 def getMaxLVSize():
133 """ Return the maximum size (in MB) of a logical volume. """
134 if iutil.getArch() in ("x86_64", "ppc64", "alpha", "ia64", "s390", "sparc"): #64bit architectures
135 return (8*1024*1024*1024*1024) #Max is 8EiB (very large number..)
136 else:
137 return (16*1024*1024) #Max is 16TiB
138
139 # apparently lvm has a limit of 126 chars for combined vg-lv names:
140 # https://bugzilla.redhat.com/show_bug.cgi?id=747278#c6
141 # https://bugzilla.redhat.com/show_bug.cgi?id=747278#c7
142 # since dashes get escaped they count double -- allow for six of them since
143 # a dhcp-provided hostname could easily contain five dashes ("dhcp-xx-xx-xx-xx")
144 LVM_MAX_NAME_LEN = 50
145
146 def safeLvmName(name, maxlen=LVM_MAX_NAME_LEN):
147 tmp = name.strip()
148 tmp = tmp.replace("/", "_")
149 tmp = re.sub("[^0-9a-zA-Z._]", "", tmp)
150 tmp = tmp.lstrip("_")
151
152 if len(tmp) > maxlen:
153 tmp = tmp[:maxlen]
154
155 return tmp
156
157 def clampSize(size, pesize, roundup=None):
158 if roundup:
159 round = math.ceil
160 else:
161 round = math.floor
162
163 return long(round(float(size)/float(pesize)) * pesize)
164
165 def lvm(args, progress=None):
166 rc = iutil.execWithPulseProgress("lvm", args,
167 stdout = "/dev/tty5",
168 stderr = "/dev/tty5",
169 progress=progress)
170 if not rc:
171 return
172
173 try:
174 msg = open("/tmp/program.log").readlines()[-1].strip()
175 except Exception:
176 msg = ""
177
178 raise LVMError(msg)
179
180 def pvcreate(device, progress=None):
181 # we force dataalignment=1024k since we cannot get lvm to tell us what
182 # the pe_start will be in advance
183 args = ["pvcreate"] + \
184 config_args + \
185 ["--dataalignment", "1024k"] + \
186 [device]
187
188 try:
189 lvm(args, progress=progress)
190 except LVMError as msg:
191 raise LVMError("pvcreate failed for %s: %s" % (device, msg))
192
193 def pvresize(device, size):
194 args = ["pvresize"] + \
195 ["--setphysicalvolumesize", ("%dm" % size)] + \
196 config_args + \
197 [device]
198
199 try:
200 lvm(args)
201 except LVMError as msg:
202 raise LVMError("pvresize failed for %s: %s" % (device, msg))
203
204 def pvremove(device):
205 args = ["pvremove"] + \
206 config_args + \
207 [device]
208
209 try:
210 lvm(args)
211 except LVMError as msg:
212 raise LVMError("pvremove failed for %s: %s" % (device, msg))
213
214 def pvinfo(device):
215 """
216 If the PV was created with '--metadacopies 0', lvm will do some
217 scanning of devices to determine from their metadata which VG
218 this PV belongs to.
219
220 pvs -o pv_name,pv_mda_count,vg_name,vg_uuid --config \
221 'devices { scan = "/dev" filter = ["a/loop0/", "r/.*/"] }'
222 """
223 #cfg = "'devices { scan = \"/dev\" filter = [\"a/%s/\", \"r/.*/\"] }'"
224 args = ["pvs", "--noheadings"] + \
225 ["--units", "m"] + \
226 ["-o", "pv_name,pv_mda_count,vg_name,vg_uuid"] + \
227 config_args + \
228 [device]
229
230 rc = iutil.execWithCapture("lvm", args,
231 stderr = "/dev/tty5")
232 vals = rc.split()
233 if not vals:
234 raise LVMError("pvinfo failed for %s" % device)
235
236 # don't raise an exception if pv is not a part of any vg
237 pv_name = vals[0]
238 try:
239 vg_name, vg_uuid = vals[2], vals[3]
240 except IndexError:
241 vg_name, vg_uuid = "", ""
242
243 info = {'pv_name': pv_name,
244 'vg_name': vg_name,
245 'vg_uuid': vg_uuid}
246
247 return info
248
249 def vgcreate(vg_name, pv_list, pe_size, progress=None):
250 argv = ["vgcreate"]
251 if pe_size:
252 argv.extend(["-s", "%dm" % pe_size])
253 argv.extend(config_args)
254 argv.append(vg_name)
255 argv.extend(pv_list)
256
257 try:
258 lvm(argv, progress=progress)
259 except LVMError as msg:
260 raise LVMError("vgcreate failed for %s: %s" % (vg_name, msg))
261
262 def vgremove(vg_name):
263 args = ["vgremove", "--force"] + \
264 config_args +\
265 [vg_name]
266
267 try:
268 lvm(args)
269 except LVMError as msg:
270 raise LVMError("vgremove failed for %s: %s" % (vg_name, msg))
271
272 def vgactivate(vg_name):
273 args = ["vgchange", "-a", "y"] + \
274 config_args + \
275 [vg_name]
276
277 try:
278 lvm(args)
279 except LVMError as msg:
280 raise LVMError("vgactivate failed for %s: %s" % (vg_name, msg))
281
282 def vgdeactivate(vg_name):
283 args = ["vgchange", "-a", "n"] + \
284 config_args + \
285 [vg_name]
286
287 try:
288 lvm(args)
289 except LVMError as msg:
290 raise LVMError("vgdeactivate failed for %s: %s" % (vg_name, msg))
291
292 def vgreduce(vg_name, pv_list, rm=False):
293 """ Reduce a VG.
294
295 rm -> with RemoveMissing option.
296 Use pv_list when rm=False, otherwise ignore pv_list and call vgreduce with
297 the --removemissing option.
298 """
299 args = ["vgreduce"]
300 args.extend(config_args)
301 if rm:
302 args.extend(["--removemissing", vg_name])
303 else:
304 args.extend([vg_name] + pv_list)
305
306 try:
307 lvm(args)
308 except LVMError as msg:
309 raise LVMError("vgreduce failed for %s: %s" % (vg_name, msg))
310
311 def vginfo(vg_name):
312 args = ["vgs", "--noheadings", "--nosuffix"] + \
313 ["--units", "m"] + \
314 ["-o", "uuid,size,free,extent_size,extent_count,free_count,pv_count"] + \
315 config_args + \
316 [vg_name]
317
318 buf = iutil.execWithCapture("lvm",
319 args,
320 stderr="/dev/tty5")
321 info = buf.split()
322 if len(info) != 7:
323 raise LVMError(_("vginfo failed for %s" % vg_name))
324
325 d = {}
326 (d['uuid'],d['size'],d['free'],d['pe_size'],
327 d['pe_count'],d['pe_free'],d['pv_count']) = info
328 return d
329
330 def lvs(vg_name):
331 args = ["lvs", "--noheadings", "--nosuffix"] + \
332 ["--units", "m"] + \
333 ["-o", "lv_name,lv_uuid,lv_size,lv_attr"] + \
334 config_args + \
335 [vg_name]
336
337 buf = iutil.execWithCapture("lvm",
338 args,
339 stderr="/dev/tty5")
340
341 lvs = {}
342 for line in buf.splitlines():
343 line = line.strip()
344 if not line:
345 continue
346 (name, uuid, size, attr) = line.split()
347 lvs[name] = {"size": size,
348 "uuid": uuid,
349 "attr": attr}
350
351 if not lvs:
352 raise LVMError(_("lvs failed for %s" % vg_name))
353
354 return lvs
355
356 def lvorigin(vg_name, lv_name):
357 args = ["lvs", "--noheadings", "-o", "origin"] + \
358 config_args + \
359 ["%s/%s" % (vg_name, lv_name)]
360
361 buf = iutil.execWithCapture("lvm",
362 args,
363 stderr="/dev/tty5")
364
365 try:
366 origin = buf.splitlines()[0].strip()
367 except IndexError:
368 origin = ''
369
370 return origin
371
372 def lvcreate(vg_name, lv_name, size, progress=None, pvs=[]):
373 args = ["lvcreate"] + \
374 ["-L", "%dm" % size] + \
375 ["-n", lv_name] + \
376 config_args + \
377 [vg_name] + pvs
378
379 try:
380 lvm(args, progress=progress)
381 except LVMError as msg:
382 raise LVMError("lvcreate failed for %s/%s: %s" % (vg_name, lv_name, msg))
383
384 def lvremove(vg_name, lv_name):
385 args = ["lvremove"] + \
386 config_args + \
387 ["%s/%s" % (vg_name, lv_name)]
388
389 try:
390 lvm(args)
391 except LVMError as msg:
392 raise LVMError("lvremove failed for %s: %s" % (lv_name, msg))
393
394 def lvresize(vg_name, lv_name, size):
395 args = ["lvresize"] + \
396 ["--force", "-L", "%dm" % size] + \
397 config_args + \
398 ["%s/%s" % (vg_name, lv_name)]
399
400 try:
401 lvm(args)
402 except LVMError as msg:
403 raise LVMError("lvresize failed for %s: %s" % (lv_name, msg))
404
405 def lvactivate(vg_name, lv_name):
406 # see if lvchange accepts paths of the form 'mapper/$vg-$lv'
407 args = ["lvchange", "-a", "y"] + \
408 config_args + \
409 ["%s/%s" % (vg_name, lv_name)]
410
411 try:
412 lvm(args)
413 except LVMError as msg:
414 raise LVMError("lvactivate failed for %s: %s" % (lv_name, msg))
415
416 def lvdeactivate(vg_name, lv_name):
417 args = ["lvchange", "-a", "n"] + \
418 config_args + \
419 ["%s/%s" % (vg_name, lv_name)]
420
421 try:
422 lvm(args)
423 except LVMError as msg:
424 raise LVMError("lvdeactivate failed for %s: %s" % (lv_name, msg))
425

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