Hi,

Attached is a patch that makes the parent guardian process exit to the 
OS only after fbserver has called listen() initializing its network 
socket.

Without it, the following loop fails (sooner or later):

while true; do sudo service firebird3.0 restart; echo "select 'ready' from 
rdb\$database;" | isql localhost:employee; sleep 2.1; done

(the sleep is there to avoid the systemd limitation of 5 service 
restarts per 10 seconds).

The patch makes the fbserver process send a SIGUSR1 signal to the 
parent guardian process, which waits for it before exiting to the OS.

The patch applies (with a bit of fuzz) to master, B3_0_Release and 
B2_5_Release branches.

I hope you find it useful. I'll be including the patch in the next 
Debian release, after Debian 9 "stretch" is released later this year.

Please tell me if you prefer a ticket in JIRA or pull requests on 
github.


Cheers,
    dam
--- a/src/remote/inet.cpp
+++ b/src/remote/inet.cpp
@@ -1012,6 +1012,12 @@ static rem_port* listener_socket(rem_por
 
 	inet_ports->registerPort(port);
 
+	char *parent_pid;
+	if (parent_pid = getenv("FB_SIGNAL_PROCESS"))
+	{
+		kill(atoi(parent_pid), SIGUSR1);
+	}
+
 	if (flag & SRVR_multi_client)
 	{
 		// Prevent the generation of dummy keepalive packets on the connect port.
--- a/src/utilities/guard/guard.cpp
+++ b/src/utilities/guard/guard.cpp
@@ -162,13 +162,32 @@ int CLIB_ROUTINE main( int argc, char **
 		exit(-5);
 	}
 
+	sigset_t ss, save_sig_mask;
+	sigemptyset(&ss);
+	sigaddset(&ss, SIGUSR1);
+	sigprocmask(SIG_BLOCK, &ss, &save_sig_mask);
+
 	// detach from controlling tty
 	if (daemon && fork()) {
+		int sig;
+
+		struct timespec ts = { .tv_sec=15, .tv_nsec= 0 };
+		do {
+			sig = sigtimedwait( &ss, NULL, &ts );
+		} while ( sig == EINTR );
+
+		if ( sig != SIGUSR1 ) {
+			fprintf( stderr, "Time out waiting for fbserver process start\n");
+			exit(-4);
+		}
+
 		exit(0);
 	}
+	sigprocmask(SIG_SETMASK, &save_sig_mask, NULL);
 	divorce_terminal(0);
 
 	time_t timer = 0;
+	bool first_start = true;
 
 	do {
 		int ret_code;
@@ -187,6 +206,18 @@ int CLIB_ROUTINE main( int argc, char **
 		}
 		timer = time(0);
 
+		if (first_start)
+		{
+			char pid[10];
+			snprintf(pid, sizeof(pid), "%d", getppid());
+			setenv("FB_SIGNAL_PROCESS", pid, 1);
+			first_start = false;
+		}
+		else
+		{
+			unsetenv("FB_SIGNAL_PROCESS");
+		}
+
 		pid_t child_pid =
 			UTIL_start_process(SERVER_BINARY, server_args, prog_name);
 		if (child_pid == -1)
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to