From 7ad14cf09b447fcdbfe76ac739971be8609aa862 Mon Sep 17 00:00:00 2001 From: Venky Shankar Date: Tue, 3 Dec 2019 01:47:20 -0500 Subject: [PATCH] mgr/volumes: fetch oldest clone entry Signed-off-by: Venky Shankar --- src/pybind/mgr/volumes/fs/fs_util.py | 14 ++++++++++++ .../mgr/volumes/fs/operations/clone_index.py | 22 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/pybind/mgr/volumes/fs/fs_util.py b/src/pybind/mgr/volumes/fs/fs_util.py index 3a1d392983d..10deffae798 100644 --- a/src/pybind/mgr/volumes/fs/fs_util.py +++ b/src/pybind/mgr/volumes/fs/fs_util.py @@ -71,6 +71,20 @@ def listdir(fs, dirpath): raise VolumeException(-e.args[0], e.args[1]) return dirs +def list_one_entry_at_a_time(fs, dirpath): + """ + Get a directory entry (one entry a time) + """ + try: + with fs.opendir(dirpath) as dir_handle: + d = fs.readdir(dir_handle) + while d: + if d.d_name not in (b".", b".."): + yield d + d = fs.readdir(dir_handle) + except cephfs.Error as e: + raise VolumeException(-e.args[0], e.args[1]) + def get_ancestor_xattr(fs, path, attr): """ Helper for reading layout information: if this xattr is missing diff --git a/src/pybind/mgr/volumes/fs/operations/clone_index.py b/src/pybind/mgr/volumes/fs/operations/clone_index.py index 2e25af1763f..c15fb54c79a 100644 --- a/src/pybind/mgr/volumes/fs/operations/clone_index.py +++ b/src/pybind/mgr/volumes/fs/operations/clone_index.py @@ -9,11 +9,13 @@ import cephfs from .index import Index from ..exception import IndexException, VolumeException +from ..fs_util import list_one_entry_at_a_time log = logging.getLogger(__name__) class CloneIndex(Index): SUB_GROUP_NAME = "clone" + PATH_MAX = 4096 @property def path(self): @@ -45,6 +47,26 @@ class CloneIndex(Index): except cephfs.Error as e: raise IndexException(-e.args[0], e.args[1]) + def get_oldest_clone_entry(self, exclude=[]): + min_ctime_entry = None + exclude_tracking_ids = [v[0] for v in exclude] + log.debug("excluded tracking ids: {0}".format(exclude_tracking_ids)) + for entry in list_one_entry_at_a_time(self.fs, self.path): + dname = entry.d_name + dpath = os.path.join(self.path, dname) + st = self.fs.lstat(dpath) + if dname not in exclude_tracking_ids and stat.S_ISLNK(st.st_mode): + if min_ctime_entry is None or st.st_ctime < min_ctime_entry[1].st_ctime: + min_ctime_entry = (dname, st) + if min_ctime_entry: + try: + linklen = min_ctime_entry[1].st_size + sink_path = self.fs.readlink(os.path.join(self.path, min_ctime_entry[0]), CloneIndex.PATH_MAX) + return (min_ctime_entry[0], sink_path[:linklen]) + except cephfs.Error as e: + raise IndexException(-e.args[0], e.args[1]) + return None + def create_clone_index(fs, vol_spec): clone_index = CloneIndex(fs, vol_spec) try: -- 2.39.5