Blame SOURCES/0004-thin_dump-Fix-leaked-shared-object-handle.patch

5a5b1b
From 7fbd79cab2e548eb388bc782dd39f1cde027173b Mon Sep 17 00:00:00 2001
5a5b1b
From: Ming-Hung Tsai <mtsai@redhat.com>
5a5b1b
Date: Tue, 1 Jun 2021 23:37:36 +0800
5a5b1b
Subject: [PATCH 04/10] [thin_dump] Fix leaked shared object handle
5a5b1b
5a5b1b
---
5a5b1b
 thin-provisioning/shared_library_emitter.cc | 113 ++++++++++++++++++++++++----
5a5b1b
 1 file changed, 100 insertions(+), 13 deletions(-)
5a5b1b
5a5b1b
diff --git a/thin-provisioning/shared_library_emitter.cc b/thin-provisioning/shared_library_emitter.cc
5a5b1b
index 58f12d2..2e845f3 100644
5a5b1b
--- a/thin-provisioning/shared_library_emitter.cc
5a5b1b
+++ b/thin-provisioning/shared_library_emitter.cc
5a5b1b
@@ -8,22 +8,109 @@ using namespace thin_provisioning;
5a5b1b
 
5a5b1b
 //----------------------------------------------------------------
5a5b1b
 
5a5b1b
-emitter::ptr
5a5b1b
-thin_provisioning::create_custom_emitter(string const &shared_lib, ostream &out)
5a5b1b
-{
5a5b1b
-	emitter::ptr (*create_fn)(ostream &out;;
5a5b1b
-	void *handle = dlopen(shared_lib.c_str(), RTLD_LAZY);
5a5b1b
-	if (!handle)
5a5b1b
-		throw runtime_error(dlerror());
5a5b1b
+struct shared_object {
5a5b1b
+public:
5a5b1b
+	shared_object(const char *shared_lib) {
5a5b1b
+		handle_ = dlopen(shared_lib, RTLD_LAZY);
5a5b1b
+		if (!handle_)
5a5b1b
+			throw runtime_error(dlerror());
5a5b1b
+
5a5b1b
+		dlerror();    // Clear any existing error
5a5b1b
+	}
5a5b1b
+
5a5b1b
+	virtual ~shared_object() {
5a5b1b
+		dlclose(handle_);
5a5b1b
+	}
5a5b1b
+
5a5b1b
+	void *get_symbol(const char *symbol) {
5a5b1b
+		void *sym = dlsym(handle_, symbol);
5a5b1b
+
5a5b1b
+		char *error = dlerror();
5a5b1b
+		if (error)
5a5b1b
+			throw runtime_error(error);
5a5b1b
+
5a5b1b
+		return sym;
5a5b1b
+	}
5a5b1b
+
5a5b1b
+	void *handle_;
5a5b1b
+};
5a5b1b
+
5a5b1b
+class shared_emitter : public emitter {
5a5b1b
+public:
5a5b1b
+	shared_emitter(const char *shared_lib, ostream &out): sobj_(shared_lib) {
5a5b1b
+		emitter::ptr (*create_fn)(ostream &out;;
5a5b1b
+		create_fn = reinterpret_cast<emitter::ptr (*)(ostream &)>(
5a5b1b
+				sobj_.get_symbol("create_emitter"));
5a5b1b
+		inner_ = create_fn(out);
5a5b1b
+	}
5a5b1b
+
5a5b1b
+	virtual ~shared_emitter() {
5a5b1b
+	}
5a5b1b
+
5a5b1b
+	void begin_superblock(std::string const &uuid,
5a5b1b
+			      uint64_t time,
5a5b1b
+			      uint64_t trans_id,
5a5b1b
+			      boost::optional<uint32_t> flags,
5a5b1b
+			      boost::optional<uint32_t> version,
5a5b1b
+			      uint32_t data_block_size,
5a5b1b
+			      uint64_t nr_data_blocks,
5a5b1b
+			      boost::optional<uint64_t> metadata_snap) {
5a5b1b
+		inner_->begin_superblock(uuid,
5a5b1b
+					 time,
5a5b1b
+					 trans_id,
5a5b1b
+					 flags,
5a5b1b
+					 version,
5a5b1b
+					 data_block_size,
5a5b1b
+					 nr_data_blocks,
5a5b1b
+					 metadata_snap);
5a5b1b
+	}
5a5b1b
 
5a5b1b
-	dlerror();    // Clear any existing error
5a5b1b
-	create_fn = reinterpret_cast<emitter::ptr (*)(ostream &)>(dlsym(handle, "create_emitter"));
5a5b1b
+	void end_superblock() {
5a5b1b
+		inner_->end_superblock();
5a5b1b
+	}
5a5b1b
 
5a5b1b
-	char *error = dlerror();
5a5b1b
-	if (error)
5a5b1b
-		throw runtime_error(error);
5a5b1b
+	void begin_device(uint32_t dev_id,
5a5b1b
+			  uint64_t mapped_blocks,
5a5b1b
+			  uint64_t trans_id,
5a5b1b
+			  uint64_t creation_time,
5a5b1b
+			  uint64_t snap_time) {
5a5b1b
+		inner_->begin_device(dev_id, mapped_blocks, trans_id, creation_time, snap_time);
5a5b1b
+	}
5a5b1b
 
5a5b1b
-	return create_fn(out);
5a5b1b
+	void end_device() {
5a5b1b
+		inner_->end_device();
5a5b1b
+	}
5a5b1b
+
5a5b1b
+	void begin_named_mapping(std::string const &name) {
5a5b1b
+		inner_->begin_named_mapping(name);
5a5b1b
+	}
5a5b1b
+
5a5b1b
+	void end_named_mapping() {
5a5b1b
+		inner_->end_named_mapping();
5a5b1b
+	}
5a5b1b
+
5a5b1b
+	void identifier(std::string const &name) {
5a5b1b
+		inner_->identifier(name);
5a5b1b
+	}
5a5b1b
+
5a5b1b
+	void range_map(uint64_t origin_begin, uint64_t data_begin, uint32_t time, uint64_t len) {
5a5b1b
+		inner_->range_map(origin_begin, data_begin, time, len);
5a5b1b
+	}
5a5b1b
+
5a5b1b
+	void single_map(uint64_t origin_block, uint64_t data_block, uint32_t time) {
5a5b1b
+		inner_->single_map(origin_block, data_block, time);
5a5b1b
+	}
5a5b1b
+
5a5b1b
+	shared_object sobj_;
5a5b1b
+	emitter::ptr inner_;
5a5b1b
+};
5a5b1b
+
5a5b1b
+//----------------------------------------------------------------
5a5b1b
+
5a5b1b
+emitter::ptr
5a5b1b
+thin_provisioning::create_custom_emitter(string const &shared_lib, ostream &out)
5a5b1b
+{
5a5b1b
+	return emitter::ptr(new shared_emitter(shared_lib.c_str(), out));
5a5b1b
 }
5a5b1b
 
5a5b1b
 //----------------------------------------------------------------
5a5b1b
-- 
5a5b1b
1.8.3.1
5a5b1b