]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/volumes: fetch oldest clone entry
authorVenky Shankar <vshankar@redhat.com>
Tue, 3 Dec 2019 06:47:20 +0000 (01:47 -0500)
committerVenky Shankar <vshankar@redhat.com>
Fri, 31 Jan 2020 10:09:14 +0000 (05:09 -0500)
Signed-off-by: Venky Shankar <vshankar@redhat.com>
src/pybind/mgr/volumes/fs/fs_util.py
src/pybind/mgr/volumes/fs/operations/clone_index.py

index 3a1d392983da6c6a70c722e0c74a4b0920435fac..10deffae7982b2509d5dc4c76122643099c3b2c1 100644 (file)
@@ -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
index 2e25af1763fa8c93a011ffd0fe638bed1a4e8ed4..c15fb54c79a0b10ad745798bd2d80c1b23e66439 100644 (file)
@@ -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: