[thin_dump] --format custom=<shared lib>

Allow people to use their own emitters held in a shared library.

Put a trivial emitter in contrib/ as an example.
This commit is contained in:
Joe Thornber
2016-03-24 13:10:37 +00:00
parent 872a933072
commit c7813e07e4
8 changed files with 199 additions and 12 deletions

View File

@@ -0,0 +1,29 @@
#include "thin-provisioning/shared_library_emitter.h"
#include <dlfcn.h>
#include <stdexcept>
using namespace std;
using namespace thin_provisioning;
//----------------------------------------------------------------
emitter::ptr
thin_provisioning::create_custom_emitter(string const &shared_lib, ostream &out)
{
emitter::ptr (*create_fn)(ostream &out);
void *handle = dlopen(shared_lib.c_str(), RTLD_LAZY);
if (!handle)
throw runtime_error(dlerror());
dlerror(); // Clear any existing error
create_fn = reinterpret_cast<emitter::ptr (*)(ostream &)>(dlsym(handle, "create_emitter"));
char *error = dlerror();
if (error)
throw runtime_error(error);
return create_fn(out);
}
//----------------------------------------------------------------

View File

@@ -0,0 +1,14 @@
#ifndef THIN_PROVISIONING_SHARED_LIBRARY_EMITTER_H
#define THIN_PROVISIONING_SHARED_LIBRARY_EMITTER_H
#include "thin-provisioning/emitter.h"
//----------------------------------------------------------------
namespace thin_provisioning {
emitter::ptr create_custom_emitter(std::string const &shared_lib, std::ostream &out);
}
//----------------------------------------------------------------
#endif

View File

@@ -21,13 +21,14 @@
#include <getopt.h>
#include <libgen.h>
#include "human_readable_format.h"
#include "metadata_dumper.h"
#include "metadata.h"
#include "xml_format.h"
#include "version.h"
#include "thin-provisioning/commands.h"
#include "persistent-data/file_utils.h"
#include "thin-provisioning/commands.h"
#include "thin-provisioning/human_readable_format.h"
#include "thin-provisioning/metadata.h"
#include "thin-provisioning/metadata_dumper.h"
#include "thin-provisioning/shared_library_emitter.h"
#include "thin-provisioning/xml_format.h"
#include "version.h"
using namespace boost;
using namespace persistent_data;
@@ -56,6 +57,10 @@ namespace {
return md;
}
bool begins_with(string const &str, string const &prefix) {
return str.substr(0, prefix.length()) == prefix;
}
emitter::ptr create_emitter(string const &format, ostream &out) {
emitter::ptr e;
@@ -65,9 +70,13 @@ namespace {
else if (format == "human_readable")
e = create_human_readable_emitter(out);
else if (begins_with(format, "custom="))
e = create_custom_emitter(format.substr(7), out);
else {
cerr << "unknown format '" << format << "'" << endl;
exit(1);
ostringstream msg;
msg << "unknown format '" << format << "'";
throw runtime_error(msg.str());
}
return e;