Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-2609

Several close syscalls during fork if nofile is high during do_command [rhel-8.10]

    • Icon: Bug Bug
    • Resolution: Done-Errata
    • Icon: Major Major
    • rhel-8.10
    • rhel-8.10
    • cronie
    • None
    • rhel-sst-pt-python-ruby-nodejs
    • ssg_core_services
    • 14
    • 20
    • None
    • Dev ack
    • False
    • Hide

      None

      Show
      None
    • None
    • Red Hat Enterprise Linux
    • None
    • None

      Hello,

       

       

      When nofile limit is high, the close to all the (non existing) FDs will take time after the fork in do_command.
      We can use /proc/self/fd to close only existing FD.

      I submitted a PR upstream:

      https://github.com/cronie-crond/cronie/pull/151

      Patch attached for RHEL 8.6:

      ~~~

      — ./src/do_command.c  2023-09-07 09:40:32.016272074 +0200
      +++ ./src/do_command.c  2023-09-07 09:43:04.938995232 +0200
      @@ -30,6 +30,7 @@
      #include <string.h>
      #include <sys/wait.h>
      #include <unistd.h>
      +#include <dirent.h>

      #include "externs.h"
      #include "funcs.h"
      @@ -239,10 +240,26 @@
                     {
                             char *shell = env_get("SHELL", jobenv);
                             int fd, fdmax = getdtablesize();
      +                       DIR *dir;
      +                       struct dirent *dent;

      -                       /* close all unwanted open file descriptors */
      -                       for(fd = STDERR + 1; fd < fdmax; fd++) {
      -                               close(fd);
      +                       /*
      +                        * if /proc is mounted, we can optimize what fd can be closed,
      +                        * but if it isn't available, fall back to the previous behavior.
      +                        */
      +                       if ((dir = opendir("/proc/self/fd")) != NULL) {
      +                               while ((dent = readdir(dir)) != NULL) {
      +                                       if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
      +                                               continue;
      +                                       fd = atoi(dent->d_name);
      +                                       if (fd > STDERR_FILENO)
      +                                               close(fd);
      +                                       }
      +                       } else {
      +                               /* close all unwanted open file descriptors */
      +                               for(fd = STDERR + 1; fd < fdmax; fd++) {
      +                                       close(fd);
      +                               }
                             }

      #if DEBUGGING

      ~~~

       

              opohorel@redhat.com Ondrej Pohorelsky
              rhn-support-bwelterl Benoit Welterlen
              Jan Stanek Jan Stanek
              Jan Houška Jan Houška (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              7 Start watching this issue

                Created:
                Updated:
                Resolved: