diff options
Diffstat (limited to 'mail/dbmail/files/patch-0007-Disconnect-IMAP-clients-if-only-few-free-FDs-left')
-rw-r--r-- | mail/dbmail/files/patch-0007-Disconnect-IMAP-clients-if-only-few-free-FDs-left | 148 |
1 files changed, 0 insertions, 148 deletions
diff --git a/mail/dbmail/files/patch-0007-Disconnect-IMAP-clients-if-only-few-free-FDs-left b/mail/dbmail/files/patch-0007-Disconnect-IMAP-clients-if-only-few-free-FDs-left deleted file mode 100644 index eca0ae403168..000000000000 --- a/mail/dbmail/files/patch-0007-Disconnect-IMAP-clients-if-only-few-free-FDs-left +++ /dev/null @@ -1,148 +0,0 @@ -From 6b7eccfec4f76b7d9d1f865caf741ff3214b5964 Mon Sep 17 00:00:00 2001 -From: Pavlo Lavrenenko <santa.ssh@gmail.com> -Date: Thu, 2 Jun 2016 08:18:51 +0300 -Subject: [PATCH 07/33] Disconnect IMAP clients if only few free FDs left (#37) - -After network connection to DB server goes down the processing of IMAP session -stalls: DB connection pool becomes exhausted as active connections do not -close till TCP timeout kicks in (true at least for Oracle). While DBMail still -accepts incoming connections it quickly reaches the RLIMIT_NOFILE and becomes -unresponsive. Send BYE response if the number of opened FDs reaches the -RLIMIT_NOFILE value. ---- - src/dbmail.h.in | 5 +++++ - src/dm_misc.c | 20 ++++++++++++++++++++ - src/dm_misc.h | 8 ++++++++ - src/imap4.c | 23 ++++++++++++++++++++++- - 4 files changed, 55 insertions(+), 1 deletion(-) - -diff --git src/dbmail.h.in src/dbmail.h.in -index d826dc3..17215ef 100644 ---- src/dbmail.h.in -+++ src/dbmail.h.in -@@ -69,12 +69,14 @@ - #include <string.h> - #include <strings.h> - #include <sysexits.h> -+#include <dirent.h> - #include <sys/types.h> - #include <sys/stat.h> - #include <sys/mman.h> - #include <sys/socket.h> - #include <sys/un.h> - #include <sys/time.h> -+#include <sys/resource.h> - #include <sys/wait.h> - #include <sys/ipc.h> - #include <sys/shm.h> -@@ -252,6 +254,9 @@ - /* input reading linelimit */ - #define MAX_LINESIZE (64*1024) - -+/* minumun number of free file descriptors required to run the daemon */ -+#define FREE_DF_THRESHOLD 16 -+ - /* string length for query */ - #define DEF_QUERYSIZE (32*1024) - #define DEF_FRAGSIZE 256 -diff --git src/dm_misc.c src/dm_misc.c -index e27ef34..e795de1 100644 ---- src/dm_misc.c -+++ src/dm_misc.c -@@ -104,6 +104,26 @@ int drop_privileges(char *newuser, char *newgroup) - return 0; - } - -+int get_opened_fd_count(void) -+{ -+ DIR* dir = NULL; -+ struct dirent* entry = NULL; -+ char buf[32]; -+ int fd_count = 0; -+ -+ snprintf(buf, 32, "/proc/%i/fd/", getpid()); -+ -+ dir = opendir(buf); -+ if (dir == NULL) -+ return -1; -+ -+ while ((entry = readdir(dir)) != NULL) -+ fd_count++; -+ closedir(dir); -+ -+ return fd_count - 2; /* exclude '.' and '..' entries */ -+} -+ - void create_unique_id(char *target, uint64_t message_idnr) - { - char md5_str[FIELDSIZE]; -diff --git src/dm_misc.h src/dm_misc.h -index 9660dfa..b6cf24f 100644 ---- src/dm_misc.h -+++ src/dm_misc.h -@@ -45,6 +45,14 @@ void g_string_maybe_shrink(GString *s); - int drop_privileges(char *newuser, char *newgroup); - - /** -+ \brief get the number of opened files (requires /proc mounted) -+ \return -+ - -1 on error -+ - number of opened files -+*/ -+int get_opened_fd_count(void); -+ -+/** - * \brief create a unique id for a message (used for pop, stored per message) - * \param target target string. Length should be UID_SIZE - * \param message_idnr message_idnr of message -diff --git src/imap4.c src/imap4.c -index 0532f2e..e523edc 100644 ---- src/imap4.c -+++ src/imap4.c -@@ -351,6 +351,12 @@ static void send_greeting(ImapSession *session) - dbmail_imap_session_set_state(session, CLIENTSTATE_NON_AUTHENTICATED); - } - -+static void disconnect_user(ImapSession *session) -+{ -+ imap_session_printf(session, "* BYE [Service unavailable.]\r\n"); -+ imap_handle_abort(session); -+} -+ - /* - * the default timeout callback */ - -@@ -601,6 +607,8 @@ int imap_handle_connection(client_sock *c) - { - ImapSession *session; - ClientBase_T *ci; -+ struct rlimit fd_limit; -+ int fd_count; - - ci = client_init(c); - -@@ -617,7 +625,20 @@ int imap_handle_connection(client_sock *c) - Capa_remove(session->capa, "LOGINDISABLED"); - } - -- send_greeting(session); -+ fd_count = get_opened_fd_count(); -+ if (fd_count < 0 || getrlimit(RLIMIT_NPROC, &fd_limit) < 0) { -+ TRACE(TRACE_ERR, -+ "[%p] failed to retrieve fd limits, dropping client connection", -+ session); -+ disconnect_user(session); -+ } else if (fd_limit.rlim_cur - fd_count < FREE_DF_THRESHOLD) { -+ TRACE(TRACE_WARNING, -+ "[%p] fd count [%d], fd limit [%d], fd threshold [%d]: dropping client connection", -+ session, fd_count, fd_limit.rlim_cur, FREE_DF_THRESHOLD); -+ disconnect_user(session); -+ } else { -+ send_greeting(session); -+ } - - reset_callbacks(session); - --- -2.10.1 (Apple Git-78) - |