Skip to content
Snippets Groups Projects
Commit a3a4a698 authored by Thibault VINCENT's avatar Thibault VINCENT
Browse files

add: better lvm interface

parent ddb77017
No related branches found
No related tags found
No related merge requests found
......@@ -8,6 +8,7 @@ from multiprocessing import cpu_count
from platform import platform, machine, system
from socket import gethostbyaddr, gethostname
from jobs import JobManager
from lvm import LVM
class Host(object):
......@@ -36,6 +37,7 @@ class LocalHost(Host):
'''
super(LocalHost, self).__init__()
self.jobmgr = JobManager(self)
self.lvm = LVM()
def scheduler_run(self):
'''
......
......@@ -2,7 +2,7 @@
import os
from errors import LVMError
from utils import Exec
from utils import Exec, RWLock
class LVM(object):
'''
......@@ -28,11 +28,16 @@ class LVM(object):
VGREMOVE = os.path.join(BIN_PATH, 'vgremove')
DMSETUP = os.path.join(BIN_PATH, 'dmsetup')
# global class lock : do not abuse LVM/DM too much
_mutex = RWLock()
def __init__(self):
'''
'''
self.reload()
"""
FIXME not working anymore
def __str__(self):
'''
'''
......@@ -49,122 +54,127 @@ class LVM(object):
s += ' %s (path: %s, size: %s)' % (lv.name, lv.path,
lv.total)
return s
"""
def _reload_pvs(self):
'''
'''
self._pvs = {}
# execute query command
(rc, output) = Exec.call([self.LVM,
"pvs",
"--nosuffix",
"--noheadings",
"--units", "b",
"--separator", "~",
"-o", ("pv_uuid,pv_name,vg_name,pv_fmt,"
"pv_attr,dev_size,pv_size,pv_free,"
"pv_used,pv_pe_count,"
"pv_pe_alloc_count")],
merge_output = False)
if rc != 0:
raise LVMError("error getting list of PV")
# parse command output
for line in output[0].splitlines():
# extract tokens
(
p_uuid,
p_name,
p_vg,
p_format,
p_attr,
p_devsize,
p_size,
p_free,
p_used,
p_extent,
p_ext_alloc,
) = line.strip().split("~")
# if the PV is not used, set VG to None
if not len(p_vg):
p_vg = None
else:
p_vg_obj = self._vgs[p_vg]
# create PV object
pv = self._PV(self, p_vg_obj, p_uuid, p_name, p_format, p_attr,
int(p_devsize), int(p_size), int(p_free), int(p_used),
int(p_extent), int(p_ext_alloc))
# register obj
self._pvs[p_name] = pv
if p_vg:
self._vgs[p_vg].pvs[p_name] = pv
with self._mutex.write:
self._pvs = {}
# execute query command
(rc, output) = Exec.call([self.LVM,
'pvs',
'--nosuffix',
'--noheadings',
'--units', 'b',
'--separator', '~',
'-o', ('pv_uuid,pv_name,vg_name,pv_fmt,'
'pv_attr,dev_size,pv_size,pv_free,'
'pv_used,pv_pe_count,'
'pv_pe_alloc_count')],
merge_output = False)
if rc != 0:
raise LVMError('error getting list of PV')
# parse command output
for line in output[0].splitlines():
# extract tokens
(
p_uuid,
p_name,
p_vg,
p_format,
p_attr,
p_devsize,
p_size,
p_free,
p_used,
p_extent,
p_ext_alloc,
) = line.strip().split('~')
# if the PV is not used, set VG to None
if not len(p_vg):
p_vg = None
else:
p_vg_obj = self._vgs[p_vg]
# create PV object
pv = self._PV(self, p_vg_obj, p_uuid, p_name, p_format, p_attr,
int(p_devsize), int(p_size), int(p_free), int(p_used),
int(p_extent), int(p_ext_alloc))
# register obj
self._pvs[p_name] = pv
if p_vg:
self._vgs[p_vg]._pvs[p_name] = pv
def _reload_vgs(self):
'''
'''
self._vgs = {}
# execute query command
(rc, output) = Exec.call([self.LVM,
"vgs",
"--nosuffix",
"--noheadings",
"--units", "b",
"--separator", "~",
"-o", ("vg_uuid,vg_name,vg_fmt,vg_attr,"
"vg_size,vg_free,vg_extent_size,"
"vg_extent_count,vg_free_count")],
merge_output = False)
if rc != 0:
raise LVMError("error getting list of VG")
# parse command output
for line in output[0].splitlines():
# extract tokens
(
v_uuid,
v_name,
v_format,
v_attr,
v_size,
v_free,
v_ext_size,
v_extent,
v_ext_free,
) = line.strip().split("~")
# create VG object
vg = self._VG(self, v_uuid, v_name, v_format, v_attr, int(v_size),
int(v_free), int(v_ext_size), int(v_extent),
int(v_ext_free))
# register object
self._vgs[v_name] = vg
with self._mutex.write:
self._vgs = {}
# execute query command
(rc, output) = Exec.call([self.LVM,
'vgs',
'--nosuffix',
'--noheadings',
'--units', 'b',
'--separator', '~',
'-o', ('vg_uuid,vg_name,vg_fmt,vg_attr,'
'vg_size,vg_free,vg_extent_size,'
'vg_extent_count,vg_free_count')],
merge_output = False)
if rc != 0:
raise LVMError('error getting list of VG')
# parse command output
for line in output[0].splitlines():
# extract tokens
(
v_uuid,
v_name,
v_format,
v_attr,
v_size,
v_free,
v_ext_size,
v_extent,
v_ext_free,
) = line.strip().split('~')
# create VG object
vg = self._VG(self, v_uuid, v_name, v_format, v_attr, int(v_size),
int(v_free), int(v_ext_size), int(v_extent),
int(v_ext_free))
# register object
self._vgs[v_name] = vg
def _reload_lvs(self):
'''
'''
# execute query command
(rc, output) = Exec.call([self.LVM,
"lvs",
"--nosuffix",
"--noheadings",
"--units", "b",
"--separator", "~",
"-o", ("lv_uuid,lv_name,vg_name,lv_attr,"
"lv_size")],
merge_output = False)
if rc != 0:
raise LVMError("error getting list of LV")
# parse command output
for line in output[0].splitlines():
# extract tokens
(
l_uuid,
l_name,
l_vg,
l_attr,
l_size,
) = line.strip().split("~")
# create LV object
lv = self._LV(self, self._vgs[l_vg], l_uuid, l_name, l_attr, l_size)
# register object
self._vgs[l_vg].lvs[l_name] = lv
with self._mutex.write:
# execute query command
(rc, output) = Exec.call([self.LVM,
'lvs',
'--nosuffix',
'--noheadings',
'--units', 'b',
'--separator', '~',
'-o', ('lv_uuid,lv_name,vg_name,lv_attr,'
'lv_size')],
merge_output = False)
if rc != 0:
raise LVMError('error getting list of LV')
# parse command output
for line in output[0].splitlines():
# extract tokens
(
l_uuid,
l_name,
l_vg,
l_attr,
l_size,
) = line.strip().split('~')
# create LV object
lv = self._LV(self, self._vgs[l_vg], l_uuid, l_name, l_attr,
l_size)
# register object
self._vgs[l_vg]._lvs[l_name] = lv
def reload(self):
# VG must be reloaded before PV
......@@ -175,62 +185,69 @@ class LVM(object):
def get_pv(self, path):
'''
'''
return self._pvs[path]
with self._mutex.read:
return self._pvs[path]
def get_vg(self, name):
'''
'''
return self._vgs[name]
with self._mutex.read:
return self._vgs[name]
def get_lv(self, vgname, name):
'''
'''
return self._vgs[vgname].lvs[name]
with self._mutex.read:
return self._vgs[vgname]._lvs[name]
def dm_create(self, name, table):
'''
'''
rc = Exec.silent([self.DMSETUP,
'create',
name],
input=table)
if rc:
raise LVMError("failed to create DM device")
with self._mutex.write:
rc = Exec.silent([self.DMSETUP,
'create',
name],
input=table)
if rc:
raise LVMError('failed to create DM device')
def dm_remove(self, dm_name, force=True):
'''
'''
# build command arguments
argv = [self.DMSETUP, 'remove']
if force is True:
argv.append('--force')
argv.append(dm_name)
# execute command
if Exec.silent(argv):
raise LVMError("failed to remove DM")
def dm_remove(self, name, force=True):
'''
'''
with self._mutex.write:
# build command arguments
argv = [self.DMSETUP, 'remove']
if force is True:
argv.append('--force')
argv.append(name)
# execute command
if Exec.silent(argv):
raise LVMError('failed to remove DM')
def dm_get_table(self, name):
'''
'''
rc, output = Exec.call([self.DMSETUP,
'table',
'--showkeys',
name],
merge_output=False)
table = str(output[0]).strip()
if rc or not len(table):
raise LVMError("failed to get DM table")
return table
with self._mutex.read:
rc, output = Exec.call([self.DMSETUP,
'table',
'--showkeys',
name],
merge_output=False)
table = str(output[0]).strip()
if rc or not len(table):
raise LVMError('failed to get DM table')
return table
def dm_set_table(self, name, table):
'''
'''
rc = Exec.silent([self.DMSETUP,
'load',
name],
input=table)
if rc:
raise LVMError("failed to change DM table")
with self._mutex.write:
rc = Exec.silent([self.DMSETUP,
'load',
name],
input=table)
if rc:
raise LVMError('failed to change DM table')
class _Vol(object):
......@@ -239,9 +256,9 @@ class LVM(object):
def __init__(self, mngr, vg, uuid, name, attrs):
self._mngr = mngr
self.vg = vg
self.uuid = uuid
self.name = name
self.attrs = attrs
self.uuid = str(uuid)
self.name = str(name)
self.attrs = str(attrs)
class _PV(_Vol):
......@@ -250,13 +267,13 @@ class LVM(object):
def __init__(self, mngr, vg, uuid, name, format, attrs, device_size,
size, free, used, extent_total, extent_used):
super(LVM._PV, self).__init__(mngr, vg, uuid, name, attrs)
self.format = format
self.device_size = device_size
self.size = size
self.free = free
self.used = used
self.extent_total = extent_total
self.extent_used = extent_used
self.format = str(format)
self.device_size = int(device_size)
self.size = int(size)
self.free = int(free)
self.used = int(used)
self.extent_total = int(extent_total)
self.extent_used = int(extent_used)
class _VG(_Vol):
......@@ -265,42 +282,49 @@ class LVM(object):
def __init__(self, mngr, uuid, name, format, attrs, size, free,
extent_size, extent_total, extent_free):
super(LVM._VG, self).__init__(mngr, self, uuid, name, attrs)
self.pvs = {}
self.lvs = {}
self.format = format
self.size = size
self.free = free
self.extent_size = extent_size
self.extent_total = extent_total
self.extent_free = extent_free
self._pvs = {}
self._lvs = {}
self.format = str(format)
self.size = int(size)
self.free = int(free)
self.extent_size = int(extent_size)
self.extent_total = int(extent_total)
self.extent_free = int(extent_free)
def create(self, name, size):
'''
'''
# execute create command
if Exec.silent([self.LVCREATE,
"-l", int(size),
"-n", name,
if Exec.silent([LVM.LVCREATE,
'-L', '%iB' % size,
'-n', name,
self.name]) != 0:
raise LVMError("error creating LV")
raise LVMError('error creating LV')
def remove(self, name):
'''
'''
# execute create command
if Exec.silent([self.LVREMOVE,
"-f",
"%s/%s" % (self.name, name)]) != 0:
raise LVMError("error removing LV")
if Exec.silent([LVM.LVREMOVE,
'-f',
'%s/%s' % (self.name, name)]) != 0:
raise LVMError('error removing LV')
def get_lv(self, name):
'''
'''
with self._mngr._mutex.read:
return self._lvs[name]
class _LV(_Vol):
'''
'''
def __init__(self, mngr, vg, uuid, name, attrs, size):
super(LVM._LV, self).__init__(mngr, vg, uuid, name, attrs)
self.size = size
self.size = int(size)
#fixme
self.path = '/dev/%s/%s' % (self.vg.name, self.name)
def dm_name(self):
'''
'''
......@@ -311,4 +335,3 @@ class LVM(object):
'''
'''
return self._mngr.dm_get_table(self.dm_name())
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment