From: Jorrit Herder Date: Tue, 26 Jul 2005 13:08:57 +0000 (+0000) Subject: Framework (and some functionality) for new server ... X-Git-Tag: v3.1.0~540 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/index.css?a=commitdiff_plain;h=4bf6edfd14021c59b1036fe1803acdf2f2d14c13;p=minix.git Framework (and some functionality) for new server ... Work in progress ... --- diff --git a/servers/sm/Makefile b/servers/sm/Makefile new file mode 100644 index 000000000..71e332c9b --- /dev/null +++ b/servers/sm/Makefile @@ -0,0 +1,40 @@ +# Makefile for System Process Manager (SM) +SERVER = sm + +# directories +u = /usr +i = $u/include +s = $i/sys +m = $i/minix +b = $i/ibm + +# programs, flags, etc. +CC = exec cc +CFLAGS = -I$i +LDFLAGS = -i +LIBS = -lsys -lsysutil + +OBJ = sm.o manager.o + +# build local binary +all build: $(SERVER) +$(SERVER): $(OBJ) + $(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBS) +# install -S 256w $@ + +# install with other servers +install: /usr/sbin/$(SERVER) +/usr/sbin/$(SERVER): $(SERVER) + install -o root -c $? $@ +# install -o root -cs $? $@ + +# clean up local files +clean: + rm -f $(SERVER) *.o *.bak + +depend: + /usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend + +# Include generated dependencies. +include .depend + diff --git a/servers/sm/manager.c b/servers/sm/manager.c new file mode 100644 index 000000000..3bb771d55 --- /dev/null +++ b/servers/sm/manager.c @@ -0,0 +1,86 @@ +/* This file contains procedures to manage the system processes. + * + * The entry points into this file are + * do_start: + * do_stop: + * do_exit: a child of this server exited + * + * Changes: + * Jul 22, 2005: Created (Jorrit N. Herder) + */ + +#include "sm.h" +#include +#include +#include + +extern int errno; + +#define EXEC_FAILED 49 /* recognizable exit status */ + +/*===========================================================================* + * do_start * + *===========================================================================*/ +PUBLIC int do_start(message *m_ptr) +{ + pid_t child_pid; + char command[255] = "/usr/sbin/is"; + + /* Obtain command name and parameters. */ + + + /* Now try to execute the new system service. */ + child_pid = fork(); /* normal POSIX fork */ + switch(child_pid) { + case 0: /* child process, start system service */ + execve(command, NULL, NULL); /* POSIX exec */ + report("SM", "warning, exec() failed", errno); /* shouldn't happen */ + exit(EXEC_FAILED); /* terminate child */ + break; + case -1: /* fork failed, report error */ + report("SM", "warning, fork() failed", errno); /* shouldn't happen */ + return(errno); + default: /* parent process */ + report("SM", "new process forked, pid", child_pid); + /* update tables */ + } + return(OK); +} + + +/*===========================================================================* + * do_stop * + *===========================================================================*/ +PUBLIC int do_stop(message *m_ptr) +{ + return(ENOSYS); +} + +/*===========================================================================* + * do_exit * + *===========================================================================*/ +PUBLIC int do_exit(message *m_ptr) +{ + pid_t exit_pid; + int exit_status; + + printf("SM: got SIGCHLD signal, doing wait to get exited child.\n"); + + /* See which child exited and what the exit status is. This is done in a + * loop because multiple childs may have exited, all reported by one + * SIGCHLD signal. The WNOHANG options is used to prevent blocking if, + * somehow, no exited child can be found. + */ + while ( (exit_pid = waitpid(-1, &exit_status, WNOHANG)) != 0 ) { + + printf("SM: pid %d,", exit_pid); + if (WIFSIGNALED(exit_status)) { + printf("killed, signal number %d\n", WTERMSIG(exit_status)); + } else if (WIFEXITED(exit_status)) { + printf("normal exit, status %d\n", WEXITSTATUS(exit_status)); + } + } + return(OK); +} + + diff --git a/servers/sm/proto.h b/servers/sm/proto.h new file mode 100644 index 000000000..522078241 --- /dev/null +++ b/servers/sm/proto.h @@ -0,0 +1,11 @@ +/* Function prototypes. */ + +/* sm.c */ +_PROTOTYPE( void main, (void)); + +/* manager.c */ +_PROTOTYPE( int do_exit, (message *m)); +_PROTOTYPE( int do_start, (message *m)); +_PROTOTYPE( int do_stop, (message *m)); + + diff --git a/servers/sm/sm.c b/servers/sm/sm.c new file mode 100644 index 000000000..fccb78174 --- /dev/null +++ b/servers/sm/sm.c @@ -0,0 +1,138 @@ +/* System Process Manager. + * + * Created: + * Jul 22, 2005 by Jorrit N. Herder + */ + +#include "sm.h" + +/* Set debugging level to 0, 1, or 2 to see no, some, all debug output. */ +#define DEBUG_LEVEL 1 +#define DPRINTF if (DEBUG_LEVEL > 0) printf + +/* Allocate space for the global variables. */ +message m_in; /* the input message itself */ +message m_out; /* the output message used for reply */ +int who; /* caller's proc number */ +int callnr; /* system call number */ + +/* Declare some local functions. */ +FORWARD _PROTOTYPE(void init_server, (void) ); +FORWARD _PROTOTYPE(void get_work, (void) ); +FORWARD _PROTOTYPE(void reply, (int whom, int result) ); + +/*===========================================================================* + * main * + *===========================================================================*/ +PUBLIC void main(void) +{ +/* This is the main routine of this service. The main loop consists of + * three major activities: getting new work, processing the work, and + * sending the reply. The loop never terminates, unless a panic occurs. + */ + int result; + sigset_t sigset; + + /* Initialize the server, then go to work. */ + init_server(); + + /* Main loop - get work and do it, forever. */ + while (TRUE) { + + /* Wait for incoming message, sets 'callnr' and 'who'. */ + get_work(); + + switch (callnr) { + case SYS_EVENT: + /* Signals are passed by means of a notification message from SYSTEM. + * Extract the map of pending signals from the notification argument. + */ + sigset = (sigset_t) m_in.NOTIFY_ARG; + + if (sigismember(&sigset, SIGCHLD)) { + /* A child of this server exited. Take action. */ + do_exit(&m_in); + } + if (sigismember(&sigset, SIGUSR1)) { + do_start(&m_in); + } + if (sigismember(&sigset, SIGTERM)) { + /* Nothing to do on shutdown. */ + } + if (sigismember(&sigset, SIGKSTOP)) { + /* Nothing to do on shutdown. */ + } + continue; + case START_SERVICE: + result = do_start(&m_in); + break; + case STOP_SERVICE: + result = do_stop(&m_in); + break; + default: + printf("Warning, SM got unexpected request %d from %d\n", + m_in.m_type, m_in.m_source); + result = EINVAL; + } + + /* Finally send reply message, unless disabled. */ + if (result != EDONTREPLY) { + reply(who, result); + } + } +} + + +/*===========================================================================* + * init_server * + *===========================================================================*/ +PRIVATE void init_server(void) +{ +/* Initialize the information service. */ + int i, s; + struct sigaction sa; + + /* Install signal handlers. Ask PM to transform signal into message. */ + sa.sa_handler = SIG_MESS; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGCHLD, &sa, NULL)<0) panic("SM","sigaction failed", errno); + if (sigaction(SIGTERM, &sa, NULL)<0) panic("SM","sigaction failed", errno); + if (sigaction(SIGABRT, &sa, NULL)<0) panic("SM","sigaction failed", errno); + if (sigaction(SIGHUP, &sa, NULL)<0) panic("SM","sigaction failed", errno); + + /* Report successfull start. */ + report("SM","system service manager successfully initialized", NO_NUM); +} + + +/*===========================================================================* + * get_work * + *===========================================================================*/ +PRIVATE void get_work() +{ + int status = 0; + status = receive(ANY, &m_in); /* this blocks until message arrives */ + if (OK != status) + panic("SM","failed to receive message!", status); + who = m_in.m_source; /* message arrived! set sender */ + callnr = m_in.m_type; /* set function call number */ +} + + +/*===========================================================================* + * reply * + *===========================================================================*/ +PRIVATE void reply(who, result) +int who; /* destination */ +int result; /* report result to replyee */ +{ + int send_status; + m_out.m_type = result; /* build reply message */ + send_status = send(who, &m_out); /* send the message */ + if (OK != send_status) + panic("SM", "unable to send reply!", send_status); +} + + + diff --git a/servers/sm/sm.h b/servers/sm/sm.h new file mode 100644 index 000000000..5f3eebf5a --- /dev/null +++ b/servers/sm/sm.h @@ -0,0 +1,33 @@ +/* Header file for the system service manager server. + * + * Created: + * Jul 22, 2005 by Jorrit N. Herder + */ + +#define _SYSTEM 1 /* get OK and negative error codes */ +#define _MINIX 1 /* tell headers to include MINIX stuff */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "proto.h" +