[lvm-devel] master - lvmdbusd: VDO Pool LV representation
Tony Asleson
tasleson at sourceware.org
Wed Oct 30 15:44:57 UTC 2019
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=5971da2c72a6fe2d83f65a7d6ea7f7bf68971dd8
Commit: 5971da2c72a6fe2d83f65a7d6ea7f7bf68971dd8
Parent: 455498f206e60c513ce36083d1f336aad11e33f8
Author: Tony Asleson <tasleson at redhat.com>
AuthorDate: Wed Oct 9 07:49:58 2019 -0500
Committer: Tony Asleson <tasleson at 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
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'OperatingMode', 's')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'CompressionState', 's')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'IndexState', 's')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'UsedSize', 't')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'SavingPercent', 'd')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'Compression', 's')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'Deduplication', 's')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'UseMetadataHints', 's')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'MinimumIoSize', 'u')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'BlockMapCacheSize', "t")
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'BlockMapEraLength', 'u')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'UseSparseIndex', 's')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'IndexMemorySize', 't')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'SlabSize', 't')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'AckThreads', 'u')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'BioThreads', 'u')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'BioRotation', 'u')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'CpuThreads', 'u')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'HashZoneThreads', 'u')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'LogicalThreads', 'u')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'PhysicalThreads', 'u')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'MaxDiscard', 'u')
+ at utils.dbus_property(VDO_POOL_INTERFACE, 'WritePolicy', 's')
+ at 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))
+ at 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]
More information about the lvm-devel
mailing list