New ceph_osd.cc code did ObjectStore init work before global_init_daemonize(),
and WBThrottle thread is created when objectstore constructed. So after
daemon(), WBThrottle thread won't exist in new process. It will result in
deadlock.
When "cur_ios" which is member of WBThrottle hits hard limit, there exists two
ways to decrease "cur_ios". The first is WBThrottle thread which is dead if
deamonize, another is SyncThread. SyncThread will block at op_tp.pause()
because thread in op_tp(threadpool) block at
wbthrottle.throttle(FileStore::doop). So no thread will continue process jobs
in filestore layer and all threads is waiting.
Fix #7062 (http://tracker.ceph.com/issues/7062)
Signed-off-by: Haomai Wang <haomaiwang@gmail.com>
}
}
+ wbthrottle.start();
sync_thread.create();
ret = journal_replay(initial_op_seq);
lock.Unlock();
sync_thread.join();
+ wbthrottle.stop();
+
goto close_current_fd;
}
sync_cond.Signal();
lock.Unlock();
sync_thread.join();
+ wbthrottle.stop();
op_tp.stop();
journal_stop();
cur_ios(0), cur_size(0),
cct(cct),
logger(NULL),
- stopping(false),
+ stopping(true),
lock("WBThrottle::lock", false, true, false, cct),
fs(XFS)
{
logger->set(i, 0);
cct->_conf->add_observer(this);
- create();
}
WBThrottle::~WBThrottle() {
assert(cct);
+ cct->get_perfcounters_collection()->remove(logger);
+ delete logger;
+ cct->_conf->remove_observer(this);
+}
+
+void WBThrottle::start()
+{
+ {
+ Mutex::Locker l(lock);
+ stopping = false;
+ }
+ create();
+}
+
+void WBThrottle::stop()
+{
{
Mutex::Locker l(lock);
stopping = true;
cond.Signal();
}
+
join();
- cct->get_perfcounters_collection()->remove(logger);
- delete logger;
- cct->_conf->remove_observer(this);
}
const char** WBThrottle::get_tracked_conf_keys() const
WBThrottle(CephContext *cct);
~WBThrottle();
+ void stop();
/// Set fs as XFS or BTRFS
void set_fs(FS new_fs) {
Mutex::Locker l(lock);