From: Kefu Chai Date: Sat, 27 Jun 2020 14:11:50 +0000 (+0800) Subject: kv/RocksDBStore: use unique_ptr for destroying cf X-Git-Tag: wip-pdonnell-testing-20200918.022351~811^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d5443fed3d32284760c25b22e1e32da8b6274a2e;p=ceph-ci.git kv/RocksDBStore: use unique_ptr for destroying cf to avoid leak in ColumnFamilySet Fixes: https://tracker.ceph.com/issues/46054 Signed-off-by: Kefu Chai --- diff --git a/src/kv/RocksDBStore.cc b/src/kv/RocksDBStore.cc index bad2b761b2a..ffa861ad1db 100644 --- a/src/kv/RocksDBStore.cc +++ b/src/kv/RocksDBStore.cc @@ -2878,6 +2878,9 @@ int RocksDBStore::prepare_for_reshard(const std::string& new_sharding, if (rocksdb::kDefaultColumnFamilyName == base_name) { default_cf = handles[i]; must_close_default_cf = true; + std::unique_ptr ptr{ + cf, [](rocksdb::ColumnFamilyHandle*) {}}; + to_process_columns.emplace(full_name, std::move(ptr)); } else { for (const auto& nsd : new_sharding_def) { if (nsd.name == base_name) { @@ -2889,8 +2892,12 @@ int RocksDBStore::prepare_for_reshard(const std::string& new_sharding, break; } } + std::unique_ptr ptr{ + cf, [this](rocksdb::ColumnFamilyHandle* handle) { + db->DestroyColumnFamilyHandle(handle); + }}; + to_process_columns.emplace(full_name, std::move(ptr)); } - to_process_columns.emplace(full_name, cf); } //8. check if all cf_handles are filled @@ -2930,12 +2937,12 @@ int RocksDBStore::reshard_cleanup(const RocksDBStore::columns_t& current_columns // verify that column is empty std::unique_ptr it{ - db->NewIterator(rocksdb::ReadOptions(), handle)}; + db->NewIterator(rocksdb::ReadOptions(), handle.get())}; ceph_assert(it); it->SeekToFirst(); ceph_assert(!it->Valid()); - if (rocksdb::Status status = db->DropColumnFamily(handle); !status.ok()) { + if (rocksdb::Status status = db->DropColumnFamily(handle.get()); !status.ok()) { derr << __func__ << " Failed to drop column: " << name << dendl; return -EINVAL; } @@ -3053,14 +3060,14 @@ int RocksDBStore::reshard(const std::string& new_sharding, const RocksDBStore::r for (auto& [name, handle] : to_process_columns) { dout(5) << "Processing column=" << name - << " handle=" << handle << dendl; + << " handle=" << handle.get() << dendl; if (name == rocksdb::kDefaultColumnFamilyName) { - ceph_assert(handle == default_cf); + ceph_assert(handle.get() == default_cf); r = process_column(default_cf, std::string()); } else { std::string fixed_prefix = name.substr(0, name.find('-')); dout(10) << "Prefix: " << fixed_prefix << dendl; - r = process_column(handle, fixed_prefix); + r = process_column(handle.get(), fixed_prefix); } if (r != 0) { derr << "Error processing column " << name << dendl; @@ -3090,13 +3097,7 @@ int RocksDBStore::reshard(const std::string& new_sharding, const RocksDBStore::r r = -EIO; } - cleanup: - //close column handles - for (const auto& col: cf_handles) { - for (size_t i = 0; i < col.second.handles.size(); i++) { - db->DestroyColumnFamilyHandle(col.second.handles[i]); - } - } +cleanup: cf_handles.clear(); close(); return r; diff --git a/src/kv/RocksDBStore.h b/src/kv/RocksDBStore.h index 6400f536d55..cfeb0ae235b 100644 --- a/src/kv/RocksDBStore.h +++ b/src/kv/RocksDBStore.h @@ -478,7 +478,10 @@ err: private: WholeSpaceIterator get_default_cf_iterator(); - using columns_t = std::map; + using cf_deleter_t = std::function; + using columns_t = std::map>; int prepare_for_reshard(const std::string& new_sharding, columns_t& to_process_columns); int reshard_cleanup(const columns_t& current_columns);