]> Zhao Yanbai Git Server - minix.git/commitdiff
Framework (and some functionality) for new server ...
authorJorrit Herder <jnherder@minix3.org>
Tue, 26 Jul 2005 13:08:57 +0000 (13:08 +0000)
committerJorrit Herder <jnherder@minix3.org>
Tue, 26 Jul 2005 13:08:57 +0000 (13:08 +0000)
Work in progress ...

servers/sm/Makefile [new file with mode: 0644]
servers/sm/manager.c [new file with mode: 0644]
servers/sm/proto.h [new file with mode: 0644]
servers/sm/sm.c [new file with mode: 0644]
servers/sm/sm.h [new file with mode: 0644]

diff --git a/servers/sm/Makefile b/servers/sm/Makefile
new file mode 100644 (file)
index 0000000..71e332c
--- /dev/null
@@ -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 (file)
index 0000000..3bb771d
--- /dev/null
@@ -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);
+}
+
+
diff --git a/servers/sm/proto.h b/servers/sm/proto.h
new file mode 100644 (file)
index 0000000..5220782
--- /dev/null
@@ -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 (file)
index 0000000..fccb781
--- /dev/null
@@ -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 (file)
index 0000000..5f3eebf
--- /dev/null
@@ -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"
+