[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 564
  • Last Modified:

Daemon program problem

Hi,

How can I write a script file so when a user use rpm to install my program and it can be ran as a daemon program???
Help please~~


Xenia
0
xenia27
Asked:
xenia27
  • 14
  • 3
  • 3
  • +1
3 Solutions
 
xenia27Author Commented:
I mean a daemon program that will run automatically from the boot time...^^
0
 
stefan73Commented:
Hi xenia27,
Daemons need a couple of things:
1. They are not attached to a tty.
2. They are direct descendants of the init process.
3. They usually react to a SIGHUP signal by re-reading the configuration, or a reset.

As per installing:
Have a look at /etc/rc.d
There you'll find the various run modes and the startup+shutdown order of programs when entering or leaving a run mode. Just figure out how to place a startup and shutdown script there, and check that all other processes you rely on are already "on the air" once your daemon starts.


Cheers,
Stefan
0
 
sunnycoderCommented:
Hi Xenia,

>I mean a daemon program that will run automatically from the boot time...^^
I assume that you already have the daemon process programmed ... All you want is to add it to the list of processes which are invoked at boot time.

Stefan has guided you correctly

The /etc/rc.d/rc.local script is executed by the init command at boot time or when changing runlevels. Adding commands to this script is an easy way to perform necessary tasks like starting special services or initialize devices without writing complex initialization scripts in the /etc/rc.d/init.d/ directory and creating symbolic links.

The /etc/rc.serial script is used if serial ports must be setup at boot time. This script runs setserial commands to configure the system's serial ports. See the setserial man page for more information

http://www.redhat.com/docs/manuals/linux/RHL-9-Manual/ref-guide/s1-boot-init-shutdown-run-boot.html
http://www.redhat.com/docs/manuals/linux/RHL-9-Manual/ref-guide/s1-boot-init-shutdown-process.html
man init

cheers
sunnycoder
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
xenia27Author Commented:
so can I write a script file and it can be run in order to add my program into the script files in /etc/rc.xxx???  If yes, how can I do so??
0
 
xenia27Author Commented:
sorry~~  thanks a lot...need to try now...^^
0
 
stefan73Commented:
xenia27,
> how can I do so??
The easiest way is to look at the existing entries there. Choose a simple example and duplicate it. Your daemon needs to implement start and stop functionality via signals.

In case you're not familiar with signals, see this little example:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

static void sighandler(int sig){
      printf("Caught signal %d, resetting signal handler\n",sig);
      signal(sig,sighandler);
}

int main(){
      /* Setup signal handler */
      signal(SIGHUP,sighandler);
      signal(SIGINT,sighandler);
      signal(SIGTERM,sighandler);

      /* sleep() is interrupted by a signal, so we loop here */
      while(1) {
            sleep(999);
            printf("Sleep woke up.\n");
      }
}

Normally, SIGTERM should shutdown your daemon.      


Stefan
0
 
xenia27Author Commented:
OK...check whether what I think is correct or not...
So I should add some lines in /etc/rc.d/rc.local??  Or /etc/rc.serial??
My program will pull some data through either RS232 or SCSI/ Fibre...so which file I should add my program??
And if I have my executable program which is a daemon program under this directory.../usr/local/sbin/TestDir and the executable program is "TestRun".

What should I write in the /etc/rc.d/rc.local..if that the correct place I should add...

Also, should I put some "signal" lines in the beginng of main()???
0
 
xenia27Author Commented:
Now...I added those lines in my codes and they work fine
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

static void sighandler(int sig){
     printf("Caught signal %d, resetting signal handler\n",sig);
     signal(sig,sighandler);
}

int main(){
     /* Setup signal handler */
     signal(SIGHUP,sighandler);
     signal(SIGINT,sighandler);
     signal(SIGTERM,sighandler);

     /* sleep() is interrupted by a signal, so we loop here */
     while(1) {
          sleep(999);
          printf("Sleep woke up.\n");
     }
}

And now...I would like to add some lines that can open the right file in /etc/rc.d/ and add some lines that I can make my program run at the boot time in a RPM  spec...how can I do this???
0
 
stefan73Commented:
xenia27,
> add some lines that I can make my program run at the boot time in a
> RPM  spec...how can I do this???

The /rc.d scripts should be supplied as normal files in the RPM packet. Just make sure they are working fine when the run mode is changed.

Stefan
0
 
xenia27Author Commented:
here is what I did in my RPM  file....I can link my executable program but it cannot be ran...what's going on?

# I got all usual header here...Summary...Name...Version...

%build
cd TempDir
make -f Makefile.linux
%install
mkdir -p /usr/local/sbin/TempDir/
cd TempDir
install -D -m 755 /etc/init.d/TempExe

%clean
rm -rf /usr/src/redhat/BUILD/TempDir-1.1
# i got problem here...if you try to remove the program with rpm...will the daemon part remove, too??
%files
%defattr(-,root,root)
/usr/local/sbin/TempDir/b.conf
/etc/rc.d/init.d/TempExe
%doc
/usr/local/sbin/TempDir/b.conf

%post
sysvdir=/etc/rc.d
if [ ! -x $sysvdir/init.d/TempExe ]
then
cat <<EOT > $sysvdir/init.d/TempExe
#!/bin/bash
# TempExe
# description:
# chkconfig: 345 98 01
#
EOT
fi
chmod 755 $sysvdir/init.d/TempExe

cd $sysvdir
ln-sf ../init.d/TempExe $sysvdir/rc1.d/K01TempExe
ln-sf ../init.d/TempExe $sysvdir/rc2.d/S99TempExe
ln-sf ../init.d/TempExe $sysvdir/rc3.d/S99TempExe
ln-sf ../init.d/TempExe $sysvdir/rc4.d/S99TempExe
ln-sf ../init.d/TempExe $sysvdir/rc5.d/S99TempExe
ln-sf ../init.d/TempExe $sysvdir/rc6.d/K01TempExe

cat << EOT

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
when the boot time, it seems not start at all
and then when Linux is complete running, i check it with "ps -al"...the program didn't run...
so what should I do???
0
 
da99rmdCommented:
What did you put in your $sysvdir/init.d/TempExe file ?
An example of such a file is like this:
#!/bin/bash
#
# Raymond 25DEC2003 support@bigriverinfotech.com
# /etc/rc.d/init.d/jabberd2
# init script for jabberd2 processes
# Tested under jabberd-2.0rc2 and Fedora 1.0 only
#
# processname: jabberd2
# description: jabberd2 is the next generation of the jabberd server
# chkconfig: 2345 85 15
#

if [ -f /etc/init.d/functions ]; then
   . /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ]; then
   . /etc/rc.d/init.d/functions
else
   echo -e "\ajabberd2: unable to locate functions lib. Cannot continue."
   exit -1
fi
#
progs="upslagsjabberbot.php"
progsPath="/usr/local/mybin"
confPath="/etc/jabberbots"
pidPath="/usr/local/var/jabber/pid"
statusCol="echo -ne \\033[60G"
statusColorOK="echo -ne \\033[1;32m"
statusColorFailed="echo -ne \\033[1;31m"
statusColorNormal="echo -ne \\033[0;39m"
retval=0
antproc=1
#
StatusOK ( ) {
   ${statusCol}
   echo -n "[  "
   ${statusColorOK}
   echo -n "OK"
   ${statusColorNormal}
   echo "  ]"
   return 0
}
#
StatusFailed ( ) {
   echo -ne "\a"
   ${statusCol}
   echo -n "["
   ${statusColorFailed}
   echo -n "FAILED"
   ${statusColorNormal}
   echo "]"
   return 0
}
#
ReqBins ( ) {
   for prog in ${progs}; do
      if [ ! -x ${progsPath}/${prog} ]; then
         echo -n "jabber bot binary [${prog}] not found."
         StatusFailed
         echo "Cannot continue."
         return -1
      fi
   done
   return 0
}
#
ReqConfs ( ) {
   for prog in ${progs}; do
      if [ ! -f ${confPath}/${prog}.xml ]; then
         echo -n "jabberd2 configuration [${prog}.xml] not found."
         StatusFailed
         echo "Cannot continue."
         return -1
      fi
   done
   return 0
}
#
ReqDirs ( ) {
   if [ ! -d ${pidPath} ]; then
      echo -n "jabber bot PID directory not found. Cannot continue."
      StatusFailed
      return -1
   fi
   return 0
}
#
Start ( ) {
   for req in ReqBins ReqDirs ReqConfs; do
      ${req}
      retval=$?
      [ ${retval} == 0 ] || return ${retval}
   done
   echo "Initializing jabber bot processes ..."
   for prog in ${progs}; do
      if [ -f /proc/$(cat ${pidPath}/${prog}.pid 2> /dev/null)/mem ]; then
         echo -ne "\tprocess [${prog}] already running"
         StatusFailed
         sleep 1
         continue
      fi
      echo -ne "\tStarting ${prog}: "
      rm -f ${pidPath}/${prog}.pid
      args="${confPath}/${prog}.xml"
   nohup su jabber -s /bin/bash -c "${progsPath}/${prog} ${args} & 2> /dev/null" 2> /dev/null
      retval=$?
      if [ ${retval} == 0 ]; then
         StatusOK
      else
         StatusFailed
         Stop
         let retval=-1
         break
      fi
      sleep 1
   done
   return ${retval}
}
#
Stop ( ) {
   echo "Terminating jabber bot processes ..."
   for prog in ${progs}; do
      echo -ne "\tStopping ${prog}: "
      kill -INT `cat ${pidPath}/${prog}.pid 2> /dev/null` 2> /dev/null
      retval=$?
      if [ ${retval} == 0 ]; then
         rm -f ${pidPath}/${prog}.pid
         StatusOK
      else
         StatusFailed
      fi
      sleep 1
   done
   return ${retval}
}

Cond ( ) {
   for prog in ${progs}; do
      if [ -f ${pidPath}/${prog}.pid ]; then
         if [ -e /proc/$(cat ${pidPath}/${prog}.pid) ]; then
            let antproc-=1
         fi
      fi
   done
   if [ ${antproc} -ne 0 ]; then
      Start
   fi
   return ${retval}
}


#
case "$1" in
   start)
      Start
      ;;
   stop)
      Stop
      ;;
   restart)
      Stop
      Start
     ;;
   condrestart)
      Cond
      ;;
   *)
      echo "Usage: $0 {start|stop|restart|condrestart}"
      let retval=-1
esac
exit ${retval}
#
# eof

/Rob
0
 
xenia27Author Commented:
Question,

Can this code that I should have for /etc/rc.d/init.d/TempExe automatically write in when I run rpm for installation?  Can I write some script that will do that in RPM???
0
 
da99rmdCommented:
You can just add the file to your rpm package and install it there directly.

/Rob
0
 
xenia27Author Commented:
how can I do this???  Help please~~~~
0
 
xenia27Author Commented:
how can I know the script of /etc/rc.d/init.d/TempExe is working without reboot my computer again???  ^^
0
 
xenia27Author Commented:
how can you be sure whether the program is runnnig or not??
0
 
xenia27Author Commented:
Question...this is what I wrote but when I complied it...the system showed "syntax error near unexpected token 'then'"
what's wrong??


ReqBins()
{

}
0
 
xenia27Author Commented:
Sorry~~ here is my codes

ReqBins()
{
  for prog in ${progs}; do
    if [! -x ${progsPath}/{prog}]; then
      echo -n "TempExe not found."
      StatusFailed
      echo "Cannot Continue"
      return -1
    fi
    done
    return 0
}
0
 
xenia27Author Commented:
how can I use "nohup"???  and how can I kill a running process???
0
 
da99rmdCommented:
You just need this if you only have one application.

ReqBins()
{
     if [! -x ${progsPath}/{prog}]; then
      echo -n "TempExe not found."
      StatusFailed
      echo "Cannot Continue"
      return -1
    fi
    return 0
}

To se what process is running do a:
ps axf  | grep TempExe
And to kill it
killall TempExe

/Rob
0
 
xenia27Author Commented:
something wrong with my code and I post another question now...@@  please check out the other question...
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 14
  • 3
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now