LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Server
User Name
Password
Linux - Server This forum is for the discussion of Linux Software used in a server related context.

Notices

Reply
 
Search this Thread
Old 04-28-2010, 02:45 PM   #1
forrie
Member
 
Registered: Sep 2003
Distribution: RedHat
Posts: 37

Rep: Reputation: 15
Getting an /etc/init.d script to run at system shutdown


We require a script in /etc/init.d to run at shutdown, which (will eventually) calls a perl script that will turn off a service gracefully.

(specifically, this is RHEL 5.5)

I have been testing a basic shell script, based on the common templates available from /etc/init.d -- including the creation and deletion of a /var/lock/subsys file and appropriate chkconfig values, using customary shell routines for start, stop and restart.

We can get the start and restart options to work, but the script will not run or perform any basic tasks (even shell) as/when the system is shutting down.

The /etc/rc?.d links are correctly created via chkconfig.

According to the documentation, what we are doing should technically work, but it does not.

This is a mission critical issue for the software we have running and its dependencies. One of our daemons that supplies info to another remote system must perform some tasks and tell it that it's shut down.

Below is a simplified test we were using. The resulting log file in /tmp only gets data written to it when the system starts up. This happens whether or not we're using perl or /bin/sh.

This has been a very awkward task to figure out -- I've never seen it before, and just "presumed" it would work. :-)

Pointers appreciated!


Thanks,

Forrest






========

#!/bin/bash
#
# mytest
#
# chkconfig: 012345 12 02
# description: some script


binary="/tmp/mytest"

[ -x $binary ] || exit 0

RETVAL=0

start() {
echo -n "Starting mytest: "
/usr/local/bin/perl /tmp/mytest
RETVAL=$?
PID=$!
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/mytest

}


### This part does not work:

stop() {
echo -n "Shutting down mytest: "
/usr/local/bin/perl /tmp/mytest
RETVAL=$?
echo
if [ $RETVAL -eq 0 ]; then
rm -f /var/lock/subsys/mytest
fi
}

restart() {
echo -n "Restarting mytest: "
stop
sleep 2
start
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo "Usage: $0 {start|stop|restart}"
;;
esac

exit 0

===========
 
Old 04-28-2010, 05:06 PM   #2
TB0ne
Guru
 
Registered: Jul 2003
Location: Birmingham, Alabama
Distribution: SuSE, RedHat, Slack,CentOS
Posts: 14,642

Rep: Reputation: 2574Reputation: 2574Reputation: 2574Reputation: 2574Reputation: 2574Reputation: 2574Reputation: 2574Reputation: 2574Reputation: 2574Reputation: 2574Reputation: 2574
If I was you, I'd look in RedHat's knowledgebase online, and call them to verify (you are paying for support with RHEL). But, have you tried to put a link to the program/script/whatever, into something like /etc/rc.d/rc5.d? Link it to a KXXsomefile name. Something like K09myprogram. The capital K indicates a Kill (or stop, in this case), when the system leaves that runlevel. So when you're shutting down, it'll go through and run those scripts. RC5 is X windows/GUI, but you may be booting up in RC3 (text-mode) so put the link where appropriate.

And please verify this with RH...this works for me on SuSE/openSUSE...
 
Old 04-28-2010, 05:25 PM   #3
Linux_Kidd
Member
 
Registered: Jan 2006
Location: USA
Posts: 533

Rep: Reputation: 51
stop() {
echo -n "Shutting down mytest: "
/usr/local/bin/perl /tmp/mytest
RETVAL=$?
echo
if [ $RETVAL -eq 0 ]; then
rm -f /var/lock/subsys/mytest
fi
}

this looks like it runs /tmp/mytest


i think your stop routine needs a killproc in there, like most init.d scripts have. just take a look at any K script.
 
Old 04-28-2010, 07:56 PM   #4
tommylovell
Member
 
Registered: Nov 2005
Distribution: Fedora, Redhat
Posts: 372

Rep: Reputation: 101Reputation: 101
Code:
# chkconfig: 012345 12 02
# description: some script
This will produce S12xxxx start scripts in /etc/rc.d/rc0.d through /etc/rc.d/rc5.d, and an K02xxxx stop script in /etc/rc.d/rc6.d.

So if you 'shutdown -h now' (or init 0, or telinit 0) there is no "K" script to run when the system goes to runlevel 0. The S12xxxx script will be driven with an argument of "start" passed to it.

If you 'reboot' or 'shutdown -r now', I would bet your K02xxxx script is driven with an arg of "stop".

I think your "# chkconfig" should be:
Code:
# chkconfig: 12345 12 02
# description: some script
Out of curiousity, how does your perl script know if you are starting or stopping?

Let us know if this corrects the problem. Thanks.

Last edited by tommylovell; 04-28-2010 at 07:59 PM.
 
Old 05-04-2010, 11:28 AM   #5
forrie
Member
 
Registered: Sep 2003
Distribution: RedHat
Posts: 37

Original Poster
Rep: Reputation: 15
The script that runs does not initiate or maintain a process/daemon, so having a killproc in there really wouldn't make any sense.

We just want to have the script run, at shut down, to be a intermediary procedure for properly shutting down a complex process for which an external system is dependent. So, in other words, this script will do stuff locally, but it will first tell the remote system "I'm shutting down" so it doesn't continue expecting events.

I had assumed this would be a nobrainer. Was I ever wrong! LOL


Quote:
Originally Posted by Linux_Kidd View Post
stop() {
echo -n "Shutting down mytest: "
/usr/local/bin/perl /tmp/mytest
RETVAL=$?
echo
if [ $RETVAL -eq 0 ]; then
rm -f /var/lock/subsys/mytest
fi
}

this looks like it runs /tmp/mytest


i think your stop routine needs a killproc in there, like most init.d scripts have. just take a look at any K script.
 
Old 05-04-2010, 11:33 AM   #6
forrie
Member
 
Registered: Sep 2003
Distribution: RedHat
Posts: 37

Original Poster
Rep: Reputation: 15
The chkconfig script makes the proper links for the S and K scripts.

I have tried 12345 as the runlevel in chkconfig and it didn't make any difference.

I actually reduced this down to a very simple shell script, based on templates on the existing system, and it still doesn't work.

My hunch is that this scripting procedure was designed to work with ongoing, daemon processes; where our script is just a script that runs a few things then politely exits.

The perl script in question does know about "stop" and "start".

The shell script I mentioned above, will respond to "stop" and "start" if the system is running -- ie: if I send a "restart" it works. But it will not run any commands when the system is being shutdown and when, presumably, the script is being issued a "stop" by chkconfig at the appropriate time.

I'm very puzzled. I've never seen this before....

For sake of completion, here is the simple init.d shell script I've been testing:

Code:
#!/bin/bash
#
# mytest 
#
# chkconfig: 012345 12 02
# description: some script

# Source function library.
. /etc/init.d/functions

binary="/tmp/mytest"

[ -x $binary ] || exit 0

RETVAL=0

start() {
    echo -n "Starting mytest: "
    /usr/local/bin/perl /tmp/mytest
    RETVAL=$?
    PID=$!
    echo
    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/mytest

    # echo $PID > /var/run/mytest.pid
}

stop() {
    echo -n "Shutting down mytest: "
    /usr/local/bin/perl /tmp/mytest
    RETVAL=$?
    echo
    if [ $RETVAL -eq 0 ]; then
        rm -f /var/lock/subsys/mytest
    fi
}

restart() {
    echo -n "Restarting mytest: "
    stop
    sleep 2
    start
}

case "$1" in
    start)
        start
    ;;
    stop)
        stop
    ;;
    restart)
        restart
    ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
    ;;
esac

exit 0


Thanks (to everyone),

Forrest




Quote:
Originally Posted by tommylovell View Post
Code:
# chkconfig: 012345 12 02
# description: some script
This will produce S12xxxx start scripts in /etc/rc.d/rc0.d through /etc/rc.d/rc5.d, and an K02xxxx stop script in /etc/rc.d/rc6.d.

So if you 'shutdown -h now' (or init 0, or telinit 0) there is no "K" script to run when the system goes to runlevel 0. The S12xxxx script will be driven with an argument of "start" passed to it.

If you 'reboot' or 'shutdown -r now', I would bet your K02xxxx script is driven with an arg of "stop".

I think your "# chkconfig" should be:
Code:
# chkconfig: 12345 12 02
# description: some script
Out of curiousity, how does your perl script know if you are starting or stopping?

Let us know if this corrects the problem. Thanks.
 
Old 05-05-2010, 01:19 PM   #7
tommylovell
Member
 
Registered: Nov 2005
Distribution: Fedora, Redhat
Posts: 372

Rep: Reputation: 101Reputation: 101
Quote:
I have tried 12345 as the runlevel in chkconfig and it didn't make any difference.
Were you careful to do a "chkconfig --del mytest" first, then a "chkconfig --add mystest"? If you changed the
script and did not --del then --add, the change would not be effective.

Quote:
My hunch is that this scripting procedure was designed to work with ongoing, daemon processes; where our script is
just a script that runs a few things then politely exits.
That is not the case. I have this service (see code) and it runs just fine. It just emails a message and exits.
No daemon running.

Code:
#!/bin/bash
#
# mytest          Just send an email                        
#
# chkconfig: 12345 90 10
# description: Just send an email when runlevel changes
#
MAIL="/bin/mailx"
RMAIL="root@`hostname`"
WHO="mytest"
WHERE="`hostname`"

case "$1" in
'start')
[ -f /var/lock/subsys/$WHO ] \
       && logger -ist $WHO "$WHO appears already started"
${MAIL} -s "$WHO starting on $WHERE" ${RMAIL} < /dev/null >/dev/null 2>&1
touch /var/lock/subsys/$WHO
;;

'stop')
[ -f /var/lock/subsys/$WHO ] \
       || logger -ist $WHO "$WHO appears already stopped"
${MAIL} -s "$WHO stopping on $WHERE" ${RMAIL} < /dev/null >/dev/null 2>&1
/bin/rm -f /var/lock/subsys/$WHO
;;

*)
echo "Usage: $0 { start | stop }"
exit 1
;;
esac
exit 0
Quote:
The perl script in question does know about "stop" and "start".
Cool. Most people keep their start and stop logic in separate files, but that's personal preference.

Quote:
... But it will not run any commands when the system is being shutdown and when, presumably, the script is being
issued a "stop" by chkconfig at the appropriate time.
A slight misconception. 'chkconfig' does not drive your script nor issue a 'stop' to it.

'chkconfig' is a small utility that creates and manipulates the stop and start softlinks that the 'init' process
drives when you change runlevels. On a "chkconfig --add <service>", it reads the shell script for that service
in /etc/rc.d/init.d, and based on the "# chkconfig:" comment, generates "K" and "S" softlinks in the /etc/rc.d/rc0./
through /etc/rc.d/rc6.d/ directories pointing back to the script in /etc/rc.d/init.d.

As an example, when you did the "chkconfig --add mytest", it would have made certain first that the "mytest" was
in /etc/rc.d/init.d and was executable; then it would have read it to get the "# chkconfig: 012345 12 02" comment;
and finally would have created softlinks named "S12mytest" in directories /etc/rc.d/rc0.d through /etc/rc.d/rc5.d
pointing to /etc/rc.d/init.d/mytest, and a softlink named "K02mytest" in /etc/rc.d/rc.6.

With my "mytest", I have.
Code:
[root@athlonz ~]# grep chkconfig: /etc/rc.d/init.d/mytest
# chkconfig: 12345 90 10

[root@athlonz ~]# find /etc/rc* -name \*mytest -exec ls -l {} \;
lrwxrwxrwx 1 root root 16 2010-05-05 09:27 /etc/rc.d/rc1.d/S90mytest -> ../init.d/mytest
lrwxrwxrwx 1 root root 16 2010-05-05 09:27 /etc/rc.d/rc5.d/S90mytest -> ../init.d/mytest
-rwxr-xr-x 1 root root 709 2010-05-05 09:31 /etc/rc.d/init.d/mytest
lrwxrwxrwx 1 root root 16 2010-05-05 09:27 /etc/rc.d/rc0.d/K10mytest -> ../init.d/mytest
lrwxrwxrwx 1 root root 16 2010-05-05 09:27 /etc/rc.d/rc3.d/S90mytest -> ../init.d/mytest
lrwxrwxrwx 1 root root 16 2010-05-05 09:27 /etc/rc.d/rc4.d/S90mytest -> ../init.d/mytest
lrwxrwxrwx 1 root root 16 2010-05-05 09:27 /etc/rc.d/rc2.d/S90mytest -> ../init.d/mytest
lrwxrwxrwx 1 root root 16 2010-05-05 09:27 /etc/rc.d/rc6.d/K10mytest -> ../init.d/mytest
[root@athlonz ~]#
With your original "mytest".
Code:
[root@athlonz ~]# grep chkconfig: /etc/rc.d/init.d/mytest.orig 
# chkconfig: 012345 12 02

[root@athlonz ~]# find /etc/rc* -name \*mytest.orig -exec ls -l {} \;
lrwxrwxrwx 1 root root 21 2010-05-05 11:17 /etc/rc.d/rc1.d/S12mytest.orig -> ../init.d/mytest.orig
lrwxrwxrwx 1 root root 21 2010-05-05 11:17 /etc/rc.d/rc5.d/S12mytest.orig -> ../init.d/mytest.orig
-rwxr-xr-x 1 root root 990 2010-05-05 11:17 /etc/rc.d/init.d/mytest.orig
lrwxrwxrwx 1 root root 21 2010-05-05 11:17 /etc/rc.d/rc0.d/S12mytest.orig -> ../init.d/mytest.orig
lrwxrwxrwx 1 root root 21 2010-05-05 11:17 /etc/rc.d/rc3.d/S12mytest.orig -> ../init.d/mytest.orig
lrwxrwxrwx 1 root root 21 2010-05-05 11:17 /etc/rc.d/rc4.d/S12mytest.orig -> ../init.d/mytest.orig
lrwxrwxrwx 1 root root 21 2010-05-05 11:17 /etc/rc.d/rc2.d/S12mytest.orig -> ../init.d/mytest.orig
lrwxrwxrwx 1 root root 21 2010-05-05 11:17 /etc/rc.d/rc6.d/K02mytest.orig -> ../init.d/mytest.orig
[root@athlonz ~]#
Note the difference for runlevel 0 for both services, /etc/rc.d/rc0.d/K10mytest vs. /etc/rc.d/rc0.d/S12mytest.orig.
Mine is a "K" (kill) script and yours is an "S" (start) script.

When you "shutdown -h", "teleinit 0" or "init 0", you are asking the system to go to runlevel 0; when you "reboot",
"shutdown -r", "telinit 6" or 'init 6", you are asking the system to go to runlevel 6. What is happening is that
'init' gets told "change to runlevel X". What it does is execute a script "/etc/rc.d/rc".

"/etc/rc.d/rc" first executes all of the "K" scripts for the new runlevel, one at a time in numerical order, passing
each one an argument of 'stop'; then executes all of the "S" scripts for the new runlevel, also one at a time and
in numerical order, passing each one an argument of 'start'.

A popular misconception is that it runs the scripts for your current runlevel. In fact, it just does the ones for
the new runlevel.

Take a look at "/etc/rc.d/rc". It is pretty simple. You can see in the "KILL scripts" section (processing the "K"
scripts) that it will bypass any that are missing the "lock file"
Code:
[ -f /var/lock/subsys/$subsys -o -f /var/lock/subsys/$subsys.init ] || continue
And in the "START scripts" section (processing the "S" scripts), it will bypass any that already have a lock file.
Code:
[ -f /var/lock/subsys/$subsys -o -f /var/lock/subsys/$subsys.init ] \
               && continue
When the system comes back from the shutdown or reboot, 'init' looks at "/etc/inittab" for the default runlevel
(or uses an overriden value), then drives the "/etc/rc.d/rc" script just as it did at shutdown.

You can see from this scheme that when you "shutdown -h" and your script was added with "# chkconfig: 012345 12 02",
the "/etc/rc.d/rc0.d/S12mytest" script will be executed and passed an argument of 'start'. That's not what you want.

Also, with a "priority" of "12", your script will be invoked well before some of the things it may be dependent on, like the network, if you need to communicate with another system... I always use a pretty high number for starting a service -- in the 90's, and a low one for stopping -- in the zero's or 10's.

Unfortunately, I wasn't able to get your script to work. I spent about two hours on it, and I'm stubborn, but
there's a limit... I suspect there is something funky about the lock file handling. My testing would only invoke
the stop scripts! I couldn't get it to invoke the start scripts. The exact opposite of your experience.

I'd suggest using the script I supplied above and see if that will work.

I'm interested in a resolution if you find one. Good luck.

Last edited by tommylovell; 05-05-2010 at 03:16 PM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Init.d script not executing at shutdown and reboot roberbizimhatemo Linux - General 13 05-04-2012 07:28 AM
init script does not run at the shutdown time procfs Linux - Newbie 4 02-16-2010 02:00 AM
Is a script, run at boot time from init.d, run with root authority? tmbrwolf53 Linux - Server 2 03-31-2007 08:15 PM
Run init script as daemon isuck@linux Linux - Software 5 02-12-2007 01:29 AM
setting script to run when system enter init 3 fowlerlfc Linux - Newbie 2 10-29-2002 03:02 PM


All times are GMT -5. The time now is 01:20 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration