S3: Stop creating SMBD cores when failing to create a pipe.
authortodd stecher <todd.stecher@gmail.com>
Thu, 12 Feb 2009 08:11:38 +0000 (00:11 -0800)
committerSteven Danneman <steven.danneman@isilon.com>
Thu, 19 Feb 2009 02:08:33 +0000 (18:08 -0800)
This was uncovered when the MAX FD limit was hit, causing an instant core
and invoking error reporting. This fix causes SMBD to exit, but without
building a core.

source3/lib/select.c
source3/printing/printing.c
source3/smbd/server.c

index 14e59257bac03c715f40ef32d87172d7b380a0f4..a58530af8d343eebe72ac484ce94e61a812999b1 100644 (file)
@@ -59,7 +59,17 @@ int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, s
 
        if (initialised != sys_getpid()) {
                if (pipe(select_pipe) == -1)
-                       smb_panic("Could not create select pipe");
+               {
+                       DEBUG(0, ("sys_select: pipe failed (%s)\n",
+                               strerror(errno)));
+                       if (readfds != NULL)
+                               FD_ZERO(readfds);
+                       if (writefds != NULL)
+                               FD_ZERO(writefds);
+                       if (errorfds != NULL)
+                               FD_ZERO(errorfds);
+                       return -1;
+               }
 
                /*
                 * These next two lines seem to fix a bug with the Linux
index 17ddc55efac615e52d359c7f3d9ab75f609d8e49..7179184b735542a5b9dc6ef63a99fd9823b828d6 100644 (file)
@@ -1478,9 +1478,13 @@ void start_background_queue(void)
 
                        ret = sys_select(maxfd, &r_fds, &w_fds, NULL, &to);
 
-                       /* If pause_pipe[1] is closed it means the parent smbd
-                        * and children exited or aborted. */
-                       if (ret == 1 && FD_ISSET(pause_pipe[1], &r_fds)) {
+                       /*
+                        * If pause_pipe[1] is closed it means the parent smbd
+                        * and children exited or aborted. If sys_select()
+                        * failed, then something more sinister is wrong
+                        */
+                       if ((ret < 0) ||
+                           (ret == 1 && FD_ISSET(pause_pipe[1], &r_fds))) {
                                 exit_server_cleanly(NULL);
                        }
 
index 76dab96ad94ad5847d5feafcd57f8252b5d8c181..e8ccba0873aef5bd4ee968ede959fb6ec17bd745 100644 (file)
@@ -694,6 +694,10 @@ static void smbd_parent_loop(struct smbd_parent_context *parent)
                        continue;
                }
 
+               /* socket error */
+               if (num < 0)
+                       exit_server_cleanly("socket error");
+
                /* If the idle timeout fired and we don't have any connected
                 * users, exit gracefully. We should be running under a process
                 * controller that will restart us if necessry.