From 376638513d1792429653756c24788c913107732d Mon Sep 17 00:00:00 2001 From: cheng Date: Wed, 28 Sep 2016 18:03:31 +0000 Subject: [PATCH] Close connection to ceph after cinder bakcup If we don't close connection to ceph cluster, The connection count increases with cinder bakcup until exceed max open files. Then rise OSError: [Errno 24] Too many open files This patch is to close connection to ceph cluster after cinder backup. Change-Id: I2fb243d2a57771dc3589e96db54e998e2c1c8ef7 Closes-bug: #1628626 (cherry picked from commit 1d51eb64acebf7bafa277f0060bc5d2c7ca73d52) --- os_brick/initiator/linuxrbd.py | 13 ++++++++----- os_brick/tests/initiator/test_linuxrbd.py | 12 ++++++++++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/os_brick/initiator/linuxrbd.py b/os_brick/initiator/linuxrbd.py index ae15e32ca..6b1376fea 100644 --- a/os_brick/initiator/linuxrbd.py +++ b/os_brick/initiator/linuxrbd.py @@ -112,15 +112,18 @@ class RBDVolume(object): self.client = client - def __enter__(self): - return self - - def __exit__(self, type_, value, traceback): + def close(self): try: self.image.close() finally: self.client.disconnect() + def __enter__(self): + return self + + def __exit__(self, type_, value, traceback): + self.close() + def __getattr__(self, attrib): return getattr(self.image, attrib) @@ -229,4 +232,4 @@ class RBDVolumeIOWrapper(io.RawIOBase): # in this case is unwanted since the rbd image may have been closed prior # to the autoclean - currently triggering a segfault in librbd. def close(self): - pass + self.rbd_image.close() diff --git a/os_brick/tests/initiator/test_linuxrbd.py b/os_brick/tests/initiator/test_linuxrbd.py index 5f8aca73c..c3ff1af9b 100644 --- a/os_brick/tests/initiator/test_linuxrbd.py +++ b/os_brick/tests/initiator/test_linuxrbd.py @@ -146,5 +146,13 @@ class RBDVolumeIOWrapperTestCase(base.TestCase): def test_fileno(self): self.assertRaises(IOError, self.mock_volume_wrapper.fileno) - def test_close(self): - self.mock_volume_wrapper.close() + @mock.patch('os_brick.initiator.linuxrbd.rbd') + @mock.patch('os_brick.initiator.linuxrbd.rados') + @mock.patch.object(linuxrbd.RBDClient, 'disconnect') + def test_close(self, rbd_disconnect, mock_rados, mock_rbd): + rbd_client = linuxrbd.RBDClient('user', 'pool') + rbd_volume = linuxrbd.RBDVolume(rbd_client, 'volume') + rbd_handle = linuxrbd.RBDVolumeIOWrapper( + linuxrbd.RBDImageMetadata(rbd_volume, 'pool', 'user', None)) + rbd_handle.close() + self.assertEqual(1, rbd_disconnect.call_count)