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();
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
}
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,
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()) {
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;
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;
::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
}
<< ": 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);
<< ": 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);
<< ": 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);
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());
::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());
::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());
::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;
::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());
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) {
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);
}
}
-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) {
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) {
;
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);
}
}
}
- 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);
}
}
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;