From: John Mulligan Date: Tue, 12 Jul 2022 22:33:07 +0000 (-0400) Subject: mgr/volumes: write volume metadata with shim class X-Git-Tag: v16.2.11~278^2~8 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=55a82a4edc5309ad4719387e546b77d575628cd5;p=ceph.git mgr/volumes: write volume metadata with shim class 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 (cherry picked from commit d06d8a1f5255b5da9106cd70acc0de99f89d2b96) --- diff --git a/src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py b/src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py index ac6a5a12c91..5ef8bb67682 100644 --- a/src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py +++ b/src/pybind/mgr/volumes/fs/operations/versions/metadata_manager.py @@ -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)