]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
librados: fix resources leakage in RadosClient::connect().
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Mon, 19 Jan 2015 14:07:21 +0000 (15:07 +0100)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Sun, 1 Feb 2015 20:36:49 +0000 (21:36 +0100)
If RadosClient::connect was called a second time (which could
happen as a part of recovery from failure), the instances
of Objecter and Messenger allocated by the first call were leaked.

Additionally, the implementation of the method wrongly reported
memory allocation problems -- it throwed std::bad_alloc exception
instead of returning -ENOMEM error code.

Fixes: #10425
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/librados/RadosClient.cc
src/test/librados/misc.cc

index ad018325ed9327066a57b5d559f7f125b1dd721d..6f349f5571969c45d846d08799b27c95c27b6dd9 100644 (file)
@@ -221,7 +221,7 @@ int librados::RadosClient::connect()
   ldout(cct, 1) << "starting objecter" << dendl;
 
   err = -ENOMEM;
-  objecter = new Objecter(cct, messenger, &monclient,
+  objecter = new (std::nothrow) Objecter(cct, messenger, &monclient,
                          &finisher,
                          cct->_conf->rados_mon_op_timeout,
                          cct->_conf->rados_osd_op_timeout);
@@ -274,8 +274,19 @@ int librados::RadosClient::connect()
   err = 0;
 
  out:
-  if (err)
+  if (err) {
     state = DISCONNECTED;
+
+    if (objecter) {
+      delete objecter;
+      objecter = NULL;
+    }
+    if (messenger) {
+      delete messenger;
+      messenger = NULL;
+    }
+  }
+
   return err;
 }
 
index f4a291d2c35117b2b6276f93d51a4c377e9bb877..93195572644fe4bffe8aff453902e09129294ff7 100644 (file)
@@ -39,6 +39,25 @@ TEST(LibRadosMiscVersion, VersionPP) {
   Rados::version(&major, &minor, &extra);
 }
 
+TEST(LibRadosMiscConnectFailure, ConnectFailure) {
+  rados_t cluster;
+
+  char *id = getenv("CEPH_CLIENT_ID");
+  if (id)
+    std::cerr << "Client id is: " << id << std::endl;
+
+  ASSERT_EQ(0, rados_create(&cluster, NULL));
+  ASSERT_EQ(0, rados_conf_read_file(cluster, NULL));
+  ASSERT_EQ(0, rados_conf_parse_env(cluster, NULL));
+
+  ASSERT_EQ(0, rados_conf_set(cluster, "client_mount_timeout", "0.000001"));
+
+  ASSERT_NE(0, rados_connect(cluster));
+  ASSERT_NE(0, rados_connect(cluster));
+
+  rados_shutdown(cluster);
+}
+
 TEST_F(LibRadosMisc, ClusterFSID) {
   char fsid[37];
   ASSERT_EQ(-ERANGE, rados_cluster_fsid(cluster, fsid, sizeof(fsid) - 1));