***SPAM*** [OpenSRF-GIT] OpenSRF branch master updated. d3499f22bb56a1f153d068df2f66a56867ec5560

Evergreen Git git at git.evergreen-ils.org
Fri Mar 7 12:11:09 EST 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "OpenSRF".

The branch, master has been updated
       via  d3499f22bb56a1f153d068df2f66a56867ec5560 (commit)
       via  ff43e389fd744022e3e68e803e454950379593ce (commit)
       via  81cdb6f841b0adfcf1b621a49b2120cc2a5a5752 (commit)
       via  82f19d82a316919e76bf5349272022a309872a01 (commit)
      from  3692bb33cccdf3106df96883033b20ab9170c5a5 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit d3499f22bb56a1f153d068df2f66a56867ec5560
Author: Galen Charlton <gmc at esilibrary.com>
Date:   Fri Mar 7 08:22:38 2014 -0800

    LP#1286198: use --ignore-orphans rather than --are-there-no-prisons
    
    The joke was fine while it lasted, but might be confusing to somebody
    who doesn't catch the literary reference.  This patch also fixes
    a minor typo.
    
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>

diff --git a/bin/opensrf-perl.pl.in b/bin/opensrf-perl.pl.in
index 20b1829..e98eed6 100755
--- a/bin/opensrf-perl.pl.in
+++ b/bin/opensrf-perl.pl.in
@@ -103,7 +103,7 @@ GetOptions(
     'reload' => \$opt_reload,
     'reload-all' => \$opt_reload_all,
     'diagnostic' => \$opt_diagnostic,
-    'are-there-no-prisons' => \$opt_ignore_orphans
+    'ignore-orphans' => \$opt_ignore_orphans
 );
 
 if ($opt_localhost) {
@@ -661,8 +661,8 @@ sub do_help {
         but no pidfile exists, kill the service process before starting
         the new one. This applies to routers too.
 
-    --are-there-no-prisons
-        When starting a service, if a service procses is already running but
+    --ignore-orphans
+        When starting a service, if a service process is already running but
         no pidfile exists, ignore the existing process and carry on starting
         the new one (i.e., ignore orphans).  This applies to routers too.
 

commit ff43e389fd744022e3e68e803e454950379593ce
Author: Lebbeous Fogle-Weekley <lebbeous at esilibrary.com>
Date:   Tue Feb 4 17:56:07 2014 -0500

    LP#1286198: Teach osrf_router to (optionally) write its own PID files
    
    Also, tiny bit of noise squelching on osrf_control/opensrf-perl.pl
    
    Signed-off-by: Lebbeous Fogle-Weekley <lebbeous at esilibrary.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>

diff --git a/bin/opensrf-perl.pl.in b/bin/opensrf-perl.pl.in
index c95e2b3..20b1829 100755
--- a/bin/opensrf-perl.pl.in
+++ b/bin/opensrf-perl.pl.in
@@ -288,20 +288,11 @@ sub do_diagnostic {
 
 
 sub do_start_router {
-    `opensrf_router $opt_config routers`;
-
-    sleep 2; # give the router time to fork
-    my @pids = `ps -C opensrf_router -o pid=`;
-    s/^\s*|\n//g for @pids;
 
     my $pidfile = get_pid_file('router');
-    open(PF, '>', $pidfile) or die "Cannot open $pidfile: $!\n";
-    foreach (@pids) {
-        chomp;
-        msg("starting service pid=$_ router");
-        print PF "$_\n";
-    }
-    close PF;
+    `opensrf_router $opt_config routers $pidfile`;
+
+    sleep 2; # give the router time to fork (probably not need now but w/e)
 }
 
 # stop a specific service
@@ -762,7 +753,9 @@ do_init() and verify_services($opt_service) if
     $opt_start_services or
     $opt_restart or
     $opt_restart_all or
-    $opt_restart_services) and $opt_service ne 'router';
+    $opt_restart_services) and (
+        not defined $opt_service or $opt_service ne 'router'
+    );
 
 # starting services.  do_init() handled above
 do_start($opt_service) if $opt_start;
diff --git a/include/opensrf/utils.h b/include/opensrf/utils.h
index 2f9c786..2276dd6 100644
--- a/include/opensrf/utils.h
+++ b/include/opensrf/utils.h
@@ -280,6 +280,7 @@ extern "C" {
 int init_proc_title( int argc, char* argv[] );
 int set_proc_title( const char* format, ... );
 
+int daemonizeWithCallback( void (*)(pid_t, int), int );
 int daemonize( void );
 
 void* safe_malloc(int size);
diff --git a/src/libopensrf/utils.c b/src/libopensrf/utils.c
index 52e8a68..6628c8c 100644
--- a/src/libopensrf/utils.c
+++ b/src/libopensrf/utils.c
@@ -645,12 +645,14 @@ char* uescape( const char* string, int size, int full_escape ) {
 
 /**
 	@brief Become a proper daemon.
+	@param callback Ptr to a function.  From parent, called with child PID as first argument, and the next argument to *this* function as the second argument.  From child, called with -1, -1 (yes pid_t is signed)
+	@param callback_arg An integer argument passed as the second argument to the callback function from the parent process post-fork()
 	@return 0 if successful, or -1 if not.
 
 	Call fork().  The parent exits.  The child moves to the root directory, detaches from
 	the terminal, and redirects the standard streams (stdin, stdout, stderr) to /dev/null.
 */
-int daemonize( void ) {
+int daemonizeWithCallback( void (*callback)(pid_t, int), int callback_arg ) {
 	pid_t f = fork();
 
 	if (f == -1) {
@@ -659,6 +661,9 @@ int daemonize( void ) {
 
 	} else if (f == 0) { // We're in the child now...
 		
+		if( callback )
+			callback( -1, -1 );
+
 		// Change directories.  Otherwise whatever directory
 		// we're in couldn't be deleted until the program
 		// terminated -- possibly causing some inconvenience.
@@ -676,10 +681,23 @@ int daemonize( void ) {
 		return 0;
 
 	} else { // We're in the parent...
+		if( callback )
+			callback( f, callback_arg );
+
 		_exit(0);
 	}
 }
 
+/**
+	@brief Become a proper daemon.
+	@return 0 if successful, or -1 if not.
+
+	See daemonizeWithCallback() for details.
+*/
+int daemonize( void ) {
+	return daemonizeWithCallback( NULL, 0 );
+}
+
 
 /**
 	@brief Determine whether a string represents a decimal integer.
diff --git a/src/router/osrf_router_main.c b/src/router/osrf_router_main.c
index 202e99a..5e51062 100644
--- a/src/router/osrf_router_main.c
+++ b/src/router/osrf_router_main.c
@@ -18,6 +18,7 @@
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <sys/mman.h>
 #include <errno.h>
 #include "opensrf/utils.h"
 #include "opensrf/log.h"
@@ -30,7 +31,14 @@ static osrfRouter* router = NULL;
 
 static volatile sig_atomic_t stop_signal = 0;
 
-static void setupRouter( const jsonObject* configChunk );
+static void setupRouter( const jsonObject* configChunk, int configPos );
+
+/* I think it's important these following things not be static */
+pid_t* daemon_pid_list;
+size_t	daemon_pid_list_size;
+
+
+void storeRouterDaemonPid( pid_t, int );
 
 /**
 	@brief Respond to signal by setting a switch that will interrupt the main loop.
@@ -58,12 +66,14 @@ int main( int argc, char* argv[] ) {
 
 	if( argc < 3 ) {
 		osrfLogError( OSRF_LOG_MARK,
-			"Usage: %s <path_to_config_file> <config_context>", argv[0] );
+			"Usage: %s <path_to_config_file> <config_context> [pid_file]",
+			argv[0] );
 		exit( EXIT_FAILURE );
 	}
 
 	const char* config_file = argv[1];
 	const char* context = argv[2];
+	char* pid_file = argc >= 4 ? strdup(argv[3]) : NULL;
 
 	/* Get a set of router definitions from a config file */
 
@@ -87,11 +97,35 @@ int main( int argc, char* argv[] ) {
 	init_proc_title( argc, argv );
 	set_proc_title( "OpenSRF Router" );
 
+	/* Set up some shared memory so after some forking(), our children
+	 * can tell us about all our grandchildren's PIDs, and we can write
+	 * them to a file.
+	 */
+	daemon_pid_list_size = configInfo->size * sizeof(pid_t);
+	daemon_pid_list = mmap(
+		NULL, daemon_pid_list_size, PROT_READ | PROT_WRITE,
+		MAP_ANONYMOUS | MAP_SHARED, -1 , 0
+	);
+
+	if ( daemon_pid_list == MAP_FAILED ) {
+		osrfLogError(
+			OSRF_LOG_MARK,
+			"mmap() for router daemon PID list failed: %s",
+			strerror(errno)
+		);
+		exit( EXIT_FAILURE );
+	}
+
+	memset( daemon_pid_list, 0, daemon_pid_list_size );
+
 	/* Spawn child process(es) */
 
 	int rc = EXIT_SUCCESS;
 	int parent = 1;    // boolean
 	int i;
+
+	FILE *pid_fp;
+
 	for(i = 0; i < configInfo->size; i++) {
 		const jsonObject* configChunk = jsonObjectGetIndex( configInfo, i );
 		if( ! jsonObjectGetKeyConst( configChunk, "transport" ) )
@@ -107,8 +141,10 @@ int main( int argc, char* argv[] ) {
 			// typo or other such error, making it look spurious.  In that case, well, too bad.
 			continue;
 		}
+
 		if(fork() == 0) { /* create a new child to run this router instance */
-			setupRouter(configChunk);
+			free( pid_file );   /* we don't need this as a child */
+			setupRouter(configChunk, i);
 			parent = 0;
 			break;  /* We're a child; don't spawn any more children here */
 		}
@@ -150,6 +186,43 @@ int main( int argc, char* argv[] ) {
 				rc = EXIT_FAILURE;
 			}
 		}
+
+		/* If rc is still EXIT_SUCCESS after the preceding loop,
+		 * all our children have spawned grandchildren and will have
+		 * reported their IDs via our shared memory daemon_pid_list
+		 * buffer by now.
+		 *
+		 * A note about that list: it's going to have one pid_t-sized
+		 * slot for every configInfo chunk in the config.  Commonly,
+		 * this code sees empty chunks or chunks that don't correspond
+		 * to full router configs, so the slots for these unused chunks
+		 * get left at zero.  We skip those zeros both when writing the
+		 * PID file and when reporting to the log.
+		 * */
+		if ( rc == EXIT_SUCCESS ) {
+			if ( pid_file ) {
+				if ( (pid_fp = fopen(pid_file, "w")) ) {
+					for (i = 0; i < configInfo->size; i++) {
+						if ( daemon_pid_list[i] > 0 )
+							fprintf(pid_fp, "%d\n", daemon_pid_list[i]);
+					}
+					fclose(pid_fp);
+				} else {
+					osrfLogWarning(OSRF_LOG_MARK,
+						"Tried to write PID file at %s but couldn't: %s",
+						pid_file, strerror(errno));
+				}
+				free( pid_file );
+			}
+
+//			for (i = 0; i < configInfo->size; i++) {
+//				if ( daemon_pid_list[i] > 0 ) {
+//					osrfLogInfo(OSRF_LOG_MARK,
+//						"Reporting a grandchild with PID %d", daemon_pid_list[i]);
+//				}
+//			}
+		}
+		munmap( daemon_pid_list, daemon_pid_list_size );
 	}
 
 	if( stop_signal ) {
@@ -166,11 +239,12 @@ int main( int argc, char* argv[] ) {
 /**
 	@brief Configure and run a child process.
 	@param configChunk Pointer to a subset of the loaded configuration.
+	@param configPos Index of configChunk in its original containing array, doubling as index for storing PID of child from daemonization (the original process' grandchild)
 
 	Configure oneself, daemonize, and then call osrfRouterRun() to go into a
 	near-endless loop.  Return when interrupted by a signal, or when something goes wrong.
 */
-static void setupRouter( const jsonObject* configChunk ) {
+static void setupRouter( const jsonObject* configChunk, int configPos ) {
 
 	const jsonObject* transport_cfg = jsonObjectGetKeyConst( configChunk, "transport" );
 
@@ -266,7 +340,7 @@ static void setupRouter( const jsonObject* configChunk ) {
 
 	// Done configuring?  Let's get to work.
 
-	daemonize();
+	daemonizeWithCallback( storeRouterDaemonPid, configPos );
 	osrfRouterRun( router );
 
 	osrfRouterFree(router);
@@ -275,3 +349,8 @@ static void setupRouter( const jsonObject* configChunk ) {
 
 	return;
 }
+
+void storeRouterDaemonPid( pid_t p, int i ) {
+	if( i != -1 )
+		daemon_pid_list[i] = p;
+}

commit 81cdb6f841b0adfcf1b621a49b2120cc2a5a5752
Author: Lebbeous Fogle-Weekley <lebbeous at esilibrary.com>
Date:   Fri Jan 31 15:50:01 2014 -0500

    LP#1286198: Offer ability to ignore what seem like orphan processes when starting things
    
    Signed-off-by: Lebbeous Fogle-Weekley <lebbeous at esilibrary.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>

diff --git a/bin/opensrf-perl.pl.in b/bin/opensrf-perl.pl.in
index a939efe..c95e2b3 100755
--- a/bin/opensrf-perl.pl.in
+++ b/bin/opensrf-perl.pl.in
@@ -61,6 +61,7 @@ my $opt_reload = 0;
 my $opt_reload_all = 0;
 my $opt_quiet = 0;
 my $opt_diagnostic = 0;
+my $opt_ignore_orphans = 0;
 my $sclient;
 my @perl_services;
 my @nonperl_services;
@@ -101,7 +102,8 @@ GetOptions(
     'router-re-register-all' => \$opt_router_re_register_all,
     'reload' => \$opt_reload,
     'reload-all' => \$opt_reload_all,
-    'diagnostic' => \$opt_diagnostic
+    'diagnostic' => \$opt_diagnostic,
+    'are-there-no-prisons' => \$opt_ignore_orphans
 );
 
 if ($opt_localhost) {
@@ -369,7 +371,7 @@ sub do_start {
             unlink $pidfile;
         }
 
-    } elsif (@ps_pids) { # orphan process
+    } elsif (@ps_pids and not $opt_ignore_orphans) { # orphan process
 
         if ($opt_force_clean_process) {
             msg("service $service pid=@ps_pids is running with no pidfile");
@@ -666,7 +668,12 @@ sub do_help {
     --force-clean-process
         When starting a service, if a service process is already running 
         but no pidfile exists, kill the service process before starting
-        the new one.
+        the new one. This applies to routers too.
+
+    --are-there-no-prisons
+        When starting a service, if a service procses is already running but
+        no pidfile exists, ignore the existing process and carry on starting
+        the new one (i.e., ignore orphans).  This applies to routers too.
 
     ==== stopping services =====
 

commit 82f19d82a316919e76bf5349272022a309872a01
Author: Lebbeous Fogle-Weekley <lebbeous at esilibrary.com>
Date:   Thu Jan 30 18:32:24 2014 -0500

    LP#1286198: When doing router-specific things, we don't need as much configuration loaded
    
    Signed-off-by: Lebbeous Fogle-Weekley <lebbeous at esilibrary.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Galen Charlton <gmc at esilibrary.com>

diff --git a/bin/opensrf-perl.pl.in b/bin/opensrf-perl.pl.in
index d5961da..a939efe 100755
--- a/bin/opensrf-perl.pl.in
+++ b/bin/opensrf-perl.pl.in
@@ -749,13 +749,13 @@ exit;
 # we do not verify services for stop/signal actions, since those may
 # legitimately be used against services not (or no longer) configured
 # to run on the selected host.
-do_init() and verify_services($opt_service) if 
-    $opt_start or 
+do_init() and verify_services($opt_service) if
+    ($opt_start or
     $opt_start_all or
     $opt_start_services or
     $opt_restart or
     $opt_restart_all or
-    $opt_restart_services;
+    $opt_restart_services) and $opt_service ne 'router';
 
 # starting services.  do_init() handled above
 do_start($opt_service) if $opt_start;

-----------------------------------------------------------------------

Summary of changes:
 bin/opensrf-perl.pl.in        |   36 ++++++++--------
 include/opensrf/utils.h       |    1 +
 src/libopensrf/utils.c        |   20 +++++++++-
 src/router/osrf_router_main.c |   89 ++++++++++++++++++++++++++++++++++++++--
 4 files changed, 122 insertions(+), 24 deletions(-)


hooks/post-receive
-- 
OpenSRF


More information about the opensrf-commits mailing list