]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/volumes: write volume metadata with shim class
authorJohn Mulligan <jmulligan@redhat.com>
Tue, 12 Jul 2022 22:33:07 +0000 (18:33 -0400)
committerKotresh HR <khiremat@redhat.com>
Tue, 23 Aug 2022 04:46:50 +0000 (10:16 +0530)
Add a class that works a bit like a python file object so that we
can simplify the flush function. Providing a file-like object to
the ConfigParser's write function avoids unnecessary copies to
a StringIO object and makes the code easier to read.

With no more uses of StringIO, the StringIO imports are removed.

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

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

index 5416315f5e21cc4f0df9a4d296728094400a4978..8f9211804d71ed3e9011655220331a7477a0d1c5 100644 (file)
@@ -8,11 +8,6 @@ if sys.version_info >= (3, 2):
 else:
     import ConfigParser as configparser
 
-try:
-    from StringIO import StringIO
-except ImportError:
-    from io import StringIO
-
 import cephfs
 
 from ...exception import MetadataMgrException
@@ -29,6 +24,32 @@ def _conf_reader(fs, fd, offset=0, length=4096):
         yield buf.decode('utf-8')
 
 
+class _ConfigWriter:
+    def __init__(self, fs, fd):
+        self._fs = fs
+        self._fd = fd
+        self._wrote = 0
+
+    def write(self, value):
+        buf = value.encode('utf-8')
+        wrote = self._fs.write(self._fd, buf, -1)
+        self._wrote += wrote
+        return wrote
+
+    def fsync(self):
+        self._fs.fsync(self._fd, 0)
+
+    @property
+    def wrote(self):
+        return self._wrote
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_value, tb):
+        self._fs.close(self._fd)
+
+
 class MetadataManager(object):
     GLOBAL_SECTION = "GLOBAL"
     USER_METADATA_SECTION   = "USER_METADATA"
@@ -77,26 +98,15 @@ class MetadataManager(object):
             if len(self.config.items(section)) == 0:
                 self.config.remove_section(section)
 
-        conf_data = StringIO()
-        self.config.write(conf_data)
-        conf_data.seek(0)
 
-        fd = None
         try:
             fd = self.fs.open(self.config_path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, self.mode)
-            wrote = 0
-            while True:
-                data = conf_data.read()
-                if not len(data):
-                    break
-                wrote += self.fs.write(fd, data.encode('utf-8'), -1)
-            self.fs.fsync(fd, 0)
-            log.info("wrote {0} bytes to config {1}".format(wrote, self.config_path))
+            with _ConfigWriter(self.fs, fd) as cfg_writer:
+                self.config.write(cfg_writer)
+                cfg_writer.fsync()
+            log.info("wrote {0} bytes to config {1}".format(cfg_writer.wrote, 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)
 
     def init(self, version, typ, path, state):
         # you may init just once before refresh (helps to overwrite conf)