开发者

service build with perl - is it correct

I tried putting a script i saw together, plus used an existing script to make something run as a service. Now I have the following pl script and the init.d / start/stop scripts.

They work, but I am wondering if I did it right, because when I start the service and i would start it again, it would just start again and give a new PID number (is this what I want? shouldn't it be saying "already running?") Also what I didn't understand is what the "cache" part of the STDIN and STDOUT does. Nor the filecheck (file set in the beginning and in the final loop checked for newer version...not sure what that does) Here goes:

#!/usr/bin/perl

#use strict;
use POSIX;
use DateTime;
use Fcntl qw(:flock);
use File::CacheDir qw(cache_dir);

Log("Initializing...");

# Find and read config file
if (@ARGV != 1) {
    print("Usage: miniserv.pl <config file>");
    die;
}

if ($ARGV[0] =~ /^([a-z]:)?\//i) {
    $config_file = $ARGV[0];
}
else {
    print("NO CORRECT CONFIG FILE SPECIFIED");
    die;
}

%config = &read_config_file($config_file);
Log("Initialized...");
Log("Loaded config file.");


my $file = $0;
my $age = -M $file;
Log("File - ".$file.", age - ".$age);



# Change dir to the server root
@roots = ( $config{'root'} );
for($i=0; defined($config{"extraroot_$i"}); $i++) {
    push(@roots, $config{"extraroot_$i"});
}
chdir($roots[0]);
Log("Changed working directory: ".$roots[0]);


Status("Daemonizing...");
my $pid = fork;
if(!defined $pid)
{
    LogError("Unable to fork : $!");
    die;
}
if($pid)
{
    Log("Parent process exiting, let the deamon (".$pid.") go...");
    sleep 3;
    exit;
}
POSIX::setsid;


if(-e $config{'pidfile'})
{
    open(PID, "<".$config{'pidfile'});
    my $runningpid = <PID>;
    close PID;
    unlink $config{'pidfile'};
    while(-e "/proc/".$runningpid)
    {
        Status("Waiting for ".$runningpid." to exit...");
        Log("Waiting for ".$runningpid." to exit...");
        sleep 1;
    }
}

open(PID, ">".$config{'pidfile'}) || die "Failed to create PID file $_[0] : $!";
print PID $$;
close PID;

Log("The deamon is now running...");
Status("Deamon running");

my $stdout = cache_dir({base_dir => $config{'root'}.'/cache', ttl => '1 day', filename => "STDOUT".$$});
my $stderr = cache_dir({base_dir => $config{'root'}.'/cache', ttl => '1 day', filename => "STDERR".$$});
Log("STDOUT : ".$stdout);
Log("STDERR : ".$stderr);
open STDIN, '/dev/null';
open STDOUT, '>>'.$stdout;
open STDERR, '>>'.$stderr;

while(1)
{
    #### Code to be performed by the daemon





    if($age - (-M $file))
    {
        Log("File modified, restarting");
        open(FILE, $file ." |");
        close(FILE);
        last;
    }
    if(!-e $config{'pidfile'})
    {
        Log("Pid file doesn't exist, time go exit.");
        last;
    }
    sleep 5;
}



sub Log
{
    my $string = shift;
    if($string)
    {
        my $time = DateTime->now();
        if(open(LOG, ">>".$config{'logfile'}))
        {
            flock(LOG, LOCK_EX);
            print LOG $$." [".$time->ymd." ".$time->hms."] - ".$string."\r\n";
            close LOG;
        }
    }
}

sub LogError
{
    my $string = shift;

    if($string)
    {
        my $time = DateTime->now();
        if(open(LOG, ">>".$config{'errorlog'}))
        {
            flock(LOG, LOCK_EX);
            print LOG $$." [".$time->ymd." ".$time->hms."] - ".$string."\r\n";
            close LOG;
        }
    }
}

sub Status
{
    my $string = shift;
    if($string)
    {
        $0 = "My Daemon- ".$string;
    }
    return $0;
}


# read_config_file(file)
# Reads the given config file, and returns a hash of values
sub read_config_file
{
    local %rv;
    if(-e $_[0]) 
    {
        open(CONF, $_[0]) || die "Failed to open config file $_[0] : $!";
        while(<CONF>) {
            s/\r|\n//g;
            if (/^#/ || !/\S/) { next; }
            /^([^=]+)=(.*)$/;
            $name = $1; $val = $2;
            $name =~ s/^\s+//g; $name =~ s/\s+$//g;
            $val =~ s/^\s+//g; $val =~ s/\s+$//g;
            $rv{$name} = $val;
            }
        close(CONF);
        return %rv;
    } else {
        print("COULD NOT FIND CONFIG FILE");
        die;
    }
}

the start script

#!/bin/sh
echo Starting reliand server in /usr/libexec/reliand
trap '' 1
LANG=
export LANG
#PERLIO=:raw
unset PERLIO
export PERLIO
PERLLIB=/usr/libexec/reliand
export PERLLIB
exec '/usr/libexec/reliand/miniserv.pl' /etc/reliand/miniserv.conf

the init.d script

#!/bin/sh
# chkconfig: 235 99 10
# description: Start or stop the reliand server
#
### BEGIN INIT INFO
# Provides: reliand
# Required-Start: $network $syslog
# Required-Stop: $network
# Default-Start: 2 3 5
# Default-Stop: 0 1 6
# Description: Start or stop the reliand server
### END INIT INFO

start=/etc/reliand/start
stop=/etc/reliand/stop
lockfile=/var/lock/subsys/reliand
confFile=/etc/reliand/miniserv.conf
pidFile=/var/reliand/miniserv.pid
name='reliand'

case "$1" in
'start')
    $start >/dev/null 2>&1 </dev/null
    RETVAL=$?
    if [ "$RETVAL" = "0" ]; then
        touch $lockfile >/dev/null 2>&1
    fi
    ;;
'stop')
    $stop
    RETVAL=$?
    if [ "$RETVAL" = "0" ]; then
        rm -f $lo开发者_如何转开发ckfile
    fi
    pidfile=`grep "^pidfile=" $confFile | sed -e 's/pidfile=//g'`
    if [ "$pidfile" = "" ]; then
        pidfile=$pidFile
    fi
    rm -f $pidfile
    ;;
'status')
    pidfile=`grep "^pidfile=" $confFile | sed -e 's/pidfile=//g'`
    if [ "$pidfile" = "" ]; then
        pidfile=$pidFile
    fi
    if [ -s $pidfile ]; then
        pid=`cat $pidfile`
        kill -0 $pid >/dev/null 2>&1
        if [ "$?" = "0" ]; then
            echo "$name (pid $pid) is running"
            RETVAL=0
        else
            echo "$name is stopped"
            RETVAL=1
        fi
    else
        echo "$name is stopped"
        RETVAL=1
    fi
    ;;
'restart')
    $stop ; $start
    RETVAL=$?
    ;;
*)
    echo "Usage: $0 { start | stop | restart }"
    RETVAL=1
    ;;
esac
exit $RETVAL


The script will give you a new PID.

As for the cache file, it is storing the standard I/O streams; this is normal for Bash so the script does not keep having to perpetually create new streams each time it initializes the daemon.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜