ContainerizationOS: Speed up fd closes (#222)

Instead of looping through from minimum fd -> rlimit max, we can
close_range(2) or read /proc/self/fd on Linux, and read /dev/fd on
macOS.
This commit is contained in:
Danny Canter
2025-07-22 10:30:10 -04:00
committed by GitHub
parent 8b93a2083a
commit fcd198e968
2 changed files with 65 additions and 8 deletions
+62 -8
View File
@@ -14,8 +14,12 @@
* limitations under the License.
*/
#if defined(__linux__) || defined(__APPLE__)
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <limits.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
@@ -31,6 +35,60 @@
#include "exec_command.h"
#ifndef SYS_close_range
#define SYS_close_range 436
#endif
#ifndef CLOSE_RANGE_CLOEXEC
#define CLOSE_RANGE_CLOEXEC 0x4
#endif
static int mark_cloexec(int fd) {
int flags = fcntl(fd, F_GETFD);
if (flags == -1) return flags;
if (flags & FD_CLOEXEC) return 0;
return fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
}
static int cloexec_from(int min_fd) {
#if defined(__linux__)
// First try close_range.
long ret = syscall(SYS_close_range, min_fd, ~0U, CLOSE_RANGE_CLOEXEC);
if (ret == 0) {
return 0;
}
const char* dirpath = "/proc/self/fd";
#elif defined(__APPLE__)
const char* dirpath = "/dev/fd";
#endif
DIR *dp = opendir(dirpath);
if (!dp) return -1;
int dp_fd = dirfd(dp);
struct dirent *de;
while ((de = readdir(dp))) {
if (de->d_name[0] == '.') continue;
char *end;
long val = strtol(de->d_name, &end, 10);
if (*end || val < 0 || val > INT_MAX) continue;
int fd = (int)val;
if (fd < min_fd || fd == dp_fd) continue;
int ret = mark_cloexec(fd);
if (ret != 0) {
return ret;
}
}
close(dp_fd);
closedir(dp);
return 0;
}
void exec_command_attrs_init(struct exec_command_attrs *attrs) {
attrs->setpgid = 0;
attrs->pgid = 0;
@@ -195,16 +253,10 @@ static void child_handler(const int sync_pipes[2], const char *executable,
}
}
// Get our current open fd limit and close exec everything outside of our
// child's fd_table.
if (getrlimit(RLIMIT_NOFILE, &limits) < 0) {
// close exec everything outside of our child's fd_table.
if (cloexec_from(file_handle_count) != 0) {
goto fail;
}
for (i = file_handle_count; i <= limits.rlim_cur; i++) {
if (fcntl(i, F_SETFD, FD_CLOEXEC) == -1 && errno != EBADF) {
goto fail;
}
}
// set gid
if (attrs.gid != -1) {
@@ -312,3 +364,5 @@ fail:
}
return 0;
}
#endif
+3
View File
@@ -17,6 +17,8 @@
#ifndef exec_command_h
#define exec_command_h
#if defined(__linux__) || defined(__APPLE__)
#include <sys/types.h>
#include <unistd.h>
@@ -46,4 +48,5 @@ int exec_command(pid_t *result, const char *executable, char *const argv[],
const int file_handle_count, const char *working_directory,
struct exec_command_attrs *attrs);
#endif /* defined(__linux__) || defined(__APPLE__) */
#endif /* exec_command_h */