Framework (and some functionality) for new server ...
Work in progress ...
This commit is contained in:
parent
2bb508a71c
commit
4bf6edfd14
5 changed files with 308 additions and 0 deletions
40
servers/sm/Makefile
Normal file
40
servers/sm/Makefile
Normal file
|
@ -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
|
||||
|
86
servers/sm/manager.c
Normal file
86
servers/sm/manager.c
Normal file
|
@ -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 <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
11
servers/sm/proto.h
Normal file
11
servers/sm/proto.h
Normal file
|
@ -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));
|
||||
|
||||
|
138
servers/sm/sm.c
Normal file
138
servers/sm/sm.c
Normal file
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
33
servers/sm/sm.h
Normal file
33
servers/sm/sm.h
Normal file
|
@ -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 <ansi.h>
|
||||
#include <sys/types.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <minix/callnr.h>
|
||||
#include <minix/config.h>
|
||||
#include <minix/type.h>
|
||||
#include <minix/const.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/syslib.h>
|
||||
#include <minix/sysutil.h>
|
||||
#include <minix/keymap.h>
|
||||
#include <minix/bitmap.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "proto.h"
|
||||
|
Loading…
Reference in a new issue