mirror of
https://github.com/ceph/ceph
synced 2025-02-01 07:52:57 +00:00
common/admin_socket: close socket descriptor in destructor
Long-running processes that do not reuse a single client connection will see accumulating file descriptors as a result of not closing the listening socket. In this case, eventually the system will reach file-max and subsequent connections will fail. Fixes: #11535 Signed-off-by: Jon Bernard <jbernard@tuxion.com>
This commit is contained in:
parent
92bcf6c5ec
commit
88fabb1ee6
@ -149,6 +149,33 @@ std::string AdminSocket::create_shutdown_pipe(int *pipe_rd, int *pipe_wr)
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string AdminSocket::destroy_shutdown_pipe()
|
||||
{
|
||||
// Send a byte to the shutdown pipe that the thread is listening to
|
||||
char buf[1] = { 0x0 };
|
||||
int ret = safe_write(m_shutdown_wr_fd, buf, sizeof(buf));
|
||||
|
||||
// Close write end
|
||||
VOID_TEMP_FAILURE_RETRY(close(m_shutdown_wr_fd));
|
||||
m_shutdown_wr_fd = -1;
|
||||
|
||||
if (ret != 0) {
|
||||
ostringstream oss;
|
||||
oss << "AdminSocket::destroy_shutdown_pipe error: failed to write"
|
||||
"to thread shutdown pipe: error " << ret;
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
join();
|
||||
|
||||
// Close read end. Doing this before join() blocks the listenter and prevents
|
||||
// joining.
|
||||
VOID_TEMP_FAILURE_RETRY(close(m_shutdown_rd_fd));
|
||||
m_shutdown_rd_fd = -1;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string AdminSocket::bind_and_listen(const std::string &sock_path, int *fd)
|
||||
{
|
||||
ldout(m_cct, 5) << "bind_and_listen " << sock_path << dendl;
|
||||
@ -536,30 +563,31 @@ bool AdminSocket::init(const std::string &path)
|
||||
|
||||
void AdminSocket::shutdown()
|
||||
{
|
||||
std::string err;
|
||||
|
||||
// Under normal operation this is unlikely to occur. However for some unit
|
||||
// tests, some object members are not initialized and so cannot be deleted
|
||||
// without fault.
|
||||
if (m_shutdown_wr_fd < 0)
|
||||
return;
|
||||
|
||||
ldout(m_cct, 5) << "shutdown" << dendl;
|
||||
|
||||
// Send a byte to the shutdown pipe that the thread is listening to
|
||||
char buf[1] = { 0x0 };
|
||||
int ret = safe_write(m_shutdown_wr_fd, buf, sizeof(buf));
|
||||
VOID_TEMP_FAILURE_RETRY(close(m_shutdown_wr_fd));
|
||||
m_shutdown_wr_fd = -1;
|
||||
|
||||
if (ret == 0) {
|
||||
join();
|
||||
} else {
|
||||
lderr(m_cct) << "AdminSocket::shutdown: failed to write "
|
||||
"to thread shutdown pipe: error " << ret << dendl;
|
||||
err = destroy_shutdown_pipe();
|
||||
if (!err.empty()) {
|
||||
lderr(m_cct) << "AdminSocket::shutdown: error: " << err << dendl;
|
||||
}
|
||||
|
||||
VOID_TEMP_FAILURE_RETRY(close(m_sock_fd));
|
||||
|
||||
unregister_command("version");
|
||||
unregister_command("git_version");
|
||||
unregister_command("0");
|
||||
delete m_version_hook;
|
||||
|
||||
unregister_command("help");
|
||||
delete m_help_hook;
|
||||
|
||||
unregister_command("get_command_descriptions");
|
||||
delete m_getdescs_hook;
|
||||
|
||||
|
@ -79,6 +79,7 @@ private:
|
||||
void shutdown();
|
||||
|
||||
std::string create_shutdown_pipe(int *pipe_rd, int *pipe_wr);
|
||||
std::string destroy_shutdown_pipe();
|
||||
std::string bind_and_listen(const std::string &sock_path, int *fd);
|
||||
|
||||
void *entry();
|
||||
|
Loading…
Reference in New Issue
Block a user