Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Nov 2017 00:58:47 +0100
From:      Polytropon <freebsd@edvax.de>
To:        Ian Smith <smithi@nimnet.asn.au>
Cc:        Edgar Pettijohn <edgar@pettijohn-web.com>, Ernie Luzar <luzar722@gmail.com>, freebsd-questions@freebsd.org
Subject:   Re: Need help with rc.d script
Message-ID:  <20171110005847.34dc13f8.freebsd@edvax.de>
In-Reply-To: <20171109185331.B72828@sola.nimnet.asn.au>
References:  <mailman.444.1510052978.1530.freebsd-questions@freebsd.org> <20171108021900.W9710@sola.nimnet.asn.au> <20171108043726.N72828@sola.nimnet.asn.au> <5A01F758.1050706@gmail.com> <20171109005843.E72828@sola.nimnet.asn.au> <5A0332D1.90509@gmail.com> <20171109013818.GA31584@FreeBSD> <20171109040452.d3c25fe2.freebsd@edvax.de> <20171109185331.B72828@sola.nimnet.asn.au>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 9 Nov 2017 20:01:56 +1100 (EST), Ian Smith wrote:
> On Thu, 9 Nov 2017 04:04:52 +0100, Polytropon wrote:
> 
> Another night owl, hmm? :)

Idiotic "standby time"... ;-)



>  > On Wed, 8 Nov 2017 19:42:36 -0600, Edgar Pettijohn wrote:
>  > > On Wed, Nov 08, 2017 at 11:37:37AM -0500, Ernie Luzar wrote:
>  > > > Ian Smith wrote:
>  > > > > On Tue, 7 Nov 2017 13:11:36 -0500, Ernie Luzar wrote:
> [..]
>  > > > I tested with and without the enclosing ( and ) on the while loop 
>  > > > and it made no difference. No pidfile exists before the "service 
>  > > >  dynip start" is issued and non exists afterwards.
> 
>  > > I don't believe the rc system can write a pidfile for you. Most of if not all
>  > > of the services being started by the rc system are written in c and take care
>  > > of writing their own pidfile. I suspect you could overcome this by writing a c
>  > > program that does so and executes your script every 10 minutes. Or some form of
>  > > pgrep perhaps.
> 
>  > It's easy to create a pidfile from within the shell script for
>  > the shell itself (and its subshells) as well as for an invoked
>  > external program:
>  > 
>  > 	echo $$ > /var/run/${0##*/}.pid
>  > 	myprog -foo -bar baz -meow
>  > 	echo $! > /var/run/myprog.pid
> 
> In that case - unless myprog daemonised itself? - I believe you'd need:
>  	myprog -foo -bar baz -meow &
> so then $! is specifically the PID of the (now background) myprog

Good observation. Of course a PID cannot be obtained usefully after
a program has finished running. :-)



>  > The documentation says:
>  > 
>  >      $$      Expands to the process ID of the invoked shell.  A subshell
>  >              retains the same value of $ as its parent.
>  > 
>  >      $!      Expands to the process ID of the most recent background command
>  >              executed from the current shell.  For a pipeline, the process ID
>  >              is that of the last command in the pipeline.
>  > 
>  > See "man sh", section "Special Parameters", for details
> 
> Indeed.  I was trying to find out whether or not rc made the pidfile, or 
> one had to do it in the program (here a sh script) being run; as Edgar 
> indicated, seems the program|script needs to do it.  Even if rc had done 
> so, for a bg subshell (and not $$) you'd need to overwrite it anyway.

That is correct. While the individual rc script often define
a variable called pidfile (either with a specific hardcoded
name or one depending on variable evaluation), they do not
create it. In /etc/rc.subr, you can find subroutines to be
used by said rc script that can _check_ for a PID file. There
is a whole bunch of PID-related and process-related utility
functions.



> I think what's needed here for Ernie's dynip script is like:
> 
> 	# setup code ..
> 	[..]
> 	# repeated loop subshell code, to be left running
> 	(
> 		while true; do
> 			[..]
> 			sleep $delay
> 		done
> 	) &
> 	echo $! > /var/run/dynip.pid	# post PID of bg subshell
> 	echo ok or such confirmation	# if desired
> 	exit 0				# finished startup script
> 
> Then 'service dynip stop' should find and kill the correct process.

Correct. If the rc script defines the pidfile variable, the rc-related
tools (for example service, or by calling the rc.d script itself with
the "stop" or "restart" parameter) can use it.



> I generally go a bit further, finding sometimes that only the sleep in 
> such a loop may get killed - since it's running 99.9%+ of the time - so 
> usually take the trouble so any of the usual signals work to end it:
> 
> 	(	done=0
> 		trap "done=1" int quit term	# signals set done=1
> 		while [ $done -eq 0 ]; do
> 			[..]
> 			sleep $delay
> 		done;
> 		echo `basename $0` killed by signal int, quit or term
> 		trap - int quit term	# for tidyness, overkill here
> 	) &
> 	echo $! > /var/run/dynip.pid	# correct PID for external kill
> 	exit 0
> 
> Consult sh(1) regarding how to trap - and/or block - various signals.

A useful idea, especially for debugging and diagnostics.



-- 
Polytropon
Magdeburg, Germany
Happy FreeBSD user since 4.0
Andra moi ennepe, Mousa, ...



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20171110005847.34dc13f8.freebsd>