source: branches/minix3-book/servers/rs/rs.c@ 25

Last change on this file since 25 was 4, checked in by Mattia Monga, 14 years ago

Importazione sorgenti libro

File size: 4.5 KB
RevLine 
[4]1/* Reincarnation Server. This servers starts new system services and detects
2 * they are exiting. In case of errors, system services can be restarted.
3 *
4 * Created:
5 * Jul 22, 2005 by Jorrit N. Herder
6 */
7
8#include "rs.h"
9
10/* Set debugging level to 0, 1, or 2 to see no, some, all debug output. */
11#define DEBUG_LEVEL 1
12#define DPRINTF if (DEBUG_LEVEL > 0) printf
13
14/* Allocate space for the global variables. */
15message m_in; /* the input message itself */
16message m_out; /* the output message used for reply */
17int who; /* caller's proc number */
18int callnr; /* system call number */
19
20/* Declare some local functions. */
21FORWARD _PROTOTYPE(void init_server, (void) );
22FORWARD _PROTOTYPE(void get_work, (void) );
23FORWARD _PROTOTYPE(void reply, (int whom, int result) );
24
25/*===========================================================================*
26 * main *
27 *===========================================================================*/
28PUBLIC int main(void)
29{
30/* This is the main routine of this service. The main loop consists of
31 * three major activities: getting new work, processing the work, and
32 * sending the reply. The loop never terminates, unless a panic occurs.
33 */
34 int result;
35 sigset_t sigset;
36
37 /* Initialize the server, then go to work. */
38 init_server();
39
40 /* Main loop - get work and do it, forever. */
41 while (TRUE) {
42
43 /* Wait for incoming message, sets 'callnr' and 'who'. */
44 get_work();
45
46 switch (callnr) {
47 case SYS_SIG:
48 /* Signals are passed by means of a notification message from SYSTEM.
49 * Extract the map of pending signals from the notification argument.
50 */
51 sigset = (sigset_t) m_in.NOTIFY_ARG;
52
53 if (sigismember(&sigset, SIGCHLD)) {
54 /* A child of this server exited. Take action. */
55 do_exit(&m_in);
56 }
57 if (sigismember(&sigset, SIGUSR1)) {
58 do_start(&m_in);
59 }
60 if (sigismember(&sigset, SIGTERM)) {
61 /* Nothing to do on shutdown. */
62 }
63 if (sigismember(&sigset, SIGKSTOP)) {
64 /* Nothing to do on shutdown. */
65 }
66 continue;
67 case SRV_UP:
68 result = do_start(&m_in);
69 break;
70 case SRV_DOWN:
71 result = do_stop(&m_in);
72 break;
73 default:
74 printf("Warning, RS got unexpected request %d from %d\n",
75 m_in.m_type, m_in.m_source);
76 result = EINVAL;
77 }
78
79 /* Finally send reply message, unless disabled. */
80 if (result != EDONTREPLY) {
81 reply(who, result);
82 }
83 }
84}
85
86
87/*===========================================================================*
88 * init_server *
89 *===========================================================================*/
90PRIVATE void init_server(void)
91{
92/* Initialize the reincarnation server. */
93 struct sigaction sa;
94
95 /* Install signal handlers. Ask PM to transform signal into message. */
96 sa.sa_handler = SIG_MESS;
97 sigemptyset(&sa.sa_mask);
98 sa.sa_flags = 0;
99 if (sigaction(SIGCHLD, &sa, NULL)<0) panic("RS","sigaction failed", errno);
100 if (sigaction(SIGTERM, &sa, NULL)<0) panic("RS","sigaction failed", errno);
101 if (sigaction(SIGABRT, &sa, NULL)<0) panic("RS","sigaction failed", errno);
102 if (sigaction(SIGHUP, &sa, NULL)<0) panic("RS","sigaction failed", errno);
103}
104
105
106/*===========================================================================*
107 * get_work *
108 *===========================================================================*/
109PRIVATE void get_work()
110{
111 int status = 0;
112 status = receive(ANY, &m_in); /* this blocks until message arrives */
113 if (OK != status)
114 panic("RS","failed to receive message!", status);
115 who = m_in.m_source; /* message arrived! set sender */
116 callnr = m_in.m_type; /* set function call number */
117}
118
119
120/*===========================================================================*
121 * reply *
122 *===========================================================================*/
123PRIVATE void reply(who, result)
124int who; /* destination */
125int result; /* report result to replyee */
126{
127 int send_status;
128 m_out.m_type = result; /* build reply message */
129 send_status = send(who, &m_out); /* send the message */
130 if (OK != send_status)
131 panic("RS", "unable to send reply!", send_status);
132}
133
134
135
Note: See TracBrowser for help on using the repository browser.