示例#1
0
/*
 * 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);
}
示例#3
0
/** 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);
}
示例#4
0
/** 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;
}
示例#5
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);
}
示例#6
0
    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);
}
示例#9
0
static void
terminate(int retval)
{
	close_connections();
	logger_shutdown();

	if (pid_file)
	{
		unlink(pid_file);
	}

	log_info("Terminating...\n");

	exit(retval);
}
示例#10
0
/*
 * 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);
}
示例#12
0
文件: main.c 项目: ebichu/dd-wrt
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 */
}
示例#13
0
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;
}
示例#14
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;
}
示例#15
0
/** 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;
}
示例#16
0
文件: core.c 项目: eckeman/mathopd
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");
}