]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/volumes: read volume metadata file using read_string
authorJohn Mulligan <jmulligan@redhat.com>
Tue, 12 Jul 2022 22:32:54 +0000 (18:32 -0400)
committerKotresh HR <khiremat@redhat.com>
Tue, 23 Aug 2022 04:46:50 +0000 (10:16 +0530)
The read_string method, available in Python 3.2 (we assume Python 3.6 as
our current minimum python versino), supports parsing a provided string
for ini-style configuration parameters. Refactoring the reading of the
config file from cephfs into a simple iterator function and then
providing it to the ConfigParser as a single string, allows us to avoid
using StringIO and  simplifies the refresh function.

Signed-off-by: John Mulligan <jmulligan@redhat.com>
(cherry picked from commit dc1b4aac90beb82fd994ad7fa8ccf3b72b9936ac)

src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py

index 665eec6b8a9c1670a3977c8140919d25eb550b16..5416315f5e21cc4f0df9a4d296728094400a4978 100644 (file)
@@ -19,6 +19,16 @@ from ...exception import MetadataMgrException
 
 log = logging.getLogger(__name__)
 
+
+def _conf_reader(fs, fd, offset=0, length=4096):
+    while True:
+        buf = fs.read(fd, offset, length)
+        offset += len(buf)
+        if not buf:
+            return
+        yield buf.decode('utf-8')
+
+
 class MetadataManager(object):
     GLOBAL_SECTION = "GLOBAL"
     USER_METADATA_SECTION   = "USER_METADATA"
@@ -31,8 +41,6 @@ class MetadataManager(object):
     CLONE_FAILURE_META_KEY_ERRNO = "errno"
     CLONE_FAILURE_META_KEY_ERROR_MSG = "error_msg"
 
-    MAX_IO_BYTES = 8 * 1024
-
     def __init__(self, fs, config_path, mode):
         self.fs = fs
         self.mode = mode
@@ -44,15 +52,11 @@ class MetadataManager(object):
 
     def refresh(self):
         fd = None
-        conf_data = StringIO()
-        log.debug("opening config {0}".format(self.config_path))
         try:
+            log.debug("opening config {0}".format(self.config_path))
             fd = self.fs.open(self.config_path, os.O_RDONLY)
-            while True:
-                data = self.fs.read(fd, -1, MetadataManager.MAX_IO_BYTES)
-                if not len(data):
-                    break
-                conf_data.write(data.decode('utf-8'))
+            cfg = ''.join(_conf_reader(self.fs, fd))
+            self.config.read_string(cfg, source=self.config_path)
         except UnicodeDecodeError:
             raise MetadataMgrException(-errno.EINVAL,
                     "failed to decode, erroneous metadata config '{0}'".format(self.config_path))
@@ -60,19 +64,12 @@ class MetadataManager(object):
             raise MetadataMgrException(-errno.ENOENT, "metadata config '{0}' not found".format(self.config_path))
         except cephfs.Error as e:
             raise MetadataMgrException(-e.args[0], e.args[1])
-        finally:
-            if fd is not None:
-                self.fs.close(fd)
-
-        conf_data.seek(0)
-        try:
-            if sys.version_info >= (3, 2):
-                self.config.read_file(conf_data)
-            else:
-                self.config.readfp(conf_data)
         except configparser.Error:
             raise MetadataMgrException(-errno.EINVAL, "failed to parse, erroneous metadata config "
                     "'{0}'".format(self.config_path))
+        finally:
+            if fd is not None:
+                self.fs.close(fd)
 
     def flush(self):
         # cull empty sections