Merge pull request #18535 from yanghonggang/master

os/bluestore/bluestore_tool: add log-dump command to dump bluefs's log

Reviewed-by: xie xingguo <xie.xingguo@zte.com.cn>
Reviewed-by: Sage Weil <sage@redhat.com>
Reviewed-by: Igor Fedotov <ifedotov@mirantis.com>
This commit is contained in:
Kefu Chai 2017-10-31 12:04:09 +08:00 committed by GitHub
commit 529f036b1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 143 additions and 11 deletions

View File

@ -403,7 +403,7 @@ int BlueFS::mount()
block_all.resize(MAX_BDEV);
_init_alloc();
r = _replay(false);
r = _replay(false, false);
if (r < 0) {
derr << __func__ << " failed to replay log: " << cpp_strerror(r) << dendl;
_stop_alloc();
@ -521,7 +521,7 @@ int BlueFS::_open_super()
return 0;
}
int BlueFS::_replay(bool noop)
int BlueFS::_replay(bool noop, bool to_stdout)
{
dout(10) << __func__ << (noop ? " NO-OP" : "") << dendl;
ino_last = 1; // by the log
@ -535,6 +535,9 @@ int BlueFS::_replay(bool noop)
}
log_file->fnode = super.log_fnode;
dout(10) << __func__ << " log_fnode " << super.log_fnode << dendl;
if (unlikely(to_stdout)) {
std::cout << " log_fnode " << super.log_fnode << std::endl;
}
FileReader *log_reader = new FileReader(
log_file, cct->_conf->bluefs_max_prefetch,
@ -609,6 +612,10 @@ int BlueFS::_replay(bool noop)
assert(seq == t.seq);
dout(10) << __func__ << " 0x" << std::hex << pos << std::dec
<< ": " << t << dendl;
if (unlikely(to_stdout)) {
std::cout << " 0x" << std::hex << pos << std::dec
<< ": " << t << std::endl;
}
bufferlist::iterator p = t.op_bl.begin();
while (!p.end()) {
@ -619,6 +626,11 @@ int BlueFS::_replay(bool noop)
case bluefs_transaction_t::OP_INIT:
dout(20) << __func__ << " 0x" << std::hex << pos << std::dec
<< ": op_init" << dendl;
if (unlikely(to_stdout)) {
std::cout << " 0x" << std::hex << pos << std::dec
<< ": op_init" << std::endl;
}
assert(t.seq == 1);
break;
@ -631,6 +643,13 @@ int BlueFS::_replay(bool noop)
dout(20) << __func__ << " 0x" << std::hex << pos << std::dec
<< ": op_jump seq " << next_seq
<< " offset 0x" << std::hex << offset << std::dec << dendl;
if (unlikely(to_stdout)) {
std::cout << " 0x" << std::hex << pos << std::dec
<< ": op_jump seq " << next_seq
<< " offset 0x" << std::hex << offset << std::dec
<< std::endl;
}
assert(next_seq >= log_seq);
log_seq = next_seq - 1; // we will increment it below
uint64_t skip = offset - read_pos;
@ -654,6 +673,11 @@ int BlueFS::_replay(bool noop)
::decode(next_seq, p);
dout(20) << __func__ << " 0x" << std::hex << pos << std::dec
<< ": op_jump_seq " << next_seq << dendl;
if (unlikely(to_stdout)) {
std::cout << " 0x" << std::hex << pos << std::dec
<< ": op_jump_seq " << next_seq << std::endl;
}
assert(next_seq >= log_seq);
log_seq = next_seq - 1; // we will increment it below
}
@ -670,6 +694,13 @@ int BlueFS::_replay(bool noop)
<< ": op_alloc_add " << " " << (int)id
<< ":0x" << std::hex << offset << "~" << length << std::dec
<< dendl;
if (unlikely(to_stdout)) {
std::cout << " 0x" << std::hex << pos << std::dec
<< ": op_alloc_add " << " " << (int)id
<< ":0x" << std::hex << offset << "~" << length << std::dec
<< std::endl;
}
if (!noop) {
block_all[id].insert(offset, length);
alloc[id]->init_add_free(offset, length);
@ -688,6 +719,13 @@ int BlueFS::_replay(bool noop)
<< ": op_alloc_rm " << " " << (int)id
<< ":0x" << std::hex << offset << "~" << length << std::dec
<< dendl;
if (unlikely(to_stdout)) {
std::cout << " 0x" << std::hex << pos << std::dec
<< ": op_alloc_rm " << " " << (int)id
<< ":0x" << std::hex << offset << "~" << length << std::dec
<< std::endl;
}
if (!noop) {
block_all[id].erase(offset, length);
alloc[id]->init_rm_free(offset, length);
@ -706,6 +744,13 @@ int BlueFS::_replay(bool noop)
<< ": op_dir_link " << " " << dirname << "/" << filename
<< " to " << ino
<< dendl;
if (unlikely(to_stdout)) {
std::cout << " 0x" << std::hex << pos << std::dec
<< ": op_dir_link " << " " << dirname << "/" << filename
<< " to " << ino
<< std::endl;
}
if (!noop) {
FileRef file = _get_file(ino);
assert(file->fnode.ino);
@ -727,6 +772,12 @@ int BlueFS::_replay(bool noop)
dout(20) << __func__ << " 0x" << std::hex << pos << std::dec
<< ": op_dir_unlink " << " " << dirname << "/" << filename
<< dendl;
if (unlikely(to_stdout)) {
std::cout << " 0x" << std::hex << pos << std::dec
<< ": op_dir_unlink " << " " << dirname << "/" << filename
<< std::endl;
}
if (!noop) {
map<string,DirRef>::iterator q = dir_map.find(dirname);
assert(q != dir_map.end());
@ -745,6 +796,11 @@ int BlueFS::_replay(bool noop)
::decode(dirname, p);
dout(20) << __func__ << " 0x" << std::hex << pos << std::dec
<< ": op_dir_create " << dirname << dendl;
if (unlikely(to_stdout)) {
std::cout << " 0x" << std::hex << pos << std::dec
<< ": op_dir_create " << dirname << std::endl;
}
if (!noop) {
map<string,DirRef>::iterator q = dir_map.find(dirname);
assert(q == dir_map.end());
@ -759,6 +815,11 @@ int BlueFS::_replay(bool noop)
::decode(dirname, p);
dout(20) << __func__ << " 0x" << std::hex << pos << std::dec
<< ": op_dir_remove " << dirname << dendl;
if (unlikely(to_stdout)) {
std::cout << " 0x" << std::hex << pos << std::dec
<< ": op_dir_remove " << dirname << std::endl;
}
if (!noop) {
map<string,DirRef>::iterator q = dir_map.find(dirname);
assert(q != dir_map.end());
@ -774,6 +835,11 @@ int BlueFS::_replay(bool noop)
::decode(fnode, p);
dout(20) << __func__ << " 0x" << std::hex << pos << std::dec
<< ": op_file_update " << " " << fnode << dendl;
if (unlikely(to_stdout)) {
std::cout << " 0x" << std::hex << pos << std::dec
<< ": op_file_update " << " " << fnode << std::endl;
}
if (!noop) {
FileRef f = _get_file(fnode.ino);
f->fnode = fnode;
@ -790,6 +856,11 @@ int BlueFS::_replay(bool noop)
::decode(ino, p);
dout(20) << __func__ << " 0x" << std::hex << pos << std::dec
<< ": op_file_remove " << ino << dendl;
if (unlikely(to_stdout)) {
std::cout << " 0x" << std::hex << pos << std::dec
<< ": op_file_remove " << ino << std::endl;
}
if (!noop) {
auto p = file_map.find(ino);
assert(p != file_map.end());
@ -814,6 +885,11 @@ int BlueFS::_replay(bool noop)
dout(10) << __func__ << " log file size was 0x"
<< std::hex << log_file->fnode.size << std::dec << dendl;
if (unlikely(to_stdout)) {
std::cout << " log file size was 0x"
<< std::hex << log_file->fnode.size << std::dec << std::endl;
}
delete log_reader;
if (!noop) {
@ -832,6 +908,27 @@ int BlueFS::_replay(bool noop)
return 0;
}
int BlueFS::log_dump(
CephContext *cct,
const string& path,
const vector<string>& devs)
{
int r = _open_super();
if (r < 0) {
derr << __func__ << " failed to open super: " << cpp_strerror(r) << dendl;
return r;
}
// only dump log file's content
r = _replay(true, true);
if (r < 0) {
derr << __func__ << " failed to replay log: " << cpp_strerror(r) << dendl;
return r;
}
return 0;
}
BlueFS::FileRef BlueFS::_get_file(uint64_t ino)
{
auto p = file_map.find(ino);

View File

@ -309,7 +309,7 @@ private:
int _open_super();
int _write_super();
int _replay(bool noop); ///< replay journal
int _replay(bool noop, bool to_stdout = false); ///< replay journal
FileWriter *_create_writer(FileRef f);
void _close_writer(FileWriter *h);
@ -331,6 +331,11 @@ public:
int mkfs(uuid_d osd_uuid);
int mount();
void umount();
int log_dump(
CephContext *cct,
const string& path,
const vector<string>& devs);
void collect_metadata(map<string,string> *pm, unsigned skip_bdev_id);
int fsck();

View File

@ -66,14 +66,11 @@ void validate_path(CephContext *cct, const string& path, bool bluefs)
}
}
BlueFS *open_bluefs(
void add_devices(
BlueFS *fs,
CephContext *cct,
const string& path,
const vector<string>& devs)
{
validate_path(cct, path, true);
BlueFS *fs = new BlueFS(cct);
string main;
set<int> got;
for (auto& i : devs) {
@ -113,6 +110,37 @@ BlueFS *open_bluefs(
exit(EXIT_FAILURE);
}
}
}
void log_dump(
CephContext *cct,
const string& path,
const vector<string>& devs)
{
validate_path(cct, path, true);
BlueFS *fs = new BlueFS(cct);
add_devices(fs, cct, devs);
int r = fs->log_dump(cct, path, devs);
if (r < 0) {
cerr << "log_dump failed" << ": "
<< cpp_strerror(r) << std::endl;
exit(EXIT_FAILURE);
}
delete fs;
}
BlueFS *open_bluefs(
CephContext *cct,
const string& path,
const vector<string>& devs)
{
validate_path(cct, path, true);
BlueFS *fs = new BlueFS(cct);
add_devices(fs, cct, devs);
int r = fs->mount();
if (r < 0) {
@ -147,7 +175,7 @@ int main(int argc, char **argv)
;
po::options_description po_positional("Positional options");
po_positional.add_options()
("command", po::value<string>(&action), "fsck, repair, bluefs-export, bluefs-bdev-sizes, bluefs-bdev-expand, show-label, set-label-key, rm-label-key, prime-osd-dir")
("command", po::value<string>(&action), "fsck, repair, bluefs-export, bluefs-bdev-sizes, bluefs-bdev-expand, show-label, set-label-key, rm-label-key, prime-osd-dir, bluefs-log-dump")
;
po::options_description po_all("All options");
po_all.add(po_options).add(po_positional);
@ -224,12 +252,12 @@ int main(int argc, char **argv)
}
}
}
if (action == "bluefs-export") {
if (action == "bluefs-export" || action == "bluefs-log-dump") {
if (path.empty()) {
cerr << "must specify bluestore path" << std::endl;
exit(EXIT_FAILURE);
}
if (out_dir.empty()) {
if ((action == "bluefs-export") && out_dir.empty()) {
cerr << "must specify out-dir to export bluefs" << std::endl;
exit(EXIT_FAILURE);
}
@ -544,6 +572,8 @@ int main(int argc, char **argv)
}
fs->umount();
delete fs;
} else if (action == "bluefs-log-dump") {
log_dump(cct.get(), path, devs);
} else {
cerr << "unrecognized action " << action << std::endl;
return 1;