Index: trunk/minix/servers/rs/.depend
===================================================================
--- trunk/minix/servers/rs/.depend	(revision 9)
+++ 	(revision )
@@ -1,84 +1,0 @@
-
-main.o:	../../kernel/config.h
-main.o:	../../kernel/const.h
-main.o:	../../kernel/type.h
-main.o:	/usr/include/ansi.h
-main.o:	/usr/include/errno.h
-main.o:	/usr/include/ibm/bios.h
-main.o:	/usr/include/ibm/cpu.h
-main.o:	/usr/include/ibm/interrupt.h
-main.o:	/usr/include/ibm/ports.h
-main.o:	/usr/include/limits.h
-main.o:	/usr/include/minix/bitmap.h
-main.o:	/usr/include/minix/callnr.h
-main.o:	/usr/include/minix/com.h
-main.o:	/usr/include/minix/config.h
-main.o:	/usr/include/minix/const.h
-main.o:	/usr/include/minix/devio.h
-main.o:	/usr/include/minix/dmap.h
-main.o:	/usr/include/minix/endpoint.h
-main.o:	/usr/include/minix/ipc.h
-main.o:	/usr/include/minix/keymap.h
-main.o:	/usr/include/minix/sys_config.h
-main.o:	/usr/include/minix/syslib.h
-main.o:	/usr/include/minix/sysutil.h
-main.o:	/usr/include/minix/type.h
-main.o:	/usr/include/signal.h
-main.o:	/usr/include/stdio.h
-main.o:	/usr/include/stdlib.h
-main.o:	/usr/include/string.h
-main.o:	/usr/include/sys/dir.h
-main.o:	/usr/include/sys/types.h
-main.o:	/usr/include/unistd.h
-main.o:	inc.h
-main.o:	main.c
-main.o:	manager.h
-main.o:	proto.h
-
-manager.o:	/usr/include/ansi.h
-manager.o:	/usr/include/errno.h
-manager.o:	/usr/include/limits.h
-manager.o:	/usr/include/minix/bitmap.h
-manager.o:	/usr/include/minix/callnr.h
-manager.o:	/usr/include/minix/com.h
-manager.o:	/usr/include/minix/config.h
-manager.o:	/usr/include/minix/const.h
-manager.o:	/usr/include/minix/devio.h
-manager.o:	/usr/include/minix/dmap.h
-manager.o:	/usr/include/minix/endpoint.h
-manager.o:	/usr/include/minix/ipc.h
-manager.o:	/usr/include/minix/keymap.h
-manager.o:	/usr/include/minix/sys_config.h
-manager.o:	/usr/include/minix/syslib.h
-manager.o:	/usr/include/minix/sysutil.h
-manager.o:	/usr/include/minix/type.h
-manager.o:	/usr/include/signal.h
-manager.o:	/usr/include/stdio.h
-manager.o:	/usr/include/stdlib.h
-manager.o:	/usr/include/string.h
-manager.o:	/usr/include/sys/dir.h
-manager.o:	/usr/include/sys/types.h
-manager.o:	/usr/include/sys/wait.h
-manager.o:	/usr/include/unistd.h
-manager.o:	inc.h
-manager.o:	manager.c
-manager.o:	manager.h
-manager.o:	proto.h
-
-service.o:	/usr/include/ansi.h
-service.o:	/usr/include/errno.h
-service.o:	/usr/include/minix/com.h
-service.o:	/usr/include/minix/config.h
-service.o:	/usr/include/minix/const.h
-service.o:	/usr/include/minix/devio.h
-service.o:	/usr/include/minix/ipc.h
-service.o:	/usr/include/minix/sys_config.h
-service.o:	/usr/include/minix/syslib.h
-service.o:	/usr/include/minix/type.h
-service.o:	/usr/include/stdio.h
-service.o:	/usr/include/stdlib.h
-service.o:	/usr/include/string.h
-service.o:	/usr/include/sys/dir.h
-service.o:	/usr/include/sys/stat.h
-service.o:	/usr/include/sys/types.h
-service.o:	service.c
Index: trunk/minix/servers/rs/Makefile
===================================================================
--- trunk/minix/servers/rs/Makefile	(revision 9)
+++ 	(revision )
@@ -1,46 +1,0 @@
-# Makefile for Reincarnation Server (RS)
-SERVER = rs
-UTIL = service
-
-# 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
-UTIL_LIBS = -lsys 
-LIBS = -lsys -lsysutil 
-
-UTIL_OBJ = service.o
-OBJ = main.o manager.o 
-
-# build local binary
-all build:	$(SERVER) $(UTIL)
-$(UTIL):	$(UTIL_OBJ)
-	$(CC) -o $@ $(LDFLAGS) $(UTIL_OBJ) $(UTIL_LIBS)
-$(SERVER):	$(OBJ)
-	$(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBS)
-	install -S 16k $@
-
-# install with other servers
-install:	/bin/$(UTIL) /usr/sbin/$(SERVER)
-/bin/$(UTIL):	$(UTIL)
-	install -c $? $@
-/usr/sbin/$(SERVER):	$(SERVER)
-	install -o root -c $? $@
-
-# clean up local files
-clean:
-	rm -f $(UTIL) $(SERVER) *.o *.bak 
-
-depend: 
-	/usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend
-
-# Include generated dependencies.
-include .depend
-
Index: trunk/minix/servers/rs/inc.h
===================================================================
--- trunk/minix/servers/rs/inc.h	(revision 9)
+++ 	(revision )
@@ -1,37 +1,0 @@
-/* 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 */
-
-#define VERBOSE		   0	/* display diagnostics */
-
-#include <ansi.h>
-#include <sys/types.h>
-#include <limits.h>
-#include <errno.h>
-#include <signal.h>
-#include <unistd.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"
-#include "manager.h"
-
Index: trunk/minix/servers/rs/main.c
===================================================================
--- trunk/minix/servers/rs/main.c	(revision 9)
+++ 	(revision )
@@ -1,201 +1,0 @@
-/* Reincarnation Server.  This servers starts new system services and detects
- * they are exiting.   In case of errors, system services can be restarted.  
- * The RS server periodically checks the status of all registered services
- * services to see whether they are still alive.   The system services are 
- * expected to periodically send a heartbeat message. 
- * 
- * Created:
- *   Jul 22, 2005	by Jorrit N. Herder
- */
-#include "inc.h"
-#include <minix/dmap.h>
-#include <minix/endpoint.h>
-#include "../../kernel/const.h"
-#include "../../kernel/type.h"
-
-/* Declare some local functions. */
-FORWARD _PROTOTYPE(void init_server, (void)				);
-FORWARD _PROTOTYPE(void sig_handler, (void)				);
-FORWARD _PROTOTYPE(void get_work, (message *m)				);
-FORWARD _PROTOTYPE(void reply, (int whom, int result)			);
-
-/* Data buffers to retrieve info during initialization. */
-PRIVATE struct boot_image image[NR_BOOT_PROCS];
-PUBLIC struct dmap dmap[NR_DEVICES];
-
-/*===========================================================================*
- *				main                                         *
- *===========================================================================*/
-PUBLIC int 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.
- */
-  message m;					/* request message */
-  int call_nr, who_e,who_p;			/* call number and caller */
-  int result;                 			/* result to return */
-  sigset_t sigset;				/* system signal set */
-  int s;
-
-  /* Initialize the server, then go to work. */
-  init_server();	
-
-  /* Main loop - get work and do it, forever. */         
-  while (TRUE) {              
-
-      /* Wait for request message. */
-      get_work(&m);
-      who_e = m.m_source;
-      who_p = _ENDPOINT_P(who_e);
-      if(who_p < -NR_TASKS || who_p >= NR_PROCS)
-	panic("RS","message from bogus source", who_e);
-
-      call_nr = m.m_type;
-
-      /* Now determine what to do.  Three types of requests are expected: 
-       * - Heartbeat messages (notifications from registered system services)
-       * - System notifications (POSIX signals or synchronous alarm)
-       * - User requests (control messages to manage system services)
-       */
-
-      /* Notification messages are control messages and do not need a reply.
-       * These include heartbeat messages and system notifications.
-       */
-      if (m.m_type & NOTIFY_MESSAGE) {
-          switch (call_nr) {
-          case SYN_ALARM:
-	      do_period(&m);			/* check drivers status */
-	      continue;				
-          case PROC_EVENT:
-	      sig_handler();
-              continue;				
-	  default:				/* heartbeat notification */
-	      if (rproc_ptr[who_p] != NULL)	/* mark heartbeat time */ 
-		  rproc_ptr[who_p]->r_alive_tm = m.NOTIFY_TIMESTAMP;
-	  }
-      }
-
-      /* If this is not a notification message, it is a normal request. 
-       * Handle the request and send a reply to the caller. 
-       */
-      else {	
-          switch(call_nr) {
-          case RS_UP: 		result = do_up(&m); 		break;
-          case RS_DOWN: 	result = do_down(&m); 		break;
-          case RS_REFRESH: 	result = do_refresh(&m); 	break;
-          case RS_RESCUE: 	result = do_rescue(&m); 	break;
-          case RS_SHUTDOWN: 	result = do_shutdown(&m); 	break;
-          case GETSYSINFO: 	result = do_getsysinfo(&m); 	break;
-          default: 
-              printf("Warning, RS got unexpected request %d from %d\n",
-                  m.m_type, m.m_source);
-              result = EINVAL;
-          }
-
-          /* Finally send reply message, unless disabled. */
-          if (result != EDONTREPLY) {
-              reply(who_e, result);
-          }
-      }
-  }
-}
-
-
-/*===========================================================================*
- *				init_server                                  *
- *===========================================================================*/
-PRIVATE void init_server(void)
-{
-/* Initialize the reincarnation server. */
-  struct sigaction sa;
-  struct boot_image *ip;
-  int s,t;
-
-  /* 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("RS","sigaction failed", errno);
-  if (sigaction(SIGTERM,&sa,NULL)<0) panic("RS","sigaction failed", errno);
-
-  /* Initialize the system process table. Use the boot image from the kernel
-   * and the device map from the FS to gather all needed information.
-   */
-  if ((s = sys_getimage(image)) != OK) 
-      panic("RS","warning: couldn't get copy of image table", s);
-  if ((s = getsysinfo(FS_PROC_NR, SI_DMAP_TAB, dmap)) < 0)
-      panic("RS","warning: couldn't get copy of dmap table", errno);
-  
-  /* Now initialize the table with the processes in the system image. 
-   * Prepend /sbin/ to the binaries so that we can actually find them. 
-   */
-  for (s=0; s< NR_BOOT_PROCS; s++) {
-      ip = &image[s];
-      if (ip->proc_nr >= 0) {
-          nr_in_use ++;
-          rproc[s].r_flags = RS_IN_USE;
-          rproc[s].r_proc_nr_e = ip->endpoint;
-          rproc[s].r_pid = getnpid(ip->proc_nr);
-	  for(t=0; t< NR_DEVICES; t++)
-	      if (dmap[t].dmap_driver == ip->proc_nr)
-                  rproc[s].r_dev_nr = t;
-	  strcpy(rproc[s].r_cmd, "/sbin/");
-          strcpy(rproc[s].r_cmd+6, ip->proc_name);
-          rproc[s].r_argc = 1;
-          rproc[s].r_argv[0] = rproc[s].r_cmd;
-          rproc[s].r_argv[1] = NULL;
-      }
-  }
-
-  /* Set alarm to periodically check driver status. */
-  if (OK != (s=sys_setalarm(RS_DELTA_T, 0)))
-      panic("RS", "couldn't set alarm", s);
-
-}
-
-/*===========================================================================*
- *				sig_handler                                  *
- *===========================================================================*/
-PRIVATE void sig_handler()
-{
-  sigset_t sigset;
-  int sig;
-
-  /* Try to obtain signal set from PM. */
-  if (getsigset(&sigset) != 0) return;
-
-  /* Check for known signals. */
-  if (sigismember(&sigset, SIGCHLD)) do_exit(NULL);
-  if (sigismember(&sigset, SIGTERM)) do_shutdown(NULL);
-}
-
-/*===========================================================================*
- *				get_work                                     *
- *===========================================================================*/
-PRIVATE void get_work(m_in)
-message *m_in;				/* pointer to message */
-{
-    int s;				/* receive status */
-    if (OK != (s=receive(ANY, m_in))) 	/* wait for message */
-        panic("RS","receive failed", s);
-}
-
-
-/*===========================================================================*
- *				reply					     *
- *===========================================================================*/
-PRIVATE void reply(who, result)
-int who;                           	/* replyee */
-int result;                           	/* report result */
-{
-    message m_out;			/* reply message */
-    int s;				/* send status */
-
-    m_out.m_type = result;  		/* build reply message */
-    if (OK != (s=send(who, &m_out)))    /* send the message */
-        panic("RS", "unable to send reply", s);
-}
-
-
-
Index: trunk/minix/servers/rs/manager.c
===================================================================
--- trunk/minix/servers/rs/manager.c	(revision 9)
+++ 	(revision )
@@ -1,458 +1,0 @@
-/*
- * Changes:
- *   Jul 22, 2005:	Created  (Jorrit N. Herder)
- */
-
-#include "inc.h"
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <minix/dmap.h>
-#include <minix/endpoint.h>
-
-/* Allocate variables. */
-struct rproc rproc[NR_SYS_PROCS];		/* system process table */
-struct rproc *rproc_ptr[NR_PROCS];		/* mapping for fast access */
-int nr_in_use; 					/* number of services */
-extern int errno;				/* error status */
-
-/* Prototypes for internal functions that do the hard work. */
-FORWARD _PROTOTYPE( int start_service, (struct rproc *rp) );
-FORWARD _PROTOTYPE( int stop_service, (struct rproc *rp,int how) );
-
-PRIVATE int shutting_down = FALSE;
-
-#define EXEC_FAILED	49			/* recognizable status */
-
-/*===========================================================================*
- *					do_up				     *
- *===========================================================================*/
-PUBLIC int do_up(m_ptr)
-message *m_ptr;					/* request message pointer */
-{
-/* A request was made to start a new system service. Dismember the request 
- * message and gather all information needed to start the service. Starting
- * is done by a helper routine.
- */
-  register struct rproc *rp;			/* system process table */
-  int slot_nr;					/* local table entry */
-  int arg_count;				/* number of arguments */
-  char *cmd_ptr;				/* parse command string */
-  enum dev_style dev_style;			/* device style */
-  int s;					/* status variable */
-
-  /* See if there is a free entry in the table with system processes. */
-  if (nr_in_use >= NR_SYS_PROCS) return(EAGAIN); 
-  for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {
-      rp = &rproc[slot_nr];			/* get pointer to slot */
-      if (! rp->r_flags & RS_IN_USE) 		/* check if available */
-	  break;
-  }
-  nr_in_use ++;					/* update administration */
-
-  /* Obtain command name and parameters. This is a space-separated string
-   * that looks like "/sbin/service arg1 arg2 ...". Arguments are optional.
-   */
-  if (m_ptr->RS_CMD_LEN > MAX_COMMAND_LEN) return(E2BIG);
-  if (OK!=(s=sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->RS_CMD_ADDR, 
-  	SELF, (vir_bytes) rp->r_cmd, m_ptr->RS_CMD_LEN))) return(s);
-  rp->r_cmd[m_ptr->RS_CMD_LEN] = '\0';		/* ensure it is terminated */
-  if (rp->r_cmd[0] != '/') return(EINVAL);	/* insist on absolute path */
-
-  /* Build argument vector to be passed to execute call. The format of the
-   * arguments vector is: path, arguments, NULL. 
-   */
-  arg_count = 0;				/* initialize arg count */
-  rp->r_argv[arg_count++] = rp->r_cmd;		/* start with path */
-  cmd_ptr = rp->r_cmd;				/* do some parsing */ 
-  while(*cmd_ptr != '\0') {			/* stop at end of string */
-      if (*cmd_ptr == ' ') {			/* next argument */
-          *cmd_ptr = '\0';			/* terminate previous */
-	  while (*++cmd_ptr == ' ') ; 		/* skip spaces */
-	  if (*cmd_ptr == '\0') break;		/* no arg following */
-	  if (arg_count>MAX_NR_ARGS+1) break;	/* arg vector full */
-          rp->r_argv[arg_count++] = cmd_ptr;	/* add to arg vector */
-      }
-      cmd_ptr ++;				/* continue parsing */
-  }
-  rp->r_argv[arg_count] = NULL;			/* end with NULL pointer */
-  rp->r_argc = arg_count;
-
-  /* Initialize some fields. */
-  rp->r_period = m_ptr->RS_PERIOD;
-  rp->r_dev_nr = m_ptr->RS_DEV_MAJOR;
-  rp->r_dev_style = STYLE_DEV; 
-  rp->r_restarts = -1; 				/* will be incremented */
-  
-  /* All information was gathered. Now try to start the system service. */
-  return(start_service(rp));
-}
-
-
-/*===========================================================================*
- *				do_down					     *
- *===========================================================================*/
-PUBLIC int do_down(message *m_ptr)
-{
-  register struct rproc *rp;
-  pid_t pid = (pid_t) m_ptr->RS_PID;
-
-  for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
-      if (rp->r_flags & RS_IN_USE && rp->r_pid == pid) {
-#if VERBOSE
-	  printf("stopping %d (%d)\n", pid, m_ptr->RS_PID);
-#endif
-	  stop_service(rp,RS_EXITING);
-	  return(OK);
-      }
-  }
-#if VERBOSE
-  printf("not found %d (%d)\n", pid, m_ptr->RS_PID);
-#endif
-  return(ESRCH);
-}
-
-
-/*===========================================================================*
- *				do_refresh				     *
- *===========================================================================*/
-PUBLIC int do_refresh(message *m_ptr)
-{
-  register struct rproc *rp;
-  pid_t pid = (pid_t) m_ptr->RS_PID;
-
-  for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
-      if (rp->r_flags & RS_IN_USE && rp->r_pid == pid) {
-#if VERBOSE
-	  printf("refreshing %d (%d)\n", pid, m_ptr->RS_PID);
-#endif
-	  stop_service(rp,RS_REFRESHING);
-	  return(OK);
-      }
-  }
-#if VERBOSE
-  printf("not found %d (%d)\n", pid, m_ptr->RS_PID);
-#endif
-  return(ESRCH);
-}
-
-/*===========================================================================*
- *				do_rescue				     *
- *===========================================================================*/
-PUBLIC int do_rescue(message *m_ptr)
-{
-  char rescue_dir[MAX_RESCUE_DIR_LEN];
-  int s;
-
-  /* Copy rescue directory from user. */
-  if (m_ptr->RS_CMD_LEN > MAX_RESCUE_DIR_LEN) return(E2BIG);
-  if (OK!=(s=sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->RS_CMD_ADDR, 
-  	SELF, (vir_bytes) rescue_dir, m_ptr->RS_CMD_LEN))) return(s);
-  rescue_dir[m_ptr->RS_CMD_LEN] = '\0';		/* ensure it is terminated */
-  if (rescue_dir[0] != '/') return(EINVAL);	/* insist on absolute path */
-
-  /* Change RS' directory to the rescue directory. Provided that the needed
-   * binaries are in the rescue dir, this makes recovery possible even if the 
-   * (root) file system is no longer available, because no directory lookups
-   * are required. Thus if an absolute path fails, we can try to strip the 
-   * path an see if the command is in the rescue dir. 
-   */
-  if (chdir(rescue_dir) != 0) return(errno);
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_shutdown				     *
- *===========================================================================*/
-PUBLIC int do_shutdown(message *m_ptr)
-{
-  /* Set flag so that RS server knows services shouldn't be restarted. */
-  shutting_down = TRUE;
-  return(OK);
-}
-
-/*===========================================================================*
- *				do_exit					     *
- *===========================================================================*/
-PUBLIC void do_exit(message *m_ptr)
-{
-  register struct rproc *rp;
-  pid_t exit_pid;
-  int exit_status;
-
-#if VERBOSE
-  printf("RS: got SIGCHLD signal, doing wait to get exited child.\n");
-#endif
-
-  /* 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 ) {
-
-#if VERBOSE
-      printf("RS: proc %d, pid %d, ", rp->r_proc_nr_e, 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));
-      }
-#endif
-
-      /* Search the system process table to see who exited. 
-       * This should always succeed. 
-       */
-      for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
-          if ((rp->r_flags & RS_IN_USE) && rp->r_pid == exit_pid) {
-	      int proc;
-	      proc = _ENDPOINT_P(rp->r_proc_nr_e);
-
-              rproc_ptr[proc] = NULL;		/* invalidate */
-
-              if ((rp->r_flags & RS_EXITING) || shutting_down) {
-		  rp->r_flags = 0;			/* release slot */
-		  rproc_ptr[proc] = NULL;
-	      }
-	      else if(rp->r_flags & RS_REFRESHING) {
-		      rp->r_restarts = -1;		/* reset counter */
-		      start_service(rp);		/* direct restart */
-	      }
-              else if (WIFEXITED(exit_status) &&
-		      WEXITSTATUS(exit_status) == EXEC_FAILED) {
-		  rp->r_flags = 0;			/* release slot */
-              }
-	      else {
-#if VERBOSE
-		  printf("Unexpected exit. Restarting %s\n", rp->r_cmd);
-#endif
-                  /* Determine what to do. If this is the first unexpected 
-		   * exit, immediately restart this service. Otherwise use
-		   * a binary exponetial backoff.
-		   */
-                  if (rp->r_restarts > 0) {
-		      rp->r_backoff = 1 << MIN(rp->r_restarts,(BACKOFF_BITS-1));
-		      rp->r_backoff = MIN(rp->r_backoff,MAX_BACKOFF); 
-		  }
-		  else {
-		      start_service(rp);		/* direct restart */
-		  }
-              }
-	      break;
-	  }
-      }
-  }
-}
-
-/*===========================================================================*
- *				do_period				     *
- *===========================================================================*/
-PUBLIC void do_period(m_ptr)
-message *m_ptr;
-{
-  register struct rproc *rp;
-  clock_t now = m_ptr->NOTIFY_TIMESTAMP;
-  int s;
-
-  /* Search system services table. Only check slots that are in use. */
-  for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {
-      if (rp->r_flags & RS_IN_USE) {
-
-          /* If the service is to be revived (because it repeatedly exited, 
-	   * and was not directly restarted), the binary backoff field is  
-	   * greater than zero. 
-	   */
-	  if (rp->r_backoff > 0) {
-              rp->r_backoff -= 1;
-	      if (rp->r_backoff == 0) {
-		  start_service(rp);
-	      }
-	  }
-
-	  /* If the service was signaled with a SIGTERM and fails to respond,
-	   * kill the system service with a SIGKILL signal.
-	   */
-	  else if (rp->r_stop_tm > 0 && now - rp->r_stop_tm > 2*RS_DELTA_T
-	   && rp->r_pid > 0) {
-              kill(rp->r_pid, SIGKILL);		/* terminate */
-	  }
-	
-	  /* There seems to be no special conditions. If the service has a 
-	   * period assigned check its status. 
-	   */
-	  else if (rp->r_period > 0) {
-
-	      /* Check if an answer to a status request is still pending. If 
-	       * the driver didn't respond within time, kill it to simulate 
-	       * a crash. The failure will be detected and the service will 
-	       * be restarted automatically.
-	       */
-              if (rp->r_alive_tm < rp->r_check_tm) { 
-	          if (now - rp->r_alive_tm > 2*rp->r_period &&
-		      rp->r_pid > 0) { 
-#if VERBOSE
-                      printf("RS: service %d reported late\n", rp->r_proc_nr_e); 
-#endif
-                      kill(rp->r_pid, SIGKILL);		/* simulate crash */
-		  }
-	      }
-
-	      /* No answer pending. Check if a period expired since the last
-	       * check and, if so request the system service's status.
-	       */
-	      else if (now - rp->r_check_tm > rp->r_period) {
-#if VERBOSE
-                  printf("RS: status request sent to %d\n", rp->r_proc_nr_e); 
-#endif
-		  notify(rp->r_proc_nr_e);		/* request status */
-		  rp->r_check_tm = now;			/* mark time */
-              }
-          }
-      }
-  }
-
-  /* Reschedule a synchronous alarm for the next period. */
-  if (OK != (s=sys_setalarm(RS_DELTA_T, 0)))
-      panic("RS", "couldn't set alarm", s);
-}
-
-
-/*===========================================================================*
- *				start_service				     *
- *===========================================================================*/
-PRIVATE int start_service(rp)
-struct rproc *rp;
-{
-/* Try to execute the given system service. Fork a new process. The child
- * process will be inhibited from running by the NO_PRIV flag. Only let the
- * child run once its privileges have been set by the parent.
- */
-  int child_proc_nr_e, child_proc_nr_n;		/* child process slot */
-  pid_t child_pid;				/* child's process id */
-  char *file_only;
-  int s;
-  message m;
-
-  /* Now fork and branch for parent and child process (and check for error). */
-  child_pid = fork();
-  switch(child_pid) {					/* see fork(2) */
-  case -1:						/* fork failed */
-      report("RS", "warning, fork() failed", errno);	/* shouldn't happen */
-      return(errno);					/* return error */
-
-  case 0:						/* child process */
-      /* Try to execute the binary that has an absolute path. If this fails, 
-       * e.g., because the root file system cannot be read, try to strip of
-       * the path, and see if the command is in RS' current working dir.
-       */
-      execve(rp->r_argv[0], rp->r_argv, NULL);		/* POSIX execute */
-      file_only = strrchr(rp->r_argv[0], '/') + 1;
-      execve(file_only, rp->r_argv, NULL);		/* POSIX execute */
-      printf("RS: exec failed for %s: %d\n", rp->r_argv[0], errno);
-      exit(EXEC_FAILED);				/* terminate child */
-
-  default:						/* parent process */
-      child_proc_nr_e = getnprocnr(child_pid);		/* get child slot */ 
-      break;						/* continue below */
-  }
-
-  /* Only the parent process (the RS server) gets to this point. The child
-   * is still inhibited from running because it's privilege structure is
-   * not yet set. First try to set the device driver mapping at the FS.
-   */
-  if (rp->r_dev_nr > 0) {				/* set driver map */
-      if ((s=mapdriver(child_proc_nr_e, rp->r_dev_nr, rp->r_dev_style)) < 0) {
-          report("RS", "couldn't map driver", errno);
-          rp->r_flags |= RS_EXITING;			/* expect exit */
-	  if(child_pid > 0) kill(child_pid, SIGKILL);	/* kill driver */
-	  else report("RS", "didn't kill pid", child_pid);
-	  return(s);					/* return error */
-      }
-  }
-
-  /* The device driver mapping has been set, or the service was not a driver.
-   * Now, set the privilege structure for the child process to let is run.
-   * This should succeed: we tested number in use above.
-   */
-  if ((s = sys_privctl(child_proc_nr_e, SYS_PRIV_INIT, 0, NULL)) < 0) {
-      report("RS","call to SYSTEM failed", s);		/* to let child run */
-      rp->r_flags |= RS_EXITING;			/* expect exit */
-      if(child_pid > 0) kill(child_pid, SIGKILL);	/* kill driver */
-      else report("RS", "didn't kill pid", child_pid);
-      return(s);					/* return error */
-  }
-
-#if VERBOSE
-      printf("RS: started '%s', major %d, pid %d, endpoint %d, proc %d\n", 
-          rp->r_cmd, rp->r_dev_nr, child_pid,
-	  child_proc_nr_e, child_proc_nr_n);
-#endif
-
-  /* The system service now has been successfully started. Update the rest
-   * of the system process table that is maintain by the RS server. The only 
-   * thing that can go wrong now, is that execution fails at the child. If 
-   * that's the case, the child will exit. 
-   */
-  child_proc_nr_n = _ENDPOINT_P(child_proc_nr_e);
-  rp->r_flags = RS_IN_USE;			/* mark slot in use */
-  rp->r_restarts += 1;				/* raise nr of restarts */
-  rp->r_proc_nr_e = child_proc_nr_e;		/* set child details */
-  rp->r_pid = child_pid;
-  rp->r_check_tm = 0;				/* not check yet */
-  getuptime(&rp->r_alive_tm); 			/* currently alive */
-  rp->r_stop_tm = 0;				/* not exiting yet */
-  rproc_ptr[child_proc_nr_n] = rp;		/* mapping for fast access */
-  return(OK);
-}
-
-/*===========================================================================*
- *				stop_service				     *
- *===========================================================================*/
-PRIVATE int stop_service(rp,how)
-struct rproc *rp;
-int how;
-{
-  /* Try to stop the system service. First send a SIGTERM signal to ask the
-   * system service to terminate. If the service didn't install a signal 
-   * handler, it will be killed. If it did and ignores the signal, we'll
-   * find out because we record the time here and send a SIGKILL.
-   */
-#if VERBOSE
-  printf("RS tries to stop %s (pid %d)\n", rp->r_cmd, rp->r_pid);
-#endif
-
-  rp->r_flags |= how;				/* what to on exit? */
-  if(rp->r_pid > 0) kill(rp->r_pid, SIGTERM);	/* first try friendly */
-  else report("RS", "didn't kill pid", rp->r_pid);
-  getuptime(&rp->r_stop_tm); 			/* record current time */
-}
-
-
-/*===========================================================================*
- *				do_getsysinfo				     *
- *===========================================================================*/
-PUBLIC int do_getsysinfo(m_ptr)
-message *m_ptr;
-{
-  vir_bytes src_addr, dst_addr;
-  int dst_proc;
-  size_t len;
-  int s;
-
-  switch(m_ptr->m1_i1) {
-  case SI_PROC_TAB:
-  	src_addr = (vir_bytes) rproc;
-  	len = sizeof(struct rproc) * NR_SYS_PROCS;
-  	break; 
-  default:
-  	return(EINVAL);
-  }
-
-  dst_proc = m_ptr->m_source;
-  dst_addr = (vir_bytes) m_ptr->m1_p1;
-  if (OK != (s=sys_datacopy(SELF, src_addr, dst_proc, dst_addr, len)))
-  	return(s);
-  return(OK);
-}
-
Index: trunk/minix/servers/rs/manager.h
===================================================================
--- trunk/minix/servers/rs/manager.h	(revision 9)
+++ 	(revision )
@@ -1,52 +1,0 @@
-/* This table has one slot per system process.  It contains information for
- * servers and driver needed by the reincarnation server to keep track of 
- * each process' status. 
- */
-
-/* Space reserved for program and arguments. */
-#define MAX_COMMAND_LEN     512		/* maximum argument string length */
-#define MAX_NR_ARGS	      4		/* maximum number of arguments */
-#define MAX_RESCUE_DIR_LEN   64		/* maximum rescue dir length */
-
-/* Definition of the system process table. This table only has entries for
- * the servers and drivers, and thus is not directly indexed by slot number.
- */
-extern struct rproc {
-  int r_proc_nr_e;		/* process endpoint number */
-  pid_t r_pid;			/* process id */
-  dev_t r_dev_nr;		/* major device number */
-  int r_dev_style;		/* device style */
-
-  int r_restarts;		/* number of restarts (initially zero) */
-  long r_backoff;		/* number of periods to wait before revive */
-  unsigned r_flags; 		/* status and policy flags */
-
-  long r_period;		/* heartbeat period (or zero) */
-  clock_t r_check_tm;		/* timestamp of last check */
-  clock_t r_alive_tm;		/* timestamp of last heartbeat */
-  clock_t r_stop_tm;		/* timestamp of SIGTERM signal */
-
-  char r_cmd[MAX_COMMAND_LEN];	/* raw command plus arguments */
-  char *r_argv[MAX_NR_ARGS+2];  /* parsed arguments vector */
-  int r_argc;  			/* number of arguments */
-} rproc[NR_SYS_PROCS];
-
-/* Mapping for fast access to the system process table. */ 
-extern struct rproc *rproc_ptr[NR_PROCS];
-extern int nr_in_use;
-
-/* Flag values. */
-#define RS_IN_USE       0x001	/* set when process slot is in use */
-#define RS_EXITING      0x002	/* set when exit is expected */
-#define RS_REFRESHING   0x004	/* set when refresh must be done */
-
-/* Constants determining RS period and binary exponential backoff. */
-#define RS_DELTA_T       60			/* check every T ticks */
-#define BACKOFF_BITS 	(sizeof(long)*8)	/* bits in backoff field */
-#define MAX_BACKOFF     30			/* max backoff in RS_DELTA_T */
-
-/* Magic process table addresses. */
-#define BEG_RPROC_ADDR	(&rproc[0])
-#define END_RPROC_ADDR	(&rproc[NR_SYS_PROCS])
-#define NIL_RPROC ((struct mproc *) 0)
-
Index: trunk/minix/servers/rs/proto.h
===================================================================
--- trunk/minix/servers/rs/proto.h	(revision 9)
+++ 	(revision )
@@ -1,16 +1,0 @@
-/* Function prototypes. */
-
-/* main.c */
-_PROTOTYPE( int main, (void));
-
-/* manager.c */
-_PROTOTYPE( int do_up, (message *m));
-_PROTOTYPE( int do_down, (message *m));
-_PROTOTYPE( int do_refresh, (message *m));
-_PROTOTYPE( int do_rescue, (message *m));
-_PROTOTYPE( int do_shutdown, (message *m));
-_PROTOTYPE( void do_period, (message *m));
-_PROTOTYPE( void do_exit, (message *m));
-_PROTOTYPE( int do_getsysinfo, (message *m));
-
-
Index: trunk/minix/servers/rs/service.c
===================================================================
--- trunk/minix/servers/rs/service.c	(revision 9)
+++ 	(revision )
@@ -1,278 +1,0 @@
-/* Utility to start or stop system services.  Requests are sent to the 
- * reincarnation server that does the actual work. 
- *
- * Changes:
- *   Jul 22, 2005:	Created  (Jorrit N. Herder)
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <minix/config.h>
-#include <minix/com.h>
-#include <minix/const.h>
-#include <minix/type.h>
-#include <minix/ipc.h>
-#include <minix/syslib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-
-/* This array defines all known requests. */
-PRIVATE char *known_requests[] = {
-  "up", 
-  "down",
-  "refresh", 
-  "rescue", 
-  "shutdown", 
-  "catch for illegal requests"
-};
-#define ILLEGAL_REQUEST  sizeof(known_requests)/sizeof(char *)
-
-/* Global error number set for failed system calls. */
-#define OK 0
-extern int errno;
-
-/* Define names for arguments provided to this utility. The first few 
- * arguments are required and have a known index. Thereafter, some optional
- * argument pairs like "-args arglist" follow.
- */
-#define ARG_NAME	0		/* own application name */
-#define ARG_REQUEST	1		/* request to perform */
-#define ARG_PATH	2		/* rescue dir or system service */
-#define ARG_PID		2		/* pid of system service */
-
-#define MIN_ARG_COUNT	2		/* require an action */
-
-#define ARG_ARGS	"-args"		/* list of arguments to be passed */
-#define ARG_DEV		"-dev"		/* major device number for drivers */
-#define ARG_PRIV	"-priv"		/* required privileges */
-#define ARG_PERIOD	"-period"	/* heartbeat period in ticks */
-
-/* The function parse_arguments() verifies and parses the command line 
- * parameters passed to this utility. Request parameters that are needed
- * are stored globally in the following variables:
- */
-PRIVATE int req_type;
-PRIVATE int req_pid;
-PRIVATE char *req_path;
-PRIVATE char *req_args;
-PRIVATE int req_major;
-PRIVATE long req_period;
-PRIVATE char *req_priv;
-
-/* Buffer to build "/command arg1 arg2 ..." string to pass to RS server. */
-PRIVATE char command[4096];	
-
-/* An error occurred. Report the problem, print the usage, and exit. 
- */
-PRIVATE void print_usage(char *app_name, char *problem) 
-{
-  printf("Warning, %s\n", problem);
-  printf("Usage:\n");
-  printf("    %s up <binary> [%s <args>] [%s <special>] [%s <ticks>]\n", 
-	app_name, ARG_ARGS, ARG_DEV, ARG_PERIOD);
-  printf("    %s down <pid>\n", app_name);
-  printf("    %s refresh <pid>\n", app_name);
-  printf("    %s rescue <dir>\n", app_name);
-  printf("    %s shutdown\n", app_name);
-  printf("\n");
-}
-
-/* A request to the RS server failed. Report and exit. 
- */
-PRIVATE void failure(int num) 
-{
-  printf("Request to RS failed: %s (%d)\n", strerror(num), num);
-  exit(num);
-}
-
-
-/* Parse and verify correctness of arguments. Report problem and exit if an 
- * error is found. Store needed parameters in global variables.
- */
-PRIVATE int parse_arguments(int argc, char **argv)
-{
-  struct stat stat_buf;
-  char *hz;
-  int req_nr;
-  int i;
-
-  /* Verify argument count. */ 
-  if (argc < MIN_ARG_COUNT) {
-      print_usage(argv[ARG_NAME], "wrong number of arguments");
-      exit(EINVAL);
-  }
-
-  /* Verify request type. */
-  for (req_type=0; req_type< ILLEGAL_REQUEST; req_type++) {
-      if (strcmp(known_requests[req_type],argv[ARG_REQUEST])==0) break;
-  }
-  if (req_type == ILLEGAL_REQUEST) {
-      print_usage(argv[ARG_NAME], "illegal request type");
-      exit(ENOSYS);
-  }
-  req_nr = RS_RQ_BASE + req_type;
-
-  if (req_nr == RS_UP) {
-
-      /* Verify argument count. */ 
-      if (argc - 1 < ARG_PATH) {
-          print_usage(argv[ARG_NAME], "action requires a binary to start");
-          exit(EINVAL);
-      }
-
-      /* Verify the name of the binary of the system service. */
-      req_path = argv[ARG_PATH];
-      if (req_path[0] != '/') {
-          print_usage(argv[ARG_NAME], "binary should be absolute path");
-          exit(EINVAL);
-      }
-      if (stat(req_path, &stat_buf) == -1) {
-	  perror(req_path);
-          fprintf(stderr, "couldn't get stat binary\n");
-          exit(errno);
-      }
-      if (! (stat_buf.st_mode & S_IFREG)) {
-          print_usage(argv[ARG_NAME], "binary is not a regular file");
-          exit(EINVAL);
-      }
-
-      /* Check optional arguments that come in pairs like "-args arglist". */
-      for (i=MIN_ARG_COUNT+1; i<argc; i=i+2) {
-          if (! (i+1 < argc)) {
-              print_usage(argv[ARG_NAME], "optional argument not complete");
-              exit(EINVAL);
-          }
-          if (strcmp(argv[i], ARG_ARGS)==0) {
-              req_args = argv[i+1];
-          }
-          else if (strcmp(argv[i], ARG_PERIOD)==0) {
-	      req_period = strtol(argv[i+1], &hz, 10);
-	      if (strcmp(hz,"HZ")==0) req_period *= HZ;
-	      if (req_period < 1) {
-                  print_usage(argv[ARG_NAME], "period is at least be one tick");
-                  exit(EINVAL);
-	      }
-          }
-          else if (strcmp(argv[i], ARG_DEV)==0) {
-              if (stat(argv[i+1], &stat_buf) == -1) {
-                  print_usage(argv[ARG_NAME], "couldn't get status of device");
-                  exit(errno);
-              }
-	      if ( ! (stat_buf.st_mode & (S_IFBLK | S_IFCHR))) {
-                  print_usage(argv[ARG_NAME], "special file is not a device");
-                  exit(EINVAL);
-       	      } 
-              req_major = (stat_buf.st_rdev >> MAJOR) & BYTE;
-          }
-          else if (strcmp(argv[i], ARG_ARGS)==0) {
-              req_priv = argv[i+1];
-          }
-          else {
-              print_usage(argv[ARG_NAME], "unknown optional argument given");
-              exit(EINVAL);
-          }
-      }
-  }
-  else if (req_nr == RS_DOWN || req_nr == RS_REFRESH) {
-
-      /* Verify argument count. */ 
-      if (argc - 1 < ARG_PID) {
-          print_usage(argv[ARG_NAME], "action requires a pid to stop");
-          exit(EINVAL);
-      }
-      if (! (req_pid = atoi(argv[ARG_PID])) > 0) {
-          print_usage(argv[ARG_NAME], "pid must be greater than zero");
-          exit(EINVAL);
-      }
-  } 
-  else if (req_nr == RS_RESCUE) {
-
-      /* Verify argument count. */ 
-      if (argc - 1 < ARG_PATH) {
-          print_usage(argv[ARG_NAME], "action requires rescue directory");
-          exit(EINVAL);
-      }
-      req_path = argv[ARG_PATH];
-      if (req_path[0] != '/') {
-          print_usage(argv[ARG_NAME], "rescue dir should be absolute path");
-          exit(EINVAL);
-      }
-      if (stat(argv[ARG_PATH], &stat_buf) == -1) {
-          print_usage(argv[ARG_NAME], "couldn't get status of directory");
-          exit(errno);
-      }
-      if ( ! (stat_buf.st_mode & S_IFDIR)) {
-          print_usage(argv[ARG_NAME], "file is not a directory");
-          exit(EINVAL);
-      } 
-  } 
-  else if (req_nr == RS_SHUTDOWN) {
-        /* no extra arguments required */
-  }
-
-  /* Return the request number if no error were found. */
-  return(req_nr);
-}
-
-
-/* Main program. 
- */
-PUBLIC int main(int argc, char **argv)
-{
-  message m;
-  int result;
-  int request;
-  int s;
-
-  /* Verify and parse the command line arguments. All arguments are checked
-   * here. If an error occurs, the problem is reported and exit(2) is called. 
-   * all needed parameters to perform the request are extracted and stored
-   * global variables. 
-   */
-  request = parse_arguments(argc, argv);
-
-  /* Arguments seem fine. Try to perform the request. Only valid requests 
-   * should end up here. The default is used for not yet supported requests. 
-   */
-  switch(request) {
-  case RS_UP:
-      /* Build space-separated command string to be passed to RS server. */
-      strcpy(command, req_path);
-      command[strlen(req_path)] = ' ';
-      strcpy(command+strlen(req_path)+1, req_args);
-
-      /* Build request message and send the request. */
-      m.RS_CMD_ADDR = command;
-      m.RS_CMD_LEN = strlen(command);
-      m.RS_DEV_MAJOR = req_major;
-      m.RS_PERIOD = req_period;
-      if (OK != (s=_taskcall(RS_PROC_NR, request, &m))) 
-          failure(s);
-      result = m.m_type;
-      break;
-  case RS_DOWN:
-  case RS_REFRESH:
-      m.RS_PID = req_pid;
-      if (OK != (s=_taskcall(RS_PROC_NR, request, &m))) 
-          failure(s);
-      break;
-  case RS_RESCUE:
-      m.RS_CMD_ADDR = req_path;
-      m.RS_CMD_LEN = strlen(req_path);
-      if (OK != (s=_taskcall(RS_PROC_NR, request, &m))) 
-          failure(s);
-      break;
-  case RS_SHUTDOWN:
-      if (OK != (s=_taskcall(RS_PROC_NR, request, &m))) 
-          failure(s);
-      break;
-  default:
-      print_usage(argv[ARG_NAME], "request is not yet supported");
-      result = EGENERIC;
-  }
-  return(result);
-}
-
