-
Notifications
You must be signed in to change notification settings - Fork 375
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Optimize and unite setting CLOEXEC on fds
In case maximum number of open files limit is set too high, both luaext/Pexec() and lib/doScriptExec() spend way too much time trying to set FD_CLOEXEC flag for all those file descriptors, resulting in severe increase of time it takes to execute rpm or dnf. This becomes increasingly noticeable when running with e.g. under Docker because: > $ docker run fedora ulimit -n > 1048576 One obvious fix is to use procfs to get the actual list of opened fds and iterate over it. My quick-n-dirty benchmark shows the /proc approach is about 10x faster than iterating through a list of 1024 fds. Note that the old method is still used in case /proc is not available. While at it, unite the two implementations, and future* proof it by making sure we modify the existing flags. * - currently the only known flag is FD_CLOEXEC. This should fix: - moby/moby#23137 - https://bugzilla.redhat.com/show_bug.cgi?id=1537564 Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
- Loading branch information
Showing
5 changed files
with
60 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
#include <stdlib.h> | ||
#include <fcntl.h> | ||
#include <unistd.h> | ||
#include <sys/types.h> | ||
#include <dirent.h> | ||
#include "rpmutil.h" | ||
|
||
static void set_cloexec(int fd) | ||
{ | ||
int flags = fcntl(fd, F_GETFD); | ||
|
||
if (flags == -1 || (flags & FD_CLOEXEC)) | ||
return; | ||
|
||
fcntl(fd, F_SETFD, flags | FD_CLOEXEC); | ||
} | ||
|
||
void rpmSetCloseOnExec(void) | ||
{ | ||
const int min_fd = STDERR_FILENO; // don't touch stdin/out/err | ||
int fd, open_max; | ||
|
||
// iterate over fds obtained from /proc | ||
DIR *dir = opendir("/proc/self/fd"); | ||
if (dir == NULL) { | ||
// no /proc mounted | ||
goto fallback; | ||
} | ||
|
||
struct dirent *entry; | ||
while ((entry = readdir(dir)) != NULL) { | ||
fd = atoi(entry->d_name); | ||
if (fd > min_fd) | ||
set_cloexec(fd); | ||
} | ||
closedir(dir); | ||
|
||
return; | ||
|
||
fallback: | ||
// iterate over all possible fds | ||
open_max = sysconf(_SC_OPEN_MAX); | ||
if (open_max == -1) { | ||
open_max = 1024; | ||
} | ||
|
||
for (fd = min_fd + 1; fd < open_max; fd++) | ||
set_cloexec(fd); | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters