WelcomeWelcome | FAQFAQ | DownloadsDownloads | WikiWiki

Author Topic: Basic init.d script example  (Read 82202 times)

Offline Jason W

  • Administrator
  • Hero Member
  • *****
  • Posts: 9730
Basic init.d script example
« on: December 02, 2009, 07:23:18 AM »
When extensions contain daemons, it is helpful to provide  an init script to allow the user to start and stop it.  /usr/local/etc/init.d/ is the standard location for extension startup script on TC.  We have the start-stop-daemon in base to make it easy to start and stop processes.  Below is an example of an init script to start and stop rpc.mountd:

Code: [Select]
#!/bin/sh
# Starts and stops rpc.mountd
#


case "$1" in
start)

start-stop-daemon --start --exec /usr/local/sbin/portmap -u `id -u`
        start-stop-daemon --start --exec /usr/local/sbin/rpc.mountd

;;

stop)

start-stop-daemon --stop --exec /usr/local/sbin/rpc.mountd
;;

restart)
   $0 stop
   $0 start
;;

status)
             if pidof -o %PPID rpc.mountd > /dev/null; then
                     echo "Running"
                     exit 0
             else
                     echo "Not running"
                     exit 1
             fi
;;

*)
        echo "Usage: $0 {start|stop|restart|status}"
        exit 1
esac


Notice that as rpc.mountd depends on portmap already running, portmap is started by the start-stop-daemon in the rpc.mountd script.  The start-stop-daemon does not force start a process, it simply echoes "portmap already running" if it has already been started.  There are other ways to check for a pid and such, but start-stop-daemon makes it easy for most daemons.   Also, the rpc.mountd script does not stop portmap when the stop function is used since portmap may be needed by other processes.

It is my personal preference not to start processes in the /usr/local/tce.installed startup script as I don't believe that is where daemons should be started.  But a call to the init.d script can be put in the tce.installed script if the extension maker feels it is absolutely necessary to have that daemon running at all times unless the user feels the need to stop it.   Since init.d scripts can start dependent processes, and most distros use that approach, there really should not be a need to start a daemon in the tce.installed script in my opinion.  But the support for it is there if needed with the order of execution of startup scripts.

There is no push to remake extensions that use another method to fit this method, this approach can be seamlessly worked in as extensions are updated.

As always, any ideas or suggestions are welcome.

A pid approach would be like below:

Code: [Select]
#!/bin/sh
# Starts and stops rpc.mountd
#


case "$1" in
start)


             if ! pidof portmap >/dev/null; then
                   /usr/local/sbin/portmap -u `id -u`
                   echo "Starting portmap..."
             else
                    echo "Portmap already running.."
             fi
             fi
             if ! pidof rpc.mountd >/dev/null; then
                    /usr/local/sbin/rpc.mountd
                    echo "Starting rpc.mountd.."
             else
                    echo "Rpc.mountd already running.."
             fi

;;

stop)

               if pidof rpc.mountd >/dev/null; then
                    killall -9 rpc.mountd  >/dev/null
                    echo "Rpc.mountd stopped.."
               else
                    echo "Rpc.mountd not running.."
               fi
;;

restart)
   $0 stop
   $0 start
;;

*)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac
« Last Edit: May 28, 2010, 02:38:24 AM by curaga »

Offline danielibarnes

  • Hero Member
  • *****
  • Posts: 548
Re: Basic init.d script example
« Reply #1 on: December 02, 2009, 01:47:58 PM »
That looks useful. Has anyone considered the use of Upstart with TC to help manage this? Debian is transitioning to it, and it looks interesting.

Offline Jason W

  • Administrator
  • Hero Member
  • *****
  • Posts: 9730
Re: Basic init.d script example
« Reply #2 on: December 02, 2009, 02:18:09 PM »
The main purpose with the init.d scripts is to simply give the user the ability to start/stop/restart processes.   To automate them, placing the command in bootlocal.sh would start on boot, while a shutdown.sh seems planned for 2.7 so that would provide basic control during startup/shutdown.  Of course, one process that simple distros (Arch, Crux) use and has been mentioned here is having a file like /etc/rc.conf that has a place to enter the init scripts' name to be ran during boot and stopped during shutdown.  

Though that approach is simple, it does add one more file to manage and back up.  Also, with some things like alsa or cups the timing of the starting of those files seems to be touchy.  Alsa needs a sleep command to work properly on some machines and I believe cups likes X to be already started (correct me Juanito if I am wrong about cups).  

With bootlocal.sh and a shutdown.sh equivalent, I am not sure we want to add more complexity, however small, or files involved to the process.  


Correction:  The first post said "There is push to remake extensions".  It meant to say "There is no push to remake extensions". 

Offline danielibarnes

  • Hero Member
  • *****
  • Posts: 548
Re: Basic init.d script example
« Reply #3 on: December 02, 2009, 02:50:03 PM »
Quote
I am not sure we want to add more complexity, however small, or files involved to the process.
I agree. Perhaps an Upstart extension (or similar) could provide that complexity as an option rather than part of the base. Then, extensions which require this complexity could add it as a dependency. Using sleeps to manage timing is very touchy, and using an event-based startup could smooth that out.

Offline Juanito

  • Administrator
  • Hero Member
  • *****
  • Posts: 14516
Re: Basic init.d script example
« Reply #4 on: December 02, 2009, 07:26:34 PM »
..and I believe cups likes X to be already started (correct me Juanito if I am wrong about cups).

It looks that way, but I've not yet managed to find out why.

I've added init.d scripts to a few extensions - acpid, cpufreqd, samba3 - and have already noticed that one size does not fit all, but with further testing, we should be able to refine them for tc.

Offline jpeters

  • Restricted
  • Hero Member
  • *****
  • Posts: 1017
Re: Basic init.d script example
« Reply #5 on: December 02, 2009, 09:32:34 PM »
..and I believe cups likes X to be already started (correct me Juanito if I am wrong about cups).

It looks that way, but I've not yet managed to find out why.

yep.....

Offline Jason W

  • Administrator
  • Hero Member
  • *****
  • Posts: 9730
Re: Basic init.d script example
« Reply #6 on: December 03, 2009, 09:11:18 AM »
Upstart is definitely a no go.  It is a replacement for the init process and seems Debian/Ubuntu specific.  

The alsa issue is one that also seems to affect Arch and other fast booting distros when alsa restoring is done during boot.  My thoughts are that as some machines require a "waitusb" boot code, the user simply adds the boot code to accomodate his machine.  And on boot, if a command or script in bootlocal needs a couple of seconds for other parts of the system to settle, then a simple sleep command will do.  I added various checks for waiting on depmod & udevtrigger to complete, as well as the presence of /proc/asound directory to the alsa init.d script to no avail.  Rather than adding any possible test conditions to the init.d script, I think even if that did work it is better for a user to add a sleep command to bootlocal.sh if his machine needs it.  There should not be many scripts affected like this, and for the ones that are the remedy is common knowledge, and will also be put in the info file.

As for a way a system to start the init scripts, we have bootlocal.sh. Or .xsession for things needing to start after X.  I would like this process to stay as simple as possible.
« Last Edit: December 03, 2009, 09:13:25 AM by Jason W »

Offline combo3

  • Full Member
  • ***
  • Posts: 148
Re: Basic init.d script example
« Reply #7 on: December 03, 2009, 01:02:47 PM »
Having submitted two extensions with daemon scripts affected by this policy, I have a few questions.

For monkey, I debated placing the daemon in four places:

 - /etc/init.d (where the author intended),
 - /usr/local/etc/init.d (the logical alternative)
 - /usr/local/bin
 - /usr/local/sbin
 
I ruled out the first choice for PPI compatability reasons, and would have gone with the second except that it requires the user to enter the complete path or create an alias.

Options 3 and 4 require some explaining:

Monkey can be run by any user on unprivileged ports, but requires root privileges for anything below 1024. To keep things simple (and avoid confusion over something which may not be readily apparent), I modified the script to run only as root user and placed it in /usr/local/bin

So my first question is:

Will /usr/local/etc/init.d be included in the environment path for future releases,
or is there a valid reason why it isn't?

My second question concerns config files.

Some extensions put them in /home/tc/.app while others put them in /home/tc/.config/app

Which is the preferred location?

Finally, what role (if any) does /opt play in Tinycore vis-a-vis extensions?
« Last Edit: December 03, 2009, 02:49:56 PM by combo3 »

Offline Jason W

  • Administrator
  • Hero Member
  • *****
  • Posts: 9730
Re: Basic init.d script example
« Reply #8 on: December 03, 2009, 03:17:20 PM »
Are you talking about a wrapper or an init script?  A wrapper would go in /usr/local/bin,sbin as usual.

Init scripts use a start, restart or stop switch, and are usually not in $PATH.  /etc/init.d is never in $PATH in the distros I have used though their init scripts are there.  We use /usr/local/etc/init.d for PPI compatibility.  And with one basic location, it is simpler to locate them. 

Very few extensions are installed into /opt, but perhaps /opt/init.d would be the logical place.

Config files are normally determined by the application itself as far as the ones in /home.  But for the /etc/ config files, my preference is in /usr/local/etc or /usr/local/etc/appname.  Sometimes /etc is hardcoded into the application, in that case the startup script can copy the configs into /etc/ from a PPI compatible location.  But that is preferable only if /usr/local/etc is not a compile time option.

Offline combo3

  • Full Member
  • ***
  • Posts: 148
Re: Basic init.d script example
« Reply #9 on: December 05, 2009, 10:38:19 PM »
It's a start-stop-restart script, and the author's configure script adds it to BINDIR (not /etc/init.d as I posted earlier). The binary is hardcoded to search for the config files in BINDIR/config, but provides an override switch allowing the user to specify an alternate location at runtime. I chose $HOME based on the assumption most users include that in their backup or set up a persistent home directory on their partition.

No problem. I'll rebuild the extension and resubmit it after the weekend.

Thanks for the clarification.

Offline curaga

  • Administrator
  • Hero Member
  • *****
  • Posts: 10957
Re: Basic init.d script example
« Reply #10 on: May 28, 2010, 02:39:19 AM »
Added status function example to the script.
The only barriers that can stop you are the ones you create yourself.

Offline bigpcman

  • Hero Member
  • *****
  • Posts: 719
Re: Basic init.d script example
« Reply #11 on: May 28, 2010, 01:19:07 PM »
When extensions contain daemons, it is helpful to provide  an init script to allow the user to start and stop it.  /usr/local/etc/init.d/ is the standard location for extension startup script on TC.  We have the start-stop-daemon in base to make it easy to start and stop processes.  Below is an example of an init script to start and stop rpc.mountd:

Code: [Select]
#!/bin/sh
# Starts and stops rpc.mountd
#


case "$1" in
start)

start-stop-daemon --start --exec /usr/local/sbin/portmap -u `id -u`
        start-stop-daemon --start --exec /usr/local/sbin/rpc.mountd

;;

stop)

start-stop-daemon --stop --exec /usr/local/sbin/rpc.mountd
;;

restart)
  $0 stop
  $0 start
;;

status)
             if pidof -o %PPID rpc.mountd > /dev/null; then
                     echo "Running"
                     exit 0
             else
                     echo "Not running"
                     exit 1
             fi
;;

*)
        echo "Usage: $0 {start|stop|restart|status}"
        exit 1
esac


It took me awhile to figure out that pidof is not instantaneous for some services. I had to insert a delay to get the correct status of x0vncserver as follows:
Code: [Select]
VNCPID=$(pidof x0vncserver)
 sleep 2
 if [ -n "$VNCPID" ]; then
 ....
 else
 ....
  fi
 
big pc man

Offline Jason W

  • Administrator
  • Hero Member
  • *****
  • Posts: 9730
Re: Basic init.d script example
« Reply #12 on: May 28, 2010, 04:58:05 PM »
Another way could grep the ps command:

Code: [Select]
status)
if ps | awk '{print $3}' | grep -e "/usr/local/sbin/rpc.statd" >/dev/null; then
echo "NFS-client is running."
exit 0
else
echo "NFS-client is not running."
exit 1
fi
;;

Offline ^thehatsrule^

  • Administrator
  • Hero Member
  • *****
  • Posts: 1726
Re: Basic init.d script example
« Reply #13 on: May 28, 2010, 05:07:32 PM »
Keep in mind that grep expects a regex pattern.

Offline Tomaster

  • Newbie
  • *
  • Posts: 1
Re: Basic init.d script example
« Reply #14 on: April 04, 2011, 05:13:59 AM »
ICT