int transfer_listening_sockets (struct mc_config *MC, struct mc_config *MC_Old) { int i, j, k; for (i = 0; i < MC->clusters_num; i++) { struct mc_cluster *C = &MC->Clusters[i]; j = C->other_cluster_no; if (j >= 0) { assert (j < MC_Old->clusters_num); struct mc_cluster *OC = &MC_Old->Clusters[j]; assert (OC->port == C->port && OC->other_cluster_no == i); C->server_socket = OC->server_socket; C->listening_connection = OC->listening_connection; OC->server_socket = -1; OC->listening_connection = 0; C->listening_connection->extra = &C->mc_proxy_inbound; } else { assert (init_listening_connection (C->server_socket, &ct_memcache_server, &C->mc_proxy_inbound) >= 0); C->listening_connection = Connections + C->server_socket; } } for (k = 0; k <= max_connection; k++) { struct connection *c = Connections + k; if (c->basic_type != ct_inbound || c->fd != k) { continue; } struct mc_cluster *OC = ((struct memcache_server_functions *) c->extra)->info; assert (OC && &OC->mc_proxy_inbound == c->extra); j = OC->cluster_no; i = OC->other_cluster_no; assert (OC == &MC_Old->Clusters[j]); if (i >= 0) { struct mc_cluster *C = &MC->Clusters[i]; assert (C->cluster_no == i && C->other_cluster_no == j); vkprintf (2, "transferring inbound connection #%d (port %d) from old cluster %d to new cluster %d\n", k, OC->port, j, i); c->extra = &C->mc_proxy_inbound; } else { vkprintf (2, "closing inbound connection #%d (port %d) belonging to old cluster %d, no new cluster\n", k, OC->port, j); force_clear_connection (c); epoll_close (k); close (k); } } for (i = 0; i < MC_Old->clusters_num; i++) { struct mc_cluster *OC = &MC_Old->Clusters[i]; if (OC->other_cluster_no == -1) { assert (OC->server_socket >= 0); k = OC->server_socket; vkprintf (1, "closing unneeded listening connection #%d for port %d belonging to old cluster %d (%s)\n", k, OC->port, i, OC->cluster_name); force_clear_connection (&Connections[k]); epoll_close (k); close (k); OC->server_socket = -1; OC->listening_connection = 0; } else { assert (OC->server_socket == -1 && !OC->listening_connection); } } return 0; }
void server_init (engine_t *E, server_functions_t *F, conn_type_t *listen_connection_type, void *listen_connection_extra) { if (F != NULL) { if (F->sighup) { sf.sighup = F->sighup; } if (F->sigusr1) { sf.sigusr1 = F->sigusr1; } if (F->save_index) { sf.save_index = F->save_index; } if (F->cron) { sf.cron = F->cron; } } init_epoll (); init_netbuffers (); if (udp_enabled) { init_msg_buffers (0); } if (daemonize) { setsid (); reopen_logs (); } if (!E->sfd) { E->sfd = server_socket (port, E->settings_addr, backlog, 0); } if (E->sfd < 0) { kprintf ("cannot open server socket at port %d: %m\n", port); exit (1); } 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 (E->sfd, listen_connection_type, listen_connection_extra); if (udp_enabled) { add_udp_socket (port, 0); } if (binlog_disabled && binlog_fd >= 0) { epoll_pre_event = read_new_events; } struct sigaction sa; memset (&sa, 0, sizeof (sa)); sa.sa_handler = sigint_handler; sigemptyset (&sa.sa_mask); sigaddset (&sa.sa_mask, SIGTERM); sigaction (SIGINT, &sa, NULL); sa.sa_handler = sigterm_handler; sigemptyset (&sa.sa_mask); sigaddset (&sa.sa_mask, SIGINT); sigaction (SIGTERM, &sa, NULL); sa.sa_handler = SIG_IGN; sigaction (SIGPIPE, &sa, NULL); sigaction (SIGPOLL, &sa, NULL); if (daemonize) { sa.sa_handler = sighup_handler; sigemptyset (&sa.sa_mask); sigaction (SIGHUP, &sa, NULL); } }
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); }