We are triggering the cleanup_timeout_fn() too often, on exiting when an smbd is...
[ddiss/samba.git] / source3 / smbd / server_exit.c
index 3e0da3e1cf71d1bdd5fc860d27d4e17eded2a9d9..fc77deec72b241e699f53dde81c5b997fc59d350 100644 (file)
 */
 
 #include "includes.h"
+#include "smbd/smbd.h"
 #include "smbd/globals.h"
-#include "librpc/gen_ndr/messaging.h"
+#include "ntdomain.h"
+#include "../librpc/gen_ndr/srv_dfs.h"
+#include "../librpc/gen_ndr/srv_dssetup.h"
+#include "../librpc/gen_ndr/srv_echo.h"
+#include "../librpc/gen_ndr/srv_eventlog.h"
+#include "../librpc/gen_ndr/srv_initshutdown.h"
+#include "../librpc/gen_ndr/srv_lsa.h"
+#include "../librpc/gen_ndr/srv_netlogon.h"
+#include "../librpc/gen_ndr/srv_ntsvcs.h"
+#include "../librpc/gen_ndr/srv_samr.h"
+#include "../librpc/gen_ndr/srv_spoolss.h"
+#include "../librpc/gen_ndr/srv_srvsvc.h"
+#include "../librpc/gen_ndr/srv_svcctl.h"
+#include "../librpc/gen_ndr/srv_winreg.h"
+#include "../librpc/gen_ndr/srv_wkssvc.h"
+#include "printing/notify.h"
+#include "printing.h"
+#include "serverid.h"
 
 static struct files_struct *log_writeable_file_fn(
        struct files_struct *fsp, void *private_data)
@@ -65,7 +83,6 @@ static void exit_server_common(enum server_exit_reason how,
 static void exit_server_common(enum server_exit_reason how,
        const char *const reason)
 {
-       bool had_open_conn = false;
        struct smbd_server_connection *sconn = smbd_server_conn;
 
        if (!exit_firsttime)
@@ -75,25 +92,28 @@ static void exit_server_common(enum server_exit_reason how,
        change_to_root_user();
 
        if (sconn && sconn->smb1.negprot.auth_context) {
-               struct auth_context *a = sconn->smb1.negprot.auth_context;
-               a->free(&sconn->smb1.negprot.auth_context);
-       }
-
-       if (lp_log_writeable_files_on_exit()) {
-               bool found = false;
-               files_forall(log_writeable_file_fn, &found);
+               TALLOC_FREE(sconn->smb1.negprot.auth_context);
        }
 
        if (sconn) {
-               had_open_conn = conn_close_all(sconn);
+               if (lp_log_writeable_files_on_exit()) {
+                       bool found = false;
+                       files_forall(sconn, log_writeable_file_fn, &found);
+               }
+               (void)conn_close_all(sconn);
                invalidate_all_vuids(sconn);
        }
 
        /* 3 second timeout. */
-       print_notify_send_messages(smbd_messaging_context(), 3);
+       print_notify_send_messages(sconn->msg_ctx, 3);
 
        /* delete our entry in the serverid database. */
-       serverid_deregister_self();
+       if (am_parent) {
+               /*
+                * For children the parent takes care of cleaning up
+                */
+               serverid_deregister(sconn_server_id(sconn));
+       }
 
 #ifdef WITH_DFS
        if (dcelogin_atmost_once) {
@@ -110,8 +130,26 @@ static void exit_server_common(enum server_exit_reason how,
        }
 #endif
 
-       locking_end();
-       printing_end();
+       if (am_parent) {
+               rpc_wkssvc_shutdown();
+               rpc_dssetup_shutdown();
+#ifdef DEVELOPER
+               rpc_rpcecho_shutdown();
+#endif
+               rpc_netdfs_shutdown();
+               rpc_initshutdown_shutdown();
+               rpc_eventlog_shutdown();
+               rpc_ntsvcs_shutdown();
+               rpc_svcctl_shutdown();
+               rpc_spoolss_shutdown();
+
+               rpc_srvsvc_shutdown();
+               rpc_winreg_shutdown();
+
+               rpc_netlogon_shutdown();
+               rpc_samr_shutdown();
+               rpc_lsarpc_shutdown();
+       }
 
        /*
         * we need to force the order of freeing the following,
@@ -119,15 +157,14 @@ static void exit_server_common(enum server_exit_reason how,
         */
        sconn = NULL;
        TALLOC_FREE(smbd_server_conn);
-       TALLOC_FREE(smbd_msg_ctx);
-       TALLOC_FREE(smbd_event_ctx);
+       server_messaging_context_free();
+       server_event_context_free();
        TALLOC_FREE(smbd_memcache_ctx);
 
-       if (how != SERVER_EXIT_NORMAL) {
-               int oldlevel = DEBUGLEVEL;
-
-               DEBUGLEVEL = 10;
+       locking_end();
+       printing_end();
 
+       if (how != SERVER_EXIT_NORMAL) {
                DEBUGSEP(0);
                DEBUG(0,("Abnormal server exit: %s\n",
                        reason ? reason : "no explanation provided"));
@@ -135,9 +172,10 @@ static void exit_server_common(enum server_exit_reason how,
 
                log_stack_trace();
 
-               DEBUGLEVEL = oldlevel;
                dump_core();
 
+               /* Notreached. */
+               exit(1);
        } else {
                DEBUG(3,("Server exit (%s)\n",
                        (reason ? reason : "normal exit")));
@@ -147,15 +185,7 @@ static void exit_server_common(enum server_exit_reason how,
                gencache_stabilize();
        }
 
-       /* if we had any open SMB connections when we exited then we
-          need to tell the parent smbd so that it can trigger a retry
-          of any locks we may have been holding or open files we were
-          blocking */
-       if (had_open_conn) {
-               exit(1);
-       } else {
-               exit(0);
-       }
+       exit(0);
 }
 
 void exit_server(const char *const explanation)