Revert "s3-printing: update parent smbd pcap cache"
[samba.git] / source3 / smbd / server.c
index 4b1c803d759530db9e3bd47b42f5cf7d9fbb23d3..0c591357548a9e0a1c4096310c24bc348a59d663 100644 (file)
@@ -219,19 +219,53 @@ static void add_child_pid(pid_t pid)
        num_children += 1;
 }
 
+/*
+  at most every smbd:cleanuptime seconds (default 20), we scan the BRL
+  and locking database for entries to cleanup. As a side effect this
+  also cleans up dead entries in the connections database (due to the
+  traversal in message_send_all()
+
+  Using a timer for this prevents a flood of traversals when a large
+  number of clients disconnect at the same time (perhaps due to a
+  network outage).  
+*/
+
+static void cleanup_timeout_fn(struct event_context *event_ctx,
+                               struct timed_event *te,
+                               struct timeval now,
+                               void *private_data)
+{
+       struct timed_event **cleanup_te = (struct timed_event **)private_data;
+
+       DEBUG(1,("Cleaning up brl and lock database after unclean shutdown\n"));
+       message_send_all(smbd_messaging_context(), MSG_SMB_UNLOCK, NULL, 0, NULL);
+       messaging_send_buf(smbd_messaging_context(), procid_self(), 
+                               MSG_SMB_BRL_VALIDATE, NULL, 0);
+       /* mark the cleanup as having been done */
+       (*cleanup_te) = NULL;
+}
+
 static void remove_child_pid(pid_t pid, bool unclean_shutdown)
 {
        struct child_pid *child;
+       static struct timed_event *cleanup_te;
 
        if (unclean_shutdown) {
-               /* a child terminated uncleanly so tickle all processes to see 
-                  if they can grab any of the pending locks
-               */
-               DEBUG(3,(__location__ " Unclean shutdown of pid %u\n", (unsigned int)pid));
-               messaging_send_buf(smbd_messaging_context(), procid_self(), 
-                                  MSG_SMB_BRL_VALIDATE, NULL, 0);
-               message_send_all(smbd_messaging_context(), 
-                                MSG_SMB_UNLOCK, NULL, 0, NULL);
+               /* a child terminated uncleanly so tickle all
+                  processes to see if they can grab any of the
+                  pending locks
+                */
+               DEBUG(3,(__location__ " Unclean shutdown of pid %u\n", 
+                       (unsigned int)pid));
+               if (!cleanup_te) {
+                       /* call the cleanup timer, but not too often */
+                       int cleanup_time = lp_parm_int(-1, "smbd", "cleanuptime", 20);
+                       cleanup_te = event_add_timed(smbd_event_context(), NULL,
+                                               timeval_current_ofs(cleanup_time, 0),
+                                               cleanup_timeout_fn, 
+                                               &cleanup_te);
+                       DEBUG(1,("Scheduled cleanup of brl and lock database after unclean shutdown\n"));
+               }
        }
 
        for (child = children; child != NULL; child = child->next) {
@@ -914,8 +948,6 @@ static bool init_structs(void )
 
        file_init();
 
-       init_dptrs();
-
        if (!secrets_init())
                return False;
 
@@ -1220,6 +1252,15 @@ extern void build_options(bool screen);
                return -1;
        }
 
+       /* Open the share_info.tdb here, so we don't have to open
+          after the fork on every single connection.  This is a small
+          performance improvment and reduces the total number of system
+          fds used. */
+       if (!share_info_db_init()) {
+               DEBUG(0,("ERROR: failed to load share info db.\n"));
+               exit(1);
+       }
+
        /* only start the background queue daemon if we are 
           running as a daemon -- bad things will happen if
           smbd is launched via inetd and we fork a copy of 
@@ -1265,9 +1306,12 @@ extern void build_options(bool screen);
                exit_server("open_sockets_smbd() failed");
 
        TALLOC_FREE(frame);
+       /* make sure we always have a valid stackframe */
+       frame = talloc_stackframe();
 
        smbd_parent_loop(parent);
 
        exit_server_cleanly(NULL);
+       TALLOC_FREE(frame);
        return(0);
 }