]> git.ipfire.org Git - pakfire.git/commitdiff
libpakfire: Set number of max open files to 512k
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 21 May 2021 10:32:28 +0000 (10:32 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 21 May 2021 10:32:28 +0000 (10:32 +0000)
Following this: http://0pointer.net/blog/file-descriptor-limits.html

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/execute.c
src/libpakfire/include/pakfire/util.h
src/libpakfire/pakfire.c
src/libpakfire/util.c

index 143e78bb657d0c4fbad2f9d3a43858ecccc56093..cb806fbd672f0ff2147671e1625f595e63f9282a 100644 (file)
@@ -368,8 +368,13 @@ static int pakfire_execute_fork(void* data) {
                close(env->stderr[0]);
        }
 
+       // Reset open file limit (http://0pointer.net/blog/file-descriptor-limits.html)
+       int r = pakfire_rlimit_reset_nofile(pakfire);
+       if (r)
+               return r;
+
        // exec() command
-       int r = execvpe(env->argv[0], (char**)env->argv, env->envp);
+       r = execvpe(env->argv[0], (char**)env->argv, env->envp);
        if (r < 0) {
                ERROR(pakfire, "Could not execve(): %s\n", strerror(errno));
        }
index 61573f160689e88b20401b5b9c639d7487ec9e19..74c4f5f339da948160de165117bba7651efee2b9 100644 (file)
@@ -97,6 +97,13 @@ struct timespec timespec_from_ms(int milliseconds);
 
 int timespec_lt(struct timespec* t1, struct timespec* t2);
 
+// Resource Limits
+
+#define PAKFIRE_RLIMIT_NOFILE_MAX (512 * 1024)
+
+int pakfire_rlimit_set(Pakfire pakfire, int limit);
+int pakfire_rlimit_reset_nofile(Pakfire pakfire);
+
 #endif
 
 #endif /* PAKFIRE_UTIL_H */
index 1045aeb54b68725a9d1cc74de1648687e9119982..2f87d8230e059c24f518e68e6253e53e6b0a11d8 100644 (file)
@@ -849,6 +849,11 @@ PAKFIRE_EXPORT int pakfire_create(
        if (r && errno != ENOENT)
                goto ERROR;
 
+       // Bump RLIMIT_NOFILE to maximum
+       r = pakfire_rlimit_set(p, PAKFIRE_RLIMIT_NOFILE_MAX);
+       if (r)
+               goto ERROR;
+
        DEBUG(p, "Pakfire initialized at %p\n", p);
        DEBUG(p, "  arch   = %s\n", pakfire_get_arch(p));
        DEBUG(p, "  path   = %s\n", pakfire_get_path(p));
index 9dd14d6a96d15c53afea92936984fc1d99f89474..fd29b683bca092c2ef27198bd6f2654af57247b6 100644 (file)
@@ -28,6 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <time.h>
@@ -839,3 +840,46 @@ int timespec_lt(struct timespec* t1, struct timespec* t2) {
                (t1->tv_sec == t2->tv_sec && t1->tv_nsec < t2->tv_nsec)
        );
 }
+
+// Resource Limits
+
+int pakfire_rlimit_set(Pakfire pakfire, int limit) {
+       struct rlimit rl;
+
+       // Sanity check
+       if (limit < 3) {
+               errno = EINVAL;
+               return 1;
+       }
+
+       // Fetch current configuration
+       if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
+               ERROR(pakfire, "Could not read RLIMIT_NOFILE: %s\n", strerror(errno));
+               return 1;
+       }
+
+       // Do not attempt to set higher than maximum
+       if ((long unsigned int)limit > rl.rlim_max)
+               limit = rl.rlim_max;
+
+       rl.rlim_cur = limit;
+
+       // Set the new limit
+       if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
+               ERROR(pakfire, "Could not set RLIMIT_NOFILE to %lu: %s\n",
+                       rl.rlim_cur, strerror(errno));
+               return 1;
+       }
+
+       DEBUG(pakfire, "RLIMIT_NOFILE set to %d\n", limit);
+
+       return 0;
+}
+
+/*
+       Resets RLIMIT_NOFILE to FD_SETSIZE (e.g. 1024)
+       for compatibility with software that uses select()
+*/
+int pakfire_rlimit_reset_nofile(Pakfire pakfire) {
+       return pakfire_rlimit_set(pakfire, FD_SETSIZE);
+}