static void remove_child_pid(struct smbd_parent_context *parent, pid_t pid, bool unclean_shutdown) { struct smbd_child_pid *child; struct server_id child_id; int ret; child_id = pid_to_procid(pid); ret = messaging_cleanup(parent->msg_ctx, pid); if ((ret != 0) && (ret != ENOENT)) { DEBUG(10, ("%s: messaging_cleanup returned %s\n", __func__, strerror(ret))); } smbprofile_cleanup(pid); for (child = parent->children; child != NULL; child = child->next) { if (child->pid == pid) { struct smbd_child_pid *tmp = child; DLIST_REMOVE(parent->children, child); TALLOC_FREE(tmp); parent->num_children -= 1; break; } } if (child == NULL) { /* not all forked child processes are added to the children list */ DEBUG(2, ("Could not find child %d -- ignoring\n", (int)pid)); return; } 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)); if (parent->cleanup_te == NULL) { /* call the cleanup timer, but not too often */ int cleanup_time = lp_parm_int(-1, "smbd", "cleanuptime", 20); parent->cleanup_te = tevent_add_timer(parent->ev_ctx, parent, timeval_current_ofs(cleanup_time, 0), cleanup_timeout_fn, parent); DEBUG(1,("Scheduled cleanup of brl and lock database after unclean shutdown\n")); } } if (!serverid_deregister(child_id)) { DEBUG(1, ("Could not remove pid %d from serverid.tdb\n", (int)pid)); } }
static void remove_child_pid(struct tevent_context *ev_ctx, pid_t pid, bool unclean_shutdown) { struct child_pid *child; static struct timed_event *cleanup_te; struct server_id child_id; 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)); 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(ev_ctx, 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")); } } child_id = procid_self(); /* Just initialize pid and potentially vnn */ child_id.pid = pid; if (!serverid_deregister(child_id)) { DEBUG(1, ("Could not remove pid %d from serverid.tdb\n", (int)pid)); } for (child = children; child != NULL; child = child->next) { if (child->pid == pid) { struct child_pid *tmp = child; DLIST_REMOVE(children, child); SAFE_FREE(tmp); num_children -= 1; return; } } /* not all forked child processes are added to the children list */ DEBUG(1, ("Could not find child %d -- ignoring\n", (int)pid)); }
static void terminate(bool is_parent) { if (is_parent) { /* When parent goes away we should * remove the socket file. Not so * when children terminate. */ char *path = NULL; if (asprintf(&path, "%s/%s", get_winbind_pipe_dir(), WINBINDD_SOCKET_NAME) > 0) { unlink(path); SAFE_FREE(path); } } idmap_close(); trustdom_cache_shutdown(); gencache_stabilize(); #if 0 if (interactive) { TALLOC_CTX *mem_ctx = talloc_init("end_description"); char *description = talloc_describe_all(mem_ctx); DEBUG(3, ("tallocs left:\n%s\n", description)); talloc_destroy(mem_ctx); } #endif if (is_parent) { struct messaging_context *msg = winbind_messaging_context(); struct server_id self = messaging_server_id(msg); serverid_deregister(self); pidfile_unlink(lp_piddir(), "winbindd"); } exit(0); }
static void terminate(void) { DEBUG(0,("Got SIGTERM: going down...\n")); /* Write out wins.dat file if samba is a WINS server */ wins_write_database(0,False); /* Remove all SELF registered names from WINS */ release_wins_names(); /* Announce all server entries as 0 time-to-live, 0 type. */ announce_my_servers_removed(); /* If there was an async dns child - kill it. */ kill_async_dns_child(); gencache_stabilize(); serverid_deregister(procid_self()); pidfile_unlink(); exit(0); }
static void exit_server_common(enum server_exit_reason how, const char *reason) { struct smbXsrv_connection *conn = global_smbXsrv_connection; struct smbd_server_connection *sconn = NULL; struct messaging_context *msg_ctx = server_messaging_context(); if (conn != NULL) { sconn = conn->sconn; } if (!exit_firsttime) exit(0); exit_firsttime = false; change_to_root_user(); if (sconn) { NTSTATUS status; if (NT_STATUS_IS_OK(sconn->status)) { switch (how) { case SERVER_EXIT_ABNORMAL: sconn->status = NT_STATUS_INTERNAL_ERROR; break; case SERVER_EXIT_NORMAL: sconn->status = NT_STATUS_LOCAL_DISCONNECT; break; } } TALLOC_FREE(sconn->smb1.negprot.auth_context); if (lp_log_writeable_files_on_exit()) { bool found = false; files_forall(sconn, log_writeable_file_fn, &found); } /* * Note: this is a no-op for smb2 as * conn->tcon_table is empty */ status = smb1srv_tcon_disconnect_all(conn); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Server exit (%s)\n", (reason ? reason : "normal exit"))); DEBUG(0, ("exit_server_common: " "smb1srv_tcon_disconnect_all() failed (%s) - " "triggering cleanup\n", nt_errstr(status))); how = SERVER_EXIT_ABNORMAL; reason = "smb1srv_tcon_disconnect_all failed"; } status = smbXsrv_session_logoff_all(conn); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Server exit (%s)\n", (reason ? reason : "normal exit"))); DEBUG(0, ("exit_server_common: " "smbXsrv_session_logoff_all() failed (%s) - " "triggering cleanup\n", nt_errstr(status))); how = SERVER_EXIT_ABNORMAL; reason = "smbXsrv_session_logoff_all failed"; } change_to_root_user(); } /* 3 second timeout. */ print_notify_send_messages(msg_ctx, 3); /* delete our entry in the serverid database. */ if (am_parent) { /* * For children the parent takes care of cleaning up */ serverid_deregister(messaging_server_id(msg_ctx)); } #ifdef WITH_DFS if (dcelogin_atmost_once) { dfs_unlogin(); } #endif #ifdef USE_DMAPI /* Destroy Samba DMAPI session only if we are master smbd process */ if (am_parent) { if (!dmapi_destroy_session()) { DEBUG(0,("Unable to close Samba DMAPI session\n")); } } #endif 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, * because smbd_msg_ctx is not a talloc child of smbd_server_conn. */ sconn = NULL; conn = NULL; TALLOC_FREE(global_smbXsrv_connection); server_messaging_context_free(); server_event_context_free(); TALLOC_FREE(smbd_memcache_ctx); locking_end(); printing_end(); if (how != SERVER_EXIT_NORMAL) { smb_panic(reason); /* Notreached. */ exit(1); } else { DEBUG(3,("Server exit (%s)\n", (reason ? reason : "normal exit"))); if (am_parent) { pidfile_unlink(lp_pid_directory(), "smbd"); } gencache_stabilize(); } exit(0); }
static int smbd_scavenger_server_id_destructor(struct server_id *id) { serverid_deregister(*id); return 0; }
static void exit_server_common(enum server_exit_reason how, const char *const reason) { struct smbd_server_connection *sconn = smbd_server_conn; if (!exit_firsttime) exit(0); exit_firsttime = false; change_to_root_user(); if (sconn && sconn->smb1.negprot.auth_context) { TALLOC_FREE(sconn->smb1.negprot.auth_context); } if (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(sconn->msg_ctx, 3); /* delete our entry in the serverid database. */ 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) { dfs_unlogin(); } #endif #ifdef USE_DMAPI /* Destroy Samba DMAPI session only if we are master smbd process */ if (am_parent) { if (!dmapi_destroy_session()) { DEBUG(0,("Unable to close Samba DMAPI session\n")); } } #endif if (am_parent) { rpc_wkssvc_shutdown(); #ifdef ACTIVE_DIRECTORY rpc_dssetup_shutdown(); #endif #ifdef DEVELOPER rpc_rpcecho_shutdown(); #endif #ifdef DFS_SUPPORT rpc_netdfs_shutdown(); #endif rpc_initshutdown_shutdown(); #ifdef EXTRA_SERVICES rpc_eventlog_shutdown(); rpc_svcctl_shutdown(); rpc_ntsvcs_shutdown(); #endif #ifdef PRINTER_SUPPORT rpc_spoolss_shutdown(); #endif rpc_srvsvc_shutdown(); #ifdef WINREG_SUPPORT rpc_winreg_shutdown(); #endif #ifdef NETLOGON_SUPPORT rpc_netlogon_shutdown(); #endif #ifdef SAMR_SUPPORT rpc_samr_shutdown(); #endif #ifdef LSA_SUPPORT rpc_lsarpc_shutdown(); #endif } /* * we need to force the order of freeing the following, * because smbd_msg_ctx is not a talloc child of smbd_server_conn. */ sconn = NULL; TALLOC_FREE(smbd_server_conn); server_messaging_context_free(); server_event_context_free(); TALLOC_FREE(smbd_memcache_ctx); locking_end(); printing_end(); if (how != SERVER_EXIT_NORMAL) { DEBUGSEP(0); DEBUG(0,("Abnormal server exit: %s\n", reason ? reason : "no explanation provided")); DEBUGSEP(0); log_stack_trace(); dump_core(); /* Notreached. */ exit(1); } else { DEBUG(3,("Server exit (%s)\n", (reason ? reason : "normal exit"))); if (am_parent) { pidfile_unlink(); } gencache_stabilize(); } exit(0); }