[AWS] Shutdown of computer

Petr Holub hopet at ics.muni.cz
Thu Dec 16 22:55:02 CET 2010


> If i've right understood,
> when the computer shutdowns, there is a signal (i think it's the 9 one) sent to all processes,
> and then it wait them for quitting while a few seconds before kill them
> 
> Well, does AWS give us a process to catch this signal, to help us to quit our server properly
> ?
> I think it has its place in AWS, because i don't think it is directly in Ada, so we have to
> use something like Florist

First, it should be worth reading some literature on UNIX process
API. SIGKILL signal (number 9) is sort of "last resort" signal
and can't be caught by a handler. However, most of the process
termination procedures are more merciful than just firing SIGKILL
at the process. Usually, something else like SIGTERM or SIGINT
is used first, followed by SIGKILL after some time if the process
is stubborn and doesn't want to terminate properly.

As for signals like SIGTERM, SIGINT or even SIGHUP (1, used to
signalize to deamon processes to reread their configuration), I
use the following:

-------
interrupt_handler.ads:
-------
with Ada.Interrupts.Names;
                
package Interrupt_Handler is
                
        pragma Unreserve_All_Interrupts;
        --  GNAT will no longer handle SIGINT for us
                        
        protected Signal_Handler is
                        
                procedure Handle_Kill;
                entry Wait_For_Shutdown;

                procedure Handle_Hup;
                
                pragma Attach_Handler (Handle_Kill, Ada.Interrupts.Names.SIGTERM);
                pragma Attach_Handler (Handle_Kill, Ada.Interrupts.Names.SIGINT);
                --  attach handler for SIGINT and SIGTERM

                pragma Attach_Handler (Handle_Hup, Ada.Interrupts.Names.SIGHUP);
                
        private 
                        
                Shutdown_Flag : Boolean := False;

        end Signal_Handler;

        function Check_Handlers return Boolean;
        --  returns True when handlers are attached as expected, False when
        --  some problem occurs
                
end Interrupt_Handler;

-------
interrupt_handler.adb
-------
with Ada.Interrupts; use Ada.Interrupts;

with Logger;

package body Interrupt_Handler is

        protected body Signal_Handler is
                --  This protected type contains all our signal handlers

                procedure Handle_Kill is
                --  normal kill signal handler
                begin 
                        if Shutdown_Flag then
                                Logger.Syslog (Logger.LOG_WARNING, "The program is already shutting
down");
                        end if;
                        Shutdown_Flag := True;
                end Handle_Kill;

                entry Wait_For_Shutdown
                when Shutdown_Flag is
                begin
                        null;
                end Wait_For_Shutdown; 

                procedure Handle_Hup is
                --  HUP signal handler, reread all config
                begin
                        --  initiate the rereading
                end Handle_Hup; 

        end Signal_Handler;

        function Check_Handlers return Boolean is
        begin
                --  reserved interrupt means one can't provide a handler
                --  for it
                if Is_Reserved (Ada.Interrupts.Names.SIGINT)
                                        or not Is_Attached (Ada.Interrupts.Names.SIGINT)
                                        or Is_Reserved (Ada.Interrupts.Names.SIGTERM)
                                        or not Is_Attached (Ada.Interrupts.Names.SIGTERM)
                                        or Is_Reserved (Ada.Interrupts.Names.SIGTERM)
                                        or not Is_Attached (Ada.Interrupts.Names.SIGHUP) then
                        if not Is_Reserved (Ada.Interrupts.Names.SIGHUP) then
                                Syslog (LOG_ERR, "SIGINT not reserved!");
                        end if;
                        if not Is_Attached (Ada.Interrupts.Names.SIGINT) then
                                Syslog (LOG_ERR, "SIGINT handler not attached!");
                        end if;
                        if not Is_Reserved (Ada.Interrupts.Names.SIGTERM) then
                                Syslog (LOG_ERR, "SIGTERM not reserved!");
                        end if;
                        if not Is_Attached (Ada.Interrupts.Names.SIGTERM) then
                                Syslog (LOG_ERR, "SIGTERM handler not attached!");
                        end if;
                        return False;
                else
                       return True;
                end if;
        end Check_Handlers;

end Interrupt_Handler;
-------

I use this even with AWS and it works fine. 

-------
        procedure Wait_For_Shutdown is
        begin
                Interrupt_Handler.Signal_Handler.Wait_For_Shutdown;
                Syslog (LOG_INFO, "Server shutdown initiated");
                AWS.Server.Shutdown (WS);
                Syslog (LOG_INFO, "Server shut down.");
        end Wait_For_Shutdown;
-------

There is, however, one scenario where I haven't made it work yet.
If I daemonize the process (i.e., fork a new process and detach it
from console), the signal handlers become lost for some reason.
I was discussing that with AdaCore and it turned out that setting
handlers for daemonized processes is more complex and I didn't have
time to figure the correct apporach yet. I can provide more details
on this if somebody is interested to look into this.

HTH,
Petr

================================================================
                           Petr Holub
CESNET z.s.p.o.                       Supercomputing Center Brno
Zikova 4                             Institute of Compt. Science
162 00 Praha 6, CZ                            Masaryk University
Czech Republic                     Botanicka 68a, 60200 Brno, CZ 
e-mail: Petr.Holub at cesnet.cz               phone: +420-549493944
                                             fax: +420-541212747
                                       e-mail: hopet at ics.muni.cz




More information about the AWS mailing list