]> Zhao Yanbai Git Server - minix.git/commitdiff
Jorrit's ... "progress?"
authorJorrit Herder <jnherder@minix3.org>
Fri, 10 Mar 2006 16:10:05 +0000 (16:10 +0000)
committerJorrit Herder <jnherder@minix3.org>
Fri, 10 Mar 2006 16:10:05 +0000 (16:10 +0000)
35 files changed:
include/minix/callnr.h
include/minix/com.h
include/minix/ipc.h
include/signal.h
include/sys/resource.h
include/unistd.h
kernel/clock.c
kernel/ipc.h
kernel/main.c
kernel/mpx386.s
kernel/priv.h
kernel/proc.c
kernel/proc.h
kernel/proto.h
kernel/system/do_kill.c
kernel/system/do_nice.c
kernel/table.c
servers/ds/main.c
servers/fs/main.c
servers/fs/misc.c
servers/fs/utility.c
servers/inet/inet.c
servers/is/dmp.c
servers/is/main.c
servers/is/proto.h
servers/pm/forkexit.c
servers/pm/glo.h
servers/pm/main.c
servers/pm/misc.c
servers/pm/param.h
servers/pm/proto.h
servers/pm/signal.c
servers/pm/table.c
servers/pm/utility.c
servers/rs/main.c

index 5c5520bdebd68e9e4dd3e51e5be3254ecdd7cea3..571ddf9db830b083aafe5b46f710b6bd16940237 100755 (executable)
@@ -69,7 +69,7 @@
 
 /* MINIX specific calls, e.g., to support system services. */
 #define SVRCTL           77
-                               /* unused */
+#define PROCSTAT          78    /* to PM */
 #define GETSYSINFO       79    /* to PM or FS */
 #define GETPROCNR         80    /* to PM */
 #define DEVCTL           81    /* to FS */
index 5869138b217a4ac45ea7200f2c1f0d3fe2806b2f..ae70ace53d627419be3d5ac1f04bf6b66ce18d36 100755 (executable)
@@ -58,6 +58,7 @@
  */
 #define NOTIFY_MESSAGE           0x1000
 #define NOTIFY_FROM(p_nr)       (NOTIFY_MESSAGE | ((p_nr) + NR_TASKS)) 
+#  define PROC_EVENT   NOTIFY_FROM(PM_PROC_NR) /* process status change */
 #  define SYN_ALARM    NOTIFY_FROM(CLOCK)      /* synchronous alarm */
 #  define SYS_SIG      NOTIFY_FROM(SYSTEM)     /* system signal */
 #  define HARD_INT     NOTIFY_FROM(HARDWARE)   /* hardware interrupt */
  *===========================================================================*/
 
 /* Miscellaneous request types and field names, e.g. used by IS server. */
-#define PANIC_DUMPS            97      /* debug dumps at the TTY on RBT_PANIC */
 #define FKEY_CONTROL           98      /* control a function key at the TTY */
 #  define FKEY_REQUEST      m2_i1      /* request to perform at TTY */
 #  define    FKEY_MAP          10      /* observe function key */
index d73acde2d11c84023a02c3e9cfbdc19117dcac33..db03435dfa09bd6025b188dab94dc10de545614d 100644 (file)
@@ -90,15 +90,22 @@ typedef struct {
 #define sendrec                _sendrec
 #define receive                _receive
 #define send           _send
-#define nb_receive     _nb_receive
-#define nb_send                _nb_send
 
 _PROTOTYPE( int echo, (message *m_ptr)                                 );
 _PROTOTYPE( int notify, (int dest)                                     );
 _PROTOTYPE( int sendrec, (int src_dest, message *m_ptr)                        );
 _PROTOTYPE( int receive, (int src, message *m_ptr)                     );
 _PROTOTYPE( int send, (int dest, message *m_ptr)                       );
-_PROTOTYPE( int nb_receive, (int src, message *m_ptr)                  );
-_PROTOTYPE( int nb_send, (int dest, message *m_ptr)                    );
+
+#define ipc_request    _ipc_request
+#define ipc_reply      _ipc_reply
+#define ipc_notify     _ipc_notify
+#define ipc_select     _ipc_select
+
+_PROTOTYPE( int ipc_request, (int dst, message *m_ptr)                 );
+_PROTOTYPE( int ipc_reply, (int dst, message *m_ptr)                   );
+_PROTOTYPE( int ipc_notify, (int dst, long event_set)                  );
+_PROTOTYPE( int ipc_receive, (int src, long events, message *m_ptr)    );
+
 
 #endif /* _IPC_H */
index 5986f52e7a29a01b602b4e1d3090604f82181731..efc282fb7e2e5f25b7a383034f2c01baded33301 100755 (executable)
@@ -25,6 +25,7 @@ typedef unsigned long sigset_t;
 #endif
 #endif
 
+/* Regular signals. */
 #define SIGHUP             1   /* hangup */
 #define SIGINT             2   /* interrupt (DEL) */
 #define SIGQUIT            3   /* quit (ASCII FS) */
@@ -42,27 +43,25 @@ typedef unsigned long sigset_t;
 #define SIGTERM           15   /* software termination signal from kill */
 #define SIGEMT           16    /* EMT instruction */
 #define SIGCHLD           17   /* child process terminated or stopped */
+#define SIGWINCH         21    /* window size has changed */
 
 /* MINIX specific signals. These signals are not used by user proceses, 
  * but meant to inform system processes, like the PM, about system events.
  */
-#define SIGKMESS         18    /* new kernel message */
-#define SIGKSIG          19    /* kernel signal pending */
-#define SIGKSTOP         20    /* kernel shutting down */
-
-/* Regular signals. */
-#define SIGWINCH         21    /* window size has changed */
+#define SIGKMESS         23    /* new kernel message */
+#define SIGKSIG          24    /* kernel signal pending */
+#define SIGKSTOP         25    /* kernel shutting down */
 
-#define _NSIG             21   /* number of signals used */
+#define _NSIG             25   /* number of signals used */
 
 /* POSIX requires the following signals to be defined, even if they are
  * not supported.  Here are the definitions, but they are not supported.
  */
-#define SIGCONT           18   /* continue if stopped */
-#define SIGSTOP           19   /* stop signal */
-#define SIGTSTP           20   /* interactive stop signal */
-#define SIGTTIN           21   /* background process wants to read */
-#define SIGTTOU           22   /* background process wants to write */
+#define SIGCONT           28   /* continue if stopped */
+#define SIGSTOP           29   /* stop signal */
+#define SIGTSTP           30   /* interactive stop signal */
+#define SIGTTIN           31   /* background process wants to read */
+#define SIGTTOU           32   /* background process wants to write */
 
 #ifdef _MINIX
 #define SIGIOT             SIGABRT /* for people who speak PDP-11 */
index 6dc5bd8696e39ea8e5df430cdd01ba86d5bd9d81..1b14af4e2bfdfab4405e11fd6fb6a56b044c64e1 100755 (executable)
@@ -8,6 +8,9 @@
 #define PRIO_MIN       -20
 #define PRIO_MAX        20
 
+/* Magic, invalid priority to stop the process. */
+#define PRIO_STOP       76
+
 #define PRIO_PROCESS   0
 #define PRIO_PGRP      1
 #define PRIO_USER      2
index 69511735cd6e0ec5e97e01a43851bad289a77363..af796bba102a35fc9b18e8a94da7b946e9bb8c44 100755 (executable)
 
 #ifdef _MINIX
 /* How to exit the system or stop a server process. */
-#define RBT_HALT          0
-#define RBT_REBOOT        1
+#define RBT_HALT          0    /* shutdown and return to monitor */
+#define RBT_REBOOT        1    /* reboot the system through the monitor */
 #define RBT_PANIC         2    /* a server panics */
 #define RBT_MONITOR       3    /* let the monitor do this */
 #define RBT_RESET         4    /* hard reset the system */
+#define RBT_INVALID       5    /* first invalid reboot flag */
+
 #define _PM_SEG_FLAG (1L << 30)        /* for read() and write() to FS by PM */
 #endif
 
@@ -171,6 +173,7 @@ _PROTOTYPE( int ttyslot, (void)                                             );
 _PROTOTYPE( int fttyslot, (int _fd)                                    );
 _PROTOTYPE( char *crypt, (const char *_key, const char *_salt)         );
 _PROTOTYPE( int getsysinfo, (int who, int what, void *where)           );
+_PROTOTYPE( int getsigset, (sigset_t *sigset)                          );
 _PROTOTYPE( int getprocnr, (void)                                      );
 _PROTOTYPE( int getnprocnr, (pid_t pid)                                        );
 _PROTOTYPE( int getpprocnr, (void)                                     );
index 6417d19216f6c1eb459493ed3c066b4cce3145b6..3eaed06542a3b3e1e6382ed6c71c3299cdac588d 100755 (executable)
@@ -133,12 +133,17 @@ PRIVATE void init_clock()
   /* Initialize the CLOCK's interrupt hook. */
   clock_hook.proc_nr_e = CLOCK;
 
-  /* Initialize channel 0 of the 8253A timer to, e.g., 60 Hz. */
+  /* Initialize channel 0 of the 8253A timer to, e.g., 60 Hz, and register
+   * the CLOCK task's interrupt handler to be run on every clock tick. 
+   */
   outb(TIMER_MODE, SQUARE_WAVE);       /* set timer to run continuously */
   outb(TIMER0, TIMER_COUNT);           /* load timer low byte */
   outb(TIMER0, TIMER_COUNT >> 8);      /* load timer high byte */
-  put_irq_handler(&clock_hook, CLOCK_IRQ, clock_handler);/* register handler */
+  put_irq_handler(&clock_hook, CLOCK_IRQ, clock_handler);
   enable_irq(&clock_hook);             /* ready for clock interrupts */
+
+  /* Set a watchdog timer to periodically balance the scheduling queues. */
+  balance_queues(NULL);                        /* side-effect sets new timer */
 }
 
 /*===========================================================================*
@@ -146,7 +151,7 @@ PRIVATE void init_clock()
  *===========================================================================*/
 PUBLIC void clock_stop()
 {
-/* Reset the clock to the BIOS rate. (For rebooting) */
+/* Reset the clock to the BIOS rate. (For rebooting.) */
   outb(TIMER_MODE, 0x36);
   outb(TIMER0, 0);
   outb(TIMER0, 0);
index 4cef03e256a4a347e17fc585e3a34e7accba0770..8bd91042892739f2e12935c283ec161b1ac26bba 100644 (file)
@@ -7,24 +7,28 @@
 #include <minix/com.h>
 
 /* Masks and flags for system calls. */
-#define SYSCALL_FUNC   0x0F    /* mask for system call function */
-#define SYSCALL_FLAGS   0xF0    /* mask for system call flags */
-#define NON_BLOCKING    0x10   /* prevent blocking, return error */
+#define SYSCALL_FUNC   0x00FF  /* mask for system call function */
+#define SYSCALL_FLAGS   0xFF00  /* mask for system call flags */
+#define NON_BLOCKING    0x0100  /* do not block if target not ready */
 
 /* System call numbers that are passed when trapping to the kernel. The 
  * numbers are carefully defined so that it can easily be seen (based on 
  * the bits that are on) which checks should be done in sys_call().
  */
-#define SEND              1    /* 0 0 0 1 : blocking send */
-#define RECEIVE                   2    /* 0 0 1 0 : blocking receive */
-#define SENDREC                   3    /* 0 0 1 1 : SEND + RECEIVE */
-#define NOTIFY            4    /* 0 1 0 0 : nonblocking notify */
-#define ECHO              8    /* 1 0 0 0 : echo a message */
+#define SEND              1    /* 0000 0001 : blocking send */
+#define RECEIVE                   2    /* 0000 0010 : blocking receive */
+#define SENDREC                   3    /* 0000 0011 : SEND + RECEIVE */
+#define NOTIFY            4    /* 0000 0100 : nonblocking notify */
+#define ECHO              8    /* 0000 1000 : echo a message */
+
+#define IPC_REQUEST    0x10    /* 0001 0000 : blocking request */
+#define IPC_REPLY      0x20    /* 0010 0000 : nonblocking reply */
+#define IPC_NOTIFY     0x40    /* 0100 0000 : nonblocking notification */
+#define IPC_RECEIVE    0x80    /* 1000 0000 : blocking receive */
 
 /* The following bit masks determine what checks that should be done. */
-#define CHECK_PTR       0x0B   /* 1 0 1 1 : validate message buffer */
-#define CHECK_DST       0x05   /* 0 1 0 1 : validate message destination */
-#define CHECK_SRC       0x02   /* 0 0 1 0 : validate message source */
-#define CHECK_DEADLOCK  0x03   /* 0 0 1 1 : check for deadlock */
+#define CHECK_PTR       0xBB   /* 1011 1011 : validate message buffer */
+#define CHECK_DST       0x55   /* 0101 0101 : validate message destination */
+#define CHECK_DEADLOCK  0x93   /* 1001 0011 : check for deadlock */
 
 #endif /* IPC_H */
index 275fff8f0ccc1a88eaaac0990763142b47961112..001ec6d704f6c51dfe397349b88db53921cbddfb 100755 (executable)
@@ -203,11 +203,13 @@ int how;
    * run their shutdown code, e.g, to synchronize the FS or to let the TTY
    * switch to the first console. 
    */
+#if DEAD_CODE
   kprintf("Sending SIGKSTOP to system processes ...\n"); 
   for (rp=BEG_PROC_ADDR; rp<END_PROC_ADDR; rp++) {
       if (!isemptyp(rp) && (priv(rp)->s_flags & SYS_PROC) && !iskernelp(rp))
           send_sig(proc_nr(rp), SIGKSTOP);
   }
+#endif
 
   /* Continue after 1 second, to give processes a chance to get scheduled to 
    * do shutdown work.  Set a watchog timer to call shutdown(). The timer 
index 3eb8ec3154af58c5c126215d430439e8997897d7..0b5eee0277da837001b2eeda31961bf129f4f07f 100755 (executable)
@@ -358,19 +358,20 @@ _p_s_call:
     o16        push    es
     o16        push    fs
     o16        push    gs
-       mov     dx, ss
-       mov     ds, dx
-       mov     es, dx
-       incb    (_k_reenter)
+       mov     si, ss          ! ss is kernel data segment
+       mov     ds, si          ! load rest of kernel segments
+       mov     es, si          ! kernel does not use fs, gs
+       incb    (_k_reenter)    ! increment kernel entry count
        mov     esi, esp        ! assumes P_STACKBASE == 0
        mov     esp, k_stktop
        xor     ebp, ebp        ! for stacktrace
                                ! end of inline save
                                ! now set up parameters for sys_call()
+       push    edx             ! event set or flags bit map 
        push    ebx             ! pointer to user message
-       push    eax             ! src/dest
-       push    ecx             ! SEND/RECEIVE/BOTH
-       call    _sys_call       ! sys_call(function, src_dest, m_ptr)
+       push    eax             ! source / destination
+       push    ecx             ! call number (ipc primitive to use)
+       call    _sys_call       ! sys_call(call_nr, src_dst, m_ptr, bit_map)
                                ! caller is now explicitly in proc_ptr
        mov     AXREG(esi), eax ! sys_call MUST PRESERVE si
 
index 04adfbeba4599c1b9a6bc2047f71a161c092f145..02c1d0ca1ac7998deea94ae4e3357a2b728b6e40 100755 (executable)
@@ -43,13 +43,13 @@ struct priv {
   struct far_mem s_farmem[NR_REMOTE_SEGS];  /* remote memory map */
   reg_t *s_stack_guard;                /* stack guard word for kernel tasks */
 
-  int s_nr_io_range;
+  int s_nr_io_range;           /* allowed I/O ports */
   struct io_range s_io_tab[NR_IO_RANGE];
 
-  int s_nr_mem_range;
+  int s_nr_mem_range;          /* allowed memory ranges */
   struct mem_range s_mem_tab[NR_MEM_RANGE];
 
-  int s_nr_irq;
+  int s_nr_irq;                        /* allowed IRQ lines */
   int s_irq_tab[NR_IRQ];
 };
 
@@ -57,15 +57,13 @@ struct priv {
 #define STACK_GUARD    ((reg_t) (sizeof(reg_t) == 2 ? 0xBEEF : 0xDEADBEEF))
 
 /* Bits for the system property flags. */
-#define PREEMPTIBLE    0x01    /* kernel tasks are not preemptible */
+#define PREEMPTIBLE    0x02    /* kernel tasks are not preemptible */
 #define BILLABLE       0x04    /* some processes are not billable */
-#define SYS_PROC       0x10    /* system processes are privileged */
-#define SENDREC_BUSY   0x20    /* sendrec() in progress */
-#define CHECK_IO_PORT  0x40    /* Check whether an I/O request is allowed */
-#define CHECK_MEM      0x80    /* Check whether a (vm) memory map request is
-                                * allowed
-                                */
-#define CHECK_IRQ      0x100   /* Check whether an IRQ can be used */
+
+#define SYS_PROC       0x10    /* system processes have own priv structure */
+#define CHECK_IO_PORT  0x20    /* check if I/O request is allowed */
+#define CHECK_IRQ      0x40    /* check if IRQ can be used */
+#define CHECK_MEM      0x80    /* check if (VM) mem map request is allowed */
 
 /* Magic system structure table addresses. */
 #define BEG_PRIV_ADDR (&priv[0])
index 0e8a083dd87bfa9cd13cd4a9414f46ad6d2217af..286feb4731e741fba60cacc271da5a34d2a63a43 100755 (executable)
@@ -90,10 +90,11 @@ FORWARD _PROTOTYPE( void pick_proc, (void));
 /*===========================================================================*
  *                             sys_call                                     * 
  *===========================================================================*/
-PUBLIC int sys_call(call_nr, src_dst_e, m_ptr)
+PUBLIC int sys_call(call_nr, src_dst_e, m_ptr, bit_map)
 int call_nr;                   /* system call number and flags */
 int src_dst_e;                 /* src to receive from or dst to send to */
 message *m_ptr;                        /* pointer to message in the caller's space */
+long bit_map;                  /* notification event set or flags */
 {
 /* System calls are done by trapping to the kernel with an INT instruction.
  * The trap is caught and sys_call() is called to send or receive a message
@@ -195,7 +196,7 @@ message *m_ptr;                     /* pointer to message in the caller's space */
   switch(function) {
   case SENDREC:
       /* A flag is set so that notifications cannot interrupt SENDREC. */
-      priv(caller_ptr)->s_flags |= SENDREC_BUSY;
+      caller_ptr->p_misc_flags |= REPLY_PENDING;
       /* fall through */
   case SEND:                   
       result = mini_send(caller_ptr, src_dst_e, m_ptr, flags);
@@ -204,7 +205,7 @@ message *m_ptr;                     /* pointer to message in the caller's space */
       }                                                /* fall through for SENDREC */
   case RECEIVE:                        
       if (function == RECEIVE)
-          priv(caller_ptr)->s_flags &= ~SENDREC_BUSY;
+          caller_ptr->p_misc_flags &= ~REPLY_PENDING;
       result = mini_receive(caller_ptr, src_dst_e, m_ptr, flags);
       break;
   case NOTIFY:
@@ -353,7 +354,7 @@ unsigned flags;                             /* system call flags */
   if (!(caller_ptr->p_rts_flags & SENDING)) {
 
     /* Check if there are pending notifications, except for SENDREC. */
-    if (! (priv(caller_ptr)->s_flags & SENDREC_BUSY)) {
+    if (! (caller_ptr->p_misc_flags & REPLY_PENDING)) {
 
         map = &priv(caller_ptr)->s_notify_pending;
         for (chunk=&map->chunk[0]; chunk<&map->chunk[NR_SYS_CHUNKS]; chunk++) {
@@ -430,9 +431,9 @@ int dst;                            /* which process to notify */
    * can be both sending and receiving during a SENDREC system call.
    */
   if ((dst_ptr->p_rts_flags & (RECEIVING|SENDING)) == RECEIVING &&
-      ! (priv(dst_ptr)->s_flags & SENDREC_BUSY) &&
-      (dst_ptr->p_getfrom_e == ANY
-       || dst_ptr->p_getfrom_e == caller_ptr->p_endpoint)) {
+      ! (dst_ptr->p_misc_flags & REPLY_PENDING) &&
+      (dst_ptr->p_getfrom_e == ANY || 
+      dst_ptr->p_getfrom_e == caller_ptr->p_endpoint)) {
 
       /* Destination is indeed waiting for a message. Assemble a notification 
        * message and deliver it. Copy from pseudo-source HARDWARE, since the
@@ -600,32 +601,17 @@ int *front;                                       /* return: front or back */
  * process must be added to one of the scheduling queues to decide where to
  * insert it.  As a side-effect the process' priority may be updated.  
  */
-  static struct proc *prev_ptr = NIL_PROC;     /* previous without time */
   int time_left = (rp->p_ticks_left > 0);      /* quantum fully consumed */
-  int penalty = 0;                             /* change in priority */
 
   /* Check whether the process has time left. Otherwise give a new quantum 
-   * and possibly raise the priority.  Processes using multiple quantums 
-   * in a row get a lower priority to catch infinite loops in high priority
-   * processes (system servers and drivers). 
+   * and lower the process' priority, unless the process already is in the 
+   * lowest queue.  
    */
-  if ( ! time_left) {                          /* quantum consumed ? */
+  if (! time_left) {                           /* quantum consumed ? */
       rp->p_ticks_left = rp->p_quantum_size;   /* give new quantum */
-      if (prev_ptr == rp) penalty ++;          /* catch infinite loops */
-      else penalty --;                                 /* give slow way back */
-      prev_ptr = rp;                           /* store ptr for next */
-  }
-
-  /* Determine the new priority of this process. The bounds are determined
-   * by IDLE's queue and the maximum priority of this process. Kernel task 
-   * and the idle process are never changed in priority.
-   */
-  if (penalty != 0 && ! iskernelp(rp)) {
-      rp->p_priority += penalty;               /* update with penalty */
-      if (rp->p_priority < rp->p_max_priority)  /* check upper bound */ 
-          rp->p_priority=rp->p_max_priority;
-      else if (rp->p_priority > IDLE_Q-1)      /* check lower bound */
-         rp->p_priority = IDLE_Q-1;
+      if (rp->p_priority < (IDLE_Q-1)) {        
+          rp->p_priority += 1;                 /* lower priority */
+      }
   }
 
   /* If there is time left, the process is added to the front of its queue, 
@@ -662,6 +648,47 @@ PRIVATE void pick_proc()
   }
 }
 
+/*===========================================================================*
+ *                             balance_queues                               *
+ *===========================================================================*/
+#define Q_BALANCE_TICKS         100
+PUBLIC void balance_queues(tp)
+timer_t *tp;                                   /* watchdog timer pointer */
+{
+/* Check entire process table and give all process a higher priority. This
+ * effectively means giving a new quantum. If a process already is at its 
+ * maximum priority, its quantum will be renewed.
+ */
+  static timer_t queue_timer;                  /* timer structure to use */
+  register struct proc* rp;                    /* process table pointer  */
+  clock_t next_period;                         /* time of next period  */
+  int ticks_added = 0;                         /* total time added */
+
+  for (rp=BEG_PROC_ADDR; rp<END_PROC_ADDR; rp++) {
+      if (! isemptyp(rp)) {                            /* check slot use */
+         lock(5,"balance_queues");
+         if (rp->p_priority > rp->p_max_priority) {    /* update priority? */
+             if (rp->p_rts_flags == 0) dequeue(rp);    /* take off queue */
+             ticks_added += rp->p_quantum_size;        /* do accounting */
+             rp->p_priority -= 1;                      /* raise priority */
+             if (rp->p_rts_flags == 0) enqueue(rp);    /* put on queue */
+         }
+         else {
+             ticks_added += rp->p_quantum_size - rp->p_ticks_left;
+              rp->p_ticks_left = rp->p_quantum_size;   /* give new quantum */
+         }
+         unlock(5);
+      }
+  }
+  kprintf("ticks_added: %d\n", ticks_added);
+
+  /* Now schedule a new watchdog timer to balance the queues again.  The 
+   * period depends on the total amount of quantum ticks added.
+   */
+  next_period = MAX(Q_BALANCE_TICKS, ticks_added);     /* calculate next */
+  set_timer(&queue_timer, get_uptime() + next_period, balance_queues);
+}
+
 /*===========================================================================*
  *                             lock_send                                    *
  *===========================================================================*/
@@ -697,7 +724,7 @@ struct proc *rp;            /* this process is no longer runnable */
 {
 /* Safe gateway to dequeue() for tasks. */
   if (k_reenter >= 0) {
-       /* We're in an exception or interrupt, so don't lock (and.. 
+       /* We're in an exception or interrupt, so don't lock (and ... 
         * don't unlock).
         */
        dequeue(rp);
index 2c57e039d510a067e630d93fd64d41f4657555be..df4462413ab467eda92e791c80528b1f2b422174 100755 (executable)
@@ -28,9 +28,8 @@ struct proc {
 
   proc_nr_t p_nr;              /* number of this process (for fast access) */
   struct priv *p_priv;         /* system privileges structure */
-  char p_rts_flags;            /* SENDING, RECEIVING, etc. */
-
-  char p_misc_flags;           /* Flags that do suspend the process */
+  short p_rts_flags;           /* process is runnable only if zero */
+  short p_misc_flags;          /* flags that do suspend the process */
 
   char p_priority;             /* current scheduling priority */
   char p_max_priority;         /* maximum scheduling priority */
@@ -63,15 +62,17 @@ struct proc {
 /* Bits for the runtime flags. A process is runnable iff p_rts_flags == 0. */
 #define SLOT_FREE      0x01    /* process slot is free */
 #define NO_MAP         0x02    /* keeps unmapped forked child from running */
-#define SENDING                0x04    /* process blocked trying to SEND */
-#define RECEIVING      0x08    /* process blocked trying to RECEIVE */
+#define SENDING                0x04    /* process blocked trying to send */
+#define RECEIVING      0x08    /* process blocked trying to receive */
 #define SIGNALED       0x10    /* set when new kernel signal arrives */
 #define SIG_PENDING    0x20    /* unready while signal being processed */
 #define P_STOP         0x40    /* set when process is being traced */
 #define NO_PRIV                0x80    /* keep forked system process from running */
+#define NO_PRIORITY    0x100   /* process has been stopped */
 
 /* Misc flags */
-#define MF_VM          0x01    /* Process uses VM */
+#define REPLY_PENDING  0x01    /* reply to IPC_REQUEST is pending */
+#define MF_VM          0x08    /* process uses VM */
 
 /* Scheduling priorities for p_priority. Values must start at zero (highest
  * priority) and increment.  Priorities of the processes in the boot image 
index 3bb1f413b3df5717d9066d972f30263a53898c9d..071364ba66d364bb5e5fd698172549b6db468843 100755 (executable)
@@ -24,11 +24,13 @@ _PROTOTYPE( void kprintf, (const char *fmt, ...)                    );
 _PROTOTYPE( void panic, (_CONST char *s, int n)                                );
 
 /* proc.c */
-_PROTOTYPE( int sys_call, (int function, int src_dest, message *m_ptr) );
+_PROTOTYPE( int sys_call, (int call_nr, int src_dst, 
+                                       message *m_ptr, long bit_map)   );
 _PROTOTYPE( int lock_notify, (int src, int dst)                                );
 _PROTOTYPE( int lock_send, (int dst, message *m_ptr)                   );
 _PROTOTYPE( void lock_enqueue, (struct proc *rp)                       );
 _PROTOTYPE( void lock_dequeue, (struct proc *rp)                       );
+_PROTOTYPE( void balance_queues, (struct timer *tp)                    );
 #if DEBUG_ENABLE_IPC_WARNINGS
 _PROTOTYPE( int isokendpt_f, (char *file, int line, int e, int *p, int f));
 #define isokendpt_d(e, p, f) isokendpt_f(__FILE__, __LINE__, (e), (p), (f))
index 1c6f99c32691b26a9ded6d5ecd0071144ad7ca0e..eab947d7d0747a4da8e584633e93f4bb3d322c41 100644 (file)
@@ -33,14 +33,8 @@ message *m_ptr;                      /* pointer to request message */
   if (sig_nr > _NSIG) return(EINVAL);
   if (iskerneln(proc_nr)) return(EPERM);
 
-  if (m_ptr->m_source == PM_PROC_NR) {
-      /* Directly send signal notification to a system process. */
-      if (! (priv(proc_addr(proc_nr))->s_flags & SYS_PROC)) return(EPERM);
-      send_sig(proc_nr, sig_nr);
-  } else {
-      /* Set pending signal to be processed by the PM. */
-      cause_sig(proc_nr, sig_nr);
-  }
+  /* Set pending signal to be processed by the PM. */
+  cause_sig(proc_nr, sig_nr);
   return(OK);
 }
 
index 855e4e0679469131b510c1429070b75abae12bf5..51430a512062e9f9930103def326002f1b1cf218 100644 (file)
@@ -17,6 +17,7 @@
  *===========================================================================*/
 PUBLIC int do_nice(message *m_ptr)
 {
+/* Change process priority or stop the process. */
   int proc_nr, pri, new_q ;
   register struct proc *rp;
 
@@ -24,26 +25,36 @@ PUBLIC int do_nice(message *m_ptr)
   if(!isokendpt(m_ptr->PR_ENDPT, &proc_nr)) return EINVAL;
   if (iskerneln(proc_nr)) return(EPERM);
   pri = m_ptr->PR_PRIORITY;
-  if (pri < PRIO_MIN || pri > PRIO_MAX) return(EINVAL);
-
-  /* The priority is currently between PRIO_MIN and PRIO_MAX. We have to
-   * scale this between MIN_USER_Q and MAX_USER_Q.
-   */
-  new_q = MAX_USER_Q + (pri-PRIO_MIN) * (MIN_USER_Q-MAX_USER_Q+1) / 
-      (PRIO_MAX-PRIO_MIN+1);
-  if (new_q < MAX_USER_Q) new_q = MAX_USER_Q;  /* shouldn't happen */
-  if (new_q > MIN_USER_Q) new_q = MIN_USER_Q;  /* shouldn't happen */
-
-  /* Make sure the process is not running while changing its priority; the
-   * max_priority is the base priority. Put the process back in its new
-   * queue if it is runnable.
-   */
   rp = proc_addr(proc_nr);
-  lock_dequeue(rp);
-  rp->p_max_priority = rp->p_priority = new_q;
-  if (! rp->p_rts_flags) lock_enqueue(rp);
 
-  return(OK);
+  if (pri == PRIO_STOP) {
+
+      /* Take process off the scheduling queues. */
+      lock_dequeue(rp);
+      rp->p_rts_flags |= NO_PRIORITY;
+      return(OK);
+  }
+  else if (pri >= PRIO_MIN && pri <= PRIO_MAX) {
+
+      /* The value passed in is currently between PRIO_MIN and PRIO_MAX. 
+       * We have to scale this between MIN_USER_Q and MAX_USER_Q to match 
+       * the kernel's scheduling queues.
+       */
+      new_q = MAX_USER_Q + (pri-PRIO_MIN) * (MIN_USER_Q-MAX_USER_Q+1) / 
+          (PRIO_MAX-PRIO_MIN+1);
+      if (new_q < MAX_USER_Q) new_q = MAX_USER_Q;      /* shouldn't happen */
+      if (new_q > MIN_USER_Q) new_q = MIN_USER_Q;      /* shouldn't happen */
+
+      /* Make sure the process is not running while changing its priority. 
+       * Put the process back in its new queue if it is runnable.
+       */
+      lock_dequeue(rp);
+      rp->p_max_priority = rp->p_priority = new_q;
+      if (! rp->p_rts_flags) lock_enqueue(rp);
+
+      return(OK);
+  }
+  return(EINVAL);
 }
 
 #endif /* USE_NICE */
index c4c3ff38d2d87c9fb4b34904438e28280d2ff47a..a5b5a7273a6be77ba4360a5005a8203ce997da9f 100755 (executable)
@@ -81,8 +81,7 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
 #define DS_C   ~0      
 #define PM_C   ~(c(SYS_DEVIO) | c(SYS_SDEVIO) | c(SYS_VDEVIO) | c(SYS_IRQCTL) | c(SYS_INT86))
 #define FS_C   (c(SYS_KILL) | c(SYS_VIRCOPY) | c(SYS_VIRVCOPY) | c(SYS_UMAP) | c(SYS_GETINFO) | c(SYS_EXIT) | c(SYS_TIMES) | c(SYS_SETALARM))
-#define DRV_C  (FS_C | c(SYS_SEGCTL) | c(SYS_IRQCTL) | c(SYS_INT86) | c(SYS_DEVIO) | c(SYS_VDEVIO) | c(SYS_SDEVIO)) 
-#define PCI_C  (c(SYS_VIRCOPY) | c(SYS_DEVIO) | c(SYS_VDEVIO) | c(SYS_SDEVIO) | c(SYS_PRIVCTL) | c(SYS_GETINFO)) 
+#define DRV_C (FS_C | c(SYS_SEGCTL) | c(SYS_IRQCTL) | c(SYS_INT86) | c(SYS_DEVIO) | c(SYS_SDEVIO) | c(SYS_VDEVIO))
 #define TTY_C (DRV_C | c(SYS_ABORT) | c(SYS_VM_MAP) | c(SYS_IOPENABLE))
 #define MEM_C  (DRV_C | c(SYS_PHYSCOPY) | c(SYS_PHYSVCOPY) | c(SYS_VM_MAP) | \
        c(SYS_IOPENABLE))
@@ -90,27 +89,26 @@ PUBLIC char *t_stack[TOT_STACK_SPACE / sizeof(char *)];
 /* The system image table lists all programs that are part of the boot image. 
  * The order of the entries here MUST agree with the order of the programs
  * in the boot image and all kernel tasks must come first.
- * Each entry provides the process number, flags, quantum size (qs), scheduling
+ *
+ * Each entry provides the process number, flags, quantum size, scheduling
  * queue, allowed traps, ipc mask, and a name for the process table. The 
  * initial program counter and stack size is also provided for kernel tasks.
+ *
+ * Note: the quantum size must be positive in all cases! 
  */
 PUBLIC struct boot_image image[] = {
 /* process nr,   pc, flags, qs,  queue, stack, traps, ipcto, call,  name */ 
- { IDLE,  idle_task, IDL_F,  8, IDLE_Q, IDL_S,     0,     0,     0, "IDLE"  },
- { CLOCK,clock_task, TSK_F,  0, TASK_Q, TSK_S, TSK_T,     0,     0, "CLOCK" },
- { SYSTEM, sys_task, TSK_F,  0, TASK_Q, TSK_S, TSK_T,     0,     0, "SYSTEM"},
- { HARDWARE,      0, TSK_F,  0, TASK_Q, HRD_S,     0,     0,     0, "KERNEL"},
+ { IDLE,  idle_task, IDL_F,  8, IDLE_Q, IDL_S,     0,     0,     0, "idle"  },
+ { CLOCK,clock_task, TSK_F,  8, TASK_Q, TSK_S, TSK_T,     0,     0, "clock" },
+ { SYSTEM, sys_task, TSK_F,  8, TASK_Q, TSK_S, TSK_T,     0,     0, "system"},
+ { HARDWARE,      0, TSK_F,  8, TASK_Q, HRD_S,     0,     0,     0, "kernel"},
  { PM_PROC_NR,    0, SRV_F, 32,      3, 0,     SRV_T, SRV_M,  PM_C, "pm"    },
  { FS_PROC_NR,    0, SRV_F, 32,      4, 0,     SRV_T, SRV_M,  FS_C, "fs"    },
  { RS_PROC_NR,    0, SRV_F,  4,      3, 0,     SRV_T, SYS_M,  RS_C, "rs"    },
  { DS_PROC_NR,    0, SRV_F,  4,      3, 0,     SRV_T, SYS_M,  DS_C, "ds"    },
  { TTY_PROC_NR,   0, SRV_F,  4,      1, 0,     SRV_T, SYS_M, TTY_C, "tty"   },
- { MEM_PROC_NR,   0, SRV_F,  4,      2, 0,     SRV_T, SYS_M, MEM_C, "memory"},
+ { MEM_PROC_NR,   0, SRV_F,  4,      2, 0,     SRV_T, SYS_M, MEM_C, "mem"   },
  { LOG_PROC_NR,   0, SRV_F,  4,      2, 0,     SRV_T, SYS_M, DRV_C, "log"   },
-#if 0
- { DRVR_PROC_NR,  0, SRV_F,  4,      2, 0,     SRV_T, SYS_M, DRV_C, "driver"},
- { PCI_PROC_NR,   0, SRV_F,  4,      2, 0,     SRV_T, SYS_M, PCI_C, "pci"},
-#endif
  { INIT_PROC_NR,  0, USR_F,  8, USER_Q, 0,     USR_T, USR_M,     0, "init"  },
 };
 
index a0770aff0067b75b79b524984ab3a9875a8987a5..d90c994cf239d0dec21c6ab7e8bd9c98e385bccb 100644 (file)
@@ -20,6 +20,7 @@ extern int errno;     /* error number set by system library */
 /* Declare some local functions. */
 FORWARD _PROTOTYPE(void init_server, (int argc, char **argv)           );
 FORWARD _PROTOTYPE(void exit_server, (void)                            );
+FORWARD _PROTOTYPE(void sig_handler, (void)                            );
 FORWARD _PROTOTYPE(void get_work, (message *m_ptr)                     );
 FORWARD _PROTOTYPE(void reply, (int whom, message *m_ptr)              );
 
@@ -46,11 +47,8 @@ PUBLIC int main(int argc, char **argv)
       get_work(&m);
 
       switch (callnr) {
-      case SYS_SIG:
-          sigset = (sigset_t) m.NOTIFY_ARG;
-          if (sigismember(&sigset,SIGTERM) || sigismember(&sigset,SIGKSTOP)) {
-              exit_server();
-          }
+      case PROC_EVENT:
+         sig_handler();
           continue;
       case DS_PUBLISH:
           result = do_publish(&m);
@@ -95,6 +93,24 @@ PRIVATE void init_server(int argc, char **argv)
       report("DS","warning, sigaction() failed", errno);
 }
 
+/*===========================================================================*
+ *                              sig_handler                                 *
+ *===========================================================================*/
+PRIVATE void sig_handler()
+{
+/* Signal 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, SIGTERM)) {
+      exit_server();
+  }
+}
+
 /*===========================================================================*
  *                             exit_server                                  *
  *===========================================================================*/
index eb6aa36fddfc1e3682b45cb77e9908340ac0d79f..3d34fd35bcc5f7291b5c4ec5723963664aee3287 100644 (file)
@@ -34,8 +34,7 @@ struct super_block;           /* proto.h needs to know this */
 FORWARD _PROTOTYPE( void fs_init, (void)                               );
 FORWARD _PROTOTYPE( int igetenv, (char *var, int optional)             );
 FORWARD _PROTOTYPE( void get_work, (void)                              );
-FORWARD _PROTOTYPE( void load_ram, (void)                              );
-FORWARD _PROTOTYPE( void load_super, (Dev_t super_dev)                 );
+FORWARD _PROTOTYPE( void init_root, (void)                             );
 
 /*===========================================================================*
  *                             main                                         *
@@ -55,21 +54,15 @@ PUBLIC int main()
   /* This is the main loop that gets work, processes it, and sends replies. */
   while (TRUE) {
        get_work();             /* sets who and call_nr */
-
        fp = &fproc[who_p];     /* pointer to proc table struct */
        super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE);   /* su? */
 
        /* Check for special control messages first. */
-        if (call_nr == SYS_SIG) { 
-               sigset = m_in.NOTIFY_ARG;
-               if (sigismember(&sigset, SIGKSTOP)) {
-                       do_sync();
-                       sys_exit(0);            /* never returns */
-               }
+       if (call_nr == PROC_EVENT) {
+               /* Assume FS got signal. Synchronize, but don't exit. */
+               do_sync();
         } else if (call_nr == SYN_ALARM) {
-               /* Not a user request; system has expired one of our timers,
-                * currently only in use for select(). Check it.
-                */
+               /* Alarm timer expired. Used only for select(). Check it. */
                fs_expire_timers(m_in.NOTIFY_TIMESTAMP);
         } else if ((call_nr & NOTIFY_MESSAGE)) {
                /* Device notifies us of an event. */
@@ -78,6 +71,7 @@ PUBLIC int main()
                /* Call the internal function that does the work. */
                if (call_nr < 0 || call_nr >= NCALLS) { 
                        error = ENOSYS;
+               /* Not supposed to happen. */
                        printf("FS, warning illegal %d system call by %d\n", call_nr, who_e);
                } else if (fp->fp_pid == PID_FREE) {
                        error = ENOSYS;
@@ -184,10 +178,7 @@ PUBLIC void reply(whom, result)
 int whom;                      /* process to reply to */
 int result;                    /* result of the call (usually OK or error #) */
 {
-/* Send a reply to a user process. It may fail (if the process has just
- * been killed by a signal), so don't check the return code.  If the send
- * fails, just ignore it.
- */
+/* Send a reply to a user process.  If the send fails, just ignore it. */
   int s;
   m_out.reply_type = result;
   s = send(whom, &m_out);
@@ -247,8 +238,7 @@ PRIVATE void fs_init()
 
   buf_pool();                  /* initialize buffer pool */
   build_dmap();                        /* build device table and map boot driver */
-  load_ram();                  /* init RAM disk, load if it is root */
-  load_super(root_dev);                /* load super block for root device */
+  init_root();                 /* init root device and load super block */
   init_select();               /* init select() structures */
 
   /* The root device can now be accessed; set process directories. */
@@ -283,206 +273,37 @@ int optional;
 }
 
 /*===========================================================================*
- *                             load_ram                                     *
+ *                             init_root                                    *
  *===========================================================================*/
-PRIVATE void load_ram(void)
+PRIVATE void init_root()
 {
-/* Allocate a RAM disk with size given in the boot parameters. If a RAM disk 
- * image is given, the copy the entire image device block-by-block to a RAM 
- * disk with the same size as the image.
- * If the root device is not set, the RAM disk will be used as root instead. 
- */
-  register struct buf *bp, *bp1;
-  u32_t lcount, ram_size_kb;
-  zone_t zones;
-  struct super_block *sp, *dsp;
-  block_t b;
-  Dev_t image_dev;
-  static char sbbuf[_MIN_BLOCK_SIZE];
-  int block_size_image, block_size_ram, ramfs_block_size;
+  int bad;
+  register struct super_block *sp;
+  register struct inode *rip;
   int s;
 
-  /* Get some boot environment variables. */
-  root_dev = igetenv("rootdev", 0);
-  root_dev = DEV_IMGRD;
-  image_dev = igetenv("ramimagedev", 0);
-  ram_size_kb = igetenv("ramsize", 0);
-
   /* Open the root device. */
-  if (dev_open(root_dev, FS_PROC_NR, R_BIT|W_BIT) != OK)
-       panic(__FILE__,"Cannot open root device",NO_NUM);
-
-#if 0
-  /* If we must initialize a ram disk, get details from the image device. */
-  if (root_dev == DEV_RAM) {
-       u32_t fsmax, probedev;
-
-       /* If we are running from CD, see if we can find it. */
-       if (igetenv("cdproberoot", 1) && (probedev=cdprobe()) != NO_DEV) {
-               char devnum[10];
-               struct sysgetenv env;
-
-               /* If so, this is our new RAM image device. */
-               image_dev = probedev;
-
-               /* Tell PM about it, so userland can find out about it
-                * with sysenv interface.
-                */
-               env.key = "cdproberoot";
-               env.keylen = strlen(env.key);
-               sprintf(devnum, "%d", (int) probedev);
-               env.val = devnum;
-               env.vallen = strlen(devnum);
-               svrctl(MMSETPARAM, &env);
-       }
-
-       /* Open image device for RAM root. */
-       if (dev_open(image_dev, FS_PROC_NR, R_BIT) != OK)
-               panic(__FILE__,"Cannot open RAM image device", NO_NUM);
-
-       /* Get size of RAM disk image from the super block. */
-       sp = &super_block[0];
-       sp->s_dev = image_dev;
-       if (read_super(sp) != OK) 
-               panic(__FILE__,"Bad RAM disk image FS", NO_NUM);
-
-       lcount = sp->s_zones << sp->s_log_zone_size;    /* # blks on root dev*/
-
-       /* Stretch the RAM disk file system to the boot parameters size, but
-        * no further than the last zone bit map block allows.
-        */
-       if (ram_size_kb*1024 < lcount*sp->s_block_size)
-               ram_size_kb = lcount*sp->s_block_size/1024;
-       fsmax = (u32_t) sp->s_zmap_blocks * CHAR_BIT * sp->s_block_size;
-       fsmax = (fsmax + (sp->s_firstdatazone-1)) << sp->s_log_zone_size;
-       if (ram_size_kb*1024 > fsmax*sp->s_block_size)
-               ram_size_kb = fsmax*sp->s_block_size/1024;
-  }
-#endif
-
-  /* Tell RAM driver how big the RAM disk must be. */
-  m_out.m_type = DEV_IOCTL;
-  m_out.PR_ENDPT = FS_PROC_NR;
-  m_out.DEVICE = RAM_DEV;
-  m_out.REQUEST = MIOCRAMSIZE;                 /* I/O control to use */
-  m_out.POSITION = (ram_size_kb * 1024);       /* request in bytes */
-#if 0
-  if ((s=sendrec(MEM_PROC_NR, &m_out)) != OK)
-       panic("FS","sendrec from MEM failed", s);
-  else if (m_out.REP_STATUS != OK) {
-       /* Report and continue, unless RAM disk is required as root FS. */
-       if (root_dev != DEV_RAM) {
-               report("FS","can't set RAM disk size", m_out.REP_STATUS);
-               return;
-       } else {
-               panic(__FILE__,"can't set RAM disk size", m_out.REP_STATUS);
-       }
-  }
-#endif
+  root_dev = DEV_IMGRD;
+  if ((s=dev_open(root_dev, FS_PROC_NR, R_BIT|W_BIT)) != OK)
+       panic(__FILE__,"Cannot open root device", s);
 
 #if ENABLE_CACHE2
   /* The RAM disk is a second level block cache while not otherwise used. */
   init_cache2(ram_size);
 #endif
 
-  /* See if we must load the RAM disk image, otherwise return. */
-  if (root_dev != DEV_RAM)
-       return;
-
-#if 0
-
-  /* Copy the blocks one at a time from the image to the RAM disk. */
-  printf("Loading RAM disk onto /dev/ram:\33[23CLoaded:    0 KB");
-
-  inode[0].i_mode = I_BLOCK_SPECIAL;   /* temp inode for rahead() */
-  inode[0].i_size = LONG_MAX;
-  inode[0].i_dev = image_dev;
-  inode[0].i_zone[0] = image_dev;
-
-  block_size_ram = get_block_size(DEV_RAM);
-  block_size_image = get_block_size(image_dev);
-
-  /* RAM block size has to be a multiple of the root image block
-   * size to make copying easier.
-   */
-  if (block_size_image % block_size_ram) {
-       printf("\nram block size: %d image block size: %d\n", 
-               block_size_ram, block_size_image);
-       panic(__FILE__, "ram disk block size must be a multiple of "
-               "the image disk block size", NO_NUM);
-  }
-
-  /* Loading blocks from image device. */
-  for (b = 0; b < (block_t) lcount; b++) {
-       int rb, factor;
-       bp = rahead(&inode[0], b, (off_t)block_size_image * b, block_size_image);
-       factor = block_size_image/block_size_ram;
-       for(rb = 0; rb < factor; rb++) {
-               bp1 = get_block(root_dev, b * factor + rb, NO_READ);
-               memcpy(bp1->b_data, bp->b_data + rb * block_size_ram,
-                       (size_t) block_size_ram);
-               bp1->b_dirt = DIRTY;
-               put_block(bp1, FULL_DATA_BLOCK);
-       }
-       put_block(bp, FULL_DATA_BLOCK);
-       if (b % 11 == 0)
-       printf("\b\b\b\b\b\b\b\b\b%6ld KB", ((long) b * block_size_image)/1024L);
-  }
-
-  /* Commit changes to RAM so dev_io will see it. */
-  do_sync();
-
-  printf("\rRAM disk of %u KB loaded onto /dev/ram.", (unsigned) ram_size_kb);
-  if (root_dev == DEV_RAM) printf(" Using RAM disk as root FS.");
-  printf("  \n");
-
-  /* Invalidate and close the image device. */
-  invalidate(image_dev);
-  dev_close(image_dev);
-
-  /* Resize the RAM disk root file system. */
-  if (dev_io(DEV_READ, root_dev, FS_PROC_NR,
-       sbbuf, SUPER_BLOCK_BYTES, _MIN_BLOCK_SIZE, 0) != _MIN_BLOCK_SIZE) {
-       printf("WARNING: ramdisk read for resizing failed\n");
-  }
-  dsp = (struct super_block *) sbbuf;
-  if (dsp->s_magic == SUPER_V3)
-       ramfs_block_size = dsp->s_block_size;
-  else
-       ramfs_block_size = _STATIC_BLOCK_SIZE;
-  zones = (ram_size_kb * 1024 / ramfs_block_size) >> sp->s_log_zone_size;
-
-  dsp->s_nzones = conv2(sp->s_native, (u16_t) zones);
-  dsp->s_zones = conv4(sp->s_native, zones);
-  if (dev_io(DEV_WRITE, root_dev, FS_PROC_NR,
-       sbbuf, SUPER_BLOCK_BYTES, _MIN_BLOCK_SIZE, 0) != _MIN_BLOCK_SIZE) {
-       printf("WARNING: ramdisk write for resizing failed\n");
-  }
-#endif
-}
-
-/*===========================================================================*
- *                             load_super                                   *
- *===========================================================================*/
-PRIVATE void load_super(super_dev)
-dev_t super_dev;                       /* place to get superblock from */
-{
-  int bad;
-  register struct super_block *sp;
-  register struct inode *rip;
-
   /* Initialize the super_block table. */
   for (sp = &super_block[0]; sp < &super_block[NR_SUPERS]; sp++)
        sp->s_dev = NO_DEV;
 
   /* Read in super_block for the root file system. */
   sp = &super_block[0];
-  sp->s_dev = super_dev;
+  sp->s_dev = root_dev;
 
   /* Check super_block for consistency. */
   bad = (read_super(sp) != OK);
   if (!bad) {
-       rip = get_inode(super_dev, ROOT_INODE); /* inode for root dir */
+       rip = get_inode(root_dev, ROOT_INODE);  /* inode for root dir */
        if ( (rip->i_mode & I_TYPE) != I_DIRECTORY || rip->i_nlinks < 3) bad++;
   }
   if (bad) panic(__FILE__,"Invalid root file system", NO_NUM);
index 4b53ef8e49edc669009d22e4dda509d25c8490b8..eafc1c6621f6725c998eb00ea745a23d4110699d 100644 (file)
@@ -432,24 +432,17 @@ PUBLIC int do_exit()
   /* Invalidate endpoint number for error and sanity checks. */
   fp->fp_endpoint = NONE;
 
-  /* If a session leader exits then revoke access to its controlling tty from
-   * all other processes using it.
+  /* If a session leader exits and it has a controlling tty, then revoke 
+   * access to its controlling tty from all other processes using it.
    */
-  if (!fp->fp_sesldr) {
-       fp->fp_pid = PID_FREE;
-       return(OK);             /* not a session leader */
-  }
-  fp->fp_sesldr = FALSE;
-  if (fp->fp_tty == 0) {
-       fp->fp_pid = PID_FREE;
-       return(OK);             /* no controlling tty */
-  }
-  dev = fp->fp_tty;
+  if (fp->fp_sesldr && fp->fp_tty != 0) {
+
+      dev = fp->fp_tty;
 
-  for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
-       if (rfp->fp_tty == dev) rfp->fp_tty = 0;
+      for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
+          if (rfp->fp_tty == dev) rfp->fp_tty = 0;
 
-       for (i = 0; i < OPEN_MAX; i++) {
+          for (i = 0; i < OPEN_MAX; i++) {
                if ((rfilp = rfp->fp_filp[i]) == NIL_FILP) continue;
                if (rfilp->filp_mode == FILP_CLOSED) continue;
                rip = rfilp->filp_ino;
@@ -457,12 +450,12 @@ PUBLIC int do_exit()
                if ((dev_t) rip->i_zone[0] != dev) continue;
                dev_close(dev);
                rfilp->filp_mode = FILP_CLOSED;
-       }
+          }
+      }
   }
 
-  /* Mark slot as free. */
+  /* Exit done. Mark slot as free. */
   fp->fp_pid = PID_FREE;
-
   return(OK);
 }
 
index 44c0279d91fff3e1500633ebe163e386346dd333..afaccdfc51741fa7c8f241d4c2e227f16ef5de13 100644 (file)
@@ -106,7 +106,7 @@ int num;                    /* number to go with it */
   printf("FS panic (%s): %s ", who, mess);
   if (num != NO_NUM) printf("%d",num); 
   (void) do_sync();            /* flush everything to the disk */
-  sys_exit(1);
+  sys_exit(SELF);
 }
 
 /*===========================================================================*
index 9f650ba270daf4d1bcbe69308ddccb7e19c53c67..4d8b8698599e5dc23441a7e9a56571505da380f5 100644 (file)
@@ -245,7 +245,7 @@ PUBLIC void main()
                        clck_tick(&mq->mq_mess);
                        mq_free(mq);
                } 
-               else if (mq->mq_mess.m_type == SYS_SIG)
+               else if (mq->mq_mess.m_type == PROC_EVENT)
                {
                        /* signaled */ 
                        /* probably SIGTERM */
index bd2a256d91f8c44221c7e9764a114624365b2610..483a9c51c14397afdd63afc5313db16f8bf8e3a9 100644 (file)
@@ -12,7 +12,7 @@
 /* Define hooks for the debugging dumps. This table maps function keys
  * onto a specific dump and provides a description for it.
  */
-#define NHOOKS 19
+#define NHOOKS 18
 
 struct hook_entry {
        int key;
@@ -29,7 +29,6 @@ struct hook_entry {
        { F9,   sched_dmp, "Scheduling queues" },
        { F10,  kenv_dmp, "Kernel parameters" },
        { F11,  timing_dmp, "Timing details (if enabled)" },
-       { F12,  reboot_dmp, "Reboot system after panic." },
        { SF1,  mproc_dmp, "Process manager process table" },
        { SF2,  sigaction_dmp, "Signals" },
        { SF3,  fproc_dmp, "Filesystem process table" },
@@ -83,14 +82,6 @@ PRIVATE char *key_name(int key)
        return name;
 }
 
-/*===========================================================================*
- *                             reboot_dmp                                   *
- *===========================================================================*/
-PUBLIC void reboot_dmp(void)
-{
-  if (sys_panic) sys_abort(RBT_HALT);
-}
-
 
 /*===========================================================================*
  *                             mapping_dmp                                  *
index 07ccea2705a88db2a70d71fe6b6d8350727ab47f..37c08a64c1a5ae2ee62fcdce1367fd991ce14752 100644 (file)
@@ -18,12 +18,12 @@ message m_in;               /* the input message itself */
 message m_out;         /* the output message used for reply */
 int who_e;             /* caller's proc number */
 int callnr;            /* system call number */
-int sys_panic;         /* flag to indicate system-wide panic */
 
 extern int errno;      /* error number set by system library */
 
 /* Declare some local functions. */
 FORWARD _PROTOTYPE(void init_server, (int argc, char **argv)           );
+FORWARD _PROTOTYPE(void sig_handler, (void)                            );
 FORWARD _PROTOTYPE(void exit_server, (void)                            );
 FORWARD _PROTOTYPE(void get_work, (void)                               );
 FORWARD _PROTOTYPE(void reply, (int whom, int result)                  );
@@ -51,16 +51,16 @@ PUBLIC int main(int argc, char **argv)
 
       switch (callnr) {
       case SYS_SIG:
-          sigset = (sigset_t) m_in.NOTIFY_ARG;
-          if (sigismember(&sigset,SIGTERM) || sigismember(&sigset,SIGKSTOP)) {
-              exit_server();
-          }
-          continue;
-      case PANIC_DUMPS:
-         printf("Oops ... panic in %d.  ", who_e);
-         printf("Hit F-keys for debug dumps or F12 to shut down.\n");
-         sys_panic = TRUE;                     /* set flag to allow exit */
+         printf("got SYS_SIG message\n");
+         sigset = m_in.NOTIFY_ARG;
+         for ( result=0; result< _NSIG; result++) {
+             if (sigismember(&sigset, result))
+                 printf("signal %d found\n", result);
+         }
          continue;
+      case PROC_EVENT:
+          sig_handler();
+          continue;
       case FKEY_PRESSED:
           result = do_fkey_pressed(&m_in);
           break;
@@ -105,6 +105,23 @@ PRIVATE void init_server(int argc, char **argv)
       report("IS", "warning, fkey_map failed:", 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, SIGTERM)) {
+      exit_server();
+  }
+}
+
 /*===========================================================================*
  *                             exit_server                                  *
  *===========================================================================*/
index 42767821f27a53566dcff9b57dd9a5e6a8a7accb..53afeb9a3af95b51ee76fc739632f7d0329d2a1e 100644 (file)
@@ -6,7 +6,6 @@ _PROTOTYPE( int  main, (int argc, char **argv)                          );
 /* dmp.c */
 _PROTOTYPE( int do_fkey_pressed, (message *m)                          );
 _PROTOTYPE( void mapping_dmp, (void)                                   );
-_PROTOTYPE( void reboot_dmp, (void)                                    );
 
 /* dmp_kernel.c */
 _PROTOTYPE( void proctab_dmp, (void)                                   );
index 796e2f925a9e3eef2686d0146218dfe813576747..8e3cbf9f57022fcc24f45cbcf9dbdd44b3b14fb3 100644 (file)
@@ -17,6 +17,7 @@
 #include <sys/wait.h>
 #include <minix/callnr.h>
 #include <minix/com.h>
+#include <sys/resource.h>
 #include <signal.h>
 #include "mproc.h"
 #include "param.h"
@@ -165,9 +166,15 @@ int exit_status;           /* the process' exit status (for parent) */
   p_mp->mp_child_utime += t[0] + rmp->mp_child_utime;  /* add user time */
   p_mp->mp_child_stime += t[1] + rmp->mp_child_stime;  /* add system time */
 
-  /* Tell the kernel and FS that the process is no longer runnable. */
-  tell_fs(EXIT, proc_nr_e, 0, 0);  /* file system can free the proc slot */
-  if((r=sys_exit(proc_nr_e)) != OK)
+  /* Tell the kernel the process is no longer runnable to prevent it from 
+   * being scheduled in between the following steps. Then tell FS that it 
+   * the process has exited and finally, clean up the process at the kernel.
+   * This order is important so that FS can tell drivers to cancel requests
+   * such as copying to/ from the exiting process, before it is gone.
+   */
+  sys_nice(proc_nr_e, PRIO_STOP);      /* stop the process */
+  tell_fs(EXIT, proc_nr_e, 0, 0);      /* tell FS to free the slot */
+  if((r=sys_exit(proc_nr_e)) != OK)    /* destroy the process */
        panic(__FILE__,"pm_exit: sys_exit failed", r);
 
   /* Pending reply messages for the dead process cannot be delivered. */
index 6947b12b60810b911e9f185caf61b35e716699f7..467d1a17910ba6a6e364f1e55e5927e2266e6373 100644 (file)
@@ -8,7 +8,7 @@
 EXTERN struct mproc *mp;       /* ptr to 'mproc' slot of current process */
 EXTERN int procs_in_use;       /* how many processes are marked as IN_USE */
 EXTERN char monitor_params[128*sizeof(char *)];        /* boot monitor parameters */
-EXTERN struct kinfo kinfo;                     /* kernel information */
+EXTERN struct kinfo kinfo;     /* kernel information */
 
 /* The parameters of the call are kept here. */
 EXTERN message m_in;           /* the incoming message itself is kept here. */
index ec31baa50b34081af5ef6b1a9a4b8cde38413207..1e01a013d55ff4ddd6806abf07788f93c05c5264 100644 (file)
@@ -236,12 +236,10 @@ PRIVATE void pm_init()
                else {                                  /* system process */
                        rmp->mp_pid = get_free_pid();
                        rmp->mp_flags |= IN_USE | DONT_SWAP | PRIV_PROC; 
-#if DEAD_CODE
                        for (sig_ptr = mess_sigs; 
                                sig_ptr < mess_sigs+sizeof(mess_sigs); 
                                sig_ptr++)
                        sigaddset(&rmp->mp_sig2mess, *sig_ptr);
-#endif
                }
 
                /* Get kernel endpoint identifier. */
@@ -270,8 +268,6 @@ PRIVATE void pm_init()
   mproc[PM_PROC_NR].mp_pid = PM_PID;           /* PM has magic pid */
   mproc[RS_PROC_NR].mp_parent = INIT_PROC_NR;  /* INIT is root */
   sigfillset(&mproc[PM_PROC_NR].mp_ignore);    /* guard against signals */
-  sigfillset(&mproc[FS_PROC_NR].mp_sig2mess);  /* forward signals */
-  sigfillset(&mproc[TTY_PROC_NR].mp_sig2mess);         /* forward signals */
 
   /* Tell FS that no more system processes follow and synchronize. */
   mess.PR_ENDPT = NONE;
index 03684b065d7c47896c0a04c218baf3b04ccef390..b71adfa95a57aaa7de208ed21475980de1add7a8 100644 (file)
@@ -2,12 +2,13 @@
  *                                                             31 Mar 2000
  * The entry points into this file are:
  *   do_reboot: kill all processes, then reboot system
- *   do_svrctl: process manager control
+ *   do_procstat: request process status  (Jorrit N. Herder)
  *   do_getsysinfo: request copy of PM data structure  (Jorrit N. Herder)
  *   do_getprocnr: lookup process slot number  (Jorrit N. Herder)
  *   do_allocmem: allocate a chunk of memory  (Jorrit N. Herder)
  *   do_freemem: deallocate a chunk of memory  (Jorrit N. Herder)
  *   do_getsetpriority: get/set process priority
+ *   do_svrctl: process manager control
  */
 
 #include "pm.h"
@@ -52,6 +53,27 @@ PUBLIC int do_freemem()
   return(OK);
 }
 
+/*===========================================================================*
+ *                             do_procstat                                  *
+ *===========================================================================*/
+PUBLIC int do_procstat()
+{ 
+  /* For the moment, this is only used to return pending signals to 
+   * system processes that request the PM for their own status. 
+   *
+   * Future use might include the FS requesting for process status of
+   * any user process. 
+   */
+  if (m_in.stat_nr == SELF) {
+      mp->mp_reply.sig_set = mp->mp_sigpending;
+      sigemptyset(&mp->mp_sigpending);
+  } 
+  else {
+      return(ENOSYS);
+  }
+  return(OK);
+}
+
 /*===========================================================================*
  *                             do_getsysinfo                                *
  *===========================================================================*/
@@ -147,52 +169,42 @@ PUBLIC int do_getprocnr()
 /*===========================================================================*
  *                             do_reboot                                    *
  *===========================================================================*/
-#define REBOOT_CODE    "delay; boot"
 PUBLIC int do_reboot()
 {
   char monitor_code[32*sizeof(char *)];                
-  int code_len;
+  vir_bytes code_addr;
+  int code_size;
   int abort_flag;
 
+  /* Check permission to abort the system. */
   if (mp->mp_effuid != SUPER_USER) return(EPERM);
 
-  switch (m_in.reboot_flag) {
-  case RBT_HALT:
-  case RBT_PANIC:
-  case RBT_RESET:
-       abort_flag = m_in.reboot_flag;
-       break;
-  case RBT_REBOOT:
-       code_len = strlen(REBOOT_CODE) + 1;
-       strncpy(monitor_code, REBOOT_CODE, code_len);        
-       abort_flag = RBT_MONITOR;
-       break;
-  case RBT_MONITOR:
-       code_len = m_in.reboot_strlen + 1;
-       if (code_len > sizeof(monitor_code)) return(EINVAL);
-       if (sys_datacopy(who_e, (vir_bytes) m_in.reboot_code,
-               PM_PROC_NR, (vir_bytes) monitor_code,
-               (phys_bytes) (code_len)) != OK) return(EFAULT);
-       if (monitor_code[code_len-1] != 0) return(EINVAL);
-       abort_flag = RBT_MONITOR;
-       break;
-  default:
-       return(EINVAL);
+  /* See how the system should be aborted. */
+  abort_flag = (unsigned) m_in.reboot_flag;
+  if (abort_flag >= RBT_INVALID) return(EINVAL); 
+  if (RBT_MONITOR == abort_flag) {
+       code_addr = (vir_bytes) m_in.reboot_code;
+       code_size = m_in.reboot_strlen + 1;
   }
 
   /* Order matters here. When FS is told to reboot, it exits all its
    * processes, and then would be confused if they're exited again by
-   * SIGKILL. So first kill, then reboot.
+   * SIGKILL. So first kill, then reboot. 
    */
 
-  check_sig(-1, SIGKILL);              /* kill all processes except init */
+  printf("check_sig(-1, SIGKILL) ...\n");
+  check_sig(-1, SIGKILL);              /* kill all users except init */
+  printf("stopping init with PRIO_STOP ...\n");
+  sys_nice(INIT_PROC_NR, PRIO_STOP);   /* stop init, but keep it around */
+  printf("tell_fs to sync() ...\n");
   tell_fs(REBOOT, 0, 0, 0);            /* tell FS to synchronize */
 
+  printf("sys_abort ...\n");
   /* Ask the kernel to abort. All system services, including the PM, will 
    * get a HARD_STOP notification. Await the notification in the main loop.
    */
-  sys_abort(abort_flag, PM_PROC_NR, monitor_code, code_len);
-  return(SUSPEND);                     /* don't reply to killed process */
+  sys_abort(abort_flag, who_e, code_addr, code_size);
+  return(SUSPEND);                     /* don't reply to caller */
 }
 
 /*===========================================================================*
index 68a9b940be41d2a21e4aa4c19839c71ae04ae0aa..08e902f823f39a7cc4a10edef7350cad272fbb1a 100644 (file)
@@ -21,6 +21,7 @@
 #define sig_nsa                m1_p1
 #define sig_osa                m1_p2
 #define sig_ret                m1_p3
+#define stat_nr                m2_i1
 #define sig_set                m2_l1
 #define sig_how                m2_i1
 #define sig_flags      m2_i2
index 6913e9d893f7de618c7aa093d92c612e5eb69720..7a93dbf41baa72274ea0c4aceacd2c1343d50c33 100644 (file)
@@ -57,6 +57,7 @@ _PROTOTYPE( int main, (void)                                          );
 
 /* misc.c */
 _PROTOTYPE( int do_reboot, (void)                                      );
+_PROTOTYPE( int do_procstat, (void)                                    );
 _PROTOTYPE( int do_getsysinfo, (void)                                  );
 _PROTOTYPE( int do_getprocnr, (void)                                   );
 _PROTOTYPE( int do_svrctl, (void)                                      );
index fb4342b4f1df23d3ef9d3da8063801293305a91c..fe971f1351a10f540499456e522758f9af9f36a4 100644 (file)
@@ -37,7 +37,7 @@
 
 FORWARD _PROTOTYPE( void dump_core, (struct mproc *rmp)                        );
 FORWARD _PROTOTYPE( void unpause, (int pro)                            );
-FORWARD _PROTOTYPE( void handle_sig, (int proc_nr, sigset_t sig_map)   );
+FORWARD _PROTOTYPE( void handle_ksig, (int proc_nr, sigset_t sig_map)  );
 FORWARD _PROTOTYPE( void cause_sigalrm, (struct timer *tp)             );
 
 /*===========================================================================*
@@ -228,7 +228,7 @@ PUBLIC int ksig_pending()
        int proc_nr_p;
        if(pm_isokendpt(proc_nr_e, &proc_nr_p) != OK)
                panic(__FILE__,"sys_getksig strange process", proc_nr_e);
-       handle_sig(proc_nr_e, sig_map); /* handle the received signal */
+       handle_ksig(proc_nr_e, sig_map);        /* handle the received signal */
        /* If the process still exists to the kernel after the signal
         * has been handled ...
         */
@@ -241,9 +241,9 @@ PUBLIC int ksig_pending()
 }
 
 /*===========================================================================*
- *                             handle_sig                                   *
+ *                             handle_ksig                                  *
  *===========================================================================*/
-PRIVATE void handle_sig(proc_nr_e, sig_map)
+PRIVATE void handle_ksig(proc_nr_e, sig_map)
 int proc_nr_e;
 sigset_t sig_map;
 {
@@ -489,8 +489,10 @@ int signo;                 /* signal to send to process (1 to _NSIG) */
        panic(__FILE__, "sys_sigsend failed", s);
   }
   else if (sigismember(&rmp->mp_sig2mess, signo)) {
-       if (OK != (s=sys_kill(rmp->mp_endpoint,signo)))
-               panic(__FILE__, "warning, sys_kill failed", s);
+
+       /* Mark event pending in process slot and send notification. */
+       sigaddset(&rmp->mp_sigpending, signo);
+       notify(rmp->mp_endpoint);
        return;
   }
 
@@ -536,8 +538,8 @@ int signo;                  /* signal to send to process (0 to _NSIG) */
   /* Return EINVAL for attempts to send SIGKILL to INIT alone. */
   if (proc_id == INIT_PID && signo == SIGKILL) return(EINVAL);
 
-  /* Search the proc table for processes to signal.  (See forkexit.c about
-   * pid magic.)
+  /* Search the proc table for processes to signal.  
+   * (See forkexit.c aboutpid magic.)
    */
   count = 0;
   error_code = ESRCH;
@@ -551,6 +553,10 @@ int signo;                 /* signal to send to process (0 to _NSIG) */
        if (proc_id == -1 && rmp->mp_pid <= INIT_PID) continue;
        if (proc_id < -1 && rmp->mp_procgrp != -proc_id) continue;
 
+       /* Do not kill servers and drivers when broadcasting SIGKILL. */
+       if (proc_id == -1 && signo == SIGKILL &&
+               (rmp->mp_flags & PRIV_PROC)) continue;
+
        /* Check for permission. */
        if (mp->mp_effuid != SUPER_USER
            && mp->mp_realuid != rmp->mp_realuid
index fb053a93278019838583b5d6569ac244c37598d6..d494f2bc4d2bd0db22da7be19bc190487ce5c288 100644 (file)
@@ -93,8 +93,7 @@ _PROTOTYPE (int (*call_vec[NCALLS]), (void) ) = {
        do_sigreturn,   /* 75 = sigreturn   */
        do_reboot,      /* 76 = reboot  */
        do_svrctl,      /* 77 = svrctl  */
-
-       no_sys,         /* 78 = unused */
+       do_procstat,    /* 78 = procstat */
        do_getsysinfo,  /* 79 = getsysinfo */
        do_getprocnr,   /* 80 = getprocnr */
        no_sys,         /* 81 = unused */
index c124251280c680b4b94172ae2d7d47dad4e4eb3a..3e03f861e868b024fc17836a381a11f1002af7eb 100644 (file)
@@ -111,8 +111,7 @@ int num;                    /* number to go with it */
 {
 /* An unrecoverable error has occurred.  Panics are caused when an internal
  * inconsistency is detected, e.g., a programming error or illegal value of a
- * defined constant. The process manager decides to shut down. This results 
- * in a HARD_STOP notification to all system processes to allow local cleanup.
+ * defined constant. The process manager decides to exit.
  */
   message m;
   int s;
@@ -122,16 +121,8 @@ int num;                   /* number to go with it */
   printf("PM panic (%s): %s", who, mess);
   if (num != NO_NUM) printf(": %d",num);
   printf("\n");
-
-#if 0
-  /* Allow for debug dumps if the IS server is available. */
-  m.m_type = PANIC_DUMPS;
-  if (OK == (s= nb_send(11, &m))) {
-      return;                          /* IS responsible for exit */
-  }
-  printf("Shutting down: IS is not answering: %d\n", s);
-  sys_abort(RBT_PANIC);
-#endif
+   
+  /* Exit PM. */
   sys_exit(SELF);
 }
 
index fd18226520de535526581888186e499fd31e7ffb..4ca580dfa9176752c72ba042c7680f9214d9a3b4 100644 (file)
@@ -15,6 +15,7 @@
 
 /* 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)                  );
 
@@ -66,11 +67,8 @@ PUBLIC int main(void)
           case SYN_ALARM:
              do_period(&m);                    /* check drivers status */
              continue;                         
-          case SYS_SIG:
-              sigset = (sigset_t) m.NOTIFY_ARG;        /* check signals passed */
-              if (sigismember(&sigset, SIGCHLD)) do_exit(&m);
-              if (sigismember(&sigset, SIGTERM)) do_shutdown(NULL);
-              if (sigismember(&sigset, SIGKSTOP)) do_shutdown(NULL);
+          case PROC_EVENT:
+             sig_handler();
               continue;                                
          default:                              /* heartbeat notification */
              if (rproc_ptr[who_p] != NULL)     /* mark heartbeat time */ 
@@ -120,8 +118,6 @@ PRIVATE void init_server(void)
   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);
-  if (sigaction(SIGABRT,&sa,NULL)<0) panic("RS","sigaction failed", errno);
-  if (sigaction(SIGHUP, &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.
@@ -158,6 +154,21 @@ PRIVATE void init_server(void)
 
 }
 
+/*===========================================================================*
+ *                             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                                     *