dout(5) << __func__ << "::NCB::restore_allocator() completed successfully alloc=" << alloc << dendl;
} else {
// This must mean that we had an unplanned shutdown and didn't manage to destage the allocator
- dout(1) << __func__ << "::NCB::restore_allocator() failed!" << dendl;
- dout(1) << __func__ << "::NCB::Run Full Recovery from ONodes (might take a while) ..." << dendl;
+ dout(0) << __func__ << "::NCB::restore_allocator() failed! Run Full Recovery from ONodes (might take a while) ..." << dendl;
// if failed must recover from on-disk ONode internal state
if (read_allocation_from_drive_on_startup() != 0) {
derr << __func__ << "::NCB::Failed Recovery" << dendl;
return r;
}
-void BlueStore::_close_bluefs(bool cold_close)
+void BlueStore::_close_bluefs()
{
- bluefs->umount(cold_close);
+ bluefs->umount(db_was_opened_read_only);
_minimal_close_bluefs();
}
// load allocated extents from bluefs into allocator.
// And now it's time to do that
//
- _close_db(true);
+ _close_db();
r = _open_db(false, to_repair, read_only);
if (r < 0) {
goto out_alloc;
) {
dout(5) << __func__ << "::NCB::Commit to Null-Manager" << dendl;
commit_to_null_manager();
+ need_to_destage_allocation_file = true;
+ dout(10) << __func__ << "::NCB::need_to_destage_allocation_file was set" << dendl;
}
return 0;
out_fm:
_close_fm();
out_db:
- _close_db(read_only);
+ _close_db();
out_bdev:
_close_bdev();
out_fsid:
return r;
}
-void BlueStore::_close_db_and_around(bool read_only)
+void BlueStore::_close_db_and_around()
{
if (db) {
- _close_db_leave_bluefs();
+ _close_db();
}
if (bluefs) {
- _close_bluefs(read_only);
+ _close_bluefs();
}
_close_fm();
_close_alloc();
int BlueStore::close_db_environment()
{
- _close_db_and_around(false);
+ _close_db_and_around();
return 0;
}
if (!db) {
derr << __func__ << " error creating db" << dendl;
if (bluefs) {
- _close_bluefs(read_only);
+ _close_bluefs();
}
// delete env manually here since we can't depend on db to do this
// under this case
string kv_dir_fn;
string kv_backend;
std::string sharding_def;
+ // prevent write attempts to BlueFS in case we failed before BlueFS was opened
+ db_was_opened_read_only = true;
r = _prepare_db_environment(create, read_only, &kv_dir_fn, &kv_backend);
if (r < 0) {
derr << __func__ << " failed to prepare db environment: " << err.str() << dendl;
return -EIO;
}
+ // if reached here then BlueFS is already opened
+ db_was_opened_read_only = read_only;
+ dout(10) << __func__ << "::db_was_opened_read_only was set to " << read_only << dendl;
if (kv_backend == "rocksdb") {
options = cct->_conf->bluestore_rocksdb_options;
options_annex = cct->_conf->bluestore_rocksdb_options_annex;
}
if (r) {
derr << __func__ << " erroring opening db: " << err.str() << dendl;
- _close_db(read_only);
+ _close_db();
return -EIO;
}
dout(1) << __func__ << " opened " << kv_backend
return 0;
}
-void BlueStore::_close_db(bool cold_close)
+void BlueStore::_close_db_leave_bluefs()
{
ceph_assert(db);
delete db;
- db = NULL;
- if (bluefs) {
- _close_bluefs(cold_close);
- }
+ db = nullptr;
}
-void BlueStore::_close_db_leave_bluefs()
+void BlueStore::_close_db()
{
- ceph_assert(db);
- delete db;
- db = nullptr;
+ dout(10) << __func__ << ":read_only=" << db_was_opened_read_only << " fm=" << fm << " destage_alloc_file=" << need_to_destage_allocation_file << dendl;
+ _close_db_leave_bluefs();
+
+ if (fm && fm->is_null_manager() && !db_was_opened_read_only && need_to_destage_allocation_file) {
+ int ret = store_allocator(alloc);
+ if (ret != 0) {
+ derr << __func__ << "::NCB::store_allocator() failed (continue with bitmapFreelistManager)" << dendl;
+ }
+ }
+
+ if (bluefs) {
+ _close_bluefs();
+ }
}
void BlueStore::_dump_alloc_on_failure()
out_close_fm:
_close_fm();
out_close_db:
- _close_db(false);
+ _close_db();
out_close_alloc:
_close_alloc();
out_close_bdev:
dout(0) << __func__ << " success" << dendl;
}
- _close_db_and_around(true);
+ _close_db_and_around();
return r;
}
return r;
}
auto close_db = make_scope_guard([&] {
- _close_db_and_around(true);
+ _close_db_and_around();
});
uint64_t used_space = 0;
for(auto src_id : devs_source) {
return r;
}
auto close_db = make_scope_guard([&] {
- _close_db_and_around(true);
+ _close_db_and_around();
});
string link_db;
<< std::endl;
}
}
- _close_db_and_around(true);
+ _close_db_and_around();
// mount in read/write to sync expansion changes
r = _mount();
dout(5) << __func__ << "::NCB::calling umount()" << dendl;
umount();
} else {
- _close_db_and_around(true);
+ _close_db_and_around();
}
return r;
}
int r = _open_db_and_around(true);
ceph_assert(r == 0);
bluefs->dump_block_extents(out);
- _close_db_and_around(true);
+ _close_db_and_around();
return r;
}
}
auto close_db = make_scope_guard([&] {
if (!mounted) {
- _close_db_and_around(true);
+ _close_db_and_around();
}
});
{
dout(5) << __func__ << "::NCB::entered" << dendl;
ceph_assert(_kv_only || mounted);
- bool was_mounted = mounted;
_osr_drain_all();
mounted = false;
dout(20) << __func__ << " closing" << dendl;
}
- _close_db_leave_bluefs();
- // GBH - Vault the allocation state
- dout(5) << "NCB::BlueStore::umount->store_allocation_state_on_bluestore() " << dendl;
- if (was_mounted && fm->is_null_manager()) {
- int ret = store_allocator(alloc);
- if (ret != 0) {
- derr << __func__ << "::NCB::store_allocator() failed (continue with bitmapFreelistManager)" << dendl;
- _close_db_and_around(false);
- // should we run fsck ???
- return ret;
- }
- dout(5) << __func__ << "::NCB::store_allocator() completed successfully" << dendl;
- }
-
- _close_db_and_around(false);
-
+ _close_db_and_around();
if (cct->_conf->bluestore_fsck_on_umount) {
dout(5) << __func__ << "::NCB::calling fsck()" << dendl;
int rc = fsck(cct->_conf->bluestore_fsck_on_umount_deep);
int BlueStore::cold_close()
{
- _close_db_and_around(true);
+ _close_db_and_around();
return 0;
}
<< dendl;
// in deep mode we need R/W write access to be able to replay deferred ops
- bool read_only = !(repair || depth == FSCK_DEEP);
+ const bool read_only = !(repair || depth == FSCK_DEEP);
dout(5) << __func__ << "::NCB::calling open_db_and_around()" << dendl;
int r = _open_db_and_around(read_only);
if (r < 0) {
return r;
}
auto close_db = make_scope_guard([&] {
- _close_db_and_around(true);
+ _close_db_and_around();
});
if (!read_only) {
// we can safely ignore non-existing file
int BlueStore::invalidate_allocation_file_on_bluefs()
{
+ // mark that allocation-file was invalidated and we should destage a new copy whne closing db
+ need_to_destage_allocation_file = true;
+ dout(10) << "need_to_destage_allocation_file was set" << dendl;
+
BlueFS::FileWriter *p_handle = nullptr;
if (!bluefs->dir_exists(allocator_dir)) {
dout(5) << "allocator_dir(" << allocator_dir << ") doesn't exist" << dendl;
dout(5) <<"p_handle->pos=" << p_handle->pos << " WRITE-duration=" << duration << " seconds" << dendl;
bluefs->close_writer(p_handle);
+ need_to_destage_allocation_file = false;
+ dout(10) << "need_to_destage_allocation_file was clear" << dendl;
return 0;
}
int BlueStore::read_allocation_from_drive_on_startup()
{
int ret = 0;
- dout(5) << "Start Allocation Recovery from ONodes ..." << dendl;
ret = _open_collections();
if (ret < 0) {
int ret = 0;
uint64_t memory_target = cct->_conf.get_val<Option::size_t>("osd_memory_target");
dout(5) << "calling open_db_and_around()" << dendl;
- ret = _open_db_and_around(true, false/*, true*/);
+ ret = _open_db_and_around(true, false);
if (ret < 0) {
return ret;
}
ret = _open_collections();
if (ret < 0) {
- _close_db_and_around(false); return ret;
+ _close_db_and_around();
+ return ret;
}
read_alloc_stats_t stats = {};
utime_t start = ceph_clock_now();
ret = reconstruct_allocations(allocator, stats);
if (ret != 0) {
- _close_db_and_around(false); return ret;
+ _close_db_and_around();
+ return ret;
}
// add allocation space used by the bluefs itself
ret = add_existing_bluefs_allocation(allocator, stats);
if (ret < 0) {
- _close_db_and_around(false); return ret;
+ _close_db_and_around();
+ return ret;
}
utime_t duration = ceph_clock_now() - start;
// add allocation space used by the bluefs itself
ret = add_existing_bluefs_allocation(alloc2, stats);
if (ret < 0) {
- _close_db_and_around(false); return ret;
+ _close_db_and_around();
+ return ret;
}
// verify that we can store and restore allocator to/from drive
ret = compare_allocators(alloc2, alloc, stats.insert_count, memory_target);
//out_db:
delete allocator;
_shutdown_cache();
- _close_db_and_around(false);
- return ret;
-}
-
-//---------------------------------------------------------
-int BlueStore::db_cleanup(int ret)
-{
- _shutdown_cache();
- _close_db_and_around(false);
+ _close_db_and_around();
return ret;
}
}
}
+//---------------------------------------------------------
+int BlueStore::db_cleanup(int ret)
+{
+ _shutdown_cache();
+ _close_db_and_around();
+ return ret;
+}
+
//---------------------------------------------------------
// convert back the system from null-allocator to using rocksdb to store allocation
int BlueStore::push_allocation_to_rocksdb()