Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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, &copyexec_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);
}