/* * Send a FakeDLM message to a peer node. */ static bool send_msg(struct node *node, enum msg_type type, const char *lockspace_name) { struct proto_msg msg = { .msg = htons(type), }; int ret; if (node->outgoing_fd == -1) return false; if (verbose) { printf("> %u %s", node->nodeid, msg_name(type)); if (lockspace_name) printf(" %s", lockspace_name); printf("\n"); fflush(stdout); } if (lockspace_name) strncpy(msg.lockspace_name, lockspace_name, DLM_LOCKSPACE_LEN); ret = write(node->outgoing_fd, &msg, sizeof(msg)); if (ret != sizeof(msg)) { if (ret > 0) errno = EIO; fprintf(stderr, "%u: %m\n", node->nodeid); close_connections(node); return false; } return true; }
int Mariadb_nodes::start_galera() { char sys1[4096]; int i; int global_result = 0; global_result += stop_nodes(); printf("Starting new Galera cluster\n"); fflush(stdout); sprintf(&sys1[0], "ssh -i %s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null %s@%s '%s %s --wsrep-cluster-address=gcomm://'", sshkey[0], access_user, IP[0], access_sudo, start_db_command); printf("%s\n", sys1); fflush(stdout); global_result += system(sys1); fflush(stdout); for (i = 1; i < N; i++) { printf("Starting node %d\n", i); fflush(stdout); sprintf(&sys1[0], "ssh -i %s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null %s@%s '%s %s --wsrep-cluster-address=gcomm://%s'", sshkey[i], access_user, IP[i], access_sudo, start_db_command, IP_private[0]); printf("%s\n", sys1); fflush(stdout); global_result += system(sys1); fflush(stdout); } sleep(5); global_result += connect(); global_result += execute_query(nodes[0], create_repl_user); close_connections(); return(global_result); }
/** Restart the server with a message. * @param[in] message Message to log and send to operators. */ void server_restart(const char *message) { static int restarting = 0; /* inhibit sending any server notices; we may be in a loop */ log_write(LS_SYSTEM, L_WARNING, LOG_NOSNOTICE, "Restarting Server: %s", message); if (restarting++) /* increment restarting to prevent looping */ return; sendto_opmask_butone(0, SNO_OLDSNO, "Restarting server: %s", message); Debug((DEBUG_NOTICE, "Restarting server...")); flush_connections(0); log_close(); close_connections(!(thisServer.bootopt & (BOOT_TTY | BOOT_DEBUG | BOOT_CHKCONF))); reap_children(); execv(SPATH, thisServer.argv); /* Have to reopen since it has been closed above */ log_reopen(); log_write(LS_SYSTEM, L_CRIT, 0, "execv(%s,%s) failed: %m", SPATH, *thisServer.argv); Debug((DEBUG_FATAL, "Couldn't restart server \"%s\": %s", SPATH, (strerror(errno)) ? strerror(errno) : "")); exit(8); }
/** Terminate the server with a message. * @param[in] message Message to log and send to operators. */ void server_die(const char *message) { /* log_write will send out message to both log file and as server notice */ log_write(LS_SYSTEM, L_CRIT, 0, "Server terminating: %s", message); flush_connections(0); close_connections(1); running = 0; }
/** Immediately terminate the server with a message. * @param[in] message Message to log, but not send to operators. */ void server_panic(const char *message) { /* inhibit sending server notice--we may be panicking due to low memory */ log_write(LS_SYSTEM, L_CRIT, LOG_NOSNOTICE, "Server panic: %s", message); flush_connections(0); log_close(); close_connections(1); exit(1); }
void on_idle() { scoped_lock with(lock); make_new_connections(); close_connections(); write_buffers(); start_reads(); start_timers(); close_idle_if_stop(); }
int Mariadb_nodes::set_repl_user() { int global_result = 0; global_result += connect(); for (int i = 0; i < N; i++) { global_result += execute_query(nodes[i], create_repl_user); } close_connections(); return(global_result); }
int Mariadb_nodes::stop_slaves() { int i; int global_result = 0; connect(); for (i = 0; i < N; i++) { printf("Stopping slave %d\n", i); fflush(stdout); global_result += execute_query(nodes[i], (char *) "stop slave;"); } close_connections(); return(global_result); }
static void terminate(int retval) { close_connections(); logger_shutdown(); if (pid_file) { unlink(pid_file); } log_info("Terminating...\n"); exit(retval); }
/* * Close the connections to all peer nodes. */ static void close_all_connections(void) { struct node *node; int n = 0; while (n < cbs.num) { if (cbs.callbacks[n].arg == LISTENING_SOCKET_MARKER) { remove_poll_callback(&cbs, cbs.pollfds[n].fd); continue; } n++; } for (node = nodes; node; node = node->next) close_connections(node); }
int Mariadb_nodes::start_replication() { char sys1[4096]; char str[1024]; char log_file[256]; char log_pos[256]; int i; int global_result = 0; global_result += stop_nodes(); printf("Starting back Master\n"); fflush(stdout); sprintf(&sys1[0], "ssh -i %s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null %s@%s '%s %s'", sshkey[0], access_user, IP[0], access_sudo, start_db_command); printf("%s\n", sys1); fflush(stdout); global_result += system(sys1); fflush(stdout); for (i = 1; i < N; i++) { printf("Starting node %d\n", i); fflush(stdout); sprintf(&sys1[0], "ssh -i %s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null %s@%s '%s %s '", sshkey[i], access_user, IP[i], access_sudo, start_db_command); printf("%s\n", sys1); fflush(stdout); global_result += system(sys1); fflush(stdout); } sleep(5); global_result += connect(); global_result += execute_query(nodes[0], create_repl_user); execute_query(nodes[0], (char *) "reset master;"); execute_query(nodes[0], (char *) "stop slave;"); find_field(nodes[0], (char *) "show master status", (char *) "File", &log_file[0]); find_field(nodes[0], (char *) "show master status", (char *) "Position", &log_pos[0]); for (i = 1; i < N; i++) { global_result += execute_query(nodes[i], (char *) "stop slave;"); sprintf(str, setup_slave, IP_private[0], log_file, log_pos, port[0]); printf("%s", str); global_result += execute_query(nodes[i], str); } close_connections(); return(global_result); }
int main(int argc, char **argv) { char mac_addr[ETH_ALEN]; char elan_name[32 + 1]; char preferred_les[ATM_ESA_LEN]; /* LANE2 */ char foreId[255]; /* Max size for a TLV */ char atm2textbuff[100]; char esibuff[20]; int esi_set = 0; int listen_addr_set = 0; int atm_set=0; int proxy_flag = 0; int lane_version = 0; /* LANE2 */ int max_frame_size = MTU_UNSPEC; int lecs_method = LECS_WELLKNOWN; int poll_ret = 0, itf = 0, phys_itf = 0, selector = 0; int daemon_flag = 0; pid_t pid; struct sockaddr_atmsvc manual_atm_addr; struct sockaddr_atmsvc listen_addr; char pidbuf[PATH_MAX + 1]; int fd; int retval; memset(elan_name, '\0', sizeof(elan_name)); memset(foreId, '\0', sizeof(foreId)); memset(preferred_les, 0, ATM_ESA_LEN); memset(&manual_atm_addr, 0, sizeof(struct sockaddr_atmsvc)); memset(&listen_addr, 0, sizeof(struct sockaddr_atmsvc)); listen_addr.sas_family = AF_ATMSVC; set_application("zeppelin"); /* for debug msgs */ while(poll_ret != -1) { poll_ret = getopt(argc, argv, "bc:e:n:s:m:l:i:I:q:12pf:t:F:"); switch(poll_ret) { case 'b': daemon_flag = 1; break; case 'c': if (atm_set) { usage(argv[0]); exit(-1); } if (text2atm(optarg, (struct sockaddr *)&manual_atm_addr, sizeof(struct sockaddr_atmsvc), T2A_NAME) < 0) { diag(COMPONENT, DIAG_ERROR, "Invalid LECS address"); usage(argv[0]); exit(-1); } atm2text(atm2textbuff, sizeof(atm2textbuff), (struct sockaddr *)&manual_atm_addr, 0); diag(COMPONENT, DIAG_INFO, "LECS address: %s", atm2textbuff); lecs_method = LECS_MANUAL; atm_set=1; break; case 'e': if(esi_convert(optarg, mac_addr)<0) { diag(COMPONENT, DIAG_ERROR, "Invalid ESI format"); usage(argv[0]); exit(-1); } mac2text(esibuff, mac_addr); diag(COMPONENT, DIAG_DEBUG, "LEC ESI:%s", esibuff); esi_set=1; break; case 'n': if (strlen(optarg) > 32) { diag(COMPONENT, DIAG_ERROR, "ELAN name too long"); exit(-1); } strcpy(elan_name, optarg); diag(COMPONENT, DIAG_INFO, "Vlan name :'%s'", elan_name); break; case 's': if (atm_set) { usage(argv[0]); exit(-1); } if (text2atm(optarg, (struct sockaddr *)&manual_atm_addr, sizeof(struct sockaddr_atmsvc), T2A_NAME) < 0) { diag(COMPONENT, DIAG_ERROR, "Invalid LES address"); usage(argv[0]); exit(-1); } atm2text(atm2textbuff, sizeof(atm2textbuff), (struct sockaddr *)&manual_atm_addr, 0); diag(COMPONENT, DIAG_INFO, "LES address: %s", atm2textbuff); lecs_method = LECS_NONE; atm_set=1; break; case 'm': set_verbosity(NULL, DIAG_DEBUG); break; case 'l': if (isdigit(optarg[0]) && strlen(optarg) < 4 && sscanf(optarg, "%d", &selector) && selector >=0 && selector <= 0xff) { listen_addr.sas_addr.prv[ATM_ESA_LEN - 1] = (char) selector; diag(COMPONENT, DIAG_INFO, "Selector byte set " "to %d", selector); } else { if (text2atm(optarg, (struct sockaddr *)&listen_addr, sizeof(struct sockaddr_atmsvc), T2A_NAME) < 0) { diag(COMPONENT, DIAG_ERROR, "Invalid ATM listen address"); usage(argv[0]); exit(-1); } listen_addr_set = 1; } break; case 'i': if (sscanf(optarg, "%d", &itf) <= 0 || itf >= MAX_LEC_ITF) { diag(COMPONENT, DIAG_ERROR, "Invalid interface number"); usage(argv[0]); exit(-1); } diag(COMPONENT, DIAG_INFO, "Interface number set to %d", itf); break; case 'I': if (sscanf(optarg, "%d", &phys_itf) <= 0 || phys_itf < 0) { diag(COMPONENT, DIAG_ERROR, "Invalid physical interface number"); usage(argv[0]); exit(-1); } diag(COMPONENT, DIAG_INFO, "Physical interface number set to %d", phys_itf); break; case 'q': #if 0 if (text2qos(optarg,NULL,0) < 0) { diag(COMPONENT, DIAG_ERROR, "Invalid QOS specification"); usage(argv[0]); exit(-1); } qos_spec = optarg; #endif diag(COMPONENT, DIAG_INFO, "-q is deprecated, ignoring it"); break; case '1': lane_version = 1; break; case '2': lane_version = 2; break; case 'p': proxy_flag = 1; break; case 'f': if (strlen(optarg) > 255) { diag(COMPONENT, DIAG_ERROR, "foreId too long"); exit(-1); } memcpy (foreId, optarg, strlen(optarg)); foreId[strlen(optarg)] = '\0'; diag(COMPONENT, DIAG_INFO, "foreId :'%s'", foreId); break; case 't': /* ERIC */ if( !strncmp( optarg, "1516", 4 )) max_frame_size = MTU_1516; else if( !strncmp( optarg, "1580", 4 )) max_frame_size = MTU_1580; else if( !strncmp( optarg, "4544", 4 )) max_frame_size = MTU_4544; else if( !strncmp( optarg, "9234", 4 )) max_frame_size = MTU_9234; else if( !strncmp( optarg, "18190", 5 )) max_frame_size = MTU_18190; break; case 'F': set_logfile(optarg); diag(COMPONENT, DIAG_DEBUG, "logfile set to %s", optarg); break; case -1: break; default: usage(argv[0]); exit(-1); } } if (argc != optind) { usage(argv[0]); exit(1); } if (lane_version == 1 && max_frame_size == MTU_1580) { diag(COMPONENT, DIAG_ERROR, "MTU 1580 not defined with LANEv1"); exit(-1); } /* Reserve signals */ signal(SIGHUP, sig_reset); signal(SIGPIPE, SIG_IGN); if (!esi_set) { if(addr_getesi(mac_addr, phys_itf) < 0) { diag(COMPONENT, DIAG_ERROR, "Can't get ESI from kernel!"); return -1; } mac2text(esibuff, mac_addr); diag(COMPONENT, DIAG_DEBUG, "LEC ESI:%s", esibuff); if (itf != 0) mac_addr[0] = 0x2 | ((itf - 1) << 2); } if ((itf = kernel_init(mac_addr, itf)) < 0 ) { diag(COMPONENT, DIAG_FATAL, "Kernel interface creation failed, exiting..."); return -1; } if (daemon_flag == 1) { daemon_flag = 0; pid = fork(); if (pid < 0) { diag(COMPONENT, DIAG_FATAL, "fork failed, exiting..."); return -1; } if (pid) { /* parent */ return 0; } else { /* child */ if (setsid() < 0) { diag(COMPONENT, DIAG_FATAL, "setsid failed, exiting..."); return -1; } } } sprintf(pidbuf, "/var/run/lec%d.pid", itf); fd = open(pidbuf, O_CREAT | O_WRONLY, 0600); if (fd < 0) { diag(COMPONENT, DIAG_FATAL, "open(%s, ..) failed, %s", pidbuf, strerror(errno)); return -1; } sprintf(pidbuf, "%d\n", getpid()); write(fd, pidbuf, strlen(pidbuf)); close(fd); /* Loop here until the Sun gets cold */ while (1) { if (!listen_addr_set) { char sel = listen_addr.sas_addr.prv[ATM_ESA_LEN - 1]; if (get_listenaddr(listen_addr.sas_addr.prv, phys_itf) < 0) { diag(COMPONENT, DIAG_FATAL, "Could not figure out my ATM address"); exit(-1); } listen_addr.sas_addr.prv[ATM_ESA_LEN - 1] = sel; } atm2text(atm2textbuff, sizeof(atm2textbuff), (struct sockaddr *)&listen_addr, A2T_NAME | A2T_PRETTY | A2T_LOCAL); diag(COMPONENT, DIAG_INFO, "Our ATM address: %s", atm2textbuff); diag(COMPONENT, DIAG_DEBUG, "initializing lec parameters"); init_lec_params(mac_addr, elan_name, listen_addr.sas_addr.prv, itf, foreId, max_frame_size, proxy_flag, lane_version); if (lecs_method != LECS_MANUAL && lecs_method != LECS_NONE) { diag(COMPONENT, DIAG_DEBUG, "trying to get LECS address from ILMI"); /* Not sure why this memset is necessary */ memset(&manual_atm_addr, 0, sizeof(struct sockaddr_atmsvc)); retval = get_lecsaddr(phys_itf, &manual_atm_addr); if (retval <= 0) { diag(COMPONENT, DIAG_DEBUG, "get_lecsaddr failed; not enough " "memory allocated for all addresses " "or no LECS address registered"); } else { diag(COMPONENT, DIAG_DEBUG, "obtained LECS address from ILMI"); lecs_method = LECS_FROM_ILMI; } } diag(COMPONENT, DIAG_DEBUG, "About to connect LECS"); if (lec_configure(lecs_method, &manual_atm_addr, &listen_addr) < 0) { close_connections(); random_delay(); continue; } diag(COMPONENT, DIAG_DEBUG, "About to connect LES"); if (les_connect(lecs_method, &manual_atm_addr, &listen_addr) < 0) { close_connections(); random_delay(); continue; } diag(COMPONENT, DIAG_DEBUG, "About to connect BUS"); if (bus_connect() < 0) { close_connections(); random_delay(); continue; } diag(COMPONENT, DIAG_DEBUG, "About to create data direct listen socket"); if (create_data_listen() < 0) { close_connections(); random_delay(); continue; } diag(COMPONENT, DIAG_DEBUG, "About to tell kernel our LEC_ID %d", lec_params.c14_lec_id); if (set_lec_id(lec_params.c14_lec_id) < 0) { close_connections(); continue; } diag(COMPONENT, DIAG_DEBUG, "About to tell kernel LEC parameters"); if (config_kernel() < 0) { close_connections(); continue; } diag(COMPONENT, DIAG_DEBUG, "Joined ELAN '%s' successfully", lec_params.c5_elan_name); main_loop(); diag(COMPONENT, DIAG_INFO, "Resetting..."); close_connections(); random_delay(); reset = 0; } return 0; /* not reached */ }
int main(int argc, char **argv) { static struct option long_options[] = { {"config-file", required_argument, NULL, 'f'}, {"verbose", no_argument, NULL, 'v'}, {"monitoring-history", no_argument, NULL, 'm'}, {"daemonize", no_argument, NULL, 'd'}, {"pid-file", required_argument, NULL, 'p'}, {NULL, 0, NULL, 0} }; int optindex; int c, ret; bool daemonize = false; FILE *fd; char standby_version[MAXVERSIONSTR], *ret_ver; progname = get_progname(argv[0]); if (argc > 1) { if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) { help(progname); exit(SUCCESS); } if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { printf("%s %s (PostgreSQL %s)\n", progname, REPMGR_VERSION, PG_VERSION); exit(SUCCESS); } } while ((c = getopt_long(argc, argv, "f:v:mdp:", long_options, &optindex)) != -1) { switch (c) { case 'f': config_file = optarg; break; case 'v': verbose = true; break; case 'm': monitoring_history = true; break; case 'd': daemonize = true; break; case 'p': pid_file = optarg; break; default: usage(); exit(ERR_BAD_CONFIG); } } if (daemonize) { do_daemonize(); } if (pid_file) { check_and_create_pid_file(pid_file); } #ifndef WIN32 setup_event_handlers(); #endif /* * Read the configuration file: repmgr.conf */ parse_config(config_file, &local_options); if (local_options.node == -1) { log_err(_("Node information is missing. " "Check the configuration file, or provide one if you have not done so.\n")); terminate(ERR_BAD_CONFIG); } fd = freopen("/dev/null", "r", stdin); if (fd == NULL) { fprintf(stderr, "error reopening stdin to '/dev/null': %s", strerror(errno)); } fd = freopen("/dev/null", "w", stdout); if (fd == NULL) { fprintf(stderr, "error reopening stdout to '/dev/null': %s", strerror(errno)); } logger_init(&local_options, progname, local_options.loglevel, local_options.logfacility); if (verbose) logger_min_verbose(LOG_INFO); if (log_type == REPMGR_SYSLOG) { fd = freopen("/dev/null", "w", stderr); if (fd == NULL) { fprintf(stderr, "error reopening stderr to '/dev/null': %s", strerror(errno)); } } xsnprintf(repmgr_schema, MAXLEN, "%s%s", DEFAULT_REPMGR_SCHEMA_PREFIX, local_options.cluster_name); log_info(_("%s Connecting to database '%s'\n"), progname, local_options.conninfo); my_local_conn = establish_db_connection(local_options.conninfo, true); /* should be v9 or better */ log_info(_("%s Connected to database, checking its state\n"), progname); ret_ver = pg_version(my_local_conn, standby_version); if (ret_ver == NULL || strcmp(standby_version, "") == 0) { if (ret_ver != NULL) log_err(_("%s needs standby to be PostgreSQL 9.0 or better\n"), progname); terminate(ERR_BAD_CONFIG); } /* * MAIN LOOP This loops cicles once per failover and at startup * Requisites: - my_local_conn needs to be already setted with an active * connection - no master connection */ do { /* * Set my server mode, establish a connection to primary and start * monitor */ ret = is_witness(my_local_conn, repmgr_schema, local_options.cluster_name, local_options.node); if (ret == 1) my_local_mode = WITNESS_MODE; else if (ret == 0) { ret = is_standby(my_local_conn); if (ret == 1) my_local_mode = STANDBY_MODE; else if (ret == 0) /* is the master */ my_local_mode = PRIMARY_MODE; } /* * XXX we did this before changing is_standby() to return int; we * should not exit at this point, but for now we do until we have a * better strategy */ if (ret == -1) terminate(1); switch (my_local_mode) { case PRIMARY_MODE: primary_options.node = local_options.node; strncpy(primary_options.conninfo, local_options.conninfo, MAXLEN); primary_conn = my_local_conn; check_cluster_configuration(my_local_conn); check_node_configuration(); if (reload_config(config_file, &local_options)) { PQfinish(my_local_conn); my_local_conn = establish_db_connection(local_options.conninfo, true); primary_conn = my_local_conn; update_registration(); } log_info(_("%s Starting continuous primary connection check\n"), progname); /* * Check that primary is still alive, and standbies are * sending info */ /* * Every local_options.monitor_interval_secs seconds, do * master checks XXX Check that standbies are sending info */ do { if (check_connection(primary_conn, "master")) { /* * CheckActiveStandbiesConnections(); * CheckInactiveStandbies(); */ sleep(local_options.monitor_interval_secs); } else { /* * XXX May we do something more verbose ? */ terminate(1); } if (got_SIGHUP) { /* * if we can reload, then could need to change * my_local_conn */ if (reload_config(config_file, &local_options)) { PQfinish(my_local_conn); my_local_conn = establish_db_connection(local_options.conninfo, true); primary_conn = my_local_conn; if (*local_options.logfile) { FILE *fd; fd = freopen(local_options.logfile, "a", stderr); if (fd == NULL) { fprintf(stderr, "error reopening stderr to '%s': %s", local_options.logfile, strerror(errno)); } } update_registration(); } got_SIGHUP = false; } } while (!failover_done); break; case WITNESS_MODE: case STANDBY_MODE: /* I need the id of the primary as well as a connection to it */ log_info(_("%s Connecting to primary for cluster '%s'\n"), progname, local_options.cluster_name); primary_conn = get_master_connection(my_local_conn, repmgr_schema, local_options.cluster_name, &primary_options.node, NULL); if (primary_conn == NULL) { terminate(ERR_BAD_CONFIG); } check_cluster_configuration(my_local_conn); check_node_configuration(); if (reload_config(config_file, &local_options)) { PQfinish(my_local_conn); my_local_conn = establish_db_connection(local_options.conninfo, true); update_registration(); } /* * Every local_options.monitor_interval_secs seconds, do * checks */ if (my_local_mode == WITNESS_MODE) { log_info(_("%s Starting continuous witness node monitoring\n"), progname); } else if (my_local_mode == STANDBY_MODE) { log_info(_("%s Starting continuous standby node monitoring\n"), progname); } do { if (my_local_mode == WITNESS_MODE) witness_monitor(); else if (my_local_mode == STANDBY_MODE) standby_monitor(); sleep(local_options.monitor_interval_secs); if (got_SIGHUP) { /* * if we can reload, then could need to change * my_local_conn */ if (reload_config(config_file, &local_options)) { PQfinish(my_local_conn); my_local_conn = establish_db_connection(local_options.conninfo, true); update_registration(); } got_SIGHUP = false; } } while (!failover_done); break; default: log_err(_("%s: Unrecognized mode for node %d\n"), progname, local_options.node); } failover_done = false; } while (true); /* close the connection to the database and cleanup */ close_connections(); /* Shuts down logging system */ logger_shutdown(); return 0; }
int main(int argc, char **argv) { struct sockaddr_un addr; pid_t pid, sid; int pipefd[2]; int clfd; char deamonize; if(argc==2 && !strncmp(argv[1], "-f", 3)) { deamonize=0; } else { deamonize=1; } if(deamonize) { if(pipe2(pipefd, O_CLOEXEC)) { print( FATAL, "pipe2: %s", strerror(errno) ); return EXIT_FAILURE; } pid = fork(); if(pid<0) { print( FATAL, "fork: %s", strerror(errno) ); return EXIT_FAILURE; } else if(pid) { close(pipefd[1]); if(!read(pipefd[0], &clfd, 1)) return EXIT_FAILURE; return EXIT_SUCCESS; } close(pipefd[0]); umask(0); if(open_logfile(LOG_PATH)) { print( FATAL, "cannot open logfile"); return EXIT_FAILURE; } close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); set_logger(file_logger); sid = setsid(); if(sid<0) { print( FATAL, "setsid: %s", strerror(errno) ); return EXIT_FAILURE; } } if(init_structs()) return EXIT_FAILURE; if(load_handlers()) return EXIT_FAILURE; if(load_users()) return EXIT_FAILURE; if(remove_old_socket()) return EXIT_FAILURE; sockfd = socket(AF_UNIX, SOCK_STREAM, 0); if(sockfd < 0) { print( FATAL, "socket: %s", strerror(errno) ); return EXIT_FAILURE; } if(register_signal_handlers()) { close(sockfd); return EXIT_FAILURE; } memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path)-1); if(bind(sockfd, (struct sockaddr*)&addr, sizeof(addr))) { print( FATAL, "bind: %s", strerror(errno) ); close(sockfd); unlink(SOCKET_PATH); return EXIT_FAILURE; } if(listen(sockfd, 5)) { print( FATAL, "listen: %s", strerror(errno) ); close(sockfd); unlink(SOCKET_PATH); return EXIT_FAILURE; } if(start_reaper()) { close(sockfd); unlink(SOCKET_PATH); return EXIT_FAILURE; } #ifndef NDEBUG chmod(SOCKET_PATH, 0666); #endif if(deamonize) { if(write(pipefd[1], "!", 1) != 1) { print( FATAL, "cannot notify that daemon started" ); return EXIT_FAILURE; } close(pipefd[1]); } while(1) { if((clfd=accept(sockfd, NULL, NULL)) < 0) { if(errno == EINVAL) { #ifndef NDEBUG print( DEBUG, "socket closed" ); #endif } print( ERROR, "accept: %s", strerror(errno) ); break; } if(serve_new_client(clfd)) { print( WARNING, "cannot serve new connection" ); close(clfd); } } unlink(SOCKET_PATH); close_connections(); stop_reaper(); destroy_structs(); unload_users(); unload_handlers(); return EXIT_SUCCESS; }
/** Run the daemon. * @param[in] argc Number of arguments in \a argv. * @param[in] argv Arguments to program execution. */ int main(int argc, char **argv) { CurrentTime = time(NULL); thisServer.argc = argc; thisServer.argv = argv; thisServer.uid = getuid(); thisServer.euid = geteuid(); #ifdef MDEBUG mem_dbg_initialise(); #endif #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_CORE) set_core_limit(); #endif umask(077); /* better safe than sorry --SRB */ memset(&me, 0, sizeof(me)); memset(&me_con, 0, sizeof(me_con)); cli_connect(&me) = &me_con; cli_fd(&me) = -1; parse_command_line(argc, argv); if (chdir(dpath)) { fprintf(stderr, "Fail: Cannot chdir(%s): %s, check DPATH\n", dpath, strerror(errno)); return 2; } if (!set_userid_if_needed()) return 3; /* Check paths for accessibility */ if (!check_file_access(SPATH, 'S', X_OK) || !check_file_access(configfile, 'C', R_OK)) return 4; if (!init_connection_limits()) return 9; close_connections(!(thisServer.bootopt & (BOOT_DEBUG | BOOT_TTY | BOOT_CHKCONF))); /* daemon_init() must be before event_init() because kqueue() FDs * are, perversely, not inherited across fork(). */ daemon_init(thisServer.bootopt & BOOT_TTY); #ifdef DEBUGMODE /* Must reserve fd 2... */ if (debuglevel >= 0 && !(thisServer.bootopt & BOOT_TTY)) { int fd; if ((fd = open("/dev/null", O_WRONLY)) < 0) { fprintf(stderr, "Unable to open /dev/null (to reserve fd 2): %s\n", strerror(errno)); return 8; } if (fd != 2 && dup2(fd, 2) < 0) { fprintf(stderr, "Unable to reserve fd 2; dup2 said: %s\n", strerror(errno)); return 8; } } #endif event_init(MAXCONNECTIONS); setup_signals(); feature_init(); /* initialize features... */ log_init(*argv); set_nomem_handler(outofmemory); initload(); init_list(); init_hash(); init_class(); initwhowas(); initmsgtree(); initstats(); /* we need this for now, when we're modular this should be removed -- hikari */ ircd_crypt_init(); motd_init(); if (!init_conf()) { log_write(LS_SYSTEM, L_CRIT, 0, "Failed to read configuration file %s", configfile); return 7; } if (thisServer.bootopt & BOOT_CHKCONF) { if (dbg_client) conf_debug_iline(dbg_client); fprintf(stderr, "Configuration file %s checked okay.\n", configfile); return 0; } debug_init(thisServer.bootopt & BOOT_TTY); if (check_pid()) { Debug((DEBUG_FATAL, "Failed to acquire PID file lock after fork")); exit(2); } init_server_identity(); uping_init(); stats_init(); IPcheck_init(); timer_add(timer_init(&connect_timer), try_connections, 0, TT_RELATIVE, 1); timer_add(timer_init(&ping_timer), check_pings, 0, TT_RELATIVE, 1); timer_add(timer_init(&destruct_event_timer), exec_expired_destruct_events, 0, TT_PERIODIC, 60); timer_add(timer_init(&mute_timer), check_expired_mutes, 0, TT_PERIODIC, 30); CurrentTime = time(NULL); SetMe(&me); cli_magic(&me) = CLIENT_MAGIC; cli_from(&me) = &me; make_server(&me); cli_serv(&me)->timestamp = TStime(); /* Abuse own link timestamp as start TS */ cli_serv(&me)->prot = atoi(MAJOR_PROTOCOL); cli_serv(&me)->up = &me; cli_serv(&me)->down = NULL; cli_handler(&me) = SERVER_HANDLER; SetYXXCapacity(&me, MAXCLIENTS); cli_lasttime(&me) = cli_since(&me) = cli_firsttime(&me) = CurrentTime; hAddClient(&me); write_pidfile(); init_counters(); Debug((DEBUG_NOTICE, "Server ready...")); log_write(LS_SYSTEM, L_NOTICE, 0, "Server Ready"); event_loop(); return 0; }
void httpd_main(void) { int rv, n, t, accepting; time_t hours, last_time; accepting = 1; last_time = current_time = startuptime = time(0); hours = current_time / 3600; log_d("*** %s starting", server_version); while (gotsigterm == 0) { if (gotsighup) { gotsighup = 0; init_logs(0); if (debug) log_d("logs reopened"); } if (gotsigusr1) { gotsigusr1 = 0; close_connections(); log_d("connections closed"); } if (gotsigusr2) { gotsigusr2 = 0; close_servers(); log_d("servers closed"); } if (gotsigchld) { gotsigchld = 0; reap_children(); } if (gotsigquit) { gotsigquit = 0; debug = debug == 0; if (debug) log_d("debugging turned on"); else log_d("debugging turned off"); } if (gotsigwinch) { gotsigwinch = 0; log_d("performing internal dump"); internal_dump(); } n = 0; if (accepting && find_connection()) n = setup_server_pollfds(n); n = setup_connection_pollfds(n); n = setup_child_pollfds(n, forked_connections.head); if (n == 0 && accepting && stats.nconnections == 0) { log_d("no more sockets to poll from"); break; } t = accepting ? 60000 : 1000; if (debug) dump_pollfds(n, 0); rv = poll(pollfds, n, t); current_time = time(0); if (rv == -1) { if (errno != EINTR) { lerror("poll"); break; } else { if (debug) log_d("poll interrupted"); continue; } } if (debug) dump_pollfds(n, 1); if (current_time != last_time) { if (accepting == 0) accepting = 1; if (current_time / 3600 != hours) { hours = current_time / 3600; init_logs(0); if (debug) log_d("logs rotated"); } } if (rv) { if (accepting && run_servers() == -1) accepting = 0; run_connections(); } if (current_time != last_time) { cleanup_connections(); last_time = current_time; } } log_d("*** shutting down"); }