void start_fssd(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx) { struct rpc_srv_callbacks fss_cb; NTSTATUS status; pid_t pid; bool ok; int rc; fss_cb.init = fss_init_cb; fss_cb.shutdown = fss_shutdown_cb; fss_cb.private_data = msg_ctx; DEBUG(1, ("Forking File Server Shadow-copy Daemon\n")); pid = fork(); if (pid == -1) { DEBUG(0, ("failed to fork file server shadow-copy daemon [%s], " "aborting ...\n", strerror(errno))); exit(1); } if (pid) { /* parent */ return; } /* child */ status = smbd_reinit_after_fork(msg_ctx, ev_ctx, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("reinit_after_fork() failed\n")); smb_panic("reinit_after_fork() failed"); } fssd_reopen_logs(); fssd_setup_sig_term_handler(ev_ctx); fssd_setup_sig_hup_handler(ev_ctx, msg_ctx); ok = serverid_register(procid_self(), FLAG_MSG_GENERAL | FLAG_MSG_PRINT_GENERAL); if (!ok) { DEBUG(0, ("Failed to register serverid in fssd!\n")); exit(1); } messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED, fssd_smb_conf_updated); status = rpc_FileServerVssAgent_init(&fss_cb); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to register fssd rpc inteface! (%s)\n", nt_errstr(status))); exit(1); } /* case is normalized by smbd on connection */ ok = setup_named_pipe_socket("fssagentrpc", ev_ctx, msg_ctx); if (!ok) { DEBUG(0, ("Failed to open fssd named pipe!\n")); exit(1); } DEBUG(1, ("File Server Shadow-copy Daemon Started (%d)\n", (int)getpid())); /* loop forever */ rc = tevent_loop_wait(ev_ctx); /* should not be reached */ DEBUG(0,("tevent_loop_wait() exited with %d - %s\n", rc, (rc == 0) ? "out of events" : strerror(errno))); exit(1); }
void start_epmd(struct tevent_context *ev_ctx, struct messaging_context *msg_ctx) { struct rpc_srv_callbacks epmapper_cb; NTSTATUS status; pid_t pid; bool ok; int rc; epmapper_cb.init = NULL; epmapper_cb.shutdown = epmapper_shutdown_cb; epmapper_cb.private_data = NULL; DEBUG(1, ("Forking Endpoint Mapper Daemon\n")); pid = fork(); if (pid == -1) { DEBUG(0, ("Failed to fork Endpoint Mapper [%s], aborting ...\n", strerror(errno))); exit(1); } if (pid) { /* parent */ return; } status = smbd_reinit_after_fork(msg_ctx, ev_ctx, true, "epmd"); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("reinit_after_fork() failed\n")); smb_panic("reinit_after_fork() failed"); } epmd_reopen_logs(); epmd_setup_sig_term_handler(ev_ctx); epmd_setup_sig_hup_handler(ev_ctx, msg_ctx); ok = serverid_register(messaging_server_id(msg_ctx), FLAG_MSG_GENERAL | FLAG_MSG_PRINT_GENERAL); if (!ok) { DEBUG(0, ("Failed to register serverid in epmd!\n")); exit(1); } messaging_register(msg_ctx, ev_ctx, MSG_SMB_CONF_UPDATED, epmd_smb_conf_updated); status = rpc_epmapper_init(&epmapper_cb); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to register epmd rpc interface! (%s)\n", nt_errstr(status))); exit(1); } status = rpc_setup_tcpip_sockets(ev_ctx, msg_ctx, &ndr_table_epmapper, NULL, 135); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to open epmd tcpip sockets!\n")); exit(1); } ok = setup_dcerpc_ncalrpc_socket(ev_ctx, msg_ctx, "EPMAPPER", srv_epmapper_delete_endpoints); if (!ok) { DEBUG(0, ("Failed to open epmd ncalrpc pipe!\n")); exit(1); } ok = setup_named_pipe_socket("epmapper", ev_ctx, msg_ctx); if (!ok) { DEBUG(0, ("Failed to open epmd named pipe!\n")); exit(1); } DEBUG(1, ("Endpoint Mapper Daemon Started (%u)\n", (unsigned int)getpid())); /* loop forever */ rc = tevent_loop_wait(ev_ctx); /* should not be reached */ DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n", rc, (rc == 0) ? "out of events" : strerror(errno))); exit(1); }
static void smbd_accept_connection(struct tevent_context *ev, struct tevent_fd *fde, uint16_t flags, void *private_data) { struct smbd_open_socket *s = talloc_get_type_abort(private_data, struct smbd_open_socket); struct messaging_context *msg_ctx = s->parent->msg_ctx; struct sockaddr_storage addr; socklen_t in_addrlen = sizeof(addr); int fd; pid_t pid = 0; fd = accept(s->fd, (struct sockaddr *)(void *)&addr,&in_addrlen); if (fd == -1 && errno == EINTR) return; if (fd == -1) { DEBUG(0,("accept: %s\n", strerror(errno))); return; } if (s->parent->interactive) { reinit_after_fork(msg_ctx, ev, true, NULL); smbd_process(ev, msg_ctx, fd, true); exit_server_cleanly("end of interactive mode"); return; } if (!allowable_number_of_smbd_processes(s->parent)) { close(fd); return; } pid = fork(); if (pid == 0) { NTSTATUS status = NT_STATUS_OK; /* * Can't use TALLOC_FREE here. Nulling out the argument to it * would overwrite memory we've just freed. */ talloc_free(s->parent); s = NULL; /* Stop zombies, the parent explicitly handles * them, counting worker smbds. */ CatchChild(); status = smbd_reinit_after_fork(msg_ctx, ev, true, NULL); if (!NT_STATUS_IS_OK(status)) { if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) { DEBUG(0,("child process cannot initialize " "because too many files are open\n")); goto exit; } if (lp_clustering() && NT_STATUS_EQUAL(status, NT_STATUS_INTERNAL_DB_ERROR)) { DEBUG(1,("child process cannot initialize " "because connection to CTDB " "has failed\n")); goto exit; } DEBUG(0,("reinit_after_fork() failed\n")); smb_panic("reinit_after_fork() failed"); } smbd_process(ev, msg_ctx, fd, false); exit: exit_server_cleanly("end of child"); return; } if (pid < 0) { DEBUG(0,("smbd_accept_connection: fork() failed: %s\n", strerror(errno))); } /* The parent doesn't need this socket */ close(fd); /* Sun May 6 18:56:14 2001 [email protected]: Clear the closed fd info out of server_fd -- and more importantly, out of client_fd in util_sock.c, to avoid a possible getpeername failure if we reopen the logs and use %I in the filename. */ if (pid != 0) { add_child_pid(s->parent, pid); } /* Force parent to check log size after * spawning child. Fix from * [email protected]. The * parent smbd will log to logserver.smb. It * writes only two messages for each child * started/finished. But each child writes, * say, 50 messages also in logserver.smb, * begining with the debug_count of the * parent, before the child opens its own log * file logserver.client. In a worst case * scenario the size of logserver.smb would be * checked after about 50*50=2500 messages * (ca. 100kb). * */ force_check_log_size(); }
static bool smbd_scavenger_start(struct smbd_scavenger_state *state) { struct server_id self = messaging_server_id(state->msg); struct tevent_fd *fde = NULL; int fds[2]; int ret; uint64_t unique_id; bool ok; SMB_ASSERT(server_id_equal(&state->parent_id, &self)); if (smbd_scavenger_running(state)) { struct server_id_buf tmp; DEBUG(10, ("scavenger %s already running\n", server_id_str_buf(*state->scavenger_id, &tmp))); return true; } if (state->scavenger_id != NULL) { struct server_id_buf tmp; DEBUG(10, ("scavenger zombie %s, cleaning up\n", server_id_str_buf(*state->scavenger_id, &tmp))); TALLOC_FREE(state->scavenger_id); } state->scavenger_id = talloc_zero(state, struct server_id); if (state->scavenger_id == NULL) { DEBUG(2, ("Out of memory\n")); goto fail; } talloc_set_destructor(state->scavenger_id, smbd_scavenger_server_id_destructor); ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); if (ret == -1) { DEBUG(2, ("socketpair failed: %s", strerror(errno))); goto fail; } smb_set_close_on_exec(fds[0]); smb_set_close_on_exec(fds[1]); unique_id = serverid_get_random_unique_id(); ret = fork(); if (ret == -1) { int err = errno; close(fds[0]); close(fds[1]); DEBUG(0, ("fork failed: %s", strerror(err))); goto fail; } if (ret == 0) { /* child */ NTSTATUS status; close(fds[0]); set_my_unique_id(unique_id); status = smbd_reinit_after_fork(state->msg, state->ev, true); if (!NT_STATUS_IS_OK(status)) { DEBUG(2, ("reinit_after_fork failed: %s\n", nt_errstr(status))); exit_server("reinit_after_fork failed"); return false; } prctl_set_comment("smbd-scavenger"); state->am_scavenger = true; *state->scavenger_id = messaging_server_id(state->msg); scavenger_setup_sig_term_handler(state->ev); serverid_register(*state->scavenger_id, FLAG_MSG_GENERAL); ok = scavenger_say_hello(fds[1], *state->scavenger_id); if (!ok) { DEBUG(2, ("scavenger_say_hello failed\n")); exit_server("scavenger_say_hello failed"); return false; } fde = tevent_add_fd(state->ev, state->scavenger_id, fds[1], TEVENT_FD_READ, smbd_scavenger_parent_dead, state); if (fde == NULL) { DEBUG(2, ("tevent_add_fd(smbd_scavenger_parent_dead) " "failed\n")); exit_server("tevent_add_fd(smbd_scavenger_parent_dead) " "failed"); return false; } tevent_fd_set_auto_close(fde); ret = smbd_scavenger_main(state); DEBUG(10, ("scavenger ended: %d\n", ret)); exit_server_cleanly("scavenger ended"); return false; } /* parent */ close(fds[1]); ok = scavenger_wait_hello(fds[0], state->scavenger_id); if (!ok) { close(fds[0]); goto fail; } fde = tevent_add_fd(state->ev, state->scavenger_id, fds[0], TEVENT_FD_READ, smbd_scavenger_done, state); if (fde == NULL) { close(fds[0]); goto fail; } tevent_fd_set_auto_close(fde); return true; fail: TALLOC_FREE(state->scavenger_id); return false; }