aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Simon Ser <contact@emersion.fr>2021-10-21 21:52:17 +0200
committerLibravatar Simon Zeni <simon@bl4ckb0ne.ca>2021-10-30 08:19:35 -0600
commit38020d157ddb58e756c654e9a2ff203c1562b25b (patch)
treee042c3c6d0d9f03e75812dffc0ac2e54d9b6dd8e
parentAdd smart_gaps inverse_outer command (diff)
downloadsway-38020d157ddb58e756c654e9a2ff203c1562b25b.tar.gz
sway-38020d157ddb58e756c654e9a2ff203c1562b25b.tar.zst
sway-38020d157ddb58e756c654e9a2ff203c1562b25b.zip
Bump RLIMIT_NOFILE
Wayland compositors handle many file descriptors: client connections, DMA-BUFs, sync_files, wl_data_device pipes, and so on. Bump the limit to the max. Closes: https://github.com/swaywm/sway/issues/6285
-rw-r--r--include/sway/server.h2
-rw-r--r--sway/commands/exec_always.c2
-rw-r--r--sway/config/bar.c2
-rw-r--r--sway/config/output.c2
-rw-r--r--sway/main.c31
-rw-r--r--sway/swaynag.c2
6 files changed, 41 insertions, 0 deletions
diff --git a/include/sway/server.h b/include/sway/server.h
index 88dda097..f99bbda6 100644
--- a/include/sway/server.h
+++ b/include/sway/server.h
@@ -137,6 +137,8 @@ void server_fini(struct sway_server *server);
137bool server_start(struct sway_server *server); 137bool server_start(struct sway_server *server);
138void server_run(struct sway_server *server); 138void server_run(struct sway_server *server);
139 139
140void restore_nofile_limit(void);
141
140void handle_compositor_new_surface(struct wl_listener *listener, void *data); 142void handle_compositor_new_surface(struct wl_listener *listener, void *data);
141void handle_new_output(struct wl_listener *listener, void *data); 143void handle_new_output(struct wl_listener *listener, void *data);
142 144
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c
index fce337d5..b35065c1 100644
--- a/sway/commands/exec_always.c
+++ b/sway/commands/exec_always.c
@@ -7,6 +7,7 @@
7#include <signal.h> 7#include <signal.h>
8#include "sway/commands.h" 8#include "sway/commands.h"
9#include "sway/config.h" 9#include "sway/config.h"
10#include "sway/server.h"
10#include "sway/tree/container.h" 11#include "sway/tree/container.h"
11#include "sway/tree/root.h" 12#include "sway/tree/root.h"
12#include "sway/tree/workspace.h" 13#include "sway/tree/workspace.h"
@@ -53,6 +54,7 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) {
53 // Fork process 54 // Fork process
54 if ((pid = fork()) == 0) { 55 if ((pid = fork()) == 0) {
55 // Fork child process again 56 // Fork child process again
57 restore_nofile_limit();
56 setsid(); 58 setsid();
57 sigset_t set; 59 sigset_t set;
58 sigemptyset(&set); 60 sigemptyset(&set);
diff --git a/sway/config/bar.c b/sway/config/bar.c
index e09add44..d1b342e6 100644
--- a/sway/config/bar.c
+++ b/sway/config/bar.c
@@ -219,6 +219,8 @@ static void invoke_swaybar(struct bar_config *bar) {
219 sigprocmask(SIG_SETMASK, &set, NULL); 219 sigprocmask(SIG_SETMASK, &set, NULL);
220 signal(SIGPIPE, SIG_DFL); 220 signal(SIGPIPE, SIG_DFL);
221 221
222 restore_nofile_limit();
223
222 pid = fork(); 224 pid = fork();
223 if (pid < 0) { 225 if (pid < 0) {
224 sway_log_errno(SWAY_ERROR, "fork failed"); 226 sway_log_errno(SWAY_ERROR, "fork failed");
diff --git a/sway/config/output.c b/sway/config/output.c
index 8e937b28..6d39c2f5 100644
--- a/sway/config/output.c
+++ b/sway/config/output.c
@@ -750,6 +750,8 @@ static bool _spawn_swaybg(char **command) {
750 sway_log_errno(SWAY_ERROR, "fork failed"); 750 sway_log_errno(SWAY_ERROR, "fork failed");
751 return false; 751 return false;
752 } else if (pid == 0) { 752 } else if (pid == 0) {
753 restore_nofile_limit();
754
753 pid = fork(); 755 pid = fork();
754 if (pid < 0) { 756 if (pid < 0) {
755 sway_log_errno(SWAY_ERROR, "fork failed"); 757 sway_log_errno(SWAY_ERROR, "fork failed");
diff --git a/sway/main.c b/sway/main.c
index 264fa847..2c760524 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -6,6 +6,7 @@
6#include <stdio.h> 6#include <stdio.h>
7#include <stdlib.h> 7#include <stdlib.h>
8#include <string.h> 8#include <string.h>
9#include <sys/resource.h>
9#include <sys/stat.h> 10#include <sys/stat.h>
10#include <sys/types.h> 11#include <sys/types.h>
11#include <sys/wait.h> 12#include <sys/wait.h>
@@ -27,6 +28,7 @@
27 28
28static bool terminate_request = false; 29static bool terminate_request = false;
29static int exit_value = 0; 30static int exit_value = 0;
31static struct rlimit original_nofile_rlimit = {0};
30struct sway_server server = {0}; 32struct sway_server server = {0};
31struct sway_debug debug = {0}; 33struct sway_debug debug = {0};
32 34
@@ -169,6 +171,33 @@ static bool drop_permissions(void) {
169 return true; 171 return true;
170} 172}
171 173
174static void increase_nofile_limit(void) {
175 if (getrlimit(RLIMIT_NOFILE, &original_nofile_rlimit) != 0) {
176 sway_log_errno(SWAY_ERROR, "Failed to bump max open files limit: "
177 "getrlimit(NOFILE) failed");
178 return;
179 }
180
181 struct rlimit new_rlimit = original_nofile_rlimit;
182 new_rlimit.rlim_cur = new_rlimit.rlim_max;
183 if (setrlimit(RLIMIT_NOFILE, &new_rlimit) != 0) {
184 sway_log_errno(SWAY_ERROR, "Failed to bump max open files limit: "
185 "setrlimit(NOFILE) failed");
186 sway_log(SWAY_INFO, "Running with %d max open files",
187 (int)original_nofile_rlimit.rlim_cur);
188 }
189}
190
191void restore_nofile_limit(void) {
192 if (original_nofile_rlimit.rlim_cur == 0) {
193 return;
194 }
195 if (setrlimit(RLIMIT_NOFILE, &original_nofile_rlimit) != 0) {
196 sway_log_errno(SWAY_ERROR, "Failed to restore max open files limit: "
197 "setrlimit(NOFILE) failed");
198 }
199}
200
172void enable_debug_flag(const char *flag) { 201void enable_debug_flag(const char *flag) {
173 if (strcmp(flag, "damage=highlight") == 0) { 202 if (strcmp(flag, "damage=highlight") == 0) {
174 debug.damage = DAMAGE_HIGHLIGHT; 203 debug.damage = DAMAGE_HIGHLIGHT;
@@ -349,6 +378,8 @@ int main(int argc, char **argv) {
349 exit(EXIT_FAILURE); 378 exit(EXIT_FAILURE);
350 } 379 }
351 380
381 increase_nofile_limit();
382
352 // handle SIGTERM signals 383 // handle SIGTERM signals
353 signal(SIGTERM, sig_handler); 384 signal(SIGTERM, sig_handler);
354 signal(SIGINT, sig_handler); 385 signal(SIGINT, sig_handler);
diff --git a/sway/swaynag.c b/sway/swaynag.c
index ba582989..4a0a6d30 100644
--- a/sway/swaynag.c
+++ b/sway/swaynag.c
@@ -64,6 +64,8 @@ bool swaynag_spawn(const char *swaynag_command,
64 sway_log(SWAY_ERROR, "Failed to create fork for swaynag"); 64 sway_log(SWAY_ERROR, "Failed to create fork for swaynag");
65 goto failed; 65 goto failed;
66 } else if (pid == 0) { 66 } else if (pid == 0) {
67 restore_nofile_limit();
68
67 pid = fork(); 69 pid = fork();
68 if (pid < 0) { 70 if (pid < 0) {
69 sway_log_errno(SWAY_ERROR, "fork failed"); 71 sway_log_errno(SWAY_ERROR, "fork failed");