[thin_debug] Enhance error handling
- Handle exception thrown by commands - Add help and exit commands
This commit is contained in:
@@ -34,6 +34,7 @@
|
|||||||
#include "thin-provisioning/commands.h"
|
#include "thin-provisioning/commands.h"
|
||||||
#include "thin-provisioning/metadata.h"
|
#include "thin-provisioning/metadata.h"
|
||||||
#include "thin-provisioning/metadata_checker.h"
|
#include "thin-provisioning/metadata_checker.h"
|
||||||
|
#include "thin-provisioning/superblock.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
@@ -122,9 +123,12 @@ namespace {
|
|||||||
|
|
||||||
class command_interpreter {
|
class command_interpreter {
|
||||||
public:
|
public:
|
||||||
|
typedef std::shared_ptr<command_interpreter> ptr;
|
||||||
|
|
||||||
command_interpreter(istream &in, ostream &out)
|
command_interpreter(istream &in, ostream &out)
|
||||||
: in_(in),
|
: in_(in),
|
||||||
out_(out) {
|
out_(out),
|
||||||
|
exit_(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void register_command(string const &str, command::ptr cmd) {
|
void register_command(string const &str, command::ptr cmd) {
|
||||||
@@ -132,10 +136,14 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void enter_main_loop() {
|
void enter_main_loop() {
|
||||||
while (true)
|
while (!exit_)
|
||||||
do_once();
|
do_once();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void exit_main_loop() {
|
||||||
|
exit_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
strings read_input() {
|
strings read_input() {
|
||||||
using namespace boost::algorithm;
|
using namespace boost::algorithm;
|
||||||
@@ -160,13 +168,19 @@ namespace {
|
|||||||
it = commands_.find(args[0]);
|
it = commands_.find(args[0]);
|
||||||
if (it == commands_.end())
|
if (it == commands_.end())
|
||||||
out_ << "Unrecognised command" << endl;
|
out_ << "Unrecognised command" << endl;
|
||||||
else
|
else {
|
||||||
it->second->exec(args, out_);
|
try {
|
||||||
|
it->second->exec(args, out_);
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
cerr << e.what() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
istream &in_;
|
istream &in_;
|
||||||
ostream &out_;
|
ostream &out_;
|
||||||
map <string, command::ptr> commands_;
|
map <string, command::ptr> commands_;
|
||||||
|
bool exit_;
|
||||||
};
|
};
|
||||||
|
|
||||||
//--------------------------------
|
//--------------------------------
|
||||||
@@ -177,6 +191,31 @@ namespace {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class help : public command {
|
||||||
|
virtual void exec(strings const &args, ostream &out) {
|
||||||
|
out << "Commands:" << endl
|
||||||
|
<< " superblock" << endl
|
||||||
|
<< " m1_node <block# of top-level mapping tree node>" << endl
|
||||||
|
<< " m2_node <block# of bottom-level mapping tree node>" << endl
|
||||||
|
<< " detail_node <block# of device details tree node>" << endl
|
||||||
|
<< " exit" << endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class exit_handler : public command {
|
||||||
|
public:
|
||||||
|
exit_handler(command_interpreter &interpreter)
|
||||||
|
: interpreter_(interpreter) {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void exec(strings const &args, ostream &out) {
|
||||||
|
out << "Goodbye!" << endl;
|
||||||
|
interpreter_.exit_main_loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
command_interpreter &interpreter_;
|
||||||
|
};
|
||||||
|
|
||||||
class show_superblock : public command {
|
class show_superblock : public command {
|
||||||
public:
|
public:
|
||||||
explicit show_superblock(metadata::ptr md)
|
explicit show_superblock(metadata::ptr md)
|
||||||
@@ -298,7 +337,7 @@ namespace {
|
|||||||
|
|
||||||
//--------------------------------
|
//--------------------------------
|
||||||
|
|
||||||
int debug(string const &path) {
|
int debug(string const &path, bool ignore_metadata_sm) {
|
||||||
try {
|
try {
|
||||||
block_manager::ptr bm = open_bm(path, block_manager::READ_ONLY, 1);
|
block_manager::ptr bm = open_bm(path, block_manager::READ_ONLY, 1);
|
||||||
metadata::ptr md(new metadata(bm, false));
|
metadata::ptr md(new metadata(bm, false));
|
||||||
@@ -308,16 +347,17 @@ namespace {
|
|||||||
interp.register_command("m1_node", command::ptr(new show_btree_node<uint64_show_traits>(md)));
|
interp.register_command("m1_node", command::ptr(new show_btree_node<uint64_show_traits>(md)));
|
||||||
interp.register_command("m2_node", command::ptr(new show_btree_node<block_show_traits>(md)));
|
interp.register_command("m2_node", command::ptr(new show_btree_node<block_show_traits>(md)));
|
||||||
interp.register_command("detail_node", command::ptr(new show_btree_node<device_details_show_traits>(md)));
|
interp.register_command("detail_node", command::ptr(new show_btree_node<device_details_show_traits>(md)));
|
||||||
|
interp.register_command("help", command::ptr(new help));
|
||||||
|
interp.register_command("exit", command::ptr(new exit_handler(interp)));
|
||||||
interp.enter_main_loop();
|
interp.enter_main_loop();
|
||||||
|
|
||||||
} catch (std::exception &e) {
|
} catch (std::exception &e) {
|
||||||
cerr << e.what();
|
cerr << e.what() << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
thin_debug_cmd::thin_debug_cmd()
|
thin_debug_cmd::thin_debug_cmd()
|
||||||
@@ -342,8 +382,10 @@ thin_debug_cmd::run(int argc, char **argv)
|
|||||||
const struct option longopts[] = {
|
const struct option longopts[] = {
|
||||||
{ "help", no_argument, NULL, 'h'},
|
{ "help", no_argument, NULL, 'h'},
|
||||||
{ "version", no_argument, NULL, 'V'},
|
{ "version", no_argument, NULL, 'V'},
|
||||||
|
{ "ignore-metadata-sm", no_argument, NULL, 1},
|
||||||
{ NULL, no_argument, NULL, 0 }
|
{ NULL, no_argument, NULL, 0 }
|
||||||
};
|
};
|
||||||
|
bool ignore_metadata_sm = false;
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
|
while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
|
||||||
switch(c) {
|
switch(c) {
|
||||||
@@ -354,6 +396,10 @@ thin_debug_cmd::run(int argc, char **argv)
|
|||||||
case 'V':
|
case 'V':
|
||||||
cerr << THIN_PROVISIONING_TOOLS_VERSION << endl;
|
cerr << THIN_PROVISIONING_TOOLS_VERSION << endl;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
ignore_metadata_sm = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,5 +408,5 @@ thin_debug_cmd::run(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return debug(argv[optind]);
|
return debug(argv[optind], ignore_metadata_sm);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user