]> Zhao Yanbai Git Server - minix.git/commitdiff
Kernel: make SIGKMESS target process list dynamic 93/993/2
authorDavid van Moolenbroek <david@minix3.org>
Sat, 21 Sep 2013 13:03:20 +0000 (15:03 +0200)
committerLionel Sambuc <lionel@minix3.org>
Sat, 1 Mar 2014 08:04:54 +0000 (09:04 +0100)
The set of processes to which a SIGKMESS signal is sent whenever new
diagnostics messages are added to the kernel's message buffer, is now
no longer hardcoded. Instead, processes can (un)register themselves
to receive such notifications, by means of sys_diagctl().

Change-Id: I9d6ac006a5d9bbfad2757587a068fc1ec3cc083e

16 files changed:
drivers/log/log.c
drivers/tty/tty.c
include/minix/com.h
include/minix/config.h
include/minix/syslib.h
kernel/arch/earm/pre_init.c
kernel/arch/i386/pre_init.c
kernel/priv.h
kernel/proto.h
kernel/system.c
kernel/system/do_diagctl.c
kernel/system/do_privctl.c
kernel/system/do_update.c
kernel/utility.c
lib/libsys/kputc.c
lib/libsys/sys_diagctl.c

index 45b5e620dfaad0a7cc0e12afa627dec4ca6603c1..df267aec2a80d69b54308c321ac3392571a2ffd4 100644 (file)
@@ -99,6 +99,9 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
        logdevices[i].log_source = NONE;
   }
 
+  /* Register for diagnostics notifications. */
+  sys_diagctl_register();
+
   return(OK);
 }
 
index b0c910a6fc2768985d4453aa677ac9bb3a263b16..bdfdd142e4064eb2787e2de00da89cb7ca411621 100644 (file)
@@ -336,6 +336,9 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
   /* Final one-time keyboard initialization. */
   kb_init_once();
 
+  /* Register for diagnostics notifications. */
+  sys_diagctl_register();
+
   return(OK);
 }
 
index 8534feb7dfc40e84d8e94a0a6de6ade4296f7be1..3b659eeaec9c5b7fe2d0fd2616a7100eb7285a7e 100644 (file)
 #define DIAGCTL_ARG2           m1_i2
 #define DIAGCTL_CODE_DIAG      1       /* Print diagnostics. */
 #define DIAGCTL_CODE_STACKTRACE        2       /* Print process stack. */
+#define DIAGCTL_CODE_REGISTER  3       /* Register for diagnostic signals */
+#define DIAGCTL_CODE_UNREGISTER        4       /* Unregister for diagnostic signals */
 #define DIAG_BUFSIZE   (80*25)
 
 /* Field names for SYS_VTIMER. */
index 2ccdec4a0cc71639e2548ac53d11f0fe29eb07ce..926c64df64e1317eb5e04331b96e5ee56d536a56 100644 (file)
 /* DMA_SECTORS may be increased to speed up DMA based drivers. */
 #define DMA_SECTORS        1   /* DMA buffer size (must be >= 1) */
 
-/* Which processes should receive diagnostics from the kernel and system? 
- * Directly sending it to TTY only displays the output. Sending it to the
- * log driver will cause the diagnostics to be buffered and displayed.
- * Messages are sent by src/lib/sysutil/kputc.c to these processes, in
- * the order of this array, which must be terminated by NONE. This is used
- * by drivers and servers that printf().
- * The kernel does this for its own kprintf() in kernel/utility.c, also using
- * this array, but a slightly different mechanism.
- */
-#define OUTPUT_PROCS_ARRAY     { TTY_PROC_NR, LOG_PROC_NR, NONE }
-
 /* NR_CONS, NR_RS_LINES, and NR_PTYS determine the number of terminals the
  * system can handle.
  */
index dad15608070b43d25ec1fb89c95f696ba6371dcd..17b5812a162dc476aaed7a9efbde1de8efed4bc8 100644 (file)
@@ -69,8 +69,6 @@ int sys_vmctl_enable_paging(void * data);
 int sys_readbios(phys_bytes address, void *buf, size_t size);
 int sys_settime(int now, clockid_t clk_id, time_t sec, long nsec);
 int sys_stime(time_t boottime);
-int sys_diagctl(int ctl, char *arg1, int arg2);
-int sys_diagctl_stacktrace(endpoint_t who);
 int sys_vmctl_get_mapping(int index, phys_bytes *addr, phys_bytes *len,
        int *flags);
 int sys_vmctl_reply_mapping(int index, vir_bytes addr);
@@ -159,6 +157,17 @@ int sys_umap_data_fb(endpoint_t proc_ep, vir_bytes vir_addr, vir_bytes
 int sys_umap_remote(endpoint_t proc_ep, endpoint_t grantee, int seg,
        vir_bytes vir_addr, vir_bytes bytes, phys_bytes *phys_addr);
 
+/* Shorthands for sys_diagctl() system call. */
+#define sys_diagctl_diag(buf,len) \
+       sys_diagctl(DIAGCTL_CODE_DIAG, buf, len)
+#define sys_diagctl_stacktrace(ep) \
+       sys_diagctl(DIAGCTL_CODE_STACKTRACE, NULL, ep)
+#define sys_diagctl_register() \
+       sys_diagctl(DIAGCTL_CODE_REGISTER, NULL, 0)
+#define sys_diagctl_unregister() \
+       sys_diagctl(DIAGCTL_CODE_UNREGISTER, NULL, 0)
+int sys_diagctl(int ctl, char *arg1, int arg2);
+
 /* Shorthands for sys_getinfo() system call. */
 #define sys_getkinfo(dst)      sys_getinfo(GET_KINFO, dst, 0,0,0)
 #define sys_getloadinfo(dst)   sys_getinfo(GET_LOADINFO, dst, 0,0,0)
index 4bb133c4d8d4ab7851ec95600195f169f7b435fd..73947905dc46943c4f7217cdc8973a466f955494 100644 (file)
@@ -411,7 +411,7 @@ kinfo_t *pre_init(int argc, char **argv)
  * ensure this). The following methods are used in that context. Once we jump to kmain they are no
  * longer used and the "real" implementations are visible
  */
-int send_sig(endpoint_t proc_nr, int sig_nr) { return 0; }
+void send_diag_sig(void) { }
 void minix_shutdown(minix_timer_t *t) { arch_shutdown(RBT_PANIC); }
 void busy_delay_ms(int x) { }
 int raise(int n) { panic("raise(%d)\n", n); }
index 2a9967ac8f6533f8f53e08761f1fa8d446599177..165e6d57bb7c3ab1569e2a9661e44df41be44ce3 100644 (file)
@@ -245,7 +245,7 @@ kinfo_t *pre_init(u32_t magic, u32_t ebx)
        return &kinfo;
 }
 
-int send_sig(endpoint_t proc_nr, int sig_nr) { return 0; }
+void send_diag_sig(void) { }
 void minix_shutdown(minix_timer_t *t) { arch_shutdown(RBT_PANIC); }
 void busy_delay_ms(int x) { }
 int raise(int sig) { panic("raise(%d)\n", sig); }
index 204dacd468c3c61ef3819b5470ff855b230ecba0..0bdd009491f086daed6687f2638fcb1690d959c7 100644 (file)
@@ -45,6 +45,8 @@ struct priv {
   minix_timer_t s_alarm_timer; /* synchronous alarm timer */
   reg_t *s_stack_guard;                /* stack guard word for kernel tasks */
 
+  char s_diag_sig;             /* send a SIGKMESS when diagnostics arrive? */
+
   int s_nr_io_range;           /* allowed I/O ports */
   struct io_range s_io_tab[NR_IO_RANGE];
 
index ac2b5562547d7e9143b43775f81c13c72ed1baa8..8de351bc26fbdcf25ecf3bfb93b71f0ce0a0a68f 100644 (file)
@@ -91,6 +91,7 @@ void fill_sendto_mask(const struct proc *rc, sys_map_t *map);
 int send_sig(endpoint_t proc_nr, int sig_nr);
 void cause_sig(proc_nr_t proc_nr, int sig_nr);
 void sig_delay_done(struct proc *rp);
+void send_diag_sig(void);
 void kernel_call(message *m_user, struct proc * caller);
 void system_init(void);
 void clear_endpoint(struct proc *rc);
index 084d47760b0b5df2c074e90026d9c044ddee9763..a76d6af69185294ca7b0d86ea8fccf49d2d1926d 100644 (file)
@@ -18,6 +18,7 @@
  *   send_sig:         send a signal directly to a system process
  *   cause_sig:                take action to cause a signal to occur via a signal mgr
  *   sig_delay_done:   tell PM that a process is not sending
+ *   send_diag_sig:    send a diagnostics signal to interested processes
  *   get_randomness:   accumulate randomness in a buffer
  *   clear_endpoint:   remove a process' ability to send and receive messages
  *   sched_proc:       schedule a process
@@ -464,6 +465,25 @@ void sig_delay_done(struct proc *rp)
   cause_sig(proc_nr(rp), SIGSNDELAY);
 }
 
+/*===========================================================================*
+ *                             send_diag_sig                                *
+ *===========================================================================*/
+void send_diag_sig(void)
+{
+/* Send a SIGKMESS signal to all processes in receiving updates about new
+ * diagnostics messages.
+ */
+  struct priv *privp;
+  endpoint_t ep;
+
+  for (privp = BEG_PRIV_ADDR; privp < END_PRIV_ADDR; privp++) {
+       if (privp->s_proc_nr != NONE && privp->s_diag_sig == TRUE) {
+               ep = proc_addr(privp->s_proc_nr)->p_endpoint;
+               send_sig(ep, SIGKMESS);
+       }
+  }
+}
+
 /*===========================================================================*
  *                              clear_ipc                                   *
  *===========================================================================*/
index a75051b9dff92a24f30b6c3fdada61b1321137fa..788dddba36339ca34f36638c2d344c63b20393d6 100644 (file)
@@ -42,6 +42,21 @@ int do_diagctl(struct proc * caller, message * m_ptr)
                return EINVAL;
        proc_stacktrace(proc_addr(proc_nr));
        return OK;
+    case DIAGCTL_CODE_REGISTER:
+       if (!(priv(caller)->s_flags & SYS_PROC))
+               return EPERM;
+       priv(caller)->s_diag_sig = TRUE;
+       /* If the message log is not empty, send a first notification
+        * immediately. After bootup the log is basically never empty.
+        */
+       if (kmess.km_size > 0 && !kinfo.do_serial_debug)
+               send_sig(caller->p_endpoint, SIGKMESS);
+       return OK;
+    case DIAGCTL_CODE_UNREGISTER:
+       if (!(priv(caller)->s_flags & SYS_PROC))
+               return EPERM;
+       priv(caller)->s_diag_sig = FALSE;
+       return OK;
     default:
        printf("do_diagctl: invalid request %d\n", m_ptr->DIAGCTL_CODE);
         return(EINVAL);
index 2d3cb15b56427b8eb983469be205ece8e200f8ad..8b7dba019a583c9f6c0b2dc8f9919fe65547eabc 100644 (file)
@@ -116,6 +116,7 @@ int do_privctl(struct proc * caller, message * m_ptr)
        reset_kernel_timer(&priv(rp)->s_alarm_timer);   /* - alarm */
        priv(rp)->s_asyntab= -1;                        /* - asynsends */
        priv(rp)->s_asynsize= 0;
+       priv(rp)->s_diag_sig = FALSE;           /* no request for diag sigs */
 
        /* Set defaults for privilege bitmaps. */
        priv(rp)->s_flags= DSRV_F;           /* privilege flags */
index 38341b32a400451261b8df91bc49c11e0db93be4..d0f7ceb9083e5b514fc21cf0fdd99e1682d03858 100644 (file)
@@ -161,6 +161,7 @@ static void adjust_priv_slot(struct priv *privp, struct priv *from_privp)
   privp->s_int_pending = from_privp->s_int_pending;
   privp->s_sig_pending = from_privp->s_sig_pending;
   privp->s_alarm_timer = from_privp->s_alarm_timer;
+  privp->s_diag_sig = from_privp->s_diag_sig;
 }
 
 /*===========================================================================*
index f112ee07a33faab6c9d28b1e21fac3f9a4203c83..d5fdbdb02998cafd97de0d73e3fa7025579b2b92 100644 (file)
@@ -55,7 +55,7 @@ void kputc(c)
 int c;                                 /* character to append */
 {
 /* Accumulate a single character for a kernel message. Send a notification
- * to the output driver if an END_OF_KMESS is encountered. 
+ * to the output drivers if an END_OF_KMESS is encountered.
  */
   if (c != END_OF_KMESS) {
       int maxblpos = sizeof(kmess.kmess_buf) - 2;
@@ -75,18 +75,9 @@ int c;                                       /* character to append */
        memmove(kmess.kmess_buf,
                kmess.kmess_buf+1, sizeof(kmess.kmess_buf)-1);
       } else kmess.blpos++;
-  } else {
-      int p;
-      endpoint_t outprocs[] = OUTPUT_PROCS_ARRAY;
-      if(!(kinfo.minix_panicing || kinfo.do_serial_debug)) {
-             for(p = 0; outprocs[p] != NONE; p++) {
-                if(isokprocn(outprocs[p])) {
-                   send_sig(outprocs[p], SIGKMESS);
-                }
-       }
-     }
+  } else if (!(kinfo.minix_panicing || kinfo.do_serial_debug)) {
+       send_diag_sig();
   }
-  return;
 }
 
 /*===========================================================================*
index 5e3fbbf402bba8c3fb69c8e16054b4ada342f710..7a2106dcc8b16a1898dd11bb87538fa779dd4c38 100644 (file)
@@ -20,7 +20,7 @@ void kputc(int c)
   static int buf_count;                /* # characters in the buffer */
 
   if ((c == 0 && buf_count > 0) || buf_count == sizeof(print_buf)) {
-       sys_diagctl(DIAGCTL_CODE_DIAG, print_buf, buf_count);
+       sys_diagctl_diag(print_buf, buf_count);
        buf_count = 0;
   }
   if (c != 0) { 
index a74777c491f69e747b2b14ee5c70dc12e5cf83a9..bf7ca5d8ce28972f6c805dcf7da6779bde068204 100644 (file)
@@ -11,9 +11,3 @@ int sys_diagctl(int code, char *arg1, int arg2)
 
   return(_kernel_call(SYS_DIAGCTL, &m));
 }
-
-int sys_diagctl_stacktrace(endpoint_t ep)
-{
-  return sys_diagctl(DIAGCTL_CODE_STACKTRACE, NULL, ep);
-}
-