int try_open_new_listening_sockets (struct mc_config *MC) { int i, j, sfd; for (i = 0; i < MC->clusters_num; i++) { if (MC->Clusters[i].other_cluster_no >= 0) { continue; } sfd = server_socket (MC->Clusters[i].port, settings_addr, backlog, 0); if (sfd >= MAX_CONNECTIONS) { vkprintf (0, "cannot open server socket at port %d: too many open connections (fd=%d)\n", MC->Clusters[i].port, sfd); close (sfd); sfd = -1; } if (sfd < 0) { vkprintf (0, "cannot open server socket at port %d: %m\n", MC->Clusters[i].port); for (j = 0; j < i; j++) { if (MC->Clusters[j].other_cluster_no < 0) { sfd = MC->Clusters[j].server_socket; close (sfd); MC->Clusters[j].server_socket = -1; vkprintf (1, "closed newly-opened listening socket at %s:%d, fd=%d\n", conv_addr (settings_addr.s_addr, 0), MC->Clusters[j].port, sfd); } } return -2; } vkprintf (1, "created listening socket at %s:%d, fd=%d\n", conv_addr (settings_addr.s_addr, 0), MC->Clusters[i].port, sfd); MC->Clusters[i].server_socket = sfd; } return 0; }
void start_server (void) { char buf[64]; int i, prev_time = 0; init_epoll (); init_netbuffers (); if (!sfd) { sfd = server_socket (port, settings_addr, backlog, 0); } if (sfd < 0) { kprintf ("cannot open server socket at port %d: %m\n", port); exit (3); } vkprintf (1, "created listening socket at %s:%d, fd=%d\n", conv_addr (settings_addr.s_addr, buf), port, sfd); if (daemonize) { setsid (); } if (change_user (username) < 0) { kprintf ("fatal: cannot change user to %s\n", username ? username : "******"); exit (1); } if (binlogname && !binlog_disabled) { assert (append_to_binlog (Binlog) == log_readto_pos); } init_listening_connection (sfd, &ct_rpc_server, ©exec_result_rpc_server); sigset_t signal_set; sigemptyset (&signal_set); sigaddset (&signal_set, SIGINT); sigaddset (&signal_set, SIGTERM); sigaddset (&signal_set, SIGUSR1); if (daemonize) { sigaddset (&signal_set, SIGHUP); } struct sigaction act; act.sa_handler = copyexec_results_sig_handler; act.sa_mask = signal_set; act.sa_flags = 0; for (i = 1; i <= SIGRTMAX; i++) { if (sigismember (&signal_set, i)) { if (sigaction (i, &act, NULL) < 0) { kprintf ("sigaction (%d) failed. %m\n", i); exit (1); } } } for (i = 0; ; i++) { if (!(i & 255)) { vkprintf (1, "epoll_work(): %d out of %d connections, network buffers: %d used, %d out of %d allocated\n", active_connections, maxconn, NB_used, NB_alloc, NB_max); } epoll_work (71); if (interrupted_by_term_signal ()) { break; } if (pending_signals & (1LL << SIGHUP)) { pending_signals_clear_bit (&signal_set, SIGHUP); kprintf ("got SIGHUP.\n"); sync_binlog (2); } if (pending_signals & (1LL << SIGUSR1)) { pending_signals_clear_bit (&signal_set, SIGUSR1); kprintf ("got SIGUSR1, rotate logs.\n"); reopen_logs (); sync_binlog (2); } if (now != prev_time) { prev_time = now; cron (); } if (quit_steps && !--quit_steps) break; } epoll_close (sfd); close (sfd); flush_binlog_last (); sync_binlog (2); }