SUMMARY: Crankin' Up & Crankin' Down in /etc/init.d (Signals!)

From: Mike Adamski (mike@sed.stel.com)
Date: Thu Jan 25 1996 - 22:10:46 CST


My Original Post:::

Solaris 2.4/2.5/2.MAC(<-Just kidding!) Sparc 10's & 20's:

> Howdy Folks! This one's a good one!
>
> OK, I've got this code....fun code, in fact, that massages some data coming
> from an application, then sticks it into the database (Good 'ol Oracle)!
> But I gotta get cute, because this code should be running all of the time,
> right after the DB & my other app are up. That part's easy, cuze I know
> rc2.d, and sequencing and all that. start me up with a S99yaddah, yaddah.
>
> But now comes my "piece of resistance"
>
> I wanna take advantage of the start & stop that init will send me on startup
> & shutdown. (As I recall, any proc in /etc/rc#.d is called with a 'start'
> arguement on startup and a 'stop' on shutdown). Well I'd like to let my
> little piece of code know that we're a-goin' down, so he can disconnect from
> Oracle and other apps nicely before the machine dies, then exit.
>
> Now, I know I could use shared memory to do this (have a little proc in rc2.d
> that, on a 'stop' argument flips a flag that the real app periodically looks
> at) Or sockets, or perhaps a pipe (I'm real rusy on that stuff...it's been a
> few years, but I'll give it the ol'college try if'n I have to).
>
>
> I was wondering, what does SUN recommend? What do You recommend?
> Is there a particular method that I'm missing here? Any help you
> can suggest will be mucho appreciado!
>
>
> Thanks!
>
> Mike
>
Well folks, I've got to hand it to you....You were ALL VERY VERY helpful!

It kinda warms a guy's heart to have so much wonderfulness all in one mailing-
list! All of you, pretty much to a man, (person?) responded that I was lookin'
at a textbook case of signals....AND BOY, WERE YOU EVER RIGHT!

SIGNALS ARE GREAT! Oh, sure, they don't do everything, but for what they
do, they sure are neato! ( I get excited about the little things, don't I?)

Well, my hat's really off to jstuart@tridelta.com (Jeff), who provided just
enough code to practically do my whole job for me! (Thanks a bunch Jeff!)

I won't provide his code (hey, it's his!) But I will provide mine. I'd add
that you should kill this stuff using an almost exact adaptation of the scripts
in /etc/init.d....I'd heartily suggest autofs, particularly around the
killproc(). (It's copyrighted, so I won't copy it. but it IS a simple
way to snag the procid, and if SH**'s going down, it's safer than, say a file
access).

(Please ignore my Logit(). Suffice it to say that it stuffs strings into a log file.)

Read the man on signal, get the include, and use these:

 

/*
This should init all signals, skipping SIGKILL & SIGSTOP, which you can't init.
It also skips SIGCHLD, which hurts me because I fork a child process, and it gets
mad at me when it tries to return.
*/
        

void InitializeSignals()
{
        char Floss[1000]; /* String (get it?) Used for custom logging to loggit. */
        char *ErrorFloss; /* Error String for flossing. */
        int signal_count; /* Counting up signals. (Hey, it's a living!) */

                
        
        for (signal_count = 1; signal_count < SIGKILL ; signal_count ++)
          if (signal(signal_count, &DeathNell)== SIG_ERR)
          {
                  sprintf(Floss,"Bad Signal number %d.",signal_count);
                  Loggit(LogFile, LOW, Floss);
                  ErrorFloss = strerror(errno);
                  Loggit(LogFile, LOW, ErrorFloss);
          }
        for (signal_count = SIGKILL + 1 ; signal_count < SIGCHLD ; signal_count ++)
          if (signal(signal_count, &DeathNell)== SIG_ERR)
          {
                  sprintf(Floss,"Bad Signal number %d.",signal_count);
                  Loggit(LogFile, LOW, Floss);
                  ErrorFloss = strerror(errno);
                  Loggit(LogFile, LOW, ErrorFloss);
          }
        for (signal_count = SIGCHLD + 1 ; signal_count < SIGSTOP ; signal_count ++)
          if (signal(signal_count, &DeathNell)== SIG_ERR)
          {
                  sprintf(Floss,"Bad Signal number %d.",signal_count);
                  Loggit(LogFile, LOW, Floss);
                  ErrorFloss = strerror(errno);
                  Loggit(LogFile, LOW, ErrorFloss);
          }
        for (signal_count = SIGSTOP + 1; signal_count < SIGRTMIN ; signal_count ++)
          if (signal(signal_count, &DeathNell)== SIG_ERR)
          {
                  sprintf(Floss,"Bad Signal number %d.",signal_count);
                  Loggit(LogFile, LOW, Floss);
                  ErrorFloss = strerror(errno);
                  Loggit(LogFile, LOW, ErrorFloss);
          }
        
} /*end InitializeSignals */

void DeathNell(int signal)
{

        char Floss[1000]; /* String (get it?) Used for custom logging to loggit. */
        
        int DeathStatus = 0;

        
        sprintf(Floss,"DeathNell Running....Caught a Signal. Its number is %d.\n", signal);
        
        Loggit(LogFile, MEDIUM, Floss);

        if (signal != SIGCONT)
        {
                
                if(DB_disconnect() != 0)
                {
                        Loggit(LogFile, LOW, "Unable to disconnect from database on kill.");
                        DeathStatus += BAD_EXIT;
                }
                else
                {
                        Loggit(LogFile, LOW, "Successfully Disconnected from database.");
                        DeathStatus += GOOD_EXIT;
                }
                

                
                if(fclose(LogFile) != 0)
                {
                        printf("TrapGetter: Could Not Close Log File!\n");
                        perror("Loggit::");
                        DeathStatus += BAD_EXIT;
                }
                else
                {
                        DeathStatus += GOOD_EXIT;
                }
                
                
                if (DeathStatus == 2)
                  exit(1);
                else
                  exit(-1);
                
        }
        else
        { /* I ignore SIGCONT because I was getting these just before a SIGTERM, and tho it worked, it scared me! */
                  /* Besides, You're supposed to ignore 'em! */

                Loggit(LogFile, HIGH, "DeathNell: Got a SIGCONT. I ignore these.");
        }

} /* end DeathNell */

Thaks again folks. You're all a great bunch o'folks!

:*)
Mike

Solintosh? Macinaris? A Sun with a mac I/F? Hmmmmmmmmmmm........
Nah, it's just too hard. They'll never do it......
But Please, can you try? 'Tis better to fail in a valiant effort than suckseed in a mediocre one.
'Sides, we'd be in heaven!



This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:10:52 CDT