<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">Index: slon.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/slon.c,v
retrieving revision 1.28
diff -r1.28 slon.c
66a67,69
&gt;         FILE *pidfile=0;
&gt; 	char *pidfilename=0;
&gt; 	pid_t pid=0;
67a71
&gt; 	int			logpid=0;
69a74
&gt;         int			bgrun = 0;
76c81
&lt; 	while ((c = getopt(argc, argv, "d:s:t:g:c:h")) != EOF)
---
&gt; 	while ((c = getopt(argc, argv, "d:s:t:g:c:h:p:b")) != EOF)
132a138,143
&gt;                         case 'p':       logpid=1;
&gt; 					pidfilename=(char*)malloc(strlen(optarg)+1);
&gt; 					strcpy(pidfilename,optarg);
&gt; 					break;
&gt;                         case 'b':       bgrun=1;
&gt; 					break;
159,200c170,171
&lt; 	if (sync_interval_timeout != 0 &amp;&amp; sync_interval_timeout &lt;= sync_interval)
&lt; 		sync_interval_timeout = sync_interval * 2;
&lt; 
&lt; 	/*
&lt; 	 * Remember the cluster name and build the properly quoted 
&lt; 	 * namespace identifier
&lt; 	 */
&lt; 	slon_pid = getpid();
&lt; 	rtcfg_cluster_name	= (char *)argv[optind];
&lt; 	rtcfg_namespace		= malloc(strlen(argv[optind]) * 2 + 4);
&lt; 	cp2 = rtcfg_namespace;
&lt; 	*cp2++ = '"';
&lt; 	*cp2++ = '_';
&lt; 	for (cp1 = (char *)argv[optind]; *cp1; cp1++)
&lt; 	{
&lt; 		if (*cp1 == '"')
&lt; 			*cp2++ = '"';
&lt; 		*cp2++ = *cp1;
&lt; 	}
&lt; 	*cp2++ = '"';
&lt; 	*cp2 = '\0';
&lt; 
&lt; 	/*
&lt; 	 * Remember the connection information for the local node.
&lt; 	 */
&lt; 	rtcfg_conninfo = (char *)argv[++optind];
&lt; 
&lt; 	/*
&lt; 	 * Connect to the local database for reading the initial configuration
&lt; 	 */
&lt; 	startup_conn = PQconnectdb(rtcfg_conninfo);
&lt; 	if (startup_conn == NULL)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: PQconnectdb() failed\n");
&lt; 		slon_exit(-1);
&lt; 	}
&lt; 	if (PQstatus(startup_conn) != CONNECTION_OK)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: Cannot connect to local database - %s",
&lt; 				PQerrorMessage(startup_conn));
&lt; 		PQfinish(startup_conn);
&lt; 		slon_exit(-1);
---
&gt;         if ( bgrun == 1 ){
&gt;         	pid=fork();
201a173,184
&gt; 	if ( pid == 0 || bgrun == 0){
&gt; 		if (logpid==1){
&gt; 			pidfile=fopen(pidfilename,"w");
&gt; 			if(pidfile){
&gt; 				fprintf(pidfile,"%d",getpid());
&gt; 				fclose(pidfile);
&gt; 			} else {
&gt; 				fprintf(stderr,"couldn't open %s pidfile\n",pidfile);
&gt; 			}
&gt; 		}
&gt; 		if (sync_interval_timeout != 0 &amp;&amp; sync_interval_timeout &lt;= sync_interval)
&gt; 			sync_interval_timeout = sync_interval * 2;
203,212c186,203
&lt; 	/*
&lt; 	 * Get our local node ID
&lt; 	 */
&lt; 	rtcfg_nodeid = db_getLocalNodeId(startup_conn);
&lt; 	if (rtcfg_nodeid &lt; 0)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: Node is not initialized properly\n");
&lt; 		slon_exit(-1);
&lt; 	}
&lt; 	slon_log(SLON_CONFIG, "main: local node id = %d\n", rtcfg_nodeid);
---
&gt; 		/*
&gt; 		 * Remember the cluster name and build the properly quoted 
&gt; 		 * namespace identifier
&gt; 		 */
&gt; 		slon_pid = getpid();
&gt; 		rtcfg_cluster_name	= (char *)argv[optind];
&gt; 		rtcfg_namespace		= malloc(strlen(argv[optind]) * 2 + 4);
&gt; 		cp2 = rtcfg_namespace;
&gt; 		*cp2++ = '"';
&gt; 		*cp2++ = '_';
&gt; 		for (cp1 = (char *)argv[optind]; *cp1; cp1++)
&gt; 		{
&gt; 			if (*cp1 == '"')
&gt; 				*cp2++ = '"';
&gt; 			*cp2++ = *cp1;
&gt; 		}
&gt; 		*cp2++ = '"';
&gt; 		*cp2 = '\0';
214,218c205,225
&lt; 	/*
&lt; 	 * Start the event scheduling system
&lt; 	 */
&lt; 	if (sched_start_mainloop() &lt; 0)
&lt; 		slon_exit(-1);
---
&gt; 		/*
&gt; 		 * Remember the connection information for the local node.
&gt; 		 */
&gt; 		rtcfg_conninfo = (char *)argv[++optind];
&gt; 
&gt; 		/*
&gt; 		 * Connect to the local database for reading the initial configuration
&gt; 		 */
&gt; 		startup_conn = PQconnectdb(rtcfg_conninfo);
&gt; 		if (startup_conn == NULL)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: PQconnectdb() failed\n");
&gt; 			slon_exit(-1);
&gt; 		}
&gt; 		if (PQstatus(startup_conn) != CONNECTION_OK)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: Cannot connect to local database - %s",
&gt; 					PQerrorMessage(startup_conn));
&gt; 			PQfinish(startup_conn);
&gt; 			slon_exit(-1);
&gt; 		}
220c227,236
&lt; 	slon_log(SLON_CONFIG, "main: loading current cluster configuration\n");
---
&gt; 		/*
&gt; 		 * Get our local node ID
&gt; 		 */
&gt; 		rtcfg_nodeid = db_getLocalNodeId(startup_conn);
&gt; 		if (rtcfg_nodeid &lt; 0)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: Node is not initialized properly\n");
&gt; 			slon_exit(-1);
&gt; 		}
&gt; 		slon_log(SLON_CONFIG, "main: local node id = %d\n", rtcfg_nodeid);
222,231c238,258
&lt; 	/*
&lt; 	 * Begin a transaction
&lt; 	 */
&lt; 	res = PQexec(startup_conn, 
&lt; 			"start transaction; "
&lt; 			"set transaction isolation level serializable;");
&lt; 	if (PQresultStatus(res) != PGRES_COMMAND_OK)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "Cannot start transaction - %s",
&lt; 				PQresultErrorMessage(res));
---
&gt; 		/*
&gt; 		 * Start the event scheduling system
&gt; 		 */
&gt; 		if (sched_start_mainloop() &lt; 0)
&gt; 			slon_exit(-1);
&gt; 
&gt; 		slon_log(SLON_CONFIG, "main: loading current cluster configuration\n");
&gt; 
&gt; 		/*
&gt; 		 * Begin a transaction
&gt; 		 */
&gt; 		res = PQexec(startup_conn, 
&gt; 				"start transaction; "
&gt; 				"set transaction isolation level serializable;");
&gt; 		if (PQresultStatus(res) != PGRES_COMMAND_OK)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "Cannot start transaction - %s",
&gt; 					PQresultErrorMessage(res));
&gt; 			PQclear(res);
&gt; 			slon_exit(-1);
&gt; 		}
233,235d259
&lt; 		slon_exit(-1);
&lt; 	}
&lt; 	PQclear(res);
237,271c261,280
&lt; 	/*
&lt; 	 * Read configuration table sl_node
&lt; 	 */
&lt; 	dstring_init(&amp;query);
&lt; 	slon_mkquery(&amp;query, 
&lt; 			"select no_id, no_active, no_comment, "
&lt; 			"    (select coalesce(max(con_seqno),0) from %s.sl_confirm "
&lt; 			"        where con_origin = no_id and con_received = %d) "
&lt; 			"        as last_event "
&lt; 			"from %s.sl_node "
&lt; 			"order by no_id; ",
&lt; 			rtcfg_namespace, rtcfg_nodeid, rtcfg_namespace);
&lt; 	res = PQexec(startup_conn, dstring_data(&amp;query));
&lt; 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: Cannot get node list - %s",
&lt; 				PQresultErrorMessage(res));
&lt; 		PQclear(res);
&lt; 		dstring_free(&amp;query);
&lt; 		slon_exit(-1);
&lt; 	}
&lt; 	for (i = 0, n = PQntuples(res); i &lt; n; i++)
&lt; 	{
&lt; 		int		no_id		= (int) strtol(PQgetvalue(res, i, 0), NULL, 10);
&lt; 		int		no_active	= (*PQgetvalue(res, i, 1) == 't') ? 1 : 0;
&lt; 		char   *no_comment	= PQgetvalue(res, i, 2);
&lt; 		int64	last_event;
&lt; 
&lt; 		if (no_id == rtcfg_nodeid)
&lt; 		{
&lt; 			/*
&lt; 			 * Complete our own local node entry
&lt; 			 */
&lt; 			rtcfg_nodeactive  = no_active;
&lt; 			rtcfg_nodecomment = strdup(no_comment);
---
&gt; 		/*
&gt; 		 * Read configuration table sl_node
&gt; 		 */
&gt; 		dstring_init(&amp;query);
&gt; 		slon_mkquery(&amp;query, 
&gt; 				"select no_id, no_active, no_comment, "
&gt; 				"    (select coalesce(max(con_seqno),0) from %s.sl_confirm "
&gt; 				"        where con_origin = no_id and con_received = %d) "
&gt; 				"        as last_event "
&gt; 				"from %s.sl_node "
&gt; 				"order by no_id; ",
&gt; 				rtcfg_namespace, rtcfg_nodeid, rtcfg_namespace);
&gt; 		res = PQexec(startup_conn, dstring_data(&amp;query));
&gt; 		if (PQresultStatus(res) != PGRES_TUPLES_OK)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: Cannot get node list - %s",
&gt; 					PQresultErrorMessage(res));
&gt; 			PQclear(res);
&gt; 			dstring_free(&amp;query);
&gt; 			slon_exit(-1);
273c282
&lt; 		else
---
&gt; 		for (i = 0, n = PQntuples(res); i &lt; n; i++)
275,287c284,312
&lt; 			/*
&lt; 			 * Add a remote node
&lt; 			 */
&lt; 			slon_scanint64(PQgetvalue(res, i, 3), &amp;last_event);
&lt; 			rtcfg_storeNode(no_id, no_comment);
&lt; 			rtcfg_setNodeLastEvent(no_id, last_event);
&lt; 
&lt; 			/*
&lt; 			 * If it is active, remember for activation just before
&lt; 			 * we start processing events.
&lt; 			 */
&lt; 			if (no_active)
&lt; 				rtcfg_needActivate(no_id);
---
&gt; 			int		no_id		= (int) strtol(PQgetvalue(res, i, 0), NULL, 10);
&gt; 			int		no_active	= (*PQgetvalue(res, i, 1) == 't') ? 1 : 0;
&gt; 			char   *no_comment	= PQgetvalue(res, i, 2);
&gt; 			int64	last_event;
&gt; 
&gt; 			if (no_id == rtcfg_nodeid)
&gt; 			{
&gt; 				/*
&gt; 				 * Complete our own local node entry
&gt; 				 */
&gt; 				rtcfg_nodeactive  = no_active;
&gt; 				rtcfg_nodecomment = strdup(no_comment);
&gt; 			}
&gt; 			else
&gt; 			{
&gt; 				/*
&gt; 				 * Add a remote node
&gt; 				 */
&gt; 				slon_scanint64(PQgetvalue(res, i, 3), &amp;last_event);
&gt; 				rtcfg_storeNode(no_id, no_comment);
&gt; 				rtcfg_setNodeLastEvent(no_id, last_event);
&gt; 
&gt; 				/*
&gt; 				 * If it is active, remember for activation just before
&gt; 				 * we start processing events.
&gt; 				 */
&gt; 				if (no_active)
&gt; 					rtcfg_needActivate(no_id);
&gt; 			}
289,303d313
&lt; 	}
&lt; 	PQclear(res);
&lt; 
&lt; 	/*
&lt; 	 * Read configuration table sl_path - the interesting pieces
&lt; 	 */
&lt; 	slon_mkquery(&amp;query, 
&lt; 			"select pa_server, pa_conninfo, pa_connretry "
&lt; 			"from %s.sl_path where pa_client = %d",
&lt; 			rtcfg_namespace, rtcfg_nodeid);
&lt; 	res = PQexec(startup_conn, dstring_data(&amp;query));
&lt; 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: Cannot get path config - %s",
&lt; 				PQresultErrorMessage(res));
305,312d314
&lt; 		dstring_free(&amp;query);
&lt; 		slon_exit(-1);
&lt; 	}
&lt; 	for (i = 0, n = PQntuples(res); i &lt; n; i++)
&lt; 	{
&lt; 		int		pa_server		= (int) strtol(PQgetvalue(res, i, 0), NULL, 10);
&lt; 		char   *pa_conninfo		= PQgetvalue(res, i, 1);
&lt; 		int		pa_connretry	= (int) strtol(PQgetvalue(res, i, 2), NULL, 10);
314,316c316,336
&lt; 		rtcfg_storePath(pa_server, pa_conninfo, pa_connretry);
&lt; 	}
&lt; 	PQclear(res);
---
&gt; 		/*
&gt; 		 * Read configuration table sl_path - the interesting pieces
&gt; 		 */
&gt; 		slon_mkquery(&amp;query, 
&gt; 				"select pa_server, pa_conninfo, pa_connretry "
&gt; 				"from %s.sl_path where pa_client = %d",
&gt; 				rtcfg_namespace, rtcfg_nodeid);
&gt; 		res = PQexec(startup_conn, dstring_data(&amp;query));
&gt; 		if (PQresultStatus(res) != PGRES_TUPLES_OK)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: Cannot get path config - %s",
&gt; 					PQresultErrorMessage(res));
&gt; 			PQclear(res);
&gt; 			dstring_free(&amp;query);
&gt; 			slon_exit(-1);
&gt; 		}
&gt; 		for (i = 0, n = PQntuples(res); i &lt; n; i++)
&gt; 		{
&gt; 			int		pa_server		= (int) strtol(PQgetvalue(res, i, 0), NULL, 10);
&gt; 			char   *pa_conninfo		= PQgetvalue(res, i, 1);
&gt; 			int		pa_connretry	= (int) strtol(PQgetvalue(res, i, 2), NULL, 10);
318,329c338,339
&lt; 	/*
&lt; 	 * Read configuration table sl_listen - the interesting pieces
&lt; 	 */
&lt; 	slon_mkquery(&amp;query, 
&lt; 			"select li_origin, li_provider "
&lt; 			"from %s.sl_listen where li_receiver = %d",
&lt; 			rtcfg_namespace, rtcfg_nodeid);
&lt; 	res = PQexec(startup_conn, dstring_data(&amp;query));
&lt; 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: Cannot get listen config - %s",
&lt; 				PQresultErrorMessage(res));
---
&gt; 			rtcfg_storePath(pa_server, pa_conninfo, pa_connretry);
&gt; 		}
331,337d340
&lt; 		dstring_free(&amp;query);
&lt; 		slon_exit(-1);
&lt; 	}
&lt; 	for (i = 0, n = PQntuples(res); i &lt; n; i++)
&lt; 	{
&lt; 		int		li_origin	= (int) strtol(PQgetvalue(res, i, 0), NULL, 10);
&lt; 		int		li_provider	= (int) strtol(PQgetvalue(res, i, 1), NULL, 10);
339,341c342,361
&lt; 		rtcfg_storeListen(li_origin, li_provider);
&lt; 	}
&lt; 	PQclear(res);
---
&gt; 		/*
&gt; 		 * Read configuration table sl_listen - the interesting pieces
&gt; 		 */
&gt; 		slon_mkquery(&amp;query, 
&gt; 				"select li_origin, li_provider "
&gt; 				"from %s.sl_listen where li_receiver = %d",
&gt; 				rtcfg_namespace, rtcfg_nodeid);
&gt; 		res = PQexec(startup_conn, dstring_data(&amp;query));
&gt; 		if (PQresultStatus(res) != PGRES_TUPLES_OK)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: Cannot get listen config - %s",
&gt; 					PQresultErrorMessage(res));
&gt; 			PQclear(res);
&gt; 			dstring_free(&amp;query);
&gt; 			slon_exit(-1);
&gt; 		}
&gt; 		for (i = 0, n = PQntuples(res); i &lt; n; i++)
&gt; 		{
&gt; 			int		li_origin	= (int) strtol(PQgetvalue(res, i, 0), NULL, 10);
&gt; 			int		li_provider	= (int) strtol(PQgetvalue(res, i, 1), NULL, 10);
343,354c363,364
&lt; 	/*
&lt; 	 * Read configuration table sl_set
&lt; 	 */
&lt; 	slon_mkquery(&amp;query, 
&lt; 			"select set_id, set_origin, set_comment "
&lt; 			"from %s.sl_set",
&lt; 			rtcfg_namespace);
&lt; 	res = PQexec(startup_conn, dstring_data(&amp;query));
&lt; 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: Cannot get set config - %s",
&lt; 				PQresultErrorMessage(res));
---
&gt; 			rtcfg_storeListen(li_origin, li_provider);
&gt; 		}
356,363d365
&lt; 		dstring_free(&amp;query);
&lt; 		slon_exit(-1);
&lt; 	}
&lt; 	for (i = 0, n = PQntuples(res); i &lt; n; i++)
&lt; 	{
&lt; 		int		set_id		= (int) strtol(PQgetvalue(res, i, 0), NULL, 10);
&lt; 		int		set_origin	= (int) strtol(PQgetvalue(res, i, 1), NULL, 10);
&lt; 		char   *set_comment = PQgetvalue(res, i, 2);
365,367c367,387
&lt; 		rtcfg_storeSet(set_id, set_origin, set_comment);
&lt; 	}
&lt; 	PQclear(res);
---
&gt; 		/*
&gt; 		 * Read configuration table sl_set
&gt; 		 */
&gt; 		slon_mkquery(&amp;query, 
&gt; 				"select set_id, set_origin, set_comment "
&gt; 				"from %s.sl_set",
&gt; 				rtcfg_namespace);
&gt; 		res = PQexec(startup_conn, dstring_data(&amp;query));
&gt; 		if (PQresultStatus(res) != PGRES_TUPLES_OK)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: Cannot get set config - %s",
&gt; 					PQresultErrorMessage(res));
&gt; 			PQclear(res);
&gt; 			dstring_free(&amp;query);
&gt; 			slon_exit(-1);
&gt; 		}
&gt; 		for (i = 0, n = PQntuples(res); i &lt; n; i++)
&gt; 		{
&gt; 			int		set_id		= (int) strtol(PQgetvalue(res, i, 0), NULL, 10);
&gt; 			int		set_origin	= (int) strtol(PQgetvalue(res, i, 1), NULL, 10);
&gt; 			char   *set_comment = PQgetvalue(res, i, 2);
369,381c389,390
&lt; 	/*
&lt; 	 * Read configuration table sl_subscribe - our subscriptions only
&lt; 	 */
&lt; 	slon_mkquery(&amp;query, 
&lt; 			"select sub_set, sub_provider, sub_forward, sub_active "
&lt; 			"from %s.sl_subscribe "
&lt; 			"where sub_receiver = %d",
&lt; 			rtcfg_namespace, rtcfg_nodeid);
&lt; 	res = PQexec(startup_conn, dstring_data(&amp;query));
&lt; 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: Cannot get subscription config - %s",
&lt; 				PQresultErrorMessage(res));
---
&gt; 			rtcfg_storeSet(set_id, set_origin, set_comment);
&gt; 		}
383,397d391
&lt; 		dstring_free(&amp;query);
&lt; 		slon_exit(-1);
&lt; 	}
&lt; 	for (i = 0, n = PQntuples(res); i &lt; n; i++)
&lt; 	{
&lt; 		int		sub_set			= (int) strtol(PQgetvalue(res, i, 0), NULL, 10);
&lt; 		int		sub_provider	= (int) strtol(PQgetvalue(res, i, 1), NULL, 10);
&lt; 		char   *sub_forward		= PQgetvalue(res, i, 2);
&lt; 		char   *sub_active		= PQgetvalue(res, i, 3);
&lt; 
&lt; 		rtcfg_storeSubscribe(sub_set, sub_provider, sub_forward);
&lt; 		if (*sub_active == 't')
&lt; 			rtcfg_enableSubscription(sub_set, sub_provider, sub_forward);
&lt; 	}
&lt; 	PQclear(res);
399,410c393,420
&lt; 	/*
&lt; 	 * Remember the last known local event sequence
&lt; 	 */
&lt; 	slon_mkquery(&amp;query,
&lt; 			"select coalesce(max(ev_seqno), -1) from %s.sl_event "
&lt; 			"where ev_origin = '%d'",
&lt; 			rtcfg_namespace, rtcfg_nodeid);
&lt; 	res = PQexec(startup_conn, dstring_data(&amp;query));
&lt; 	if (PQresultStatus(res) != PGRES_TUPLES_OK)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: Cannot get last local eventid - %s",
&lt; 				PQresultErrorMessage(res));
---
&gt; 		/*
&gt; 		 * Read configuration table sl_subscribe - our subscriptions only
&gt; 		 */
&gt; 		slon_mkquery(&amp;query, 
&gt; 				"select sub_set, sub_provider, sub_forward, sub_active "
&gt; 				"from %s.sl_subscribe "
&gt; 				"where sub_receiver = %d",
&gt; 				rtcfg_namespace, rtcfg_nodeid);
&gt; 		res = PQexec(startup_conn, dstring_data(&amp;query));
&gt; 		if (PQresultStatus(res) != PGRES_TUPLES_OK)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: Cannot get subscription config - %s",
&gt; 					PQresultErrorMessage(res));
&gt; 			PQclear(res);
&gt; 			dstring_free(&amp;query);
&gt; 			slon_exit(-1);
&gt; 		}
&gt; 		for (i = 0, n = PQntuples(res); i &lt; n; i++)
&gt; 		{
&gt; 			int		sub_set			= (int) strtol(PQgetvalue(res, i, 0), NULL, 10);
&gt; 			int		sub_provider	= (int) strtol(PQgetvalue(res, i, 1), NULL, 10);
&gt; 			char   *sub_forward		= PQgetvalue(res, i, 2);
&gt; 			char   *sub_active		= PQgetvalue(res, i, 3);
&gt; 
&gt; 			rtcfg_storeSubscribe(sub_set, sub_provider, sub_forward);
&gt; 			if (*sub_active == 't')
&gt; 				rtcfg_enableSubscription(sub_set, sub_provider, sub_forward);
&gt; 		}
412,418c422,439
&lt; 		dstring_free(&amp;query);
&lt; 		slon_exit(-1);
&lt; 	}
&lt; 	if (PQntuples(res) == 0)
&lt; 		strcpy(rtcfg_lastevent, "-1");
&lt; 	else
&lt; 		if (PQgetisnull(res, 0, 0))
---
&gt; 
&gt; 		/*
&gt; 		 * Remember the last known local event sequence
&gt; 		 */
&gt; 		slon_mkquery(&amp;query,
&gt; 				"select coalesce(max(ev_seqno), -1) from %s.sl_event "
&gt; 				"where ev_origin = '%d'",
&gt; 				rtcfg_namespace, rtcfg_nodeid);
&gt; 		res = PQexec(startup_conn, dstring_data(&amp;query));
&gt; 		if (PQresultStatus(res) != PGRES_TUPLES_OK)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: Cannot get last local eventid - %s",
&gt; 					PQresultErrorMessage(res));
&gt; 			PQclear(res);
&gt; 			dstring_free(&amp;query);
&gt; 			slon_exit(-1);
&gt; 		}
&gt; 		if (PQntuples(res) == 0)
421,435c442,462
&lt; 			strcpy(rtcfg_lastevent, PQgetvalue(res, 0, 0));
&lt; 	PQclear(res);
&lt; 	dstring_free(&amp;query);
&lt; 	slon_log(SLON_DEBUG2, 
&lt; 			"main: last local event sequence = %s\n", 
&lt; 			rtcfg_lastevent);
&lt; 
&lt; 	/*
&lt; 	 * Rollback the transaction we used to get the config snapshot
&lt; 	 */
&lt; 	res = PQexec(startup_conn, "rollback transaction;");
&lt; 	if (PQresultStatus(res) != PGRES_COMMAND_OK)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: Cannot rollback transaction - %s",
&lt; 				PQresultErrorMessage(res));
---
&gt; 			if (PQgetisnull(res, 0, 0))
&gt; 				strcpy(rtcfg_lastevent, "-1");
&gt; 			else
&gt; 				strcpy(rtcfg_lastevent, PQgetvalue(res, 0, 0));
&gt; 		PQclear(res);
&gt; 		dstring_free(&amp;query);
&gt; 		slon_log(SLON_DEBUG2, 
&gt; 				"main: last local event sequence = %s\n", 
&gt; 				rtcfg_lastevent);
&gt; 
&gt; 		/*
&gt; 		 * Rollback the transaction we used to get the config snapshot
&gt; 		 */
&gt; 		res = PQexec(startup_conn, "rollback transaction;");
&gt; 		if (PQresultStatus(res) != PGRES_COMMAND_OK)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: Cannot rollback transaction - %s",
&gt; 					PQresultErrorMessage(res));
&gt; 			PQclear(res);
&gt; 			slon_exit(-1);
&gt; 		}
437,439d463
&lt; 		slon_exit(-1);
&lt; 	}
&lt; 	PQclear(res);
441,444c465,468
&lt; 	/*
&lt; 	 * Done with the startup, don't need the local connection any more.
&lt; 	 */
&lt; 	PQfinish(startup_conn);
---
&gt; 		/*
&gt; 		 * Done with the startup, don't need the local connection any more.
&gt; 		 */
&gt; 		PQfinish(startup_conn);
446c470
&lt; 	slon_log(SLON_CONFIG, "main: configuration complete - starting threads\n");
---
&gt; 		slon_log(SLON_CONFIG, "main: configuration complete - starting threads\n");
448,463c472,487
&lt; 	/*
&lt; 	 * Create the local event thread that is monitoring
&lt; 	 * the local node for administrative events to adjust the
&lt; 	 * configuration at runtime.
&lt; 	 * We wait here until the local listen thread has checked that
&lt; 	 * there is no other slon daemon running.
&lt; 	 */
&lt; 	pthread_mutex_lock(&amp;slon_wait_listen_lock);
&lt; 	if (pthread_create(&amp;local_event_thread, NULL, localListenThread_main, NULL) &lt; 0)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: cannot create localListenThread - %s\n",
&lt; 				strerror(errno));
&lt; 		slon_abort();
&lt; 	}
&lt; 	pthread_cond_wait(&amp;slon_wait_listen_cond, &amp;slon_wait_listen_lock);
&lt; 	pthread_mutex_unlock(&amp;slon_wait_listen_lock);
---
&gt; 		/*
&gt; 		 * Create the local event thread that is monitoring
&gt; 		 * the local node for administrative events to adjust the
&gt; 		 * configuration at runtime.
&gt; 		 * We wait here until the local listen thread has checked that
&gt; 		 * there is no other slon daemon running.
&gt; 		 */
&gt; 		pthread_mutex_lock(&amp;slon_wait_listen_lock);
&gt; 		if (pthread_create(&amp;local_event_thread, NULL, localListenThread_main, NULL) &lt; 0)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: cannot create localListenThread - %s\n",
&gt; 					strerror(errno));
&gt; 			slon_abort();
&gt; 		}
&gt; 		pthread_cond_wait(&amp;slon_wait_listen_cond, &amp;slon_wait_listen_lock);
&gt; 		pthread_mutex_unlock(&amp;slon_wait_listen_lock);
465,468c489,503
&lt; 	/*
&lt; 	 * Enable all nodes that are active
&lt; 	 */
&lt; 	rtcfg_doActivate();
---
&gt; 		/*
&gt; 		 * Enable all nodes that are active
&gt; 		 */
&gt; 		rtcfg_doActivate();
&gt; 
&gt; 		/*
&gt; 		 * Create the local cleanup thread that will remove old
&gt; 		 * events and log data.
&gt; 		 */
&gt; 		if (pthread_create(&amp;local_cleanup_thread, NULL, cleanupThread_main, NULL) &lt; 0)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: cannot create cleanupThread - %s\n",
&gt; 					strerror(errno));
&gt; 			slon_abort();
&gt; 		}
470,479c505,514
&lt; 	/*
&lt; 	 * Create the local cleanup thread that will remove old
&lt; 	 * events and log data.
&lt; 	 */
&lt; 	if (pthread_create(&amp;local_cleanup_thread, NULL, cleanupThread_main, NULL) &lt; 0)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: cannot create cleanupThread - %s\n",
&lt; 				strerror(errno));
&lt; 		slon_abort();
&lt; 	}
---
&gt; 		/*
&gt; 		 * Create the local sync thread that will generate SYNC
&gt; 		 * events if we had local database updates.
&gt; 		 */
&gt; 		if (pthread_create(&amp;local_sync_thread, NULL, syncThread_main, NULL) &lt; 0)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: cannot create syncThread - %s\n",
&gt; 					strerror(errno));
&gt; 			slon_abort();
&gt; 		}
481,490c516,525
&lt; 	/*
&lt; 	 * Create the local sync thread that will generate SYNC
&lt; 	 * events if we had local database updates.
&lt; 	 */
&lt; 	if (pthread_create(&amp;local_sync_thread, NULL, syncThread_main, NULL) &lt; 0)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: cannot create syncThread - %s\n",
&lt; 				strerror(errno));
&lt; 		slon_abort();
&lt; 	}
---
&gt; 		/*
&gt; 		 * Wait until the scheduler has shut down all remote connections
&gt; 		 */
&gt; 		slon_log(SLON_DEBUG1, "main: running scheduler mainloop\n");
&gt; 		if (sched_wait_mainloop() &lt; 0)
&gt; 		{
&gt; 			slon_log(SLON_FATAL, "main: scheduler returned with error\n");
&gt; 			slon_abort();
&gt; 		}
&gt; 		slon_log(SLON_DEBUG1, "main: scheduler mainloop returned\n");
492,501c527,533
&lt; 	/*
&lt; 	 * Wait until the scheduler has shut down all remote connections
&lt; 	 */
&lt; 	slon_log(SLON_DEBUG1, "main: running scheduler mainloop\n");
&lt; 	if (sched_wait_mainloop() &lt; 0)
&lt; 	{
&lt; 		slon_log(SLON_FATAL, "main: scheduler returned with error\n");
&lt; 		slon_abort();
&lt; 	}
&lt; 	slon_log(SLON_DEBUG1, "main: scheduler mainloop returned\n");
---
&gt; 		/*
&gt; 		 * Wait for all remote threads to finish
&gt; 		 */
&gt; 		main_thread = pthread_self();
&gt; 		main_argv = argv;
&gt; 		signal(SIGALRM, sigalrmhandler);
&gt; 		alarm(20);
503,509c535
&lt; 	/*
&lt; 	 * Wait for all remote threads to finish
&lt; 	 */
&lt; 	main_thread = pthread_self();
&lt; 	main_argv = argv;
&lt; 	signal(SIGALRM, sigalrmhandler);
&lt; 	alarm(20);
---
&gt; 		rtcfg_joinAllRemoteThreads();
511c537
&lt; 	rtcfg_joinAllRemoteThreads();
---
&gt; 		alarm(0);
513c539,552
&lt; 	alarm(0);
---
&gt; 		/*
&gt; 		 * Wait for the local threads to finish
&gt; 		 */
&gt; 		if (pthread_join(local_event_thread, NULL) &lt; 0)
&gt; 			slon_log(SLON_ERROR, "main: cannot join localListenThread - %s\n",
&gt; 					strerror(errno));
&gt; 
&gt; 		if (pthread_join(local_cleanup_thread, NULL) &lt; 0)
&gt; 			slon_log(SLON_ERROR, "main: cannot join cleanupThread - %s\n",
&gt; 					strerror(errno));
&gt; 
&gt; 		if (pthread_join(local_sync_thread, NULL) &lt; 0)
&gt; 			slon_log(SLON_ERROR, "main: cannot join syncThread - %s\n",
&gt; 					strerror(errno));
515,528c554,561
&lt; 	/*
&lt; 	 * Wait for the local threads to finish
&lt; 	 */
&lt; 	if (pthread_join(local_event_thread, NULL) &lt; 0)
&lt; 		slon_log(SLON_ERROR, "main: cannot join localListenThread - %s\n",
&lt; 				strerror(errno));
&lt; 
&lt; 	if (pthread_join(local_cleanup_thread, NULL) &lt; 0)
&lt; 		slon_log(SLON_ERROR, "main: cannot join cleanupThread - %s\n",
&lt; 				strerror(errno));
&lt; 
&lt; 	if (pthread_join(local_sync_thread, NULL) &lt; 0)
&lt; 		slon_log(SLON_ERROR, "main: cannot join syncThread - %s\n",
&lt; 				strerror(errno));
---
&gt; 		if (slon_restart_request)
&gt; 		{
&gt; 			slon_log(SLON_DEBUG1, "main: restart requested\n");
&gt; 			execvp(argv[0], argv);
&gt; 			slon_log(SLON_FATAL,
&gt; 					"main: cannot restart via execvp(): %s\n", strerror(errno));
&gt; 			exit(-1);
&gt; 		}
530,536c563,569
&lt; 	if (slon_restart_request)
&lt; 	{
&lt; 		slon_log(SLON_DEBUG1, "main: restart requested\n");
&lt; 		execvp(argv[0], argv);
&lt; 		slon_log(SLON_FATAL,
&lt; 				"main: cannot restart via execvp(): %s\n", strerror(errno));
&lt; 		exit(-1);
---
&gt; 		/*
&gt; 		 * That's it.
&gt; 		 */
&gt; 		slon_log(SLON_DEBUG1, "main: done\n");
&gt; 		unlink(pidfilename);
&gt; 		free(pidfilename);
&gt; 		
538,542d570
&lt; 
&lt; 	/*
&lt; 	 * That's it.
&lt; 	 */
&lt; 	slon_log(SLON_DEBUG1, "main: done\n");
</pre></body></html>