master - python_lvm_unit.py: Add test for new name validate methods
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5588a56391dd3e...
Commit: 5588a56391dd3ef61d284ea64bcb6da591a3136c
Parent: 370520a310a44e6b9a48d9507bf2136748093029
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Mon Nov 18 15:09:09 2013 -0600
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Nov 19 14:40:47 2013 -0600
python_lvm_unit.py: Add test for new name validate methods
Test naming validate names for VG and LV names.
Signed-off-by: Tony Asleson <tasleson(a)redhat.com>
---
test/api/python_lvm_unit.py | 106 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 106 insertions(+), 0 deletions(-)
diff --git a/test/api/python_lvm_unit.py b/test/api/python_lvm_unit.py
index fc8c198..8208d91 100755
--- a/test/api/python_lvm_unit.py
+++ b/test/api/python_lvm_unit.py
@@ -17,6 +17,7 @@ import random
import string
import lvm
import os
+import itertools
# Set of basic unit tests for the python bindings.
#
@@ -808,5 +809,110 @@ class TestLvm(unittest.TestCase):
for d in device_names:
lvm.pvCreate(d)
+ def test_vg_reduce(self):
+ # Test the case where we try to reduce a vg where the last PV has
+ # no metadata copies. In this case the reduce should fail.
+ vg_name = TestLvm.VG_P + 'reduce_test'
+
+ device_names = TestLvm._get_pv_device_names()
+
+ for d in device_names:
+ lvm.pvRemove(d)
+
+ lvm.pvCreate(device_names[0], 0, 0) # Size all, pvmetadatacopies 0
+ lvm.pvCreate(device_names[1])
+ lvm.pvCreate(device_names[2])
+ lvm.pvCreate(device_names[3])
+
+ vg = lvm.vgCreate(vg_name)
+
+ vg.extend(device_names[3])
+ vg.extend(device_names[2])
+ vg.extend(device_names[1])
+ vg.extend(device_names[0])
+ vg.close()
+
+ vg = None
+
+ vg = lvm.vgOpen(vg_name, 'w')
+
+ vg.reduce(device_names[3])
+ vg.reduce(device_names[2])
+
+ self.assertRaises(lvm.LibLVMError, vg.reduce, device_names[1])
+
+ vg.close()
+ vg = None
+
+ vg = lvm.vgOpen(vg_name, 'w')
+ vg.remove()
+ vg.close()
+
+ @staticmethod
+ def _test_valid_names(method):
+ sample = 'azAZ09._-+'
+
+ method('x' * 127)
+ method('.X')
+ method('..X')
+
+ for i in range(1, 7):
+ tests = (''.join(i) for i in itertools.product(sample, repeat=i))
+ for t in tests:
+ if t == '.' or t == '..':
+ t += 'X'
+ elif t.startswith('-'):
+ t = 'H' + t
+ method(t)
+
+ def _test_bad_names(self, method, dupe_name):
+ # Test for duplicate name
+ self.assertRaises(lvm.LibLVMError, method, dupe_name)
+
+ # Test for too long a name
+ self.assertRaises(lvm.LibLVMError, method, ('x' * 128))
+
+ # Test empty
+ self.assertRaises(lvm.LibLVMError, method, '')
+
+ # Invalid characters
+ self.assertRaises(lvm.LibLVMError, method, '&invalid^char')
+
+ # Cannot start with .. and no following characters
+ self.assertRaises(lvm.LibLVMError, method, '..')
+
+ # Cannot start with . and no following characters
+ self.assertRaises(lvm.LibLVMError, method, '.')
+
+ # Cannot start with a hyphen
+ self.assertRaises(lvm.LibLVMError, method, '-not_good')
+
+ def _lv_reserved_names(self, method):
+ prefixes = ['snapshot', 'pvmove']
+ reserved = ['_mlog', '_mimage', '_pmspare', '_rimage', '_rmeta',
+ '_vorigin', '_tdata', '_tmeta']
+
+ for p in prefixes:
+ self.assertRaises(lvm.LibLVMError, method, p + rs(3))
+
+ for r in reserved:
+ self.assertRaises(lvm.LibLVMError, method, rs(3) + r + rs(1))
+ self.assertRaises(lvm.LibLVMError, method, r + rs(1))
+
+ def test_vg_lv_name_validate(self):
+ lv_name = 'vg_lv_name_validate'
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
+
+ self._test_bad_names(lvm.vgNameValidate, vg.getName())
+ self._test_bad_names(vg.lvNameValidate, lv.getName())
+
+ # Test good values
+ TestLvm._test_valid_names(lvm.vgNameValidate)
+ TestLvm._test_valid_names(vg.lvNameValidate)
+ self._lv_reserved_names(vg.lvNameValidate)
+
+ vg.close()
+
if __name__ == "__main__":
unittest.main()
9 years, 4 months
master - python_lvm_unit.py: Clean-up method names & scope
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=370520a310a44e...
Commit: 370520a310a44e6b9a48d9507bf2136748093029
Parent: 12d5e53953f1dacd911190cacc153dc2343878fe
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Mon Nov 18 15:07:32 2013 -0600
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Nov 19 14:40:45 2013 -0600
python_lvm_unit.py: Clean-up method names & scope
Changed naming of methods from camel case to all lower case with
underscores per guidelines. Changed any methods that can be
static methods to static.
Signed-off-by: Tony Asleson <tasleson(a)redhat.com>
---
test/api/python_lvm_unit.py | 300 +++++++++++++++++++++++--------------------
1 files changed, 158 insertions(+), 142 deletions(-)
diff --git a/test/api/python_lvm_unit.py b/test/api/python_lvm_unit.py
index 6c13149..fc8c198 100755
--- a/test/api/python_lvm_unit.py
+++ b/test/api/python_lvm_unit.py
@@ -39,11 +39,12 @@ def l(txt):
fh.flush()
-def rs(l=10):
+def rs(rand_len=10):
"""
Generate a random string
"""
- return ''.join(random.choice(string.ascii_uppercase) for x in range(l))
+ return ''.join(random.choice(string.ascii_uppercase)
+ for x in range(rand_len))
def _get_allowed_devices():
@@ -54,9 +55,9 @@ def _get_allowed_devices():
return rc
-def compare_pv(r, l):
- r_name = r.getName()
- l_name = l.getName()
+def compare_pv(right, left):
+ r_name = right.getName()
+ l_name = left.getName()
if r_name > l_name:
return 1
@@ -74,6 +75,7 @@ class AllowedPVS(object):
def __init__(self):
self.handle = None
+ self.pvs_all = None
def __enter__(self):
rc = []
@@ -102,24 +104,27 @@ class TestLvm(unittest.TestCase):
VG_P = 'py_unit_test_'
- def _get_pv_device_names(self):
+ @staticmethod
+ def _get_pv_device_names():
rc = []
with AllowedPVS() as pvs:
for p in pvs:
rc.append(p.getName())
return rc
- def _createThickLV(self, device_list, name):
+ @staticmethod
+ def _create_thick_lv(device_list, name):
vg = lvm.vgCreate(TestLvm.VG_P + "_" + name)
for d in device_list:
vg.extend(d)
- vg.createLvLinear(name, vg.getSize()/2)
+ vg.createLvLinear(name, vg.getSize() / 2)
vg.close()
vg = None
- def _createThinPool(self, device_list, pool_name):
+ @staticmethod
+ def _create_thin_pool(device_list, pool_name):
vg = lvm.vgCreate(TestLvm.VG_P + "_" + pool_name)
for d in device_list:
@@ -129,14 +134,16 @@ class TestLvm(unittest.TestCase):
lvm.THIN_DISCARDS_PASSDOWN, 1)
return vg
- def _createThinLV(self, pv_devices, name):
+ @staticmethod
+ def _create_thin_lv(pv_devices, name):
thin_pool_name = 'thin_vg_pool_' + rs(4)
- vg = self._createThinPool(pv_devices, thin_pool_name)
+ vg = TestLvm._create_thin_pool(pv_devices, thin_pool_name)
vg.createLvThin(thin_pool_name, name, vg.getSize()/8)
vg.close()
vg = None
- def _vg_names(self):
+ @staticmethod
+ def _vg_names():
rc = []
vg_names = lvm.listVgNames()
@@ -146,25 +153,27 @@ class TestLvm(unittest.TestCase):
return rc
- def _get_lv(self, lv_vol_type=None, lv_name=None):
- vg_name_list = self._vg_names()
+ @staticmethod
+ def _get_lv(lv_vol_type=None, lv_name=None):
+ vg_name_list = TestLvm._vg_names()
for vg_name in vg_name_list:
vg = lvm.vgOpen(vg_name, "w")
lvs = vg.listLVs()
- for l in lvs:
- attr = l.getAttr()
+ for lv in lvs:
+ attr = lv.getAttr()
if lv_vol_type or lv_name:
if lv_vol_type is not None and attr[0] == lv_vol_type:
- return l, vg
- elif lv_name is not None and lv_name == l.getName():
- return l, vg
+ return lv, vg
+ elif lv_name is not None and lv_name == lv.getName():
+ return lv, vg
else:
- return l, vg
+ return lv, vg
vg.close()
return None, None
- def _remove_VG(self, vg_name):
+ @staticmethod
+ def _remove_vg(vg_name):
vg = lvm.vgOpen(vg_name, 'w')
pvs = vg.listPVs()
@@ -172,26 +181,26 @@ class TestLvm(unittest.TestCase):
pe_devices = []
#Remove old snapshots first, then lv
- for l in vg.listLVs():
- attr = l.getAttr()
+ for lv in vg.listLVs():
+ attr = lv.getAttr()
if attr[0] == 's':
- l.remove()
+ lv.remove()
lvs = vg.listLVs()
#Now remove any thin lVs
- for l in vg.listLVs():
- attr = l.getAttr()
+ for lv in vg.listLVs():
+ attr = lv.getAttr()
if attr[0] == 'V':
- l.remove()
+ lv.remove()
#now remove the rest
- for l in vg.listLVs():
- name = l.getName()
+ for lv in vg.listLVs():
+ name = lv.getName()
#Don't remove the hidden ones
- if 'tmeta' not in name and 'tdata' not in name:
- l.remove()
+ if '_tmeta' not in name and '_tdata' not in name:
+ lv.remove()
for p in pvs:
pe_devices.append(p.getName())
@@ -202,23 +211,28 @@ class TestLvm(unittest.TestCase):
vg.remove()
vg.close()
- def _clean_up(self):
+ @staticmethod
+ def _clean_up():
#Clear out the testing PVs, but only if they contain stuff
#this unit test created
- for vg_n in self._vg_names():
- self._remove_VG(vg_n)
+ for vg_n in TestLvm._vg_names():
+ TestLvm._remove_vg(vg_n)
+
+ for d in TestLvm._get_pv_device_names():
+ lvm.pvRemove(d)
+ lvm.pvCreate(d)
def setUp(self):
- device_list = self._get_pv_device_names()
+ device_list = TestLvm._get_pv_device_names()
#Make sure we have an adequate number of PVs to use
self.assertTrue(len(device_list) >= 4)
- self._clean_up()
+ TestLvm._clean_up()
def tearDown(self):
- self._clean_up()
+ TestLvm._clean_up()
- def testPVresize(self):
+ def test_pv_resize(self):
with AllowedPVS() as pvs:
pv = pvs[0]
curr_size = pv.getSize()
@@ -231,7 +245,7 @@ class TestLvm(unittest.TestCase):
self.assertTrue(resized_size != curr_size)
pv.resize(dev_size)
- def testPVlifecycle(self):
+ def test_pv_life_cycle(self):
"""
Test removing and re-creating a PV
"""
@@ -256,7 +270,8 @@ class TestLvm(unittest.TestCase):
self.assertTrue(found)
- def testPvMethods(self):
+ @staticmethod
+ def test_pv_methods():
with AllowedPVS() as pvs:
for p in pvs:
p.getName()
@@ -267,13 +282,13 @@ class TestLvm(unittest.TestCase):
p.getFree()
p = None
- def testVersion(self):
+ def test_version(self):
version = lvm.getVersion()
self.assertNotEquals(version, None)
self.assertEquals(type(version), str)
self.assertTrue(len(version) > 0)
- def testPvGetters(self):
+ def test_pv_getters(self):
with AllowedPVS() as pvs:
pv = pvs[0]
self.assertEqual(type(pv.getName()), str)
@@ -301,7 +316,7 @@ class TestLvm(unittest.TestCase):
self.assertEqual(type(result[1]), bool)
self.assertTrue(result[1] == settable)
- def testPvSegs(self):
+ def test_pv_segs(self):
with AllowedPVS() as pvs:
pv = pvs[0]
pv_segs = pv.listPVsegs()
@@ -311,39 +326,39 @@ class TestLvm(unittest.TestCase):
for i in pv_segs:
self._test_prop(i, 'pvseg_start', long, False)
- def testPvProperty(self):
+ def test_pv_property(self):
with AllowedPVS() as pvs:
pv = pvs[0]
self._test_prop(pv, 'pv_mda_count', long, False)
- def testLvProperty(self):
+ def test_lv_property(self):
lv_name = 'lv_test'
- self._createThinLV(self._get_pv_device_names(), lv_name)
- lv, vg = self._get_lv(None, lv_name)
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
self._test_prop(lv, 'seg_count', long, False)
vg.close()
- def testLvTags(self):
+ def test_lv_tags(self):
lv_name = 'lv_test'
- self._createThinLV(self._get_pv_device_names(), lv_name)
- lv, vg = self._get_lv(None, lv_name)
- self._testTags(lv)
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
+ self._test_tags(lv)
vg.close()
- def testLvActiveInactive(self):
+ def test_lv_active_inactive(self):
lv_name = 'lv_test'
- self._createThinLV(self._get_pv_device_names(), lv_name)
- lv, vg = self._get_lv(None, lv_name)
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
lv.deactivate()
self.assertTrue(lv.isActive() is False)
lv.activate()
self.assertTrue(lv.isActive() is True)
vg.close()
- def testLvRename(self):
+ def test_lv_rename(self):
lv_name = 'lv_test'
- self._createThinLV(self._get_pv_device_names(), lv_name)
- lv, vg = self._get_lv(None, lv_name)
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
current_name = lv.getName()
new_name = rs()
@@ -352,29 +367,29 @@ class TestLvm(unittest.TestCase):
lv.rename(current_name)
vg.close()
- def testLvSnapshot(self):
+ def test_lv_snapshot(self):
thin_lv = 'thin_lv'
thick_lv = 'thick_lv'
- device_names = self._get_pv_device_names()
+ device_names = TestLvm._get_pv_device_names()
- self._createThinLV(device_names[0:2], thin_lv)
- self._createThickLV(device_names[2:4], thick_lv)
+ TestLvm._create_thin_lv(device_names[0:2], thin_lv)
+ TestLvm._create_thick_lv(device_names[2:4], thick_lv)
- lv, vg = self._get_lv(None, thick_lv)
+ lv, vg = TestLvm._get_lv(None, thick_lv)
lv.snapshot('thick_snap_shot', 1024*1024)
vg.close()
- thick_ss, vg = self._get_lv(None, 'thick_snap_shot')
+ thick_ss, vg = TestLvm._get_lv(None, 'thick_snap_shot')
self.assertTrue(thick_ss is not None)
vg.close()
- thin_lv, vg = self._get_lv(None, thin_lv)
+ thin_lv, vg = TestLvm._get_lv(None, thin_lv)
thin_lv.snapshot('thin_snap_shot')
vg.close()
- thin_ss, vg = self._get_lv(None, 'thin_snap_shot')
+ thin_ss, vg = TestLvm._get_lv(None, 'thin_snap_shot')
self.assertTrue(thin_ss is not None)
origin = thin_ss.getOrigin()
@@ -382,38 +397,38 @@ class TestLvm(unittest.TestCase):
vg.close()
- def testLvSuspend(self):
+ def test_lv_suspend(self):
lv_name = 'lv_test'
- self._createThinLV(self._get_pv_device_names(), lv_name)
- lv, vg = self._get_lv(None, lv_name)
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
result = lv.isSuspended()
self.assertTrue(type(result) == bool)
vg.close()
- def testLvSize(self):
+ def test_lv_size(self):
lv_name = 'lv_test'
- self._createThinLV(self._get_pv_device_names(), lv_name)
- lv, vg = self._get_lv(None, lv_name)
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
result = lv.getSize()
self.assertTrue(type(result) == int or type(result) == long)
vg.close()
- def testLvResize(self):
+ def test_lv_resize(self):
lv_name = 'lv_test'
- self._createThinLV(self._get_pv_device_names(), lv_name)
- lv, vg = self._get_lv(None, lv_name)
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
curr_size = lv.getSize()
lv.resize(curr_size+(1024*1024))
latest = lv.getSize()
self.assertTrue(curr_size != latest)
- def testLvSeg(self):
+ def test_lv_seg(self):
lv_name = 'lv_test'
- self._createThinLV(self._get_pv_device_names(), lv_name)
- lv, vg = self._get_lv(None, lv_name)
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
lv_segs = lv.listLVsegs()
@@ -424,11 +439,11 @@ class TestLvm(unittest.TestCase):
vg.close()
- def testGetSetExtentSize(self):
+ def test_get_set_extend_size(self):
thick_lv = 'get_set_prop'
- device_names = self._get_pv_device_names()
- self._createThickLV(device_names[0:2], thick_lv)
- lv, vg = self._get_lv(None, thick_lv)
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thick_lv(device_names[0:2], thick_lv)
+ lv, vg = TestLvm._get_lv(None, thick_lv)
new_extent = 1024 * 1024 * 4
@@ -439,11 +454,11 @@ class TestLvm(unittest.TestCase):
self.assertEqual(vg.getExtentSize(), new_extent)
vg.close()
- def testVGsetGetProp(self):
+ def test_vg_get_set_prop(self):
thick_lv = 'get_set_prop'
- device_names = self._get_pv_device_names()
- self._createThickLV(device_names[0:2], thick_lv)
- lv, vg = self._get_lv(None, thick_lv)
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thick_lv(device_names[0:2], thick_lv)
+ lv, vg = TestLvm._get_lv(None, thick_lv)
self.assertTrue(vg is not None)
if vg:
@@ -451,14 +466,14 @@ class TestLvm(unittest.TestCase):
vg.setProperty('vg_mda_copies', vg_mda_copies[0])
vg.close()
- def testVGremoveRestore(self):
+ def test_vg_remove_restore(self):
#Store off the list of physical devices
pv_devices = []
thick_lv = 'get_set_prop'
- device_names = self._get_pv_device_names()
- self._createThickLV(device_names[0:2], thick_lv)
- lv, vg = self._get_lv(None, thick_lv)
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thick_lv(device_names[0:2], thick_lv)
+ lv, vg = TestLvm._get_lv(None, thick_lv)
vg_name = vg.getName()
@@ -467,22 +482,22 @@ class TestLvm(unittest.TestCase):
pv_devices.append(p.getName())
vg.close()
- self._remove_VG(vg_name)
- self._createThickLV(pv_devices, thick_lv)
+ TestLvm._remove_vg(vg_name)
+ self._create_thick_lv(pv_devices, thick_lv)
- def testVgNames(self):
+ def test_vg_names(self):
vg = lvm.listVgNames()
self.assertTrue(isinstance(vg, tuple))
- def testDupeLvCreate(self):
+ def test_dupe_lv_create(self):
"""
Try to create a lv with the same name expecting a failure
Note: This was causing a seg. fault previously
"""
thick_lv = 'dupe_name'
- device_names = self._get_pv_device_names()
- self._createThickLV(device_names[0:2], thick_lv)
- lv, vg = self._get_lv(None, thick_lv)
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thick_lv(device_names[0:2], thick_lv)
+ lv, vg = TestLvm._get_lv(None, thick_lv)
self.assertTrue(vg is not None)
@@ -496,11 +511,11 @@ class TestLvm(unittest.TestCase):
lv.getSize())
vg.close()
- def testVgUuids(self):
+ def test_vg_uuids(self):
- device_names = self._get_pv_device_names()
- self._createThinLV(device_names[0:2], 'thin')
- self._createThickLV(device_names[2:4], 'thick')
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thin_lv(device_names[0:2], 'thin')
+ TestLvm._create_thick_lv(device_names[2:4], 'thick')
vgs_uuids = lvm.listVgUuids()
@@ -523,12 +538,12 @@ class TestLvm(unittest.TestCase):
self.assertTrue(len(vgs_uuids) == 0)
- def testPvLookupFromVG(self):
- device_names = self._get_pv_device_names()
- self._createThinLV(device_names[0:2], 'thin')
- self._createThickLV(device_names[2:4], 'thick')
+ def test_pv_lookup_from_vg(self):
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thin_lv(device_names[0:2], 'thin')
+ TestLvm._create_thick_lv(device_names[2:4], 'thick')
- vg_names = self._vg_names()
+ vg_names = TestLvm._vg_names()
self.assertTrue(len(vg_names) > 0)
@@ -558,31 +573,31 @@ class TestLvm(unittest.TestCase):
pvs = None
vg.close()
- def testPercentToFloat(self):
+ def test_percent_to_float(self):
self.assertEqual(lvm.percentToFloat(0), 0.0)
self.assertEqual(lvm.percentToFloat(1000000), 1.0)
self.assertEqual(lvm.percentToFloat(1000000 / 2), 0.5)
- def testScan(self):
+ def test_scan(self):
self.assertEqual(lvm.scan(), None)
- def testConfigReload(self):
+ def test_config_reload(self):
self.assertEqual(lvm.configReload(), None)
- def testConfig_override(self):
+ def test_config_override(self):
self.assertEquals(lvm.configOverride("global.test = 1"), None)
- def testConfigFindBool(self):
+ def test_config_find_bool(self):
either_or = lvm.configFindBool("global/fallback_to_local_locking")
self.assertTrue(type(either_or) == bool)
self.assertTrue(lvm.configFindBool("global/locking_type"))
- def testVgFromPVLookups(self):
- device_names = self._get_pv_device_names()
- self._createThinLV(device_names[0:2], 'thin')
- self._createThickLV(device_names[2:4], 'thick')
+ def test_vg_from_pv_lookups(self):
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thin_lv(device_names[0:2], 'thin')
+ TestLvm._create_thick_lv(device_names[2:4], 'thick')
- vgname_list = self._vg_names()
+ vgname_list = TestLvm._vg_names()
self.assertTrue(len(vgname_list) > 0)
@@ -598,12 +613,12 @@ class TestLvm(unittest.TestCase):
self.assertEqual(vg_name, lvm.vgNameFromDevice(pv.getName()))
vg.close()
- def testVgGetName(self):
- device_names = self._get_pv_device_names()
- self._createThinLV(device_names[0:2], 'thin')
- self._createThickLV(device_names[2:4], 'thick')
+ def test_vg_get_name(self):
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thin_lv(device_names[0:2], 'thin')
+ TestLvm._create_thick_lv(device_names[2:4], 'thick')
- vgname_list = self._vg_names()
+ vgname_list = TestLvm._vg_names()
self.assertTrue(len(vgname_list) > 0)
@@ -612,12 +627,12 @@ class TestLvm(unittest.TestCase):
self.assertEqual(vg.getName(), vg_name)
vg.close()
- def testVgGetUuid(self):
- device_names = self._get_pv_device_names()
- self._createThinLV(device_names[0:2], 'thin')
- self._createThickLV(device_names[2:4], 'thick')
+ def test_vg_get_uuid(self):
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thin_lv(device_names[0:2], 'thin')
+ TestLvm._create_thick_lv(device_names[2:4], 'thick')
- vgname_list = self._vg_names()
+ vgname_list = TestLvm._vg_names()
self.assertTrue(len(vgname_list) > 0)
@@ -632,12 +647,12 @@ class TestLvm(unittest.TestCase):
"getExtentSize", "getExtentCount", "getFreeExtentCount",
"getPvCount", "getMaxPv", "getMaxLv"]
- def testVgGetters(self):
- device_names = self._get_pv_device_names()
- self._createThinLV(device_names[0:2], 'thin')
- self._createThickLV(device_names[2:4], 'thick')
+ def test_vg_getters(self):
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thin_lv(device_names[0:2], 'thin')
+ TestLvm._create_thick_lv(device_names[2:4], 'thick')
- vg_name_list = self._vg_names()
+ vg_name_list = TestLvm._vg_names()
self.assertTrue(len(vg_name_list) > 0)
@@ -655,7 +670,7 @@ class TestLvm(unittest.TestCase):
vg.close()
- def _testTags(self, tag_obj):
+ def _test_tags(self, tag_obj):
existing_tags = tag_obj.getTags()
self.assertTrue(type(existing_tags) == tuple)
@@ -688,23 +703,24 @@ class TestLvm(unittest.TestCase):
for e in existing_tags:
self.assertTrue(e in current_tags)
- def testVgTags(self):
- device_names = self._get_pv_device_names()
+ def test_vg_tags(self):
+ device_names = TestLvm._get_pv_device_names()
i = 0
for d in device_names:
if i % 2 == 0:
- self._createThinLV([d], "thin_lv%d" % i)
+ TestLvm._create_thin_lv([d], "thin_lv%d" % i)
else:
- self._createThickLV([d], "thick_lv%d" % i)
+ TestLvm._create_thick_lv([d], "thick_lv%d" % i)
i += 1
- for vg_name in self._vg_names():
+ for vg_name in TestLvm._vg_names():
vg = lvm.vgOpen(vg_name, 'w')
- self._testTags(vg)
+ self._test_tags(vg)
vg.close()
- def testListing(self):
+ @staticmethod
+ def test_listing():
env = os.environ
@@ -719,12 +735,12 @@ class TestLvm(unittest.TestCase):
for v in lvm.listVgNames():
l('vg= %s' % v)
- def testPVemptylisting(self):
+ def test_pv_empty_listing(self):
#We had a bug where we would seg. fault if we had no PVs.
l('testPVemptylisting entry')
- device_names = self._get_pv_device_names()
+ device_names = TestLvm._get_pv_device_names()
for d in device_names:
l("Removing %s" % d)
@@ -742,7 +758,7 @@ class TestLvm(unittest.TestCase):
for d in device_names:
lvm.pvCreate(d)
- def testPVCreate(self):
+ def test_pv_create(self):
size = [0, 1024*1024*4]
pvmeta_copies = [0, 1, 2]
pvmeta_size = [0, 255, 512, 1024]
@@ -750,7 +766,7 @@ class TestLvm(unittest.TestCase):
data_alignment_offset = [1, 1, 1]
zero = [0, 1]
- device_names = self._get_pv_device_names()
+ device_names = TestLvm._get_pv_device_names()
for d in device_names:
lvm.pvRemove(d)
9 years, 4 months
master - lvm2app: Remove forward declarations.
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=12d5e53953f1da...
Commit: 12d5e53953f1dacd911190cacc153dc2343878fe
Parent: fe5b538c14c47e2e206d13c17f0225e39470d720
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Thu Oct 3 16:06:05 2013 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Nov 19 14:40:44 2013 -0600
lvm2app: Remove forward declarations.
Remove the forward struct declaration. This isn't needed for
implementing opaque data pointers.
Signed-off-by: Tony Asleson <tasleson(a)redhat.com>
---
liblvm/lvm2app.h | 19 ++++++-------------
1 files changed, 6 insertions(+), 13 deletions(-)
diff --git a/liblvm/lvm2app.h b/liblvm/lvm2app.h
index 0940b6f..a91640a 100644
--- a/liblvm/lvm2app.h
+++ b/liblvm/lvm2app.h
@@ -84,20 +84,13 @@ const char *lvm_library_get_version(void);
/******************************** structures ********************************/
/**
- * Opaque structures - do not use directly. Internal structures may change
- * without notice between releases, whereas this API will be changed much less
- * frequently. Backwards compatibility will normally be preserved in future
- * releases. On any occasion when the developers do decide to break backwards
- * compatibility in any significant way, the LVM_LIBAPI number (included in
- * the library's soname) will be incremented.
- */
-struct lvm;
-struct physical_volume;
-struct volume_group;
-struct logical_volume;
-struct lv_segment;
-struct pv_segment;
-struct lvm_lv_create_params;
+ * Opaque C pointers - Internal structures may change without notice between
+ * releases, whereas this API will be changed much less frequently. Backwards
+ * compatibility will normally be preserved in future releases. On any occasion
+ * when the developers do decide to break backwards compatibility in any
+ * significant way, the LVM_LIBAPI number (included in the library's soname)
+ * will be incremented.
+ */
/**
* \class lvm_t
9 years, 4 months
master - lvm2app: Reset buffer after retrieving error message
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=fe5b538c14c47e...
Commit: fe5b538c14c47e2e206d13c17f0225e39470d720
Parent: 0c7a7d4d8433965313120254b68199525871b6a6
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Thu Sep 26 12:19:18 2013 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Nov 19 14:40:42 2013 -0600
lvm2app: Reset buffer after retrieving error message
The error buffer will stack error messages which is fine. However,
once you retrieve the error messages it doesn't make sense to keep
appending for each additional error message when running in the
context of a library call.
This patch clears and resets the buffer after the user retrieves
the error message.
Signed-off-by: Tony Asleson <tasleson(a)redhat.com>
---
lib/log/log.c | 7 +++++++
lib/log/lvm-logging.h | 1 +
liblvm/lvm_base.c | 9 ++++++++-
python/liblvm.c | 5 ++++-
4 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/lib/log/log.c b/lib/log/log.c
index e0c1e73..1af9616 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -170,6 +170,13 @@ const char *stored_errmsg(void)
return _lvm_errmsg ? : "";
}
+const char *stored_errmsg_with_clear(void)
+{
+ const char *rc = strdup(stored_errmsg());
+ reset_lvm_errno(1);
+ return rc;
+}
+
static struct dm_hash_table *_duplicated = NULL;
void reset_log_duplicated(void) {
diff --git a/lib/log/lvm-logging.h b/lib/log/lvm-logging.h
index 52cd895..145e2a1 100644
--- a/lib/log/lvm-logging.h
+++ b/lib/log/lvm-logging.h
@@ -55,6 +55,7 @@ int error_message_produced(void);
void reset_lvm_errno(int store_errmsg);
int stored_errno(void);
const char *stored_errmsg(void);
+const char *stored_errmsg_with_clear(void);
/* Suppress messages to stdout/stderr (1) or everywhere (2) */
/* Returns previous setting */
diff --git a/liblvm/lvm_base.c b/liblvm/lvm_base.c
index 139cc97..d694173 100644
--- a/liblvm/lvm_base.c
+++ b/liblvm/lvm_base.c
@@ -115,7 +115,14 @@ int lvm_errno(lvm_t libh)
const char *lvm_errmsg(lvm_t libh)
{
- return stored_errmsg();
+ const char *rc = NULL;
+ struct cmd_context *cmd = (struct cmd_context *)libh;
+ const char *msg = stored_errmsg_with_clear();
+ if (msg) {
+ rc = dm_pool_strdup(cmd->mem, msg);
+ free((void *)msg);
+ }
+ return rc;
}
const char *lvm_vgname_from_pvid(lvm_t libh, const char *pvid)
diff --git a/python/liblvm.c b/python/liblvm.c
index 330ef14..6abd5ff 100644
--- a/python/liblvm.c
+++ b/python/liblvm.c
@@ -141,6 +141,7 @@ static lvobject *_create_py_lv(vgobject *parent, lv_t lv)
static PyObject *_liblvm_get_last_error(void)
{
PyObject *info;
+ const char *msg = NULL;
LVM_VALID(NULL);
@@ -148,7 +149,9 @@ static PyObject *_liblvm_get_last_error(void)
return NULL;
PyTuple_SetItem(info, 0, PyInt_FromLong((long) lvm_errno(_libh)));
- PyTuple_SetItem(info, 1, PyString_FromString(lvm_errmsg(_libh)));
+ msg = lvm_errmsg(_libh);
+ PyTuple_SetItem(info, 1, ((msg) ? PyString_FromString(msg) :
+ PyString_FromString("Memory error while retrieving error message")));
return info;
}
9 years, 4 months
master - python-lvm: VG/LV name validation.
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0c7a7d4d843396...
Commit: 0c7a7d4d8433965313120254b68199525871b6a6
Parent: 0dd247502ace2dd20763d1b664edc280a255de06
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Thu Sep 26 11:39:40 2013 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Nov 19 14:40:40 2013 -0600
python-lvm: VG/LV name validation.
Python portion of
https://bugzilla.redhat.com/show_bug.cgi?id=883689
Signed-off-by: Tony Asleson <tasleson(a)redhat.com>
---
python/liblvm.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/python/liblvm.c b/python/liblvm.c
index 033de82..330ef14 100644
--- a/python/liblvm.c
+++ b/python/liblvm.c
@@ -391,6 +391,25 @@ static PyObject *_liblvm_lvm_percent_to_float(PyObject *self, PyObject *arg)
return Py_BuildValue("d", converted);
}
+static PyObject *_liblvm_lvm_vg_name_validate(PyObject *self, PyObject *arg)
+{
+ const char *name;
+
+ LVM_VALID(NULL);
+
+ if (!PyArg_ParseTuple(arg, "s", &name))
+ return NULL;
+
+ if (lvm_vg_name_validate(_libh, name) < 0) {
+ PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+
+ return Py_None;
+}
+
static PyObject *_liblvm_lvm_vgname_from_pvid(PyObject *self, PyObject *arg)
{
const char *pvid;
@@ -1213,6 +1232,25 @@ static PyObject *_liblvm_lvm_lv_from_uuid(vgobject *self, PyObject *arg)
return _liblvm_lvm_lv_from_N(self, arg, lvm_lv_from_uuid);
}
+static PyObject *_liblvm_lvm_lv_name_validate(vgobject *self, PyObject *args)
+{
+ const char *name;
+
+ VG_VALID(self);
+
+ if (!PyArg_ParseTuple(args, "s", &name))
+ return NULL;
+
+ if (lvm_lv_name_validate(self->vg, name) < 0) {
+ PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
+ return NULL;
+ }
+
+ Py_INCREF(Py_None);
+
+ return Py_None;
+}
+
static PyObject *_liblvm_lvm_pv_from_N(vgobject *self, PyObject *arg, pv_fetch_by_N method)
{
const char *id;
@@ -1771,6 +1809,7 @@ static PyMethodDef _Liblvm_methods[] = {
{ "pvCreate", (PyCFunction)_liblvm_lvm_pv_create, METH_VARARGS },
{ "pvRemove", (PyCFunction)_liblvm_lvm_pv_remove, METH_VARARGS },
{ "percentToFloat", (PyCFunction)_liblvm_lvm_percent_to_float, METH_VARARGS },
+ { "vgNameValidate", (PyCFunction)_liblvm_lvm_vg_name_validate, METH_VARARGS },
{ "vgNameFromPvid", (PyCFunction)_liblvm_lvm_vgname_from_pvid, METH_VARARGS },
{ "vgNameFromDevice", (PyCFunction)_liblvm_lvm_vgname_from_device, METH_VARARGS },
{ NULL, NULL } /* sentinel */
@@ -1805,6 +1844,7 @@ static PyMethodDef _liblvm_vg_methods[] = {
{ "listPVs", (PyCFunction)_liblvm_lvm_vg_list_pvs, METH_NOARGS },
{ "lvFromName", (PyCFunction)_liblvm_lvm_lv_from_name, METH_VARARGS },
{ "lvFromUuid", (PyCFunction)_liblvm_lvm_lv_from_uuid, METH_VARARGS },
+ { "lvNameValidate", (PyCFunction)_liblvm_lvm_lv_name_validate, METH_VARARGS },
{ "pvFromName", (PyCFunction)_liblvm_lvm_pv_from_name, METH_VARARGS },
{ "pvFromUuid", (PyCFunction)_liblvm_lvm_pv_from_uuid, METH_VARARGS },
{ "getTags", (PyCFunction)_liblvm_lvm_vg_get_tags, METH_NOARGS },
9 years, 4 months
master - lvm2app: Add VG/LV name validation
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0dd247502ace2d...
Commit: 0dd247502ace2dd20763d1b664edc280a255de06
Parent: e54e70dc66a8be0dbc61e1dbc65310d86d35b086
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Thu Sep 26 11:37:40 2013 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Nov 19 14:40:39 2013 -0600
lvm2app: Add VG/LV name validation
C library portion for
https://bugzilla.redhat.com/show_bug.cgi?id=883689
Signed-off-by: Tony Asleson <tasleson(a)redhat.com>
---
lib/display/display.c | 29 ++++++++++++++++++++++++++++
lib/display/display.h | 3 ++
lib/metadata/metadata-exported.h | 1 +
lib/metadata/metadata.c | 12 ++++++----
lib/misc/lvm-string.c | 39 +++++++++++++++++++++++++------------
lib/misc/lvm-string.h | 8 ++++++-
liblvm/lvm2app.h | 32 +++++++++++++++++++++++++++++++
liblvm/lvm_base.c | 1 +
liblvm/lvm_vg.c | 30 +++++++++++++++++++++++++++++
9 files changed, 136 insertions(+), 19 deletions(-)
diff --git a/lib/display/display.c b/lib/display/display.c
index be56f12..2fd37a2 100644
--- a/lib/display/display.c
+++ b/lib/display/display.c
@@ -915,6 +915,35 @@ void display_segtypes(const struct cmd_context *cmd)
}
}
+void display_name_error(name_error_t name_error)
+{
+ if (name_error != NAME_VALID) {
+ switch(name_error) {
+ case NAME_INVALID_EMPTY:
+ log_error("Name is zero length");
+ break;
+ case NAME_INVALID_HYPEN:
+ log_error("Name cannot start with hyphen");
+ break;
+ case NAME_INVALID_DOTS:
+ log_error("Name starts with . or .. and has no "
+ "following character(s)");
+ break;
+ case NAME_INVALID_CHARSET:
+ log_error("Name contains invalid character, valid set includes: "
+ "[a-zA-Z0-9.-_+]");
+ break;
+ case NAME_INVALID_LENGTH:
+ /* Report that name length -1 to accommodate nul*/
+ log_error("Name length exceeds maximum limit of %d", (NAME_LEN -1));
+ break;
+ default:
+ log_error("Unknown error %d on name validation", name_error);
+ break;
+ }
+ }
+}
+
/*
* Prompt for y or n from stdin.
* Defaults to 'no' in silent mode.
diff --git a/lib/display/display.h b/lib/display/display.h
index 8462901..077fff4 100644
--- a/lib/display/display.h
+++ b/lib/display/display.h
@@ -18,6 +18,7 @@
#include "metadata-exported.h"
#include "locking.h"
+#include "lvm-string.h"
#include <stdint.h>
@@ -53,6 +54,8 @@ void vgdisplay_short(const struct volume_group *vg);
void display_formats(const struct cmd_context *cmd);
void display_segtypes(const struct cmd_context *cmd);
+void display_name_error(name_error_t name_error);
+
/*
* Allocation policy display conversion routines.
*/
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 7429241..ed1ec8d 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -581,6 +581,7 @@ int pv_analyze(struct cmd_context *cmd, const char *pv_name,
/* FIXME: move internal to library */
uint32_t pv_list_extents_free(const struct dm_list *pvh);
+int validate_new_vg_name(struct cmd_context *cmd, const char *vg_name);
int vg_validate(struct volume_group *vg);
struct volume_group *vg_create(struct cmd_context *cmd, const char *vg_name);
int vg_remove_mdas(struct volume_group *vg);
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index d80958d..53d7e5e 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -435,13 +435,15 @@ int move_pvs_used_by_lv(struct volume_group *vg_from,
return 1;
}
-static int validate_new_vg_name(struct cmd_context *cmd, const char *vg_name)
+int validate_new_vg_name(struct cmd_context *cmd, const char *vg_name)
{
static char vg_path[PATH_MAX];
+ name_error_t name_error;
- if (!validate_name(vg_name)) {
- log_error("New volume group name \"%s\" is invalid.",
- vg_name);
+ name_error = validate_name_detailed(vg_name);
+ if (NAME_VALID != name_error) {
+ display_name_error(name_error);
+ log_error("New volume group name \"%s\" is invalid.", vg_name);
return 0;
}
@@ -4574,7 +4576,7 @@ void mda_set_ignored(struct metadata_area *mda, unsigned mda_ignored)
else
return; /* No change */
- log_debug_metadata("%s ignored flag for mda %s at offset %" PRIu64 ".",
+ log_debug_metadata("%s ignored flag for mda %s at offset %" PRIu64 ".",
mda_ignored ? "Setting" : "Clearing",
mda->ops->mda_metadata_locn_name ? mda->ops->mda_metadata_locn_name(locn) : "",
mda->ops->mda_metadata_locn_offset ? mda->ops->mda_metadata_locn_offset(locn) : UINT64_C(0));
diff --git a/lib/misc/lvm-string.c b/lib/misc/lvm-string.c
index 8aa1f6c..380fe81 100644
--- a/lib/misc/lvm-string.c
+++ b/lib/misc/lvm-string.c
@@ -63,35 +63,40 @@ int validate_tag(const char *n)
return 1;
}
-/*
- * Device layer names are all of the form <vg>-<lv>-<layer>, any
- * other hyphens that appear in these names are quoted with yet
- * another hyphen. The top layer of any device has no layer
- * name. eg, vg0-lvol0.
- */
-int validate_name(const char *n)
+static int _validate_name(const char *n)
{
register char c;
register int len = 0;
if (!n || !*n)
- return 0;
+ return -1;
/* Hyphen used as VG-LV separator - ambiguity if LV starts with it */
if (*n == '-')
- return 0;
+ return -2;
if ((*n == '.') && (!n[1] || (n[1] == '.' && !n[2]))) /* ".", ".." */
- return 0;
+ return -3;
while ((len++, c = *n++))
if (!isalnum(c) && c != '.' && c != '_' && c != '-' && c != '+')
- return 0;
+ return -4;
if (len > NAME_LEN)
- return 0;
+ return -5;
- return 1;
+ return 0;
+}
+
+/*
+ * Device layer names are all of the form <vg>-<lv>-<layer>, any
+ * other hyphens that appear in these names are quoted with yet
+ * another hyphen. The top layer of any device has no layer
+ * name. eg, vg0-lvol0.
+ */
+int validate_name(const char *n)
+{
+ return (_validate_name(n) < 0 ? 0 : 1);
}
int apply_lvname_restrictions(const char *name)
@@ -136,6 +141,14 @@ int apply_lvname_restrictions(const char *name)
return 1;
}
+/*
+ * Validates name and returns an emunerated reason for name validataion failure.
+ */
+name_error_t validate_name_detailed(const char *name)
+{
+ return _validate_name(name);
+}
+
int is_reserved_lvname(const char *name)
{
int rc, old_suppress;
diff --git a/lib/misc/lvm-string.h b/lib/misc/lvm-string.h
index 6be048d..13aacf8 100644
--- a/lib/misc/lvm-string.h
+++ b/lib/misc/lvm-string.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
+ * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
@@ -24,6 +24,11 @@
struct pool;
+typedef enum name_error { NAME_VALID = 0, NAME_INVALID_EMPTY = -1,
+ NAME_INVALID_HYPEN = -2, NAME_INVALID_DOTS = -3,
+ NAME_INVALID_CHARSET = -4, NAME_INVALID_LENGTH = -5}
+ name_error_t;
+
int emit_to_buffer(char **buffer, size_t *size, const char *fmt, ...)
__attribute__ ((format(printf, 3, 4)));
@@ -31,6 +36,7 @@ char *build_dm_uuid(struct dm_pool *mem, const char *lvid,
const char *layer);
int validate_name(const char *n);
+name_error_t validate_name_detailed(const char *n);
int validate_tag(const char *n);
int apply_lvname_restrictions(const char *name);
diff --git a/liblvm/lvm2app.h b/liblvm/lvm2app.h
index afc6793..0940b6f 100644
--- a/liblvm/lvm2app.h
+++ b/liblvm/lvm2app.h
@@ -510,6 +510,21 @@ vg_t lvm_vg_open(lvm_t libh, const char *vgname, const char *mode,
uint32_t flags);
/**
+ * Validate a name to be used for new VG construction.
+ *
+ * This function checks that the name has no invalid characters,
+ * the length doesn't exceed maximum and that the VG name isn't already in use
+ * and that the name adheres to any other limitations.
+ *
+ * \param libh
+ * Valid library handle
+ *
+ * \param name
+ * Name to validate for new VG create.
+ */
+int lvm_vg_name_validate(lvm_t libh, const char *vg_name);
+
+/**
* Create a VG with default parameters.
*
* \memberof lvm_t
@@ -1554,6 +1569,23 @@ int lvm_lv_resize(const lv_t lv, uint64_t new_size);
lv_t lvm_lv_snapshot(const lv_t lv, const char *snap_name, uint64_t max_snap_size);
/**
+ * Validate a name to be used for LV creation.
+ *
+ * Validates that the name does not contain any invalid characters, max length
+ * and that the LV name doesn't already exist for this VG.
+ *
+ * Note: You can have the same LV name in different VGs, thus the reason this
+ * function requires that you specify a VG to check against.
+ *
+ * \param lv
+ * Volume group handle.
+ *
+ * \param name
+ * Name to validate
+ */
+int lvm_lv_name_validate(const vg_t vg, const char *lv_name);
+
+/**
* Thin provisioning discard policies
*/
typedef enum {
diff --git a/liblvm/lvm_base.c b/liblvm/lvm_base.c
index b7603e3..139cc97 100644
--- a/liblvm/lvm_base.c
+++ b/liblvm/lvm_base.c
@@ -18,6 +18,7 @@
#include "lvm-version.h"
#include "metadata-exported.h"
#include "lvm2app.h"
+#include "lvm-string.h"
const char *lvm_library_get_version(void)
{
diff --git a/liblvm/lvm_vg.c b/liblvm/lvm_vg.c
index 214f459..d3c8ae2 100644
--- a/liblvm/lvm_vg.c
+++ b/liblvm/lvm_vg.c
@@ -21,6 +21,7 @@
#include "lvmetad.h"
#include "lvm_misc.h"
#include "lvm2app.h"
+#include "display.h"
int lvm_vg_add_tag(vg_t vg, const char *tag)
{
@@ -385,3 +386,32 @@ int lvm_scan(lvm_t libh)
return -1;
return 0;
}
+
+int lvm_lv_name_validate(const vg_t vg, const char *name)
+{
+ name_error_t name_error;
+
+ name_error = validate_name_detailed(name);
+
+ if (NAME_VALID == name_error) {
+ if (apply_lvname_restrictions(name)) {
+ if (!find_lv_in_vg(vg, name)) {
+ return 0;
+ } else {
+ log_errno(EINVAL, "LV name exists in VG");
+ }
+ }
+ } else {
+ display_name_error(name_error);
+ }
+ return -1;
+}
+
+int lvm_vg_name_validate(lvm_t libh, const char *name)
+{
+ struct cmd_context *cmd = (struct cmd_context *)libh;
+
+ if (validate_new_vg_name(cmd, name))
+ return 0;
+ return -1;
+}
9 years, 4 months
master - python-lvm: Update and enable unit test case
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e54e70dc66a8be...
Commit: e54e70dc66a8be0dbc61e1dbc65310d86d35b086
Parent: 531d85a0ee3854e49f9b81658dd6d7c60bb4de86
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Sep 11 18:13:18 2013 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Nov 19 14:40:37 2013 -0600
python-lvm: Update and enable unit test case
Added tests for lvm.pvCreate and enable the test suite.
Signed-off-by: Tony Asleson <tasleson(a)redhat.com>
---
test/api/pytest.sh | 4 --
test/api/python_lvm_unit.py | 99 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 4 deletions(-)
diff --git a/test/api/pytest.sh b/test/api/pytest.sh
index 791c9dc..67e224c 100644
--- a/test/api/pytest.sh
+++ b/test/api/pytest.sh
@@ -27,8 +27,4 @@ export PYTHONPATH=`dirname $python_lib`:$PYTHONPATH
#Setup which devices the unit test can use.
export PY_UNIT_PVS=$(cat DEVICES)
-
-#We will skip until we can ensure it is correct.
-skip
-
python_lvm_unit.py -v -f
diff --git a/test/api/python_lvm_unit.py b/test/api/python_lvm_unit.py
index eab9575..6c13149 100755
--- a/test/api/python_lvm_unit.py
+++ b/test/api/python_lvm_unit.py
@@ -27,6 +27,17 @@ import os
# production system. Therefore it is strongly advised that this unit test
# not be run on a system that contains data of value.
+fh = None
+
+
+def l(txt):
+ if os.environ.get('PY_UNIT_LOG') is not None:
+ global fh
+ if fh is None:
+ fh = open('/tmp/lvm_py_unit_test_' + rs(10), "a")
+ fh.write(txt + "\n")
+ fh.flush()
+
def rs(l=10):
"""
@@ -693,5 +704,93 @@ class TestLvm(unittest.TestCase):
self._testTags(vg)
vg.close()
+ def testListing(self):
+
+ env = os.environ
+
+ for k, v in env.items():
+ l("%s:%s" % (k, v))
+
+ with lvm.listPvs() as pvs:
+ for p in pvs:
+ l('pv= %s' % p.getName())
+
+ l('Checking for VG')
+ for v in lvm.listVgNames():
+ l('vg= %s' % v)
+
+ def testPVemptylisting(self):
+ #We had a bug where we would seg. fault if we had no PVs.
+
+ l('testPVemptylisting entry')
+
+ device_names = self._get_pv_device_names()
+
+ for d in device_names:
+ l("Removing %s" % d)
+ lvm.pvRemove(d)
+
+ count = 0
+
+ with lvm.listPvs() as pvs:
+ for p in pvs:
+ count += 1
+ l('pv= %s' % p.getName())
+
+ self.assertTrue(count == 0)
+
+ for d in device_names:
+ lvm.pvCreate(d)
+
+ def testPVCreate(self):
+ size = [0, 1024*1024*4]
+ pvmeta_copies = [0, 1, 2]
+ pvmeta_size = [0, 255, 512, 1024]
+ data_alignment = [0, 2048, 4096]
+ data_alignment_offset = [1, 1, 1]
+ zero = [0, 1]
+
+ device_names = self._get_pv_device_names()
+
+ for d in device_names:
+ lvm.pvRemove(d)
+
+ d = device_names[0]
+
+ #Test some error cases
+ self.assertRaises(TypeError, lvm.pvCreate, None)
+ self.assertRaises(lvm.LibLVMError, lvm.pvCreate, '')
+ self.assertRaises(lvm.LibLVMError, lvm.pvCreate, d, 4)
+ self.assertRaises(lvm.LibLVMError, lvm.pvCreate, d, 0, 4)
+ self.assertRaises(lvm.LibLVMError, lvm.pvCreate, d, 0, 0, 0, 2**34)
+ self.assertRaises(lvm.LibLVMError, lvm.pvCreate, d, 0, 0, 0, 4096,
+ 2**34)
+
+ #Try a number of combinations and permutations
+ for s in size:
+ lvm.pvCreate(d, s)
+ lvm.pvRemove(d)
+ for copies in pvmeta_copies:
+ lvm.pvCreate(d, s, copies)
+ lvm.pvRemove(d)
+ for pv_size in pvmeta_size:
+ lvm.pvCreate(d, s, copies, pv_size)
+ lvm.pvRemove(d)
+ for align in data_alignment:
+ lvm.pvCreate(d, s, copies, pv_size, align)
+ lvm.pvRemove(d)
+ for align_offset in data_alignment_offset:
+ lvm.pvCreate(d, s, copies, pv_size, align,
+ align * align_offset)
+ lvm.pvRemove(d)
+ for z in zero:
+ lvm.pvCreate(d, s, copies, pv_size, align,
+ align * align_offset, z)
+ lvm.pvRemove(d)
+
+ #Restore
+ for d in device_names:
+ lvm.pvCreate(d)
+
if __name__ == "__main__":
unittest.main()
9 years, 4 months
master - python-lvm: Add addl. PV create arguments
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=531d85a0ee3854...
Commit: 531d85a0ee3854e49f9b81658dd6d7c60bb4de86
Parent: 04304ba7356c90568dcf32f0772a2023f4684656
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Tue Sep 10 18:05:28 2013 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Nov 19 14:40:36 2013 -0600
python-lvm: Add addl. PV create arguments
Added overloaded PV create arguments with defaults for PV
creation.
Addresses bug: https://bugzilla.redhat.com/show_bug.cgi?id=880395
Signed-off-by: Tony Asleson <tasleson(a)redhat.com>
---
python/liblvm.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/python/liblvm.c b/python/liblvm.c
index 36b64e4..033de82 100644
--- a/python/liblvm.c
+++ b/python/liblvm.c
@@ -23,6 +23,7 @@
#include <Python.h>
#include "lvm2app.h"
+#include "defaults.h"
static lvm_t _libh;
@@ -317,24 +318,62 @@ static PyObject *_liblvm_lvm_pv_remove(PyObject *self, PyObject *arg)
return Py_None;
}
+static int _set_pv_numeric_prop(pv_create_params_t pv_params, const char *name,
+ unsigned long long value)
+{
+ struct lvm_property_value prop_value;
+ prop_value.is_integer = 1;
+ prop_value.value.integer = value;
+
+ return lvm_pv_params_set_property(pv_params, name, &prop_value);
+}
+
+#define SET_PV_PROP(params, name, value) \
+ do { \
+ if (_set_pv_numeric_prop(params, name, value) == -1) \
+ goto error; \
+ } while(0)\
+
static PyObject *_liblvm_lvm_pv_create(PyObject *self, PyObject *arg)
{
const char *pv_name;
- unsigned long long size;
+ unsigned long long size = 0;
+ unsigned long long pvmetadatacopies = DEFAULT_PVMETADATACOPIES;
+ unsigned long long pvmetadatasize = DEFAULT_PVMETADATASIZE;
+ unsigned long long data_alignment = 0;
+ unsigned long long data_alignment_offset = 0;
+ unsigned long long zero = 1;
+ pv_create_params_t pv_params = NULL;
LVM_VALID(NULL);
- if (!PyArg_ParseTuple(arg, "sK", &pv_name, &size))
+ if (!PyArg_ParseTuple(arg, "s|KKKKKK", &pv_name, &size, &pvmetadatacopies,
+ &pvmetadatasize, &data_alignment,
+ &data_alignment_offset, &zero))
return NULL;
- if (lvm_pv_create(_libh, pv_name, size) == -1) {
- PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
- return NULL;
+ pv_params = lvm_pv_params_create(_libh, pv_name);
+ if (!pv_params) {
+ goto error;
}
- Py_INCREF(Py_None);
+ SET_PV_PROP(pv_params, "size", size);
+ SET_PV_PROP(pv_params, "pvmetadatacopies", pvmetadatacopies);
+ SET_PV_PROP(pv_params, "pvmetadatasize", pvmetadatasize);
+ SET_PV_PROP(pv_params, "data_alignment", data_alignment);
+ SET_PV_PROP(pv_params, "data_alignment_offset", data_alignment_offset);
+ SET_PV_PROP(pv_params, "zero", zero);
+
+ if (lvm_pv_create_adv(pv_params)) {
+ goto error;
+ }
+ Py_INCREF(Py_None);
return Py_None;
+
+error:
+ PyErr_SetObject(_LibLVMError, _liblvm_get_last_error());
+ return NULL;
}
static PyObject *_liblvm_lvm_percent_to_float(PyObject *self, PyObject *arg)
9 years, 4 months
master - lvm2app: Add ability to create PV with args
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=04304ba7356c90...
Commit: 04304ba7356c90568dcf32f0772a2023f4684656
Parent: ec7f632ce08014ca5ceb3ac6c92d834fb0b8c93e
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Tue Sep 10 18:01:28 2013 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Nov 19 14:40:34 2013 -0600
lvm2app: Add ability to create PV with args
Add a PV create which takes a paramters object that
has get/set method to configure PV creation.
Current get/set operations include:
- size
- pvmetadatacopies
- pvmetadatasize
- data_alignment
- data_alignment_offset
- zero
Reference: https://bugzilla.redhat.com/show_bug.cgi?id=880395
Signed-off-by: Tony Asleson <tasleson(a)redhat.com>
---
lib/metadata/metadata.c | 28 ++++++++++
liblvm/lvm2app.h | 64 ++++++++++++++++++++++
liblvm/lvm_lv.c | 8 ++--
liblvm/lvm_misc.c | 10 ++++
liblvm/lvm_misc.h | 9 +++-
liblvm/lvm_prop.c | 31 +++++++++++
liblvm/lvm_prop.h | 14 +++++
liblvm/lvm_prop_fields.h | 7 +++
liblvm/lvm_pv.c | 136 +++++++++++++++++++++++++++++++++++++++++-----
liblvm/lvm_vg.c | 4 +-
tools/toollib.c | 6 --
11 files changed, 289 insertions(+), 28 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 7177ff0..d80958d 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -1455,6 +1455,30 @@ static int _pvcreate_write(struct cmd_context *cmd, struct pv_to_create *pvc)
return 1;
}
+static int _verify_pv_create_params(struct pvcreate_params *pp)
+{
+ /*
+ * FIXME: Some of these checks are duplicates in pvcreate_params_validate.
+ */
+ if (pp->pvmetadatacopies > 2) {
+ log_error("Metadatacopies may only be 0, 1 or 2");
+ return 0;
+ }
+
+ if (pp->data_alignment > UINT32_MAX) {
+ log_error("Physical volume data alignment is too big.");
+ return 0;
+ }
+
+ if (pp->data_alignment_offset > UINT32_MAX) {
+ log_error("Physical volume data alignment offset is too big.");
+ return 0;
+ }
+
+ return 1;
+}
+
+
/*
* pvcreate_vol() - initialize a device with PV label and metadata area
*
@@ -1479,6 +1503,10 @@ struct physical_volume *pvcreate_vol(struct cmd_context *cmd, const char *pv_nam
if (!pp)
pp = &default_pp;
+ if (!_verify_pv_create_params(pp)) {
+ goto bad;
+ }
+
if (pp->rp.idp) {
if ((dev = lvmcache_device_from_pvid(cmd, pp->rp.idp, NULL, NULL)) &&
(dev != dev_cache_get(pv_name, cmd->filter))) {
diff --git a/liblvm/lvm2app.h b/liblvm/lvm2app.h
index cb6766c..afc6793 100644
--- a/liblvm/lvm2app.h
+++ b/liblvm/lvm2app.h
@@ -162,6 +162,14 @@ typedef struct pv_segment *pvseg_t;
typedef struct lvm_lv_create_params *lv_create_params_t;
/**
+ * \class pv_create_params
+ *
+ * This pv_create_params represents the plethora of available options when
+ * creating a physical volume
+ */
+typedef struct lvm_pv_create_params *pv_create_params_t;
+
+/**
* Logical Volume object list.
*
* Lists of these structures are returned by lvm_vg_list_lvs().
@@ -582,6 +590,62 @@ int lvm_list_pvs_free(struct dm_list *pvlist);
int lvm_pv_create(lvm_t libh, const char *pv_name, uint64_t size);
/**
+ * Create a physical volume parameter object for PV creation.
+ *
+ * \param libh Library handle
+ * \param pv_name Device name
+ *
+ * \return
+ * NULL on error, else valid parameter object to use.
+ */
+pv_create_params_t lvm_pv_params_create(lvm_t libh, const char *pv_name);
+
+/**
+ * Create a parameter object to use in function lvm_pv_create_adv
+ *
+ * \param params The params object to get property value from
+ * \param name The name of the property to retrieve
+ *
+ * Available properties:
+ *
+ * size zero indicates use detected size of device
+ * (recommended and default)
+ * pvmetadatacopies Number of metadata copies (0,1,2)
+ * pvmetadatasize The approx. size to be to be set aside for metadata
+ * data_alignment Align the start of the data to a multiple of
+ * this number
+ * data_alignment_offset Shift the start of the data area by this addl.
+ * offset
+ * zero Set to 1 to zero out first 2048 bytes of
+ * device, 0 to not (default is 1)
+ *
+ * \return
+ * lvm_property_value
+ */
+struct lvm_property_value lvm_pv_params_get_property(
+ const pv_create_params_t params,
+ const char *name);
+
+/**
+ * Sets a property of a PV parameter create object.
+ *
+ * \param params The parameter object
+ * \param name The name of the property to set (see get prop list)
+ * \param prop The property to set the value on.
+ */
+int lvm_pv_params_set_property(pv_create_params_t params, const char *name,
+ struct lvm_property_value *prop);
+/**
+ * Creates a physical volume using the supplied params object.
+ *
+ * \param params The parameters to use for physical volume creation
+ *
+ * \return
+ * -1 on error, 0 on success.
+ */
+int lvm_pv_create_adv(pv_create_params_t params);
+
+/**
* Remove a physical volume.
* Note: You cannot remove a PV while iterating through the list of PVs as
* locks are held for the PV list.
diff --git a/liblvm/lvm_lv.c b/liblvm/lvm_lv.c
index 46399e4..938a16b 100644
--- a/liblvm/lvm_lv.c
+++ b/liblvm/lvm_lv.c
@@ -71,13 +71,13 @@ const char *lvm_lv_get_origin(const lv_t lv)
struct lvm_property_value lvm_lv_get_property(const lv_t lv, const char *name)
{
- return get_property(NULL, NULL, lv, NULL, NULL, NULL, name);
+ return get_property(NULL, NULL, lv, NULL, NULL, NULL, NULL, name);
}
struct lvm_property_value lvm_lvseg_get_property(const lvseg_t lvseg,
const char *name)
{
- return get_property(NULL, NULL, NULL, lvseg, NULL, NULL, name);
+ return get_property(NULL, NULL, NULL, lvseg, NULL, NULL, NULL, name);
}
uint64_t lvm_lv_is_active(const lv_t lv)
@@ -598,7 +598,7 @@ struct lvm_property_value lvm_lv_params_get_property(
};
if (params && params->magic == LV_CREATE_PARAMS_MAGIC) {
- rc = get_property(NULL, NULL, NULL, NULL, NULL, ¶ms->lvp, name);
+ rc = get_property(NULL, NULL, NULL, NULL, NULL, ¶ms->lvp, NULL, name);
} else {
log_error("Invalid lv_create_params parameter");
}
@@ -612,7 +612,7 @@ int lvm_lv_params_set_property(lv_create_params_t params, const char *name,
int rc = -1;
if (params && params->magic == LV_CREATE_PARAMS_MAGIC) {
- rc = set_property(NULL, NULL, NULL, ¶ms->lvp, name, prop);
+ rc = set_property(NULL, NULL, NULL, ¶ms->lvp, NULL, name, prop);
} else {
log_error("Invalid lv_create_params parameter");
}
diff --git a/liblvm/lvm_misc.c b/liblvm/lvm_misc.c
index c79af8f..ba77010 100644
--- a/liblvm/lvm_misc.c
+++ b/liblvm/lvm_misc.c
@@ -51,6 +51,7 @@ struct lvm_property_value get_property(const pv_t pv, const vg_t vg,
const lvseg_t lvseg,
const pvseg_t pvseg,
const struct lvcreate_params *lvcp,
+ const struct pvcreate_params *pvcp,
const char *name)
{
struct lvm_property_type prop;
@@ -76,6 +77,9 @@ struct lvm_property_value get_property(const pv_t pv, const vg_t vg,
} else if (lvcp) {
if (!lv_create_param_get_property(lvcp, &prop))
return v;
+ } else if (pvcp) {
+ if (!pv_create_param_get_property(pvcp, &prop))
+ return v;
} else {
log_errno(EINVAL, "Invalid NULL handle passed to library function.");
return v;
@@ -95,6 +99,7 @@ struct lvm_property_value get_property(const pv_t pv, const vg_t vg,
int set_property(const pv_t pv, const vg_t vg, const lv_t lv,
struct lvcreate_params *lvcp,
+ struct pvcreate_params *pvcp,
const char *name,
struct lvm_property_value *v)
{
@@ -125,6 +130,11 @@ int set_property(const pv_t pv, const vg_t vg, const lv_t lv,
v->is_valid = 0;
return -1;
}
+ } else if (pvcp) {
+ if (!pv_create_param_set_property(pvcp, &prop)) {
+ v->is_valid = 0;
+ return -1;
+ }
} else {
return -1;
}
diff --git a/liblvm/lvm_misc.h b/liblvm/lvm_misc.h
index a84125a..b187021 100644
--- a/liblvm/lvm_misc.h
+++ b/liblvm/lvm_misc.h
@@ -16,14 +16,19 @@
#include "libdevmapper.h"
#include "lvm2app.h"
+#include "metadata-exported.h"
struct dm_list *tag_list_copy(struct dm_pool *p, struct dm_list *tag_list);
struct lvm_property_value get_property(const pv_t pv, const vg_t vg,
const lv_t lv, const lvseg_t lvseg,
- const pvseg_t pvseg, const struct lvcreate_params *lvcp,
+ const pvseg_t pvseg,
+ const struct lvcreate_params *lvcp,
+ const struct pvcreate_params *pvcp,
const char *name);
int set_property(const pv_t pv, const vg_t vg, const lv_t lv,
- struct lvcreate_params *lvcp, const char *name,
+ struct lvcreate_params *lvcp,
+ struct pvcreate_params *pvcp,
+ const char *name,
struct lvm_property_value *value);
#endif
diff --git a/liblvm/lvm_prop.c b/liblvm/lvm_prop.c
index e25f03b..cbbd6f5 100644
--- a/liblvm/lvm_prop.c
+++ b/liblvm/lvm_prop.c
@@ -21,6 +21,25 @@
GET_LVCREATEPARAMS_NUM_PROPERTY_FN(skip_zero, lvcp->zero)
SET_LVCREATEPARAMS_NUM_PROPERTY_FN(skip_zero, lvcp->zero)
+/* PV create parameters */
+GET_PVCREATEPARAMS_NUM_PROPERTY_FN(size, pvcp->size)
+SET_PVCREATEPARAMS_NUM_PROPERTY_FN(size, pvcp->size)
+
+GET_PVCREATEPARAMS_NUM_PROPERTY_FN(pvmetadatacopies, pvcp->pvmetadatacopies)
+SET_PVCREATEPARAMS_NUM_PROPERTY_FN(pvmetadatacopies, pvcp->pvmetadatacopies)
+
+GET_PVCREATEPARAMS_NUM_PROPERTY_FN(pvmetadatasize, pvcp->pvmetadatasize)
+SET_PVCREATEPARAMS_NUM_PROPERTY_FN(pvmetadatasize, pvcp->pvmetadatasize)
+
+GET_PVCREATEPARAMS_NUM_PROPERTY_FN(data_alignment, pvcp->data_alignment)
+SET_PVCREATEPARAMS_NUM_PROPERTY_FN(data_alignment, pvcp->data_alignment)
+
+GET_PVCREATEPARAMS_NUM_PROPERTY_FN(data_alignment_offset, pvcp->data_alignment_offset)
+SET_PVCREATEPARAMS_NUM_PROPERTY_FN(data_alignment_offset, pvcp->data_alignment_offset)
+
+GET_PVCREATEPARAMS_NUM_PROPERTY_FN(zero, pvcp->zero)
+SET_PVCREATEPARAMS_NUM_PROPERTY_FN(zero, pvcp->zero)
+
struct lvm_property_type _lib_properties[] = {
#include "lvm_prop_fields.h"
{ 0, "", 0, 0, 0, { .integer = 0 }, prop_not_implemented_get,
@@ -42,3 +61,15 @@ int lv_create_param_set_property(struct lvcreate_params *lvcp,
{
return prop_set_property(_lib_properties, lvcp, prop, LV_CREATE_PARAMS);
}
+
+int pv_create_param_get_property(const struct pvcreate_params *pvcp,
+ struct lvm_property_type *prop)
+{
+ return prop_get_property(_lib_properties, pvcp, prop, PV_CREATE_PARAMS);
+}
+
+int pv_create_param_set_property(struct pvcreate_params *pvcp,
+ struct lvm_property_type *prop)
+{
+ return prop_set_property(_lib_properties, pvcp, prop, PV_CREATE_PARAMS);
+}
diff --git a/liblvm/lvm_prop.h b/liblvm/lvm_prop.h
index bedc078..db4cf8a 100644
--- a/liblvm/lvm_prop.h
+++ b/liblvm/lvm_prop.h
@@ -17,8 +17,10 @@
#define _LIB_LVM_PROP_H
typedef struct lvcreate_params type_lvcreate_params;
+typedef struct pvcreate_params type_pvcreate_params;
#define LV_CREATE_PARAMS 1
+#define PV_CREATE_PARAMS 2
#define GET_LVCREATEPARAMS_NUM_PROPERTY_FN(NAME, VALUE)\
GET_NUM_PROPERTY_FN(NAME, VALUE, lvcreate_params, lvcp)
@@ -26,10 +28,22 @@ typedef struct lvcreate_params type_lvcreate_params;
#define SET_LVCREATEPARAMS_NUM_PROPERTY_FN(NAME, VALUE) \
SET_NUM_PROPERTY(NAME, VALUE, lvcreate_params, lvcp)
+#define GET_PVCREATEPARAMS_NUM_PROPERTY_FN(NAME, VALUE)\
+ GET_NUM_PROPERTY_FN(NAME, VALUE, pvcreate_params, pvcp)
+
+#define SET_PVCREATEPARAMS_NUM_PROPERTY_FN(NAME, VALUE) \
+ SET_NUM_PROPERTY(NAME, VALUE, pvcreate_params, pvcp)
+
int lv_create_param_get_property(const struct lvcreate_params *lvcp,
struct lvm_property_type *prop);
int lv_create_param_set_property(struct lvcreate_params *lvcp,
struct lvm_property_type *prop);
+int pv_create_param_get_property(const struct pvcreate_params *pvcp,
+ struct lvm_property_type *prop);
+
+int pv_create_param_set_property(struct pvcreate_params *pvcp,
+ struct lvm_property_type *prop);
+
#endif
diff --git a/liblvm/lvm_prop_fields.h b/liblvm/lvm_prop_fields.h
index 99c322d..ba7dd18 100644
--- a/liblvm/lvm_prop_fields.h
+++ b/liblvm/lvm_prop_fields.h
@@ -13,3 +13,10 @@
*/
FIELD(LV_CREATE_PARAMS, lvcreate_params, NUM, "skip_zero", zero, 2, uint32, skip_zero, "Skip zeroing on lv creation", 1)
+
+FIELD(PV_CREATE_PARAMS, pvcreate_params, NUM, "size", size, 2, uint64_t, size, "PV size", 1)
+FIELD(PV_CREATE_PARAMS, pvcreate_params, NUM, "pvmetadatacopies", pvmetadatacopies, 2, uint64_t, pvmetadatacopies, "PV Metadata copies", 1)
+FIELD(PV_CREATE_PARAMS, pvcreate_params, NUM, "pvmetadatasize", pvmetadatasize, 2, uint64_t, pvmetadatasize, "PV Metadata size", 1)
+FIELD(PV_CREATE_PARAMS, pvcreate_params, NUM, "data_alignment", data_alignment, 2, uint64_t, data_alignment, "Start data to a multiple of value", 1)
+FIELD(PV_CREATE_PARAMS, pvcreate_params, NUM, "data_alignment_offset", data_alignment_offset, 2, uint64_t, data_alignment_offset, "Shift the start of the data area", 1)
+FIELD(PV_CREATE_PARAMS, pvcreate_params, NUM, "zero", zero, 2, uint64_t, zero, "Zero first 2048 bytes of device", 1)
diff --git a/liblvm/lvm_pv.c b/liblvm/lvm_pv.c
index e67e1eb..d540a6c 100644
--- a/liblvm/lvm_pv.c
+++ b/liblvm/lvm_pv.c
@@ -21,6 +21,16 @@
#include "locking.h"
#include "toolcontext.h"
+struct lvm_pv_create_params
+{
+ uint32_t magic;
+ lvm_t libh;
+ const char *pv_name;
+ struct pvcreate_params pv_p;
+};
+
+#define PV_CREATE_PARAMS_MAGIC 0xFEED0002
+
const char *lvm_pv_get_uuid(const pv_t pv)
{
return pv_uuid_dup(pv);
@@ -53,13 +63,13 @@ uint64_t lvm_pv_get_free(const pv_t pv)
struct lvm_property_value lvm_pv_get_property(const pv_t pv, const char *name)
{
- return get_property(pv, NULL, NULL, NULL, NULL, NULL, name);
+ return get_property(pv, NULL, NULL, NULL, NULL, NULL, NULL, name);
}
struct lvm_property_value lvm_pvseg_get_property(const pvseg_t pvseg,
const char *name)
{
- return get_property(NULL, NULL, NULL, NULL, pvseg, NULL, name);
+ return get_property(NULL, NULL, NULL, NULL, pvseg, NULL, NULL, name);
}
struct lvm_list_wrapper
@@ -80,6 +90,8 @@ int lvm_pv_remove(lvm_t libh, const char *pv_name)
return 0;
}
+#define PV_LIST_MAGIC 0xF005BA11
+
struct dm_list *lvm_list_pvs(lvm_t libh)
{
struct lvm_list_wrapper *rc = NULL;
@@ -109,7 +121,7 @@ struct dm_list *lvm_list_pvs(lvm_t libh)
* pointer in the free call.
*/
rc->cmd = cmd;
- rc->magic = 0xF005BA11;
+ rc->magic = PV_LIST_MAGIC;
}
return &rc->pvslist;
@@ -123,7 +135,7 @@ int lvm_list_pvs_free(struct dm_list *pvlist)
if (pvlist) {
to_delete = dm_list_struct_base(pvlist, struct lvm_list_wrapper, pvslist);
- if (to_delete->magic != 0xF005BA11) {
+ if (to_delete->magic != PV_LIST_MAGIC) {
log_errno(EINVAL, "Not a correct pvlist structure");
return -1;
}
@@ -224,26 +236,122 @@ int lvm_pv_resize(const pv_t pv, uint64_t new_size)
return 0;
}
-int lvm_pv_create(lvm_t libh, const char *pv_name, uint64_t size)
+/*
+ * Common internal code to create a parameter passing object
+ */
+static struct lvm_pv_create_params *_lvm_pv_params_create(
+ lvm_t libh,
+ const char *pv_name,
+ struct lvm_pv_create_params *pvcp_in)
{
- struct pvcreate_params pp;
+ struct lvm_pv_create_params *pvcp = NULL;
+ const char *dev = NULL;
struct cmd_context *cmd = (struct cmd_context *)libh;
- uint64_t size_sectors = size;
- pvcreate_params_set_defaults(&pp);
+ if (!pv_name || strlen(pv_name) == 0) {
+ log_error("Invalid pv_name");
+ return NULL;
+ }
+
+ if (!pvcp_in) {
+ pvcp = dm_pool_zalloc(cmd->libmem, sizeof(struct lvm_pv_create_params));
+ } else {
+ pvcp = pvcp_in;
+ }
+
+ if (!pvcp) {
+ return NULL;
+ }
+
+ dev = dm_pool_strdup(cmd->libmem, pv_name);
+ if (!dev) {
+ return NULL;
+ }
+
+ pvcreate_params_set_defaults(&pvcp->pv_p);
+ pvcp->pv_p.yes = 1;
+ pvcp->pv_p.force = DONT_PROMPT;
+ pvcp->pv_name = dev;
+ pvcp->libh = libh;
+ pvcp->magic = PV_CREATE_PARAMS_MAGIC;
+
+ return pvcp;
+}
+
+pv_create_params_t lvm_pv_params_create(lvm_t libh, const char *pv_name)
+{
+ return _lvm_pv_params_create(libh, pv_name, NULL);
+}
- if (size_sectors != 0) {
- if (size_sectors % SECTOR_SIZE) {
+struct lvm_property_value lvm_pv_params_get_property(
+ const pv_create_params_t params,
+ const char *name)
+{
+ struct lvm_property_value rc = {
+ .is_valid = 0
+ };
+
+ if (params && params->magic == PV_CREATE_PARAMS_MAGIC) {
+ rc = get_property(NULL, NULL, NULL, NULL, NULL, NULL, ¶ms->pv_p,
+ name);
+ } else {
+ log_error("Invalid pv_create_params parameter");
+ }
+
+ return rc;
+}
+
+int lvm_pv_params_set_property(pv_create_params_t params, const char *name,
+ struct lvm_property_value *prop)
+{
+ int rc = -1;
+
+ if (params && params->magic == PV_CREATE_PARAMS_MAGIC) {
+ rc = set_property(NULL, NULL, NULL, NULL, ¶ms->pv_p, name, prop);
+ } else {
+ log_error("Invalid pv_create_params parameter");
+ }
+ return rc;
+}
+
+static int _pv_create(pv_create_params_t params)
+{
+ struct cmd_context *cmd = (struct cmd_context *)params->libh;
+
+ if (params->pv_p.size) {
+ if (params->pv_p.size % SECTOR_SIZE) {
log_errno(EINVAL, "Size not a multiple of 512");
return -1;
}
- size_sectors = size_sectors >> SECTOR_SHIFT;
+ params->pv_p.size = params->pv_p.size >> SECTOR_SHIFT;
}
- pp.size = size_sectors;
+ if (!pvcreate_single(cmd, params->pv_name, ¶ms->pv_p))
+ return -1;
+ return 0;
+}
+
+int lvm_pv_create(lvm_t libh, const char *pv_name, uint64_t size)
+{
+ struct lvm_pv_create_params pp;
- if (!pvcreate_single(cmd, pv_name, &pp))
+ if (!_lvm_pv_params_create(libh, pv_name, &pp))
return -1;
- return 0;
+ pp.pv_p.size = size;
+
+ return _pv_create(&pp);
+}
+
+int lvm_pv_create_adv(pv_create_params_t params)
+{
+ int rc = -1;
+
+ if (params && params->magic == PV_CREATE_PARAMS_MAGIC) {
+ rc = _pv_create(params);
+ } else {
+ log_error("Invalid pv_create_params parameter");
+ }
+
+ return rc;
}
diff --git a/liblvm/lvm_vg.c b/liblvm/lvm_vg.c
index 3f4968e..214f459 100644
--- a/liblvm/lvm_vg.c
+++ b/liblvm/lvm_vg.c
@@ -340,7 +340,7 @@ const char *lvm_vg_get_name(const vg_t vg)
struct lvm_property_value lvm_vg_get_property(const vg_t vg, const char *name)
{
- return get_property(NULL, vg, NULL, NULL, NULL, NULL, name);
+ return get_property(NULL, vg, NULL, NULL, NULL, NULL, NULL, name);
}
int lvm_vg_set_property(const vg_t vg, const char *name,
@@ -357,7 +357,7 @@ int lvm_vg_set_property(const vg_t vg, const char *name,
strlen(value->value.string) + 1);
}
- return set_property(NULL, vg, NULL, NULL, name, value);
+ return set_property(NULL, vg, NULL, NULL, NULL, name, value);
}
struct dm_list *lvm_list_vg_names(lvm_t libh)
diff --git a/tools/toollib.c b/tools/toollib.c
index 9a33e55..b3bfd1d 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1541,12 +1541,6 @@ int pvcreate_params_validate(struct cmd_context *cmd,
return 0;
}
- if (arg_count(cmd, pvmetadatacopies_ARG) &&
- arg_int_value(cmd, pvmetadatacopies_ARG, -1) > 2) {
- log_error("Metadatacopies may only be 0, 1 or 2");
- return 0;
- }
-
if (arg_count(cmd, metadataignore_ARG))
pp->metadataignore = arg_int_value(cmd, metadataignore_ARG,
DEFAULT_PVMETADATAIGNORE);
9 years, 4 months
master - python-lvm: Test case change for vg.reduce
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ec7f632ce08014...
Commit: ec7f632ce08014ca5ceb3ac6c92d834fb0b8c93e
Parent: 5074dcc896681494309c59830803b54a84429fd0
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Tue Sep 10 17:59:45 2013 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Nov 19 14:40:32 2013 -0600
python-lvm: Test case change for vg.reduce
Fix reduce as newly changed vg reduce fails when you
try to remove the last pv in the vg.
Signed-off-by: Tony Asleson <tasleson(a)redhat.com>
---
test/api/python_lvm_unit.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/test/api/python_lvm_unit.py b/test/api/python_lvm_unit.py
index bceb82c..eab9575 100755
--- a/test/api/python_lvm_unit.py
+++ b/test/api/python_lvm_unit.py
@@ -185,7 +185,7 @@ class TestLvm(unittest.TestCase):
for p in pvs:
pe_devices.append(p.getName())
- for pv in pe_devices:
+ for pv in pe_devices[:-1]:
vg.reduce(pv)
vg.remove()
9 years, 4 months