From: Igor Fedotov Date: Thu, 28 Jun 2018 14:05:59 +0000 (+0300) Subject: os/bluestore_tool: fix multiple extents handling in BlueFS::log_dump X-Git-Tag: v14.0.1~598^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3befd56ec7363ca2ee6d2e791aa20a625c70c90a;p=ceph.git os/bluestore_tool: fix multiple extents handling in BlueFS::log_dump Without the fix the op crashed when trying to read from the second extent of the log file which was absent in superblock but actually existed. Regular replay properly retrieves it - which wasn't the case for log_dump due to 'noop' mode of operation. Signed-off-by: Igor Fedotov --- diff --git a/src/os/bluestore/BlueFS.cc b/src/os/bluestore/BlueFS.cc index 29e6217a5cc..77b2c5c0768 100644 --- a/src/os/bluestore/BlueFS.cc +++ b/src/os/bluestore/BlueFS.cc @@ -570,12 +570,15 @@ int BlueFS::_replay(bool noop, bool to_stdout) log_seq = 0; FileRef log_file; - if (noop) { - log_file = new File; + log_file = _get_file(1); + if (!noop) { + log_file->fnode = super.log_fnode; } else { - log_file = _get_file(1); + // do not use fnode from superblock in 'noop' mode - log_file's one should + // be fine and up-to-date + assert(log_file->fnode.ino == 1); + assert(log_file->fnode.extents.size() != 0); } - 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; @@ -950,19 +953,10 @@ int BlueFS::_replay(bool noop, bool to_stdout) return 0; } -int BlueFS::log_dump( - CephContext *cct, - const string& path, - const vector& devs) +int BlueFS::log_dump() { - 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); + int r = _replay(true, true); if (r < 0) { derr << __func__ << " failed to replay log: " << cpp_strerror(r) << dendl; return r; diff --git a/src/os/bluestore/BlueFS.h b/src/os/bluestore/BlueFS.h index 5e147a8cc5c..4abacb672b8 100644 --- a/src/os/bluestore/BlueFS.h +++ b/src/os/bluestore/BlueFS.h @@ -340,10 +340,7 @@ public: int mount(); void umount(); - int log_dump( - CephContext *cct, - const string& path, - const vector& devs); + int log_dump(); void collect_metadata(map *pm, unsigned skip_bdev_id); void get_devices(set *ls); diff --git a/src/os/bluestore/bluestore_tool.cc b/src/os/bluestore/bluestore_tool.cc index b756812ed23..ccdc0e403fe 100644 --- a/src/os/bluestore/bluestore_tool.cc +++ b/src/os/bluestore/bluestore_tool.cc @@ -134,43 +134,39 @@ void add_devices( } } -void log_dump( +BlueFS *open_bluefs( CephContext *cct, const string& path, const vector& devs) { validate_path(cct, path, true); BlueFS *fs = new BlueFS(cct); - + add_devices(fs, cct, devs); - int r = fs->log_dump(cct, path, devs); + int r = fs->mount(); if (r < 0) { - cerr << "log_dump failed" << ": " - << cpp_strerror(r) << std::endl; + cerr << "unable to mount bluefs: " << cpp_strerror(r) + << std::endl; exit(EXIT_FAILURE); } - - delete fs; + return fs; } -BlueFS *open_bluefs( +void log_dump( CephContext *cct, const string& path, const vector& devs) { - validate_path(cct, path, true); - BlueFS *fs = new BlueFS(cct); - - add_devices(fs, cct, devs); - - int r = fs->mount(); + BlueFS* fs = open_bluefs(cct, path, devs); + int r = fs->log_dump(); if (r < 0) { - cerr << "unable to mount bluefs: " << cpp_strerror(r) - << std::endl; + cerr << "log_dump failed" << ": " + << cpp_strerror(r) << std::endl; exit(EXIT_FAILURE); } - return fs; + + delete fs; } void inferring_bluefs_devices(vector& devs, std::string& path)