master - lvmdbustest.py: Improve concurrent test handling
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f91df163e21b283e652...
Commit: f91df163e21b283e652bc830b5af49a7bb3cf3fb
Parent: f961311436bda50b219f6d2909d8602e37148611
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Mon Oct 14 14:31:27 2019 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Wed Oct 30 10:38:40 2019 -0500
lvmdbustest.py: Improve concurrent test handling
Filter out LVs too, so that we can run more than 1 instance of the
unit test at the same time.
---
test/dbus/lvmdbustest.py | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py
index 64a126a..711b247 100755
--- a/test/dbus/lvmdbustest.py
+++ b/test/dbus/lvmdbustest.py
@@ -90,6 +90,9 @@ def _root_pv_name(res, pv_name):
if v.Vg.Name == vg_name:
pv = ClientProxy(bus, v.Vg.Pvs[0], interfaces=(PV_INT, ))
return _root_pv_name(res, pv.Pv.Name)
+def _prune_lvs(res, interface, vg_object_path):
+ lvs = [lv for lv in res[interface] if lv.LvCommon.Vg == vg_object_path]
+ res[interface] = lvs
def _prune(res, pv_filter):
@@ -106,11 +109,16 @@ def _prune(res, pv_filter):
vg_list = []
for v in res[VG_INT]:
- # Only need to validate one of the PVs is in the selection set
if v.Vg.Pvs[0] in pv_lookup:
vg_list.append(v)
+ for interface in \
+ [LV_INT, THINPOOL_INT, LV_COMMON_INT,
+ CACHE_POOL_INT, CACHE_LV_INT, VDOPOOL_INT]:
+ _prune_lvs(res, interface, v.object_path)
+
res[VG_INT] = vg_list
+
return res
@@ -134,7 +142,7 @@ def get_objects():
rc[interface].append(proxy)
# At this point we have a full population of everything, we now need to
- # prune the PV list and the VG list if we are using a sub selection
+ # prune the the objects if we are filtering PVs with a sub selection.
return _prune(rc, pv_device_list), bus
4 years, 5 months
master - lvmdbusd: Fix model inconsistency when LV loses interface
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4dcb36aba4160ffe9ae...
Commit: 4dcb36aba4160ffe9ae90c93642e717e813e4779
Parent: f56b21ae2c7667d69c050653d527f9071ef83ad5
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Thu Oct 10 16:53:10 2019 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Wed Oct 30 10:38:40 2019 -0500
lvmdbusd: Fix model inconsistency when LV loses interface
When a LV loses an interface it ends up getting removed and recreated.
This happens after the VGs have been processed and updated. Thus when
this happens we need to re-check the VGs.
---
daemons/lvmdbusd/fetch.py | 17 ++++++++++++++++-
1 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/daemons/lvmdbusd/fetch.py b/daemons/lvmdbusd/fetch.py
index e8f3521..b7eb8c8 100644
--- a/daemons/lvmdbusd/fetch.py
+++ b/daemons/lvmdbusd/fetch.py
@@ -29,11 +29,26 @@ def _main_thread_load(refresh=True, emit_signal=True):
refresh=refresh,
emit_signal=emit_signal,
cache_refresh=False)[1]
- num_total_changes += load_lvs(
+
+ lv_changes = load_lvs(
refresh=refresh,
emit_signal=emit_signal,
cache_refresh=False)[1]
+ num_total_changes += lv_changes
+
+ # When the LVs change it can cause another change in the VGs which is
+ # missed if we don't scan through the VGs again. We could achieve this
+ # the other way and re-scan the LVs, but in general there are more LVs than
+ # VGs, thus this should be more efficient. This happens when a LV interface
+ # changes causing the dbus object representing it to be removed and
+ # recreated.
+ if refresh and lv_changes > 0:
+ num_total_changes += load_vgs(
+ refresh=refresh,
+ emit_signal=emit_signal,
+ cache_refresh=False)[1]
+
return num_total_changes
4 years, 5 months
master - lvmdbusd: Bug fix for activate/deactivate
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f56b21ae2c7667d69c0...
Commit: f56b21ae2c7667d69c050653d527f9071ef83ad5
Parent: 9e15c83673436342a60b8f982e521eb32d972a0c
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Thu Oct 10 16:49:09 2019 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Wed Oct 30 10:38:40 2019 -0500
lvmdbusd: Bug fix for activate/deactivate
Prevent the daemon from stalling when it gets stuck on a y/n prompt.
---
daemons/lvmdbusd/cmdhandler.py | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/daemons/lvmdbusd/cmdhandler.py b/daemons/lvmdbusd/cmdhandler.py
index 67d4321..e0bb105 100644
--- a/daemons/lvmdbusd/cmdhandler.py
+++ b/daemons/lvmdbusd/cmdhandler.py
@@ -738,6 +738,7 @@ def activate_deactivate(op, name, activate, control_flags, options):
op += 'n'
cmd.append(op)
+ cmd.append("-y")
cmd.append(name)
return call(cmd)
4 years, 5 months
master - testlib.py: Add interface instance vars.
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=9e15c83673436342a60...
Commit: 9e15c83673436342a60b8f982e521eb32d972a0c
Parent: b7aab9ba594b9b627ec09b8e0dab5cd75e7178cf
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Thu Oct 10 09:01:27 2019 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Wed Oct 30 10:38:40 2019 -0500
testlib.py: Add interface instance vars.
---
test/dbus/testlib.py | 20 ++++++++++++++++----
1 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/test/dbus/testlib.py b/test/dbus/testlib.py
index ad2d93b..75a367d 100644
--- a/test/dbus/testlib.py
+++ b/test/dbus/testlib.py
@@ -243,10 +243,6 @@ class RemoteInterface(object):
class ClientProxy(object):
- Pv = None
- Lv = None
- Vg = None
- VgVdo = None
@staticmethod
def _intf_short_name(nm):
@@ -270,6 +266,22 @@ class ClientProxy(object):
def __init__(
self, bus, object_path, interface_prop_hash=None,
interfaces=None, timelimit=-1):
+ # Instance variables which may or may not get assigned during class
+ # construction dynamically. Assigned here so code inspection tools
+ # have knowledge of their existence.
+ self.Manager = None
+ self.Pv = None
+ self.Vg = None
+ self.Lv = None
+ self.VgVdo = None
+ self.ThinPool = None
+ self.VdoPool = None
+ self.SnapShot = None
+ self.LvCommon = None
+ self.Job = None
+ self.CachePool = None
+ self.CachedLv = None
+
self.object_path = object_path
self.short_interface_names = []
self.tmo = timelimit
4 years, 5 months
master - lvmdbustest.py: Add basic vdo test
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=89373761c808c211817...
Commit: 89373761c808c21181751d622e987b323355b677
Parent: ed7e365ae5a2b79bf14a3f9772e8e1f663bb6c4f
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Oct 9 16:55:39 2019 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Wed Oct 30 10:38:40 2019 -0500
lvmdbustest.py: Add basic vdo test
---
test/dbus/lvmdbustest.py | 54 +++++++++++++++++++++++++++++++++++++++++++++-
test/dbus/testlib.py | 1 +
2 files changed, 54 insertions(+), 1 deletions(-)
diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py
index 1d340df..f8842ef 100755
--- a/test/dbus/lvmdbustest.py
+++ b/test/dbus/lvmdbustest.py
@@ -176,6 +176,15 @@ def call_lvm(command):
return process.returncode, stdout_text, stderr_text
+def supports_vdo():
+ cmd = ['segtypes']
+ rc, out, err = call_lvm(cmd)
+ if rc == 0:
+ if "vdo" in out:
+ return True
+ return False
+
+
# noinspection PyUnresolvedReferences
class TestDbusService(unittest.TestCase):
def setUp(self):
@@ -198,6 +207,8 @@ class TestDbusService(unittest.TestCase):
for p in self.objs[PV_INT]:
self.pvs.append(p.Pv.Name)
+ self.vdo = supports_vdo()
+
def _recurse_vg_delete(self, vg_proxy, pv_proxy, nested_pv_hash):
for pv_device_name, t in nested_pv_hash.items():
@@ -320,7 +331,12 @@ class TestDbusService(unittest.TestCase):
self._validate_lookup(vg_name, vg_path)
self.assertTrue(vg_path is not None and len(vg_path) > 0)
- return ClientProxy(self.bus, vg_path, interfaces=(VG_INT, ))
+
+ intf = [VG_INT, ]
+ if self.vdo:
+ intf.append(VG_VDO_INT)
+
+ return ClientProxy(self.bus, vg_path, interfaces=intf)
def test_vg_create(self):
self._vg_create()
@@ -1776,6 +1792,42 @@ class TestDbusService(unittest.TestCase):
self.assertEqual(pv_object_path, self._lookup(symlink))
self.assertEqual(pv_object_path, self._lookup(pv_device_path))
+ def _create_vdo_pool_and_lv(self):
+ pool_name = lv_n("_vdo_pool")
+ lv_name = lv_n()
+
+ vg_proxy = self._vg_create()
+ vdo_pool_object_path = self.handle_return(
+ vg_proxy.VgVdo.CreateVdoPoolandLv(
+ pool_name, lv_name,
+ dbus.UInt64(mib(4096)),
+ dbus.UInt64(mib(8192)),
+ dbus.Int32(g_tmo),
+ EOD))
+
+ self.assertNotEqual(vdo_pool_object_path, "/")
+ self.assertEqual(
+ vdo_pool_object_path,
+ self._lookup("%s/%s" % (vg_proxy.Vg.Name, pool_name)))
+
+ vdo_lv = self._lookup("%s/%s" % (vg_proxy.Vg.Name, lv_name))
+ self.assertNotEqual(vdo_lv, "/")
+ intf = (LV_COMMON_INT, LV_INT, VDOPOOL_INT)
+ pool_lv = ClientProxy(self.bus, vdo_lv, interfaces=intf)
+ return vg_proxy, pool_lv
+
+ def test_vdo_pool_create(self):
+ # Basic vdo sanity testing
+ if not self.vdo:
+ raise unittest.SkipTest('vdo not supported')
+
+ # Do this twice to ensure we are providing the correct flags to force
+ # the operation when if finds an existing vdo signature, which likely
+ # shouldn't exist.
+ for _ in range(0, 2):
+ vg, _ = self._create_vdo_pool_and_lv()
+ self.handle_return(vg.Vg.Remove(dbus.Int32(g_tmo), EOD))
+
class AggregateResults(object):
diff --git a/test/dbus/testlib.py b/test/dbus/testlib.py
index e6655a5..bf88beb 100644
--- a/test/dbus/testlib.py
+++ b/test/dbus/testlib.py
@@ -243,6 +243,7 @@ class ClientProxy(object):
Pv = None
Lv = None
Vg = None
+ VgVdo = None
@staticmethod
def _intf_short_name(nm):
4 years, 5 months
master - testlib.py: WS corrections
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=b7aab9ba594b9b627ec...
Commit: b7aab9ba594b9b627ec09b8e0dab5cd75e7178cf
Parent: 89373761c808c21181751d622e987b323355b677
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Oct 9 19:59:44 2019 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Wed Oct 30 10:38:40 2019 -0500
testlib.py: WS corrections
---
test/dbus/testlib.py | 29 +++++++++++++++++------------
1 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/test/dbus/testlib.py b/test/dbus/testlib.py
index bf88beb..ad2d93b 100644
--- a/test/dbus/testlib.py
+++ b/test/dbus/testlib.py
@@ -169,8 +169,8 @@ class RemoteInterface(object):
if not props:
for _ in range(0, 3):
try:
- prop_interface = dbus.Interface(self.dbus_object,
- 'org.freedesktop.DBus.Properties')
+ prop_interface = dbus.Interface(
+ self.dbus_object, 'org.freedesktop.DBus.Properties')
props = prop_interface.GetAll(self.interface)
break
except dbus.exceptions.DBusException as dbe:
@@ -180,8 +180,9 @@ class RemoteInterface(object):
for kl, vl in list(props.items()):
# Verify type is correct!
if self.introspect:
- verify_type(vl, self.introspect[self.interface]
- ['properties'][kl]['p_type'])
+ verify_type(
+ vl, self.introspect[self.interface]
+ ['properties'][kl]['p_type'])
setattr(self, kl, vl)
@property
@@ -189,8 +190,8 @@ class RemoteInterface(object):
return self.dbus_object.object_path
def __init__(
- self, dbus_object, interface, introspect,
- properties=None, timelimit=-1):
+ self, dbus_object, interface,
+ introspect, properties=None, timelimit=-1):
self.dbus_object = dbus_object
self.interface = interface
self.introspect = introspect
@@ -203,6 +204,7 @@ class RemoteInterface(object):
self.dbus_interface = dbus.Interface(self.dbus_object, self.interface)
self._set_props(properties)
+ # noinspection PyTypeChecker
def __getattr__(self, item):
if hasattr(self.dbus_interface, item):
return functools.partial(self._wrapper, item)
@@ -221,8 +223,9 @@ class RemoteInterface(object):
if self.tmo > 0.0:
if diff > self.tmo:
- std_err_print("\n Time exceeded: %f > %f %s" %
- (diff, self.tmo, _method_name))
+ std_err_print(
+ "\n Time exceeded: %f > %f %s" %
+ (diff, self.tmo, _method_name))
if self.introspect:
if 'RETURN_VALUE' in self.introspect[
@@ -259,12 +262,14 @@ class ClientProxy(object):
def _common(self, interface, introspect, properties):
short_name = ClientProxy._intf_short_name(interface)
self.short_interface_names.append(short_name)
- ro = RemoteInterface(self.dbus_object, interface, introspect,
- properties, timelimit=self.tmo)
+ ro = RemoteInterface(
+ self.dbus_object, interface, introspect, properties,
+ timelimit=self.tmo)
setattr(self, short_name, ro)
- def __init__(self, bus, object_path, interface_prop_hash=None,
- interfaces=None, timelimit=-1):
+ def __init__(
+ self, bus, object_path, interface_prop_hash=None,
+ interfaces=None, timelimit=-1):
self.object_path = object_path
self.short_interface_names = []
self.tmo = timelimit
4 years, 5 months
master - lvmdbusd: VDO Pool LV representation
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=5971da2c72a6fe2d83f...
Commit: 5971da2c72a6fe2d83f65a7d6ea7f7bf68971dd8
Parent: 455498f206e60c513ce36083d1f336aad11e33f8
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Oct 9 07:49:58 2019 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Wed Oct 30 10:38:40 2019 -0500
lvmdbusd: VDO Pool LV representation
VDO pool LVs are represented by a new dbus interface VgVdo. Currently
the interface only has additional VDO properties, but when the
ability to support additional LV creation is added we can add a method
to the interface.
---
daemons/lvmdbusd/cfg.py | 3 +
daemons/lvmdbusd/cmdhandler.py | 16 ++++
daemons/lvmdbusd/lv.py | 148 ++++++++++++++++++++++++++++++++++-----
daemons/lvmdbusd/lvmdb.py.in | 14 +++-
daemons/lvmdbusd/main.py | 2 +-
daemons/lvmdbusd/utils.py | 33 ++++++++-
test/dbus/lvmdbustest.py | 5 +-
test/dbus/testlib.py | 5 ++
8 files changed, 197 insertions(+), 29 deletions(-)
diff --git a/daemons/lvmdbusd/cfg.py b/daemons/lvmdbusd/cfg.py
index b11d9f8..684c2b2 100644
--- a/daemons/lvmdbusd/cfg.py
+++ b/daemons/lvmdbusd/cfg.py
@@ -51,6 +51,7 @@ VG_VDO_INTERFACE = BASE_INTERFACE + '.VgVdo'
LV_INTERFACE = BASE_INTERFACE + '.Lv'
LV_COMMON_INTERFACE = BASE_INTERFACE + '.LvCommon'
THIN_POOL_INTERFACE = BASE_INTERFACE + '.ThinPool'
+VDO_POOL_INTERFACE = BASE_INTERFACE + '.VdoPool'
CACHE_POOL_INTERFACE = BASE_INTERFACE + '.CachePool'
LV_CACHED = BASE_INTERFACE + '.CachedLv'
SNAPSHOT_INTERFACE = BASE_INTERFACE + '.Snapshot'
@@ -62,6 +63,7 @@ PV_OBJ_PATH = BASE_OBJ_PATH + '/Pv'
VG_OBJ_PATH = BASE_OBJ_PATH + '/Vg'
LV_OBJ_PATH = BASE_OBJ_PATH + '/Lv'
THIN_POOL_PATH = BASE_OBJ_PATH + "/ThinPool"
+VDO_POOL_PATH = BASE_OBJ_PATH + "/VdoPool"
CACHE_POOL_PATH = BASE_OBJ_PATH + "/CachePool"
HIDDEN_LV_PATH = BASE_OBJ_PATH + "/HiddenLv"
MANAGER_OBJ_PATH = BASE_OBJ_PATH + '/Manager'
@@ -72,6 +74,7 @@ pv_id = itertools.count()
vg_id = itertools.count()
lv_id = itertools.count()
thin_id = itertools.count()
+vdo_id = itertools.count()
cache_pool_id = itertools.count()
job_id = itertools.count()
hidden_lv = itertools.count()
diff --git a/daemons/lvmdbusd/cmdhandler.py b/daemons/lvmdbusd/cmdhandler.py
index 137027b..67d4321 100644
--- a/daemons/lvmdbusd/cmdhandler.py
+++ b/daemons/lvmdbusd/cmdhandler.py
@@ -509,6 +509,22 @@ def lvm_full_report_json():
lv_seg_columns = ['seg_pe_ranges', 'segtype', 'lv_uuid']
+ if cfg.vdo_support:
+ lv_columns.extend(
+ ['vdo_operating_mode', 'vdo_compression_state', 'vdo_index_state',
+ 'vdo_used_size', 'vdo_saving_percent']
+ )
+
+ lv_seg_columns.extend(
+ ['vdo_compression', 'vdo_deduplication',
+ 'vdo_use_metadata_hints', 'vdo_minimum_io_size',
+ 'vdo_block_map_cache_size', 'vdo_block_map_era_length',
+ 'vdo_use_sparse_index', 'vdo_index_memory_size',
+ 'vdo_slab_size', 'vdo_ack_threads', 'vdo_bio_threads',
+ 'vdo_bio_rotation', 'vdo_cpu_threads', 'vdo_hash_zone_threads',
+ 'vdo_logical_threads', 'vdo_physical_threads',
+ 'vdo_max_discard', 'vdo_write_policy', 'vdo_header_size'])
+
cmd = _dc('fullreport', [
'-a', # Need hidden too
'--configreport', 'pv', '-o', ','.join(pv_columns),
diff --git a/daemons/lvmdbusd/lv.py b/daemons/lvmdbusd/lv.py
index 9290c19..3018749 100644
--- a/daemons/lvmdbusd/lv.py
+++ b/daemons/lvmdbusd/lv.py
@@ -15,9 +15,9 @@ import dbus
from . import cmdhandler
from . import cfg
from .cfg import LV_INTERFACE, THIN_POOL_INTERFACE, SNAPSHOT_INTERFACE, \
- LV_COMMON_INTERFACE, CACHE_POOL_INTERFACE, LV_CACHED
+ LV_COMMON_INTERFACE, CACHE_POOL_INTERFACE, LV_CACHED, VDO_POOL_INTERFACE
from .request import RequestEntry
-from .utils import n, n32
+from .utils import n, n32, d
from .loader import common
from .state import State
from . import background
@@ -74,23 +74,66 @@ def lvs_state_retrieve(selection, cache_refresh=True):
lvs = sorted(cfg.db.fetch_lvs(selection), key=get_key)
for l in lvs:
- rc.append(LvState(
- l['lv_uuid'], l['lv_name'],
- l['lv_path'], n(l['lv_size']),
- l['vg_name'],
- l['vg_uuid'], l['pool_lv_uuid'],
- l['pool_lv'], l['origin_uuid'], l['origin'],
- n32(l['data_percent']), l['lv_attr'],
- l['lv_tags'], l['lv_active'], l['data_lv'],
- l['metadata_lv'], l['segtype'], l['lv_role'],
- l['lv_layout'],
- n32(l['snap_percent']),
- n32(l['metadata_percent']),
- n32(l['copy_percent']),
- n32(l['sync_percent']),
- n(l['lv_metadata_size']),
- l['move_pv'],
- l['move_pv_uuid']))
+ if cfg.vdo_support:
+ rc.append(LvStateVdo(
+ l['lv_uuid'], l['lv_name'],
+ l['lv_path'], n(l['lv_size']),
+ l['vg_name'],
+ l['vg_uuid'], l['pool_lv_uuid'],
+ l['pool_lv'], l['origin_uuid'], l['origin'],
+ n32(l['data_percent']), l['lv_attr'],
+ l['lv_tags'], l['lv_active'], l['data_lv'],
+ l['metadata_lv'], l['segtype'], l['lv_role'],
+ l['lv_layout'],
+ n32(l['snap_percent']),
+ n32(l['metadata_percent']),
+ n32(l['copy_percent']),
+ n32(l['sync_percent']),
+ n(l['lv_metadata_size']),
+ l['move_pv'],
+ l['move_pv_uuid'],
+ l['vdo_operating_mode'],
+ l['vdo_compression_state'],
+ l['vdo_index_state'],
+ n(l['vdo_used_size']),
+ d(l['vdo_saving_percent']),
+ l['vdo_compression'],
+ l['vdo_deduplication'],
+ l['vdo_use_metadata_hints'],
+ n32(l['vdo_minimum_io_size']),
+ n(l['vdo_block_map_cache_size']),
+ n32(l['vdo_block_map_era_length']),
+ l['vdo_use_sparse_index'],
+ n(l['vdo_index_memory_size']),
+ n(l['vdo_slab_size']),
+ n32(l['vdo_ack_threads']),
+ n32(l['vdo_bio_threads']),
+ n32(l['vdo_bio_rotation']),
+ n32(l['vdo_cpu_threads']),
+ n32(l['vdo_hash_zone_threads']),
+ n32(l['vdo_logical_threads']),
+ n32(l['vdo_physical_threads']),
+ n32(l['vdo_max_discard']),
+ l['vdo_write_policy'],
+ n32(l['vdo_header_size'])))
+ else:
+ rc.append(LvState(
+ l['lv_uuid'], l['lv_name'],
+ l['lv_path'], n(l['lv_size']),
+ l['vg_name'],
+ l['vg_uuid'], l['pool_lv_uuid'],
+ l['pool_lv'], l['origin_uuid'], l['origin'],
+ n32(l['data_percent']), l['lv_attr'],
+ l['lv_tags'], l['lv_active'], l['data_lv'],
+ l['metadata_lv'], l['segtype'], l['lv_role'],
+ l['lv_layout'],
+ n32(l['snap_percent']),
+ n32(l['metadata_percent']),
+ n32(l['copy_percent']),
+ n32(l['sync_percent']),
+ n(l['lv_metadata_size']),
+ l['move_pv'],
+ l['move_pv_uuid']))
return rc
@@ -194,6 +237,8 @@ class LvState(State):
def _object_type_create(self):
if self.Attr[0] == 't':
return LvThinPool
+ elif self.Attr[0] == 'd':
+ return LvVdoPool
elif self.Attr[0] == 'C':
if 'pool' in self.layout:
return LvCachePool
@@ -220,6 +265,34 @@ class LvState(State):
return (klass, path_method)
+class LvStateVdo(LvState):
+
+ def __init__(self, Uuid, Name, Path, SizeBytes,
+ vg_name, vg_uuid, pool_lv_uuid, PoolLv,
+ origin_uuid, OriginLv, DataPercent, Attr, Tags, active,
+ data_lv, metadata_lv, segtypes, role, layout, SnapPercent,
+ MetaDataPercent, CopyPercent, SyncPercent,
+ MetaDataSizeBytes, move_pv, move_pv_uuid,
+ vdo_operating_mode, vdo_compression_state, vdo_index_state,
+ vdo_used_size,vdo_saving_percent,vdo_compression,
+ vdo_deduplication,vdo_use_metadata_hints,
+ vdo_minimum_io_size,vdo_block_map_cache_size,
+ vdo_block_map_era_length,vdo_use_sparse_index,
+ vdo_index_memory_size,vdo_slab_size,vdo_ack_threads,
+ vdo_bio_threads,vdo_bio_rotation,vdo_cpu_threads,
+ vdo_hash_zone_threads,vdo_logical_threads,
+ vdo_physical_threads,vdo_max_discard,
+ vdo_write_policy,vdo_header_size):
+ super(LvStateVdo, self).__init__(Uuid, Name, Path, SizeBytes,
+ vg_name, vg_uuid, pool_lv_uuid, PoolLv,
+ origin_uuid, OriginLv, DataPercent, Attr, Tags, active,
+ data_lv, metadata_lv, segtypes, role, layout, SnapPercent,
+ MetaDataPercent, CopyPercent, SyncPercent,
+ MetaDataSizeBytes, move_pv, move_pv_uuid)
+
+ utils.init_class_from_arguments(self, "vdo_", snake_to_pascal=True)
+
+
# noinspection PyPep8Naming
@utils.dbus_property(LV_COMMON_INTERFACE, 'Uuid', 's')
@utils.dbus_property(LV_COMMON_INTERFACE, 'Name', 's')
@@ -670,6 +743,43 @@ class Lv(LvCommon):
cb, cbe, return_tuple=False)
cfg.worker_q.put(r)
+# noinspection PyPep8Naming
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'OperatingMode', 's')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'CompressionState', 's')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'IndexState', 's')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'UsedSize', 't')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'SavingPercent', 'd')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'Compression', 's')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'Deduplication', 's')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'UseMetadataHints', 's')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'MinimumIoSize', 'u')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'BlockMapCacheSize', "t")
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'BlockMapEraLength', 'u')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'UseSparseIndex', 's')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'IndexMemorySize', 't')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'SlabSize', 't')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'AckThreads', 'u')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'BioThreads', 'u')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'BioRotation', 'u')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'CpuThreads', 'u')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'HashZoneThreads', 'u')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'LogicalThreads', 'u')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'PhysicalThreads', 'u')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'MaxDiscard', 'u')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'WritePolicy', 's')
+(a)utils.dbus_property(VDO_POOL_INTERFACE, 'HeaderSize', 'u')
+class LvVdoPool(Lv):
+ _DataLv_meta = ("o", VDO_POOL_INTERFACE)
+
+ def __init__(self, object_path, object_state):
+ super(LvVdoPool, self).__init__(object_path, object_state)
+ self.set_interface(VDO_POOL_INTERFACE)
+ self._data_lv, _ = self._get_data_meta()
+
+ @property
+ def DataLv(self):
+ return dbus.ObjectPath(self._data_lv)
+
# noinspection PyPep8Naming
class LvThinPool(Lv):
diff --git a/daemons/lvmdbusd/lvmdb.py.in b/daemons/lvmdbusd/lvmdb.py.in
index 0155d90..2e7aba9 100644
--- a/daemons/lvmdbusd/lvmdb.py.in
+++ b/daemons/lvmdbusd/lvmdb.py.in
@@ -20,7 +20,7 @@ from lvmdbusd.utils import log_debug, log_error
class DataStore(object):
- def __init__(self, usejson=True):
+ def __init__(self, usejson=True, vdo_support=False):
self.pvs = {}
self.vgs = {}
self.lvs = {}
@@ -43,6 +43,8 @@ class DataStore(object):
else:
self.json = usejson
+ self.vdo_support = vdo_support
+
@staticmethod
def _insert_record(table, key, record, allowed_multiple):
if key in table:
@@ -241,8 +243,7 @@ class DataStore(object):
return DataStore._parse_lvs_common(c_lvs, c_lv_full_lookup)
- @staticmethod
- def _parse_lvs_json(_all):
+ def _parse_lvs_json(self, _all):
c_lvs = OrderedDict()
c_lv_full_lookup = {}
@@ -262,8 +263,13 @@ class DataStore(object):
if 'seg' in r:
for s in r['seg']:
r = c_lvs[s['lv_uuid']]
- r.setdefault('seg_pe_ranges', []).append(s['seg_pe_ranges'])
+ r.setdefault('seg_pe_ranges', []).\
+ append(s['seg_pe_ranges'])
r.setdefault('segtype', []).append(s['segtype'])
+ if self.vdo_support:
+ for seg_key, seg_val in s.items():
+ if seg_key.startswith("vdo_"):
+ r[seg_key] = seg_val
return DataStore._parse_lvs_common(c_lvs, c_lv_full_lookup)
diff --git a/daemons/lvmdbusd/main.py b/daemons/lvmdbusd/main.py
index c128535..9988143 100644
--- a/daemons/lvmdbusd/main.py
+++ b/daemons/lvmdbusd/main.py
@@ -155,7 +155,7 @@ def main():
cfg.om = Lvm(BASE_OBJ_PATH)
cfg.om.register_object(Manager(MANAGER_OBJ_PATH))
- cfg.db = lvmdb.DataStore(cfg.args.use_json)
+ cfg.db = lvmdb.DataStore(cfg.args.use_json, cfg.vdo_support)
# Using a thread to process requests, we cannot hang the dbus library
# thread that is handling the dbus interface
diff --git a/daemons/lvmdbusd/utils.py b/daemons/lvmdbusd/utils.py
index 40b8a68..66dfbd6 100644
--- a/daemons/lvmdbusd/utils.py
+++ b/daemons/lvmdbusd/utils.py
@@ -66,8 +66,20 @@ def n32(v):
return int(float(v))
+(a)rtype(dbus.Double)
+def d(v):
+ if not v:
+ return 0.0
+ return float(v)
+
+
+def _snake_to_pascal(s):
+ return ''.join(x.title() for x in s.split('_'))
+
+
# noinspection PyProtectedMember
-def init_class_from_arguments(obj_instance):
+def init_class_from_arguments(
+ obj_instance, begin_suffix=None, snake_to_pascal=False):
for k, v in list(sys._getframe(1).f_locals.items()):
if k != 'self':
nt = k
@@ -78,8 +90,17 @@ def init_class_from_arguments(obj_instance):
cur = getattr(obj_instance, nt, v)
# print 'Init class %s = %s' % (nt, str(v))
- if not (cur and len(str(cur)) and (v is None or len(str(v))) == 0):
- setattr(obj_instance, nt, v)
+ if not (cur and len(str(cur)) and (v is None or len(str(v))) == 0)\
+ and (begin_suffix is None or nt.startswith(begin_suffix)):
+
+ if begin_suffix and nt.startswith(begin_suffix):
+ name = nt[len(begin_suffix):]
+ if snake_to_pascal:
+ name = _snake_to_pascal(name)
+
+ setattr(obj_instance, name, v)
+ else:
+ setattr(obj_instance, nt, v)
def get_properties(f):
@@ -347,6 +368,8 @@ def lv_object_path_method(name, meta):
return _hidden_lv_obj_path_generate
elif meta[0][0] == 't':
return _thin_pool_obj_path_generate
+ elif meta[0][0] == 'd':
+ return _vdo_pool_object_path_generate
elif meta[0][0] == 'C' and 'pool' in meta[1]:
return _cache_pool_obj_path_generate
@@ -364,6 +387,10 @@ def _thin_pool_obj_path_generate():
return cfg.THIN_POOL_PATH + "/%d" % next(cfg.thin_id)
+def _vdo_pool_object_path_generate():
+ return cfg.VDO_POOL_PATH + "/%d" % next(cfg.vdo_id)
+
+
def _cache_pool_obj_path_generate():
return cfg.CACHE_POOL_PATH + "/%d" % next(cfg.cache_pool_id)
diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py
index aed5511..1d340df 100755
--- a/test/dbus/lvmdbustest.py
+++ b/test/dbus/lvmdbustest.py
@@ -71,7 +71,8 @@ def lv_n(suffix=None):
def _is_testsuite_pv(pv_name):
- return g_prefix != "" and pv_name[-1].isdigit() and pv_name[:-1].endswith(g_prefix + "pv")
+ return g_prefix != "" and pv_name[-1].isdigit() and \
+ pv_name[:-1].endswith(g_prefix + "pv")
def is_nested_pv(pv_name):
@@ -114,7 +115,7 @@ def get_objects():
rc = {
MANAGER_INT: [], PV_INT: [], VG_INT: [], LV_INT: [],
THINPOOL_INT: [], JOB_INT: [], SNAPSHOT_INT: [], LV_COMMON_INT: [],
- CACHE_POOL_INT: [], CACHE_LV_INT: [], VG_VDO_INT: []}
+ CACHE_POOL_INT: [], CACHE_LV_INT: [], VG_VDO_INT: [], VDOPOOL_INT: []}
object_manager_object = bus.get_object(
BUS_NAME, "/com/redhat/lvmdbus1", introspect=False)
diff --git a/test/dbus/testlib.py b/test/dbus/testlib.py
index 872ed80..0335f47 100644
--- a/test/dbus/testlib.py
+++ b/test/dbus/testlib.py
@@ -27,6 +27,7 @@ VG_INT = BASE_INTERFACE + ".Vg"
VG_VDO_INT = BASE_INTERFACE + ".VgVdo"
LV_INT = BASE_INTERFACE + ".Lv"
THINPOOL_INT = BASE_INTERFACE + ".ThinPool"
+VDOPOOL_INT = BASE_INTERFACE + ".VdoPool"
SNAPSHOT_INT = BASE_INTERFACE + ".Snapshot"
LV_COMMON_INT = BASE_INTERFACE + ".LvCommon"
JOB_INT = BASE_INTERFACE + ".Job"
@@ -240,6 +241,10 @@ class RemoteInterface(object):
class ClientProxy(object):
+ Pv = None
+ Lv = None
+ Vg = None
+
@staticmethod
def _intf_short_name(nm):
return nm.split('.')[-1:][0]
4 years, 5 months
master - testlib.py: Correct dbus signature verification
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=ed7e365ae5a2b79bf14...
Commit: ed7e365ae5a2b79bf14a3f9772e8e1f663bb6c4f
Parent: 5971da2c72a6fe2d83f65a7d6ea7f7bf68971dd8
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Oct 9 16:53:34 2019 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Wed Oct 30 10:38:40 2019 -0500
testlib.py: Correct dbus signature verification
This allows us to fully verify introspection data matches what we are
getting.
---
test/dbus/testlib.py | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/test/dbus/testlib.py b/test/dbus/testlib.py
index 0335f47..e6655a5 100644
--- a/test/dbus/testlib.py
+++ b/test/dbus/testlib.py
@@ -145,6 +145,8 @@ def btsr(value):
return rc
elif t == dbus.Array:
rc = "a"
+ if hasattr(value, "signature"):
+ return rc + value.signature
for i in value:
rc += btsr(i)
break
@@ -157,12 +159,9 @@ def verify_type(value, dbus_str_rep):
actual_str_rep = btsr(value)
if dbus_str_rep != actual_str_rep:
- # print("%s ~= %s" % (dbus_str_rep, actual_str_rep))
- # Unless we have a full filled out type we won't match exactly
- if not dbus_str_rep.startswith(actual_str_rep):
- raise RuntimeError(
- "Incorrect type, expected= %s actual = %s object= %s" %
- (dbus_str_rep, actual_str_rep, str(type(value))))
+ raise RuntimeError(
+ "Incorrect type, expected= %s actual = %s object= %s" %
+ (dbus_str_rep, actual_str_rep, str(type(value))))
class RemoteInterface(object):
4 years, 5 months
master - lvmdbustest.py: Create common func. _create_cache_lv
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=455498f206e60c513ce...
Commit: 455498f206e60c513ce36083d1f336aad11e33f8
Parent: c786636afba068fc0f560b6dd1dd9dd532c35135
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Oct 9 12:29:52 2019 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Wed Oct 30 10:38:40 2019 -0500
lvmdbustest.py: Create common func. _create_cache_lv
---
test/dbus/lvmdbustest.py | 52 ++++++++++++++++++---------------------------
1 files changed, 21 insertions(+), 31 deletions(-)
diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py
index 0b7140a..aed5511 100755
--- a/test/dbus/lvmdbustest.py
+++ b/test/dbus/lvmdbustest.py
@@ -1424,22 +1424,25 @@ class TestDbusService(unittest.TestCase):
self.assertTrue(
'/com/redhat/lvmdbus1/CachePool' in cache_pool.object_path)
- def test_cache_lv_create(self):
+ def _create_cache_lv(self):
+ vg, cache_pool = self._create_cache_pool()
- for destroy_cache in [True, False]:
- vg, cache_pool = self._create_cache_pool()
+ lv_to_cache = self._create_lv(size=mib(8), vg=vg)
- lv_to_cache = self._create_lv(size=mib(8), vg=vg)
+ c_lv_path = self.handle_return(
+ cache_pool.CachePool.CacheLv(
+ dbus.ObjectPath(lv_to_cache.object_path),
+ dbus.Int32(g_tmo),
+ EOD))
- c_lv_path = self.handle_return(
- cache_pool.CachePool.CacheLv(
- dbus.ObjectPath(lv_to_cache.object_path),
- dbus.Int32(g_tmo),
- EOD))
+ intf = (LV_COMMON_INT, LV_INT, CACHE_LV_INT)
+ cached_lv = ClientProxy(self.bus, c_lv_path, interfaces=intf)
+ return vg, cache_pool, cached_lv
- intf = (LV_COMMON_INT, LV_INT, CACHE_LV_INT)
- cached_lv = ClientProxy(self.bus, c_lv_path, interfaces=intf)
+ def test_cache_lv_create(self):
+ for destroy_cache in [True, False]:
+ vg, _, cached_lv = self._create_cache_lv()
uncached_lv_path = self.handle_return(
cached_lv.CachedLv.DetachCachePool(
dbus.Boolean(destroy_cache),
@@ -1459,31 +1462,18 @@ class TestDbusService(unittest.TestCase):
internal state update.
:return:
"""
- vg, cache_pool = self._create_cache_pool()
-
- lv_to_cache = self._create_lv(size=mib(8), vg=vg)
-
- c_lv_path = self.handle_return(
- cache_pool.CachePool.CacheLv(
- dbus.ObjectPath(lv_to_cache.object_path),
- dbus.Int32(g_tmo),
- EOD))
+ def verify_cache_lv_count():
+ cur_objs, _ = get_objects()
+ self.assertEqual(len(cur_objs[CACHE_LV_INT]), 2)
+ self._check_consistency()
- # Make sure we only have expected # of cached LV
- cur_objs, _ = get_objects()
- self.assertEqual(len(cur_objs[CACHE_LV_INT]), 2)
+ _, _, cached_lv = self._create_cache_lv()
- intf = (LV_COMMON_INT, LV_INT, CACHE_LV_INT)
- cached_lv = ClientProxy(self.bus, c_lv_path, interfaces=intf)
+ verify_cache_lv_count()
new_name = 'renamed_' + cached_lv.LvCommon.Name
-
self.handle_return(
cached_lv.Lv.Rename(dbus.String(new_name), dbus.Int32(g_tmo), EOD))
-
- # Make sure we only have expected # of cached LV
- cur_objs, _ = get_objects()
- self.assertEqual(len(cur_objs[CACHE_LV_INT]), 2)
- self._check_consistency()
+ verify_cache_lv_count()
def test_vg_change(self):
vg_proxy = self._vg_create()
4 years, 5 months
master - lvmdbustest.py: Add nested helper function major_minor
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c786636afba068fc0f5...
Commit: c786636afba068fc0f560b6dd1dd9dd532c35135
Parent: e1d3a6c552e8d23837c17934a83c3925cd40252d
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Oct 9 11:48:00 2019 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Wed Oct 30 10:38:40 2019 -0500
lvmdbustest.py: Add nested helper function major_minor
---
test/dbus/lvmdbustest.py | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/test/dbus/lvmdbustest.py b/test/dbus/lvmdbustest.py
index a9d7fac..0b7140a 100755
--- a/test/dbus/lvmdbustest.py
+++ b/test/dbus/lvmdbustest.py
@@ -1316,6 +1316,10 @@ class TestDbusService(unittest.TestCase):
EOD))
def test_pv_scan(self):
+
+ def major_minor(d):
+ return (int(d.properties['MAJOR']), int(d.properties['MINOR']))
+
devices = TestDbusService._get_devices()
self.assertEqual(self._pv_scan(False, True, [], []), '/')
@@ -1327,8 +1331,7 @@ class TestDbusService(unittest.TestCase):
self.assertEqual(self._pv_scan(False, True, block_path, []), '/')
self._check_consistency()
- mm = [(int(d.properties['MAJOR']), int(d.properties['MINOR']))
- for d in devices]
+ mm = [major_minor(d) for d in devices]
self.assertEqual(self._pv_scan(False, True, block_path, mm), '/')
self._check_consistency()
4 years, 5 months