mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-22 05:04:30 +02:00
Close FDs based on /proc/self/fd
... not to waste time with close(2)ing RLIMIT_NOFILE-3 non-existing FDs. Newer kernel = higher RLIMIT_NOFILE = more time wasted refs #8437
This commit is contained in:
parent
5f548c8f89
commit
26c944125b
@ -906,24 +906,13 @@ int main(int argc, char **argv)
|
|||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
String keepFDs = Utility::GetFromEnvironment("ICINGA2_KEEP_FDS");
|
String keepFDs = Utility::GetFromEnvironment("ICINGA2_KEEP_FDS");
|
||||||
if (keepFDs.IsEmpty()) {
|
if (keepFDs.IsEmpty()) {
|
||||||
rlimit rl;
|
|
||||||
if (getrlimit(RLIMIT_NOFILE, &rl) >= 0) {
|
|
||||||
rlim_t maxfds = rl.rlim_max;
|
|
||||||
|
|
||||||
if (maxfds == RLIM_INFINITY)
|
|
||||||
maxfds = 65536;
|
|
||||||
|
|
||||||
for (rlim_t i = 3; i < maxfds; i++) {
|
|
||||||
int rc = close(i);
|
|
||||||
|
|
||||||
#ifdef I2_DEBUG
|
#ifdef I2_DEBUG
|
||||||
if (rc >= 0)
|
Utility::CloseAllFDs({0, 1, 2}, [](int fd) {
|
||||||
std::cerr << "Closed FD " << i << " which we inherited from our parent process." << std::endl;
|
std::cerr << "Closed FD " << fd << " which we inherited from our parent process." << std::endl;
|
||||||
|
});
|
||||||
#else /* I2_DEBUG */
|
#else /* I2_DEBUG */
|
||||||
(void)rc;
|
Utility::CloseAllFDs({0, 1, 2});
|
||||||
#endif /* I2_DEBUG */
|
#endif /* I2_DEBUG */
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
|
@ -240,17 +240,7 @@ static void ProcessHandler()
|
|||||||
sigfillset(&mask);
|
sigfillset(&mask);
|
||||||
sigprocmask(SIG_SETMASK, &mask, nullptr);
|
sigprocmask(SIG_SETMASK, &mask, nullptr);
|
||||||
|
|
||||||
rlimit rl;
|
Utility::CloseAllFDs({0, 1, 2, l_ProcessControlFD});
|
||||||
if (getrlimit(RLIMIT_NOFILE, &rl) >= 0) {
|
|
||||||
rlim_t maxfds = rl.rlim_max;
|
|
||||||
|
|
||||||
if (maxfds == RLIM_INFINITY)
|
|
||||||
maxfds = 65536;
|
|
||||||
|
|
||||||
for (rlim_t i = 3; i < maxfds; i++)
|
|
||||||
if (i != static_cast<rlim_t>(l_ProcessControlFD))
|
|
||||||
(void)close(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
size_t length;
|
size_t length;
|
||||||
|
@ -9,10 +9,10 @@
|
|||||||
#include "base/utility.hpp"
|
#include "base/utility.hpp"
|
||||||
#include "base/json.hpp"
|
#include "base/json.hpp"
|
||||||
#include "base/objectlock.hpp"
|
#include "base/objectlock.hpp"
|
||||||
|
#include <algorithm>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <mmatch.h>
|
#include <mmatch.h>
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/filesystem/operations.hpp>
|
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/system/error_code.hpp>
|
#include <boost/system/error_code.hpp>
|
||||||
#include <boost/thread/tss.hpp>
|
#include <boost/thread/tss.hpp>
|
||||||
@ -27,6 +27,7 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <future>
|
#include <future>
|
||||||
|
#include <set>
|
||||||
#include <utf8.h>
|
#include <utf8.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -44,6 +45,7 @@
|
|||||||
# include <pwd.h>
|
# include <pwd.h>
|
||||||
# include <grp.h>
|
# include <grp.h>
|
||||||
# include <errno.h>
|
# include <errno.h>
|
||||||
|
# include <unistd.h>
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -833,6 +835,61 @@ void Utility::SetCloExec(int fd, bool cloexec)
|
|||||||
<< boost::errinfo_errno(errno));
|
<< boost::errinfo_errno(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Utility::CloseAllFDs(const std::vector<int>& except, std::function<void(int)> onClose)
|
||||||
|
{
|
||||||
|
#if defined(__linux__) || defined(__APPLE__)
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
|
std::set<int> fds;
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
const char *dir = "/proc/self/fd";
|
||||||
|
#endif /* __linux__ */
|
||||||
|
#ifdef __APPLE__
|
||||||
|
const char *dir = "/dev/fd";
|
||||||
|
#endif /* __APPLE__ */
|
||||||
|
|
||||||
|
for (fs::directory_iterator current {fs::path(dir)}, end; current != end; ++current) {
|
||||||
|
auto entry (current->path().filename());
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
try {
|
||||||
|
fd = boost::lexical_cast<int>(entry.c_str());
|
||||||
|
} catch (...) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fds.emplace(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto fd : except) {
|
||||||
|
fds.erase(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto fd : fds) {
|
||||||
|
if (close(fd) >= 0 && onClose) {
|
||||||
|
onClose(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* __linux__ || __APPLE__ */
|
||||||
|
rlimit rl;
|
||||||
|
|
||||||
|
if (getrlimit(RLIMIT_NOFILE, &rl) >= 0) {
|
||||||
|
rlim_t maxfds = rl.rlim_max;
|
||||||
|
|
||||||
|
if (maxfds == RLIM_INFINITY) {
|
||||||
|
maxfds = 65536;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int fd = 0; fd < maxfds; ++fd) {
|
||||||
|
if (std::find(except.begin(), except.end(), fd) == except.end() && close(fd) >= 0 && onClose) {
|
||||||
|
onClose(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* __linux__ || __APPLE__ */
|
||||||
|
}
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
void Utility::SetNonBlockingSocket(SOCKET s, bool nb)
|
void Utility::SetNonBlockingSocket(SOCKET s, bool nb)
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "base/array.hpp"
|
#include "base/array.hpp"
|
||||||
#include "base/threadpool.hpp"
|
#include "base/threadpool.hpp"
|
||||||
#include <boost/thread/tss.hpp>
|
#include <boost/thread/tss.hpp>
|
||||||
|
#include <functional>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -80,6 +81,8 @@ public:
|
|||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
static void SetNonBlocking(int fd, bool nb = true);
|
static void SetNonBlocking(int fd, bool nb = true);
|
||||||
static void SetCloExec(int fd, bool cloexec = true);
|
static void SetCloExec(int fd, bool cloexec = true);
|
||||||
|
|
||||||
|
static void CloseAllFDs(const std::vector<int>& except, std::function<void(int)> onClose = nullptr);
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
static void SetNonBlockingSocket(SOCKET s, bool nb = true);
|
static void SetNonBlockingSocket(SOCKET s, bool nb = true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user