aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2017-04-25 15:25:54 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-06-26 11:39:39 +0100
commit83beee3769848e5a927f492eadbe1794e4ba757a (patch)
tree731a921c106538520b2807eeeb6a18c4e854db04
parent12c8adab7bf0a63d05c30e0ab28f0162bbba1586 (diff)
downloadpseudo-83beee3769848e5a927f492eadbe1794e4ba757a.tar.gz
pseudo-83beee3769848e5a927f492eadbe1794e4ba757a.tar.bz2
pseudo-83beee3769848e5a927f492eadbe1794e4ba757a.zip
pseudo: Handle too many files deadlock
Currently if we max out the maximum number of files, pseudo can deadlock, unable to accept new connections yet unable to move forward and unblock the other processes waiting either. Rather than hang, when this happens, close out inactive connections, allowing us to accept the new ones. The disconnected clients will simply reconnect. There is a small risk of data loss here sadly but its better than hanging. RP 2017/4/25 Upstream-Status: Submitted [Peter is aware of the issue] Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--pseudo_server.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/pseudo_server.c b/pseudo_server.c
index 898aab4..84cef05 100644
--- a/pseudo_server.c
+++ b/pseudo_server.c
@@ -792,6 +792,7 @@ pseudo_server_loop(void) {
struct sigaction eat_usr2 = {
.sa_handler = set_do_list_clients
};
+ int hitmaxfiles;
clients = malloc(16 * sizeof(*clients));
@@ -810,6 +811,7 @@ pseudo_server_loop(void) {
active_clients = 1;
max_clients = 16;
highest_client = 0;
+ hitmaxfiles = 0;
pseudo_debug(PDBGF_SERVER, "server loop started.\n");
if (listen_fd < 0) {
@@ -868,10 +870,15 @@ pseudo_server_loop(void) {
} else {
serve_client(i);
}
+ } else if (hitmaxfiles) {
+ /* Only close one per loop iteration in the interests of caution */
+ close_client(i);
+ hitmaxfiles = 0;
}
if (die_forcefully)
break;
}
+ hitmaxfiles = 0;
if (!die_forcefully &&
(FD_ISSET(clients[0].fd, &events) ||
FD_ISSET(clients[0].fd, &reads))) {
@@ -893,6 +900,9 @@ pseudo_server_loop(void) {
*/
pseudo_server_timeout = DEFAULT_PSEUDO_SERVER_TIMEOUT;
die_peacefully = 0;
+ } else if (errno == EMFILE) {
+ hitmaxfiles = 1;
+ pseudo_debug(PDBGF_SERVER, "Hit max open files, dropping a client.\n");
}
}
pseudo_debug(PDBGF_SERVER, "server loop complete [%d clients left]\n", active_clients);